private void sendSystemSubscriptions() { int i = 0; for (String destination : getSystemSubscriptions().keySet()) { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); accessor.setSubscriptionId(String.valueOf(i++)); accessor.setDestination(destination); if (logger.isDebugEnabled()) { logger.debug("Subscribing to " + destination + " on \"system\" connection."); } TcpConnection<byte[]> conn = getTcpConnection(); if (conn != null) { MessageHeaders headers = accessor.getMessageHeaders(); conn.send(MessageBuilder.createMessage(EMPTY_PAYLOAD, headers)).addCallback( result -> {}, ex -> { String error = "Failed to subscribe in \"system\" session."; handleTcpConnectionFailure(error, ex); }); } } }
@Test public void toNativeHeadersSubscribe() { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSubscriptionId("s1"); headers.setDestination("/d"); Map<String, List<String>> actual = headers.toNativeHeaderMap(); assertEquals(2, actual.size()); assertEquals("s1", actual.get(StompHeaderAccessor.STOMP_ID_HEADER).get(0)); assertEquals("/d", actual.get(StompHeaderAccessor.STOMP_DESTINATION_HEADER).get(0)); }
@Test public void toNativeHeadersMessageFrame() { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.MESSAGE); headers.setSubscriptionId("s1"); headers.setDestination("/d"); headers.setContentType(MimeTypeUtils.APPLICATION_JSON); headers.updateStompCommandAsServerMessage(); Map<String, List<String>> actual = headers.toNativeHeaderMap(); assertEquals(actual.toString(), 4, actual.size()); assertEquals("s1", actual.get(StompHeaderAccessor.STOMP_SUBSCRIPTION_HEADER).get(0)); assertEquals("/d", actual.get(StompHeaderAccessor.STOMP_DESTINATION_HEADER).get(0)); assertEquals("application/json", actual.get(StompHeaderAccessor.STOMP_CONTENT_TYPE_HEADER).get(0)); assertNotNull("message-id was not created", actual.get(StompHeaderAccessor.STOMP_MESSAGE_ID_HEADER).get(0)); }
@Test public void getShortLogMessage() { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND); accessor.setDestination("/foo"); accessor.setContentType(MimeTypeUtils.APPLICATION_JSON); accessor.setSessionId("123"); String actual = accessor.getShortLogMessage("payload".getBytes(StandardCharsets.UTF_8)); assertEquals("SEND /foo session=123 application/json payload=payload", actual); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 80; i++) { sb.append("a"); } final String payload = sb.toString() + " > 80"; actual = accessor.getShortLogMessage(payload.getBytes(StandardCharsets.UTF_8)); assertEquals("SEND /foo session=123 application/json payload=" + sb + "...(truncated)", actual); }
@Test public void sendWebSocketBinary() throws Exception { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND); accessor.setDestination("/b"); accessor.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM); byte[] payload = "payload".getBytes(StandardCharsets.UTF_8); getTcpConnection().send(MessageBuilder.createMessage(payload, accessor.getMessageHeaders())); ArgumentCaptor<BinaryMessage> binaryMessageCaptor = ArgumentCaptor.forClass(BinaryMessage.class); verify(this.webSocketSession).sendMessage(binaryMessageCaptor.capture()); BinaryMessage binaryMessage = binaryMessageCaptor.getValue(); assertNotNull(binaryMessage); assertEquals("SEND\ndestination:/b\ncontent-type:application/octet-stream\ncontent-length:7\n\npayload\0", new String(binaryMessage.getPayload().array(), StandardCharsets.UTF_8)); }
@Test public void sendWebSocketMessage() throws Exception { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND); accessor.setDestination("/topic/foo"); byte[] payload = "payload".getBytes(StandardCharsets.UTF_8); getTcpConnection().send(MessageBuilder.createMessage(payload, accessor.getMessageHeaders())); ArgumentCaptor<TextMessage> textMessageCaptor = ArgumentCaptor.forClass(TextMessage.class); verify(this.webSocketSession).sendMessage(textMessageCaptor.capture()); TextMessage textMessage = textMessageCaptor.getValue(); assertNotNull(textMessage); assertEquals("SEND\ndestination:/topic/foo\ncontent-length:7\n\npayload\0", textMessage.getPayload()); }
@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())); }
public static MessageExchangeBuilder subscribeWithReceipt(String sessionId, String subscriptionId, String destination, String receiptId) { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE); headers.setSessionId(sessionId); headers.setSubscriptionId(subscriptionId); headers.setDestination(destination); headers.setReceipt(receiptId); Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()); MessageExchangeBuilder builder = new MessageExchangeBuilder(message); builder.expected.add(new StompReceiptFrameMessageMatcher(sessionId, receiptId)); return builder; }
headers.setSessionId("sess1"); headers.setSubscriptionId("subs1"); headers.setDestination("/user/queue.q1"); Message<?> message = MessageBuilder.createMessage(new byte[0], headers.getMessageHeaders()); inChannel.send(message); headers.setDestination("/user/sess1/queue.q1"); message = MessageBuilder.createMessage("123".getBytes(), headers.getMessageHeaders()); inChannel.send(message);
@Test public void handleMessageToClientWithUserDestination() { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.MESSAGE); headers.setMessageId("mess0"); headers.setSubscriptionId("sub0"); headers.setDestination("/queue/foo-user123"); headers.setNativeHeader(StompHeaderAccessor.ORIGINAL_DESTINATION, "/user/queue/foo"); Message<byte[]> message = MessageBuilder.createMessage(EMPTY_PAYLOAD, headers.getMessageHeaders()); this.protocolHandler.handleMessageToClient(this.session, message); assertEquals(1, this.session.getSentMessages().size()); WebSocketMessage<?> textMessage = this.session.getSentMessages().get(0); assertTrue(((String) textMessage.getPayload()).contains("destination:/user/queue/foo\n")); assertFalse(((String) textMessage.getPayload()).contains(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION)); }
@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())); }
@Test public void handleMessageFrame() { this.session.afterConnected(this.connection); StompFrameHandler frameHandler = mock(StompFrameHandler.class); String destination = "/topic/foo"; Subscription subscription = this.session.subscribe(destination, frameHandler); StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE); accessor.setDestination(destination); accessor.setSubscriptionId(subscription.getSubscriptionId()); accessor.setContentType(MimeTypeUtils.TEXT_PLAIN); accessor.setMessageId("1"); accessor.setLeaveMutable(true); String payload = "sample payload"; StompHeaders stompHeaders = StompHeaders.readOnlyStompHeaders(accessor.getNativeHeaders()); when(frameHandler.getPayloadType(stompHeaders)).thenReturn(String.class); this.session.handleMessage(MessageBuilder.createMessage(payload.getBytes(StandardCharsets.UTF_8), accessor.getMessageHeaders())); verify(frameHandler).getPayloadType(stompHeaders); verify(frameHandler).handleFrame(stompHeaders, payload); verifyNoMoreInteractions(frameHandler); }
@Test public void handleMessageFrameWithConversionException() { this.session.afterConnected(this.connection); assertTrue(this.session.isConnected()); StompFrameHandler frameHandler = mock(StompFrameHandler.class); String destination = "/topic/foo"; Subscription subscription = this.session.subscribe(destination, frameHandler); StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE); accessor.setDestination(destination); accessor.setSubscriptionId(subscription.getSubscriptionId()); accessor.setContentType(MimeTypeUtils.APPLICATION_JSON); accessor.setMessageId("1"); accessor.setLeaveMutable(true); byte[] payload = "{'foo':'bar'}".getBytes(StandardCharsets.UTF_8); StompHeaders stompHeaders = StompHeaders.readOnlyStompHeaders(accessor.getNativeHeaders()); when(frameHandler.getPayloadType(stompHeaders)).thenReturn(Map.class); this.session.handleMessage(MessageBuilder.createMessage(payload, accessor.getMessageHeaders())); verify(frameHandler).getPayloadType(stompHeaders); verifyNoMoreInteractions(frameHandler); verify(this.sessionHandler).handleException(same(this.session), same(StompCommand.MESSAGE), eq(stompHeaders), same(payload), any(MessageConversionException.class)); verifyNoMoreInteractions(this.sessionHandler); }
@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())); }
@Test public void handleMessageFromBrokerWithoutActiveSession() { this.handler.setBroadcastDestination("/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(StandardCharsets.UTF_8); this.handler.handleMessage(MessageBuilder.createMessage(payload, accessor.getMessageHeaders())); // No re-broadcast verifyNoMoreInteractions(this.brokerChannel); }
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()); }
@Test public void handleMessageFromBrokerWithActiveSession() { TestSimpUser simpUser = new TestSimpUser("joe"); simpUser.addSessions(new TestSimpSession("123")); when(this.registry.getUser("joe")).thenReturn(simpUser); this.handler.setBroadcastDestination("/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(StandardCharsets.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 handleMessageToClientWithBinaryWebSocketMessage() { StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.MESSAGE); headers.setMessageId("mess0"); headers.setSubscriptionId("sub0"); headers.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM); headers.setDestination("/queue/foo"); // Non-empty payload byte[] payload = new byte[1]; Message<byte[]> message = MessageBuilder.createMessage(payload, headers.getMessageHeaders()); this.protocolHandler.handleMessageToClient(this.session, message); assertEquals(1, this.session.getSentMessages().size()); WebSocketMessage<?> webSocketMessage = this.session.getSentMessages().get(0); assertTrue(webSocketMessage instanceof BinaryMessage); // Empty payload payload = EMPTY_PAYLOAD; message = MessageBuilder.createMessage(payload, headers.getMessageHeaders()); this.protocolHandler.handleMessageToClient(this.session, message); assertEquals(2, this.session.getSentMessages().size()); webSocketMessage = this.session.getSentMessages().get(1); assertTrue(webSocketMessage instanceof TextMessage); }
@Test public void connectReceiveAndCloseWithStompFrame() throws Exception { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND); accessor.setDestination("/destination"); MessageHeaders headers = accessor.getMessageHeaders(); Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(StandardCharsets.UTF_8), headers); byte[] bytes = new StompEncoder().encode(message); TextMessage textMessage = new TextMessage(bytes); SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), textMessage.getPayload()); String body = "o\n" + frame.getContent() + "\n" + "c[3000,\"Go away!\"]"; ClientHttpResponse response = response(HttpStatus.OK, body); connect(response); verify(this.webSocketHandler).afterConnectionEstablished(any()); verify(this.webSocketHandler).handleMessage(any(), eq(textMessage)); verify(this.webSocketHandler).afterConnectionClosed(any(), eq(new CloseStatus(3000, "Go away!"))); verifyNoMoreInteractions(this.webSocketHandler); }