Support user destinations with multiple app servers
This change adds support for broadcasting messages with unresolved user destinations so that other servers can try to resolve it. That enables sending messages to users who may be connected to a different server. Issue: SPR-11620
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -79,8 +79,11 @@ import static org.mockito.Mockito.*;
|
||||
public class MessageBrokerConfigurationTests {
|
||||
|
||||
private ApplicationContext defaultContext = new AnnotationConfigApplicationContext(DefaultConfig.class);
|
||||
|
||||
private ApplicationContext simpleBrokerContext = new AnnotationConfigApplicationContext(SimpleBrokerConfig.class);
|
||||
|
||||
private ApplicationContext brokerRelayContext = new AnnotationConfigApplicationContext(BrokerRelayConfig.class);
|
||||
|
||||
private ApplicationContext customContext = new AnnotationConfigApplicationContext(CustomConfig.class);
|
||||
|
||||
|
||||
@@ -401,7 +404,17 @@ public class MessageBrokerConfigurationTests {
|
||||
assertEquals("a.a", handler.getPathMatcher().combine("a", "a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userDestinationBroadcast() throws Exception {
|
||||
StompBrokerRelayMessageHandler relay = this.brokerRelayContext.getBean(StompBrokerRelayMessageHandler.class);
|
||||
UserDestinationMessageHandler userHandler = this.brokerRelayContext.getBean(UserDestinationMessageHandler.class);
|
||||
assertEquals("/topic/unresolved", userHandler.getUserDestinationBroadcast());
|
||||
assertNotNull(relay.getSystemSubscriptions());
|
||||
assertSame(userHandler, relay.getSystemSubscriptions().get("/topic/unresolved"));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Controller
|
||||
static class TestController {
|
||||
|
||||
@@ -417,7 +430,7 @@ public class MessageBrokerConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Configuration
|
||||
static class SimpleBrokerConfig extends AbstractMessageBrokerConfiguration {
|
||||
|
||||
@@ -451,6 +464,7 @@ public class MessageBrokerConfigurationTests {
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableStompBrokerRelay("/topic", "/queue").setAutoStartup(true);
|
||||
registry.setUserDestinationBroadcast("/topic/unresolved");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,22 @@
|
||||
*/
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.StubMessageChannel;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
@@ -37,8 +44,6 @@ import org.springframework.messaging.tcp.TcpOperations;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.util.concurrent.ListenableFutureTask;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for StompBrokerRelayMessageHandler.
|
||||
*
|
||||
@@ -74,62 +79,52 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testVirtualHostHeader() throws Exception {
|
||||
public void virtualHost() throws Exception {
|
||||
|
||||
this.brokerRelay.setVirtualHost("ABC");
|
||||
|
||||
String virtualHost = "ABC";
|
||||
this.brokerRelay.setVirtualHost(virtualHost);
|
||||
this.brokerRelay.start();
|
||||
this.brokerRelay.handleMessage(connectMessage("sess1", "joe"));
|
||||
|
||||
String sessionId = "sess1";
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
assertEquals(2, this.tcpClient.getSentMessages().size());
|
||||
|
||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||
assertEquals(2, sent.size());
|
||||
StompHeaderAccessor headers1 = this.tcpClient.getSentHeaders(0);
|
||||
assertEquals(StompCommand.CONNECT, headers1.getCommand());
|
||||
assertEquals(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID, headers1.getSessionId());
|
||||
assertEquals("ABC", headers1.getHost());
|
||||
|
||||
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));
|
||||
StompHeaderAccessor headers2 = this.tcpClient.getSentHeaders(1);
|
||||
assertEquals(StompCommand.CONNECT, headers2.getCommand());
|
||||
assertEquals("sess1", headers2.getSessionId());
|
||||
assertEquals("ABC", headers2.getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoginPasscode() throws Exception {
|
||||
|
||||
this.brokerRelay.setClientLogin("clientlogin");
|
||||
this.brokerRelay.setClientPasscode("clientpasscode");
|
||||
public void loginAndPasscode() throws Exception {
|
||||
|
||||
this.brokerRelay.setSystemLogin("syslogin");
|
||||
this.brokerRelay.setSystemPasscode("syspasscode");
|
||||
this.brokerRelay.setClientLogin("clientlogin");
|
||||
this.brokerRelay.setClientPasscode("clientpasscode");
|
||||
|
||||
this.brokerRelay.start();
|
||||
this.brokerRelay.handleMessage(connectMessage("sess1", "joe"));
|
||||
|
||||
String sessionId = "sess1";
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
assertEquals(2, this.tcpClient.getSentMessages().size());
|
||||
|
||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||
assertEquals(2, sent.size());
|
||||
|
||||
StompHeaderAccessor headers1 = StompHeaderAccessor.wrap(sent.get(0));
|
||||
StompHeaderAccessor headers1 = this.tcpClient.getSentHeaders(0);
|
||||
assertEquals(StompCommand.CONNECT, headers1.getCommand());
|
||||
assertEquals("syslogin", headers1.getLogin());
|
||||
assertEquals("syspasscode", headers1.getPasscode());
|
||||
|
||||
StompHeaderAccessor headers2 = StompHeaderAccessor.wrap(sent.get(1));
|
||||
StompHeaderAccessor headers2 = this.tcpClient.getSentHeaders(1);
|
||||
assertEquals(StompCommand.CONNECT, headers2.getCommand());
|
||||
assertEquals("clientlogin", headers2.getLogin());
|
||||
assertEquals("clientpasscode", headers2.getPasscode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestinationExcluded() throws Exception {
|
||||
public void destinationExcluded() throws Exception {
|
||||
|
||||
this.brokerRelay.start();
|
||||
|
||||
@@ -138,89 +133,113 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||
headers.setDestination("/user/daisy/foo");
|
||||
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));
|
||||
assertEquals(1, this.tcpClient.getSentMessages().size());
|
||||
StompHeaderAccessor headers1 = this.tcpClient.getSentHeaders(0);
|
||||
assertEquals(StompCommand.CONNECT, headers1.getCommand());
|
||||
assertEquals(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID, headers1.getSessionId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOutboundMessageIsEnriched() throws Exception {
|
||||
public void messageFromBrokerIsEnriched() throws Exception {
|
||||
|
||||
this.brokerRelay.start();
|
||||
this.brokerRelay.handleMessage(connectMessage("sess1", "joe"));
|
||||
|
||||
String sessionId = "sess1";
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
headers.setUser(new TestPrincipal("joe"));
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
assertEquals(2, this.tcpClient.getSentMessages().size());
|
||||
assertEquals(StompCommand.CONNECT, this.tcpClient.getSentHeaders(0).getCommand());
|
||||
assertEquals(StompCommand.CONNECT, this.tcpClient.getSentHeaders(1).getCommand());
|
||||
|
||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||
assertEquals(2, sent.size());
|
||||
this.tcpClient.handleMessage(message(StompCommand.MESSAGE, null, null, null));
|
||||
|
||||
StompHeaderAccessor responseHeaders = StompHeaderAccessor.create(StompCommand.MESSAGE);
|
||||
responseHeaders.setLeaveMutable(true);
|
||||
Message<byte[]> response = MessageBuilder.createMessage(new byte[0], responseHeaders.getMessageHeaders());
|
||||
this.tcpClient.connectionHandler.handleMessage(response);
|
||||
|
||||
Message<byte[]> actual = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor actualHeaders = StompHeaderAccessor.getAccessor(actual, StompHeaderAccessor.class);
|
||||
assertEquals(sessionId, actualHeaders.getSessionId());
|
||||
assertEquals("joe", actualHeaders.getUser().getName());
|
||||
Message<byte[]> message = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
assertEquals("sess1", accessor.getSessionId());
|
||||
assertEquals("joe", accessor.getUser().getName());
|
||||
}
|
||||
|
||||
// SPR-12820
|
||||
|
||||
@Test
|
||||
public void testConnectWhenBrokerNotAvailable() throws Exception {
|
||||
public void connectWhenBrokerNotAvailable() throws Exception {
|
||||
|
||||
this.brokerRelay.start();
|
||||
this.brokerRelay.stopInternal();
|
||||
this.brokerRelay.handleMessage(connectMessage("sess1", "joe"));
|
||||
|
||||
String sessionId = "sess1";
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
headers.setUser(new TestPrincipal("joe"));
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
|
||||
Message<byte[]> actual = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor actualHeaders = StompHeaderAccessor.getAccessor(actual, StompHeaderAccessor.class);
|
||||
assertEquals(StompCommand.ERROR, actualHeaders.getCommand());
|
||||
assertEquals(sessionId, actualHeaders.getSessionId());
|
||||
assertEquals("joe", actualHeaders.getUser().getName());
|
||||
assertEquals("Broker not available.", actualHeaders.getMessage());
|
||||
Message<byte[]> message = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
assertEquals(StompCommand.ERROR, accessor.getCommand());
|
||||
assertEquals("sess1", accessor.getSessionId());
|
||||
assertEquals("joe", accessor.getUser().getName());
|
||||
assertEquals("Broker not available.", accessor.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAfterBrokerUnavailable() throws Exception {
|
||||
public void sendAfterBrokerUnavailable() throws Exception {
|
||||
|
||||
this.brokerRelay.start();
|
||||
assertEquals(1, this.brokerRelay.getConnectionCount());
|
||||
|
||||
String sessionId = "sess1";
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
headers.setUser(new TestPrincipal("joe"));
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
|
||||
this.brokerRelay.handleMessage(connectMessage("sess1", "joe"));
|
||||
assertEquals(2, this.brokerRelay.getConnectionCount());
|
||||
|
||||
this.brokerRelay.stopInternal();
|
||||
|
||||
headers = StompHeaderAccessor.create(StompCommand.SEND);
|
||||
headers.setSessionId(sessionId);
|
||||
headers.setUser(new TestPrincipal("joe"));
|
||||
headers.setDestination("/foo");
|
||||
this.brokerRelay.handleMessage(MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()));
|
||||
|
||||
this.brokerRelay.handleMessage(message(StompCommand.SEND, "sess1", "joe", "/foo"));
|
||||
assertEquals(1, this.brokerRelay.getConnectionCount());
|
||||
|
||||
Message<byte[]> actual = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor actualHeaders = StompHeaderAccessor.getAccessor(actual, StompHeaderAccessor.class);
|
||||
assertEquals(StompCommand.ERROR, actualHeaders.getCommand());
|
||||
assertEquals(sessionId, actualHeaders.getSessionId());
|
||||
assertEquals("joe", actualHeaders.getUser().getName());
|
||||
assertEquals("Broker not available.", actualHeaders.getMessage());
|
||||
Message<byte[]> message = this.outboundChannel.getMessages().get(0);
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
assertEquals(StompCommand.ERROR, accessor.getCommand());
|
||||
assertEquals("sess1", accessor.getSessionId());
|
||||
assertEquals("joe", accessor.getUser().getName());
|
||||
assertEquals("Broker not available.", accessor.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemSubscription() throws Exception {
|
||||
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
this.brokerRelay.setSystemSubscriptions(Collections.singletonMap("/topic/foo", handler));
|
||||
this.brokerRelay.start();
|
||||
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECTED);
|
||||
accessor.setLeaveMutable(true);
|
||||
MessageHeaders headers = accessor.getMessageHeaders();
|
||||
this.tcpClient.handleMessage(MessageBuilder.createMessage(new byte[0], headers));
|
||||
|
||||
assertEquals(2, this.tcpClient.getSentMessages().size());
|
||||
assertEquals(StompCommand.CONNECT, this.tcpClient.getSentHeaders(0).getCommand());
|
||||
assertEquals(StompCommand.SUBSCRIBE, this.tcpClient.getSentHeaders(1).getCommand());
|
||||
assertEquals("/topic/foo", this.tcpClient.getSentHeaders(1).getDestination());
|
||||
|
||||
Message<byte[]> message = message(StompCommand.MESSAGE, null, null, "/topic/foo");
|
||||
this.tcpClient.handleMessage(message);
|
||||
|
||||
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
|
||||
verify(handler).handleMessage(captor.capture());
|
||||
assertSame(message, captor.getValue());
|
||||
}
|
||||
|
||||
private Message<byte[]> connectMessage(String sessionId, String user) {
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||
headers.setSessionId(sessionId);
|
||||
headers.setUser(new TestPrincipal(user));
|
||||
return MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders());
|
||||
}
|
||||
|
||||
private Message<byte[]> message(StompCommand command, String sessionId, String user, String destination) {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(command);
|
||||
if (sessionId != null) {
|
||||
accessor.setSessionId(sessionId);
|
||||
}
|
||||
if (user != null) {
|
||||
accessor.setUser(new TestPrincipal(user));
|
||||
}
|
||||
if (destination != null) {
|
||||
accessor.setDestination(destination);
|
||||
}
|
||||
accessor.setLeaveMutable(true);
|
||||
return MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
|
||||
}
|
||||
|
||||
|
||||
@@ -254,17 +273,29 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||
private TcpConnectionHandler<byte[]> connectionHandler;
|
||||
|
||||
|
||||
public List<Message<byte[]>> getSentMessages() {
|
||||
return this.connection.getMessages();
|
||||
}
|
||||
|
||||
public StompHeaderAccessor getSentHeaders(int index) {
|
||||
assertTrue("Size: " + getSentMessages().size(), getSentMessages().size() > index);
|
||||
Message<byte[]> message = getSentMessages().get(index);
|
||||
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
assertNotNull(accessor);
|
||||
return accessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> connectionHandler) {
|
||||
this.connectionHandler = connectionHandler;
|
||||
connectionHandler.afterConnected(this.connection);
|
||||
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> handler) {
|
||||
this.connectionHandler = handler;
|
||||
handler.afterConnected(this.connection);
|
||||
return getVoidFuture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> connectionHandler, ReconnectStrategy reconnectStrategy) {
|
||||
this.connectionHandler = connectionHandler;
|
||||
connectionHandler.afterConnected(this.connection);
|
||||
public ListenableFuture<Void> connect(TcpConnectionHandler<byte[]> handler, ReconnectStrategy strategy) {
|
||||
this.connectionHandler = handler;
|
||||
handler.afterConnected(this.connection);
|
||||
return getVoidFuture();
|
||||
}
|
||||
|
||||
@@ -272,6 +303,11 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||
public ListenableFuture<Boolean> shutdown() {
|
||||
return getBooleanFuture();
|
||||
}
|
||||
|
||||
public void handleMessage(Message<byte[]> message) {
|
||||
this.connectionHandler.handleMessage(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +316,10 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||
private final List<Message<byte[]>> messages = new ArrayList<>();
|
||||
|
||||
|
||||
public List<Message<byte[]>> getMessages() {
|
||||
return this.messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<Void> send(Message<byte[]> message) {
|
||||
this.messages.add(message);
|
||||
|
||||
@@ -18,7 +18,9 @@ package org.springframework.messaging.simp.user;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.springframework.messaging.simp.SimpMessageHeaderAccessor.ORIGINAL_DESTINATION;
|
||||
import static org.springframework.messaging.simp.SimpMessageHeaderAccessor.*;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -33,6 +35,8 @@ import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.messaging.simp.TestPrincipal;
|
||||
import org.springframework.messaging.simp.stomp.StompCommand;
|
||||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
@@ -62,7 +66,6 @@ public class UserDestinationMessageHandlerTests {
|
||||
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void handleSubscribe() {
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
this.handler.handleMessage(createWith(SimpMessageType.SUBSCRIBE, "joe", SESSION_ID, "/user/queue/foo"));
|
||||
@@ -75,7 +78,6 @@ public class UserDestinationMessageHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void handleUnsubscribe() {
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
this.handler.handleMessage(createWith(SimpMessageType.UNSUBSCRIBE, "joe", "123", "/user/queue/foo"));
|
||||
@@ -88,7 +90,6 @@ public class UserDestinationMessageHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void handleMessage() {
|
||||
this.registry.registerSessionId("joe", "123");
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
@@ -102,6 +103,69 @@ public class UserDestinationMessageHandlerTests {
|
||||
assertEquals("/user/queue/foo", accessor.getFirstNativeHeader(ORIGINAL_DESTINATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageWithoutActiveSession() {
|
||||
this.handler.setUserDestinationBroadcast("/topic/unresolved");
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
this.handler.handleMessage(createWith(SimpMessageType.MESSAGE, "joe", "123", "/user/joe/queue/foo"));
|
||||
|
||||
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
|
||||
Mockito.verify(this.brokerChannel).send(captor.capture());
|
||||
|
||||
Message message = captor.getValue();
|
||||
SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.wrap(message);
|
||||
assertEquals("/topic/unresolved", accessor.getDestination());
|
||||
assertEquals("/user/joe/queue/foo", accessor.getFirstNativeHeader(ORIGINAL_DESTINATION));
|
||||
|
||||
// Should ignore our own broadcast to brokerChannel
|
||||
|
||||
this.handler.handleMessage(message);
|
||||
Mockito.verifyNoMoreInteractions(this.brokerChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromBrokerWithActiveSession() {
|
||||
|
||||
this.registry.registerSessionId("joe", "123");
|
||||
|
||||
this.handler.setUserDestinationBroadcast("/topic/unresolved");
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE);
|
||||
accessor.setSessionId("system123");
|
||||
accessor.setDestination("/topic/unresolved");
|
||||
accessor.setNativeHeader(ORIGINAL_DESTINATION, "/user/joe/queue/foo");
|
||||
accessor.setNativeHeader("customHeader", "customHeaderValue");
|
||||
accessor.setLeaveMutable(true);
|
||||
byte[] payload = "payload".getBytes(Charset.forName("UTF-8"));
|
||||
this.handler.handleMessage(MessageBuilder.createMessage(payload, accessor.getMessageHeaders()));
|
||||
|
||||
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
|
||||
Mockito.verify(this.brokerChannel).send(captor.capture());
|
||||
assertNotNull(captor.getValue());
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(captor.getValue());
|
||||
assertEquals("/queue/foo-user123", headers.getDestination());
|
||||
assertEquals("/user/queue/foo", headers.getFirstNativeHeader(ORIGINAL_DESTINATION));
|
||||
assertEquals("customHeaderValue", headers.getFirstNativeHeader("customHeader"));
|
||||
assertArrayEquals(payload, (byte[]) captor.getValue().getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMessageFromBrokerWithoutActiveSession() {
|
||||
this.handler.setUserDestinationBroadcast("/topic/unresolved");
|
||||
given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
|
||||
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE);
|
||||
accessor.setSessionId("system123");
|
||||
accessor.setDestination("/topic/unresolved");
|
||||
accessor.setNativeHeader(ORIGINAL_DESTINATION, "/user/joe/queue/foo");
|
||||
accessor.setLeaveMutable(true);
|
||||
byte[] payload = "payload".getBytes(Charset.forName("UTF-8"));
|
||||
this.handler.handleMessage(MessageBuilder.createMessage(payload, accessor.getMessageHeaders()));
|
||||
|
||||
// No re-broadcast
|
||||
verifyNoMoreInteractions(this.brokerChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreMessage() {
|
||||
|
||||
Reference in New Issue
Block a user