@Override protected boolean matchInternal(StompHeaderAccessor headers, Object payload) { if (!this.subscriptionId.equals(headers.getSubscriptionId()) || !this.destination.equals(headers.getDestination())) { return false; } if (payload instanceof byte[] && this.payload instanceof byte[]) { return Arrays.equals((byte[]) payload, (byte[]) this.payload); } else { return this.payload.equals(payload); } }
@Override protected void handleInboundMessage(Message<?> message) { StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); if (accessor != null && StompCommand.MESSAGE.equals(accessor.getCommand())) { String destination = accessor.getDestination(); if (destination == null) { if (logger.isDebugEnabled()) { logger.debug("Got message on \"system\" connection, with no destination: " + accessor.getDetailedLogMessage(message.getPayload())); } return; } if (!getSystemSubscriptions().containsKey(destination)) { if (logger.isDebugEnabled()) { logger.debug("Got message on \"system\" connection with no handler: " + accessor.getDetailedLogMessage(message.getPayload())); } return; } try { MessageHandler handler = getSystemSubscriptions().get(destination); handler.handleMessage(message); } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Error while handling message on \"system\" connection.", ex); } } } }
public MessageExchangeBuilder andExpectMessage(String sessionId, String subscriptionId) { Assert.state(SimpMessageType.MESSAGE.equals(this.headers.getMessageType()), "MESSAGE type expected"); String destination = this.headers.getDestination(); Object payload = this.message.getPayload(); this.expected.add(new StompMessageFrameMessageMatcher(sessionId, subscriptionId, destination, payload)); return this; }
void updateStompHeadersFromSimpMessageHeaders() { String destination = getDestination(); if (destination != null) { setNativeHeader(STOMP_DESTINATION_HEADER, destination); } MimeType contentType = getContentType(); if (contentType != null) { setNativeHeader(STOMP_CONTENT_TYPE_HEADER, contentType.toString()); } trySetStompHeaderForSubscriptionId(); }
@Test public void decodeFrame() throws UnsupportedEncodingException { Message<byte[]> frame = decode("SEND\ndestination:test\n\nThe body of the message\0"); StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame); assertEquals(StompCommand.SEND, headers.getCommand()); assertEquals(headers.toNativeHeaderMap().toString(), 1, headers.toNativeHeaderMap().size()); assertEquals("test", headers.getDestination()); String bodyText = new String(frame.getPayload()); assertEquals("The body of the message", bodyText); }
@Test public void createWithSubscribeNativeHeaders() { MultiValueMap<String, String> extHeaders = new LinkedMultiValueMap<>(); extHeaders.add(StompHeaderAccessor.STOMP_ID_HEADER, "s1"); extHeaders.add(StompHeaderAccessor.STOMP_DESTINATION_HEADER, "/d"); StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE, extHeaders); assertEquals(StompCommand.SUBSCRIBE, headers.getCommand()); assertEquals(SimpMessageType.SUBSCRIBE, headers.getMessageType()); assertEquals("/d", headers.getDestination()); assertEquals("s1", headers.getSubscriptionId()); }
String destination = stompAccessor.getDestination(); if (command != null && command.requiresDestination() && !checkDestinationPrefix(destination)) { return;
@Override public String getShortLogMessage(Object payload) { StompCommand command = getCommand(); if (StompCommand.SUBSCRIBE.equals(command)) { return "SUBSCRIBE " + getDestination() + " id=" + getSubscriptionId() + appendSession(); } else if (StompCommand.UNSUBSCRIBE.equals(command)) { return "UNSUBSCRIBE id=" + getSubscriptionId() + appendSession(); } else if (StompCommand.SEND.equals(command)) { return "SEND " + getDestination() + appendSession() + appendPayload(payload); } else if (StompCommand.CONNECT.equals(command)) { Principal user = getUser(); return "CONNECT" + (user != null ? " user=" + user.getName() : "") + appendSession(); } else if (StompCommand.CONNECTED.equals(command)) { return "CONNECTED heart-beat=" + Arrays.toString(getHeartbeat()) + appendSession(); } else if (StompCommand.DISCONNECT.equals(command)) { String receipt = getReceipt(); return "DISCONNECT" + (receipt != null ? " receipt=" + receipt : "") + appendSession(); } else { return getDetailedLogMessage(payload); } }
@Test public void doSendWithStompHeaders() { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); accessor.setDestination("/user/queue/foo"); Message<?> message = MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders()); this.messagingTemplate.doSend("/queue/foo-user123", message); List<Message<byte[]>> messages = this.messageChannel.getMessages(); Message<byte[]> sentMessage = messages.get(0); MessageHeaderAccessor sentAccessor = MessageHeaderAccessor.getAccessor(sentMessage, MessageHeaderAccessor.class); assertEquals(StompHeaderAccessor.class, sentAccessor.getClass()); assertEquals("/queue/foo-user123", ((StompHeaderAccessor) sentAccessor).getDestination()); }
@Test public void brokerChannelUsedByAnnotatedMethod() { ApplicationContext context = loadConfig(SimpleBrokerConfig.class); TestChannel channel = context.getBean("brokerChannel", TestChannel.class); SimpAnnotationMethodMessageHandler messageHandler = context.getBean(SimpAnnotationMethodMessageHandler.class); StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SEND); headers.setSessionId("sess1"); headers.setSessionAttributes(new ConcurrentHashMap<>()); headers.setDestination("/foo"); Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()); messageHandler.handleMessage(message); message = channel.messages.get(0); headers = StompHeaderAccessor.wrap(message); assertEquals(SimpMessageType.MESSAGE, headers.getMessageType()); assertEquals("/bar", headers.getDestination()); assertEquals("bar", new String((byte[]) message.getPayload())); }
@Test public void clientOutboundChannelUsedByAnnotatedMethod() { ApplicationContext context = loadConfig(SimpleBrokerConfig.class); TestChannel channel = context.getBean("clientOutboundChannel", TestChannel.class); SimpAnnotationMethodMessageHandler messageHandler = context.getBean(SimpAnnotationMethodMessageHandler.class); StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSessionId("sess1"); headers.setSessionAttributes(new ConcurrentHashMap<>()); headers.setSubscriptionId("subs1"); headers.setDestination("/foo"); Message<?> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build(); messageHandler.handleMessage(message); message = channel.messages.get(0); headers = StompHeaderAccessor.wrap(message); assertEquals(SimpMessageType.MESSAGE, headers.getMessageType()); assertEquals("/foo", headers.getDestination()); assertEquals("bar", new String((byte[]) message.getPayload())); }
assertEquals(expectLeadingSlash ? "/queue.q1-usersess1" : "queue.q1-usersess1", headers.getDestination()); assertEquals("123", new String((byte[]) outputMessage.getPayload())); outChannel.messages.clear(); assertEquals(expectLeadingSlash ? "/queue.q1-usersess1" : "queue.q1-usersess1", headers.getDestination()); assertEquals("456", new String((byte[]) outputMessage.getPayload()));
@Test public void clientInboundChannelSendMessage() throws Exception { ApplicationContext config = createConfig(TestChannelConfig.class, TestConfigurer.class); TestChannel channel = config.getBean("clientInboundChannel", TestChannel.class); SubProtocolWebSocketHandler webSocketHandler = config.getBean(SubProtocolWebSocketHandler.class); List<ChannelInterceptor> interceptors = channel.getInterceptors(); assertEquals(ImmutableMessageChannelInterceptor.class, interceptors.get(interceptors.size()-1).getClass()); TestWebSocketSession session = new TestWebSocketSession("s1"); session.setOpen(true); webSocketHandler.afterConnectionEstablished(session); webSocketHandler.handleMessage(session, StompTextMessageBuilder.create(StompCommand.SEND).headers("destination:/foo").build()); Message<?> message = channel.messages.get(0); StompHeaderAccessor accessor = StompHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); assertNotNull(accessor); assertFalse(accessor.isMutable()); assertEquals(SimpMessageType.MESSAGE, accessor.getMessageType()); assertEquals("/foo", accessor.getDestination()); }
@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()); }
@Test public void clientOutboundChannelUsedBySimpleBroker() { ApplicationContext context = loadConfig(SimpleBrokerConfig.class); TestChannel outboundChannel = context.getBean("clientOutboundChannel", TestChannel.class); SimpleBrokerMessageHandler broker = context.getBean(SimpleBrokerMessageHandler.class); StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSessionId("sess1"); headers.setSubscriptionId("subs1"); headers.setDestination("/foo"); Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()); // subscribe broker.handleMessage(createConnectMessage("sess1", new long[] {0,0})); broker.handleMessage(message); headers = StompHeaderAccessor.create(StompCommand.SEND); headers.setSessionId("sess1"); headers.setDestination("/foo"); message = MessageBuilder.createMessage("bar".getBytes(), headers.getMessageHeaders()); // message broker.handleMessage(message); message = outboundChannel.messages.get(1); headers = StompHeaderAccessor.wrap(message); assertEquals(SimpMessageType.MESSAGE, headers.getMessageType()); assertEquals("/foo", headers.getDestination()); assertEquals("bar", new String((byte[]) message.getPayload())); }
void updateStompHeadersFromSimpMessageHeaders() { String destination = getDestination(); if (destination != null) { setNativeHeader(STOMP_DESTINATION_HEADER, destination); } MimeType contentType = getContentType(); if (contentType != null) { setNativeHeader(STOMP_CONTENT_TYPE_HEADER, contentType.toString()); } trySetStompHeaderForSubscriptionId(); }
@Override public String getShortLogMessage(Object payload) { StompCommand command = getCommand(); if (StompCommand.SUBSCRIBE.equals(command)) { return "SUBSCRIBE " + getDestination() + " id=" + getSubscriptionId() + appendSession(); } else if (StompCommand.UNSUBSCRIBE.equals(command)) { return "UNSUBSCRIBE id=" + getSubscriptionId() + appendSession(); } else if (StompCommand.SEND.equals(command)) { return "SEND " + getDestination() + appendSession() + appendPayload(payload); } else if (StompCommand.CONNECT.equals(command)) { Principal user = getUser(); return "CONNECT" + (user != null ? " user=" + user.getName() : "") + appendSession(); } else if (StompCommand.CONNECTED.equals(command)) { return "CONNECTED heart-beat=" + Arrays.toString(getHeartbeat()) + appendSession(); } else if (StompCommand.DISCONNECT.equals(command)) { String receipt = getReceipt(); return "DISCONNECT" + (receipt != null ? " receipt=" + receipt : "") + appendSession(); } else { return getDetailedLogMessage(payload); } }
@Test public void sendSubscribeToControllerAndReceiveReply() { String destHeader = "/app/number"; StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSubscriptionId("subs1"); headers.setDestination(destHeader); Message<byte[]> message = MessageBuilder.withPayload(ByteBuffer.allocate(0).array()) .setHeaders(headers) .build(); this.webSocketOutputChannel.send(message); Message<?> receive = webSocketInputChannel.receive(20000); assertNotNull(receive); StompHeaderAccessor stompHeaderAccessor = StompHeaderAccessor.wrap(receive); assertEquals("Expected STOMP destination=/app/number, got " + stompHeaderAccessor, destHeader, stompHeaderAccessor.getDestination()); Object payload = receive.getPayload(); assertEquals("Expected STOMP Payload=42, got " + payload, "42", payload); }
@Test public void handleExceptionAndSendToUser() throws Exception { String destHeader = "/user/queue/error"; StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSubscriptionId("subs1"); headers.setDestination(destHeader); Message<byte[]> message = MessageBuilder.withPayload(ByteBuffer.allocate(0).array()) .setHeaders(headers) .build(); headers = StompHeaderAccessor.create(StompCommand.SEND); headers.setSubscriptionId("subs1"); headers.setDestination("/app/exception"); Message<String> message2 = MessageBuilder.withPayload("foo").setHeaders(headers).build(); this.webSocketOutputChannel.send(message); waitForSubscribe("/queue/error-user" + this.clientWebSocketContainer.getSession(null).getId()); this.webSocketOutputChannel.send(message2); Message<?> receive = webSocketInputChannel.receive(20000); assertNotNull(receive); StompHeaderAccessor stompHeaderAccessor = StompHeaderAccessor.wrap(receive); assertEquals("Expected STOMP destination=/user/queue/error, got " + stompHeaderAccessor, destHeader, stompHeaderAccessor.getDestination()); assertEquals("Got error: Bad input", receive.getPayload()); }
@Test public void testWebSocketOutboundMessageHandler() throws Exception { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SEND); headers.setMessageId("mess0"); headers.setSubscriptionId("sub0"); headers.setDestination("/foo"); String payload = "Hello World"; Message<String> message = MessageBuilder.withPayload(payload).setHeaders(headers).build(); this.messageHandler.handleMessage(message); Message<?> received = this.clientInboundChannel.receive(10000); assertNotNull(received); StompHeaderAccessor receivedHeaders = StompHeaderAccessor.wrap(received); assertEquals("mess0", receivedHeaders.getMessageId()); assertEquals("sub0", receivedHeaders.getSubscriptionId()); assertEquals("/foo", receivedHeaders.getDestination()); Object receivedPayload = received.getPayload(); assertThat(receivedPayload, instanceOf(byte[].class)); assertArrayEquals((byte[]) receivedPayload, payload.getBytes()); }