@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); } } } }
@Override public void run() { Message<?> message = this.inputMessage; try { message = applyBeforeHandle(message); if (message == null) { return; } this.messageHandler.handleMessage(message); triggerAfterMessageHandled(message, null); } catch (Exception ex) { triggerAfterMessageHandled(message, ex); if (ex instanceof MessagingException) { throw (MessagingException) ex; } String description = "Failed to handle " + message + " to " + this + " in " + this.messageHandler; throw new MessageDeliveryException(message, description, ex); } catch (Throwable err) { String description = "Failed to handle " + message + " to " + this + " in " + this.messageHandler; MessageDeliveryException ex2 = new MessageDeliveryException(message, description, err); triggerAfterMessageHandled(message, ex2); throw ex2; } }
@Test public void subscribeTwice() { assertThat(this.channel.subscribe(this.handler), equalTo(true)); assertThat(this.channel.subscribe(this.handler), equalTo(false)); this.channel.send(this.message); verify(this.handler, times(1)).handleMessage(this.message); }
@Test public void unsubscribeTwice() { this.channel.subscribe(this.handler); assertThat(this.channel.unsubscribe(this.handler), equalTo(true)); assertThat(this.channel.unsubscribe(this.handler), equalTo(false)); this.channel.send(this.message); verify(this.handler, never()).handleMessage(this.message); }
@Test public void sendWithExecutor() { BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor(); TaskExecutor executor = mock(TaskExecutor.class); ExecutorSubscribableChannel testChannel = new ExecutorSubscribableChannel(executor); testChannel.addInterceptor(interceptor); testChannel.subscribe(this.handler); testChannel.send(this.message); verify(executor).execute(this.runnableCaptor.capture()); verify(this.handler, never()).handleMessage(this.message); this.runnableCaptor.getValue().run(); verify(this.handler).handleMessage(this.message); assertEquals(1, interceptor.getCounter().get()); assertTrue(interceptor.wasAfterHandledInvoked()); }
@Test public void concurrentModification() { this.channel.subscribe(message1 -> channel.unsubscribe(handler)); this.channel.subscribe(this.handler); this.channel.send(this.message); verify(this.handler).handleMessage(this.message); }
@Test public void interceptorWithException() { IllegalStateException expected = new IllegalStateException("Fake exception"); willThrow(expected).given(this.handler).handleMessage(this.message); BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor(); this.channel.addInterceptor(interceptor); this.channel.subscribe(this.handler); try { this.channel.send(this.message); } catch (MessageDeliveryException actual) { assertSame(expected, actual.getCause()); } verify(this.handler).handleMessage(this.message); assertEquals(1, interceptor.getCounter().get()); assertTrue(interceptor.wasAfterHandledInvoked()); }
@Test public void failurePropagates() { RuntimeException ex = new RuntimeException(); willThrow(ex).given(this.handler).handleMessage(this.message); MessageHandler secondHandler = mock(MessageHandler.class); this.channel.subscribe(this.handler); this.channel.subscribe(secondHandler); try { this.channel.send(message); } catch (MessageDeliveryException actualException) { assertThat(actualException.getCause(), equalTo(ex)); } verifyZeroInteractions(secondHandler); }
@Test public void sendWithoutExecutor() { BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor(); this.channel.addInterceptor(interceptor); this.channel.subscribe(this.handler); this.channel.send(this.message); verify(this.handler).handleMessage(this.message); assertEquals(1, interceptor.getCounter().get()); assertTrue(interceptor.wasAfterHandledInvoked()); }
@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 interceptorWithModifiedMessage() { Message<?> expected = mock(Message.class); BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor(); interceptor.setMessageToReturn(expected); this.channel.addInterceptor(interceptor); this.channel.subscribe(this.handler); this.channel.send(this.message); verify(this.handler).handleMessage(expected); assertEquals(1, interceptor.getCounter().get()); assertTrue(interceptor.wasAfterHandledInvoked()); }
@Test public void validateDefaultChannelPublishing() { MessageHandler handler = Mockito.mock(MessageHandler.class); defaultChannel.subscribe(handler); doAnswer(invocation -> { Message<?> message = invocation.getArgument(0); assertEquals("hello", message.getPayload()); return null; }).when(handler).handleMessage(any(Message.class)); testBean.echoDefaultChannel("hello"); verify(handler, times(1)).handleMessage(any(Message.class)); }
@Test public void multipleTargetsPartialFailureFirst() { dispatcher = new BroadcastingDispatcher(taskExecutorMock); dispatcher.addHandler(targetMock1); dispatcher.addHandler(targetMock2); dispatcher.addHandler(targetMock3); partialFailingExecutorMock(false, true, true); dispatcher.dispatch(messageMock); verify(targetMock1, Mockito.never()).handleMessage(eq(messageMock)); verify(targetMock2).handleMessage(eq(messageMock)); verify(targetMock3).handleMessage(eq(messageMock)); }
@Test public void advised() { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context.xml", this.getClass()); Object consumer = context.getBean("advised"); MessageHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageHandler.class); handler.handleMessage(new GenericMessage<String>("foo")); assertEquals(1, adviceCalled); context.close(); }
@Test public void advised() { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( "mailOutboundChannelAdapterParserTests.xml", this.getClass()); Object adapter = context.getBean("advised.adapter"); MessageHandler handler = (MessageHandler) new DirectFieldAccessor(adapter).getPropertyValue("handler"); handler.handleMessage(new GenericMessage<>("foo")); assertEquals(1, adviceCalled); context.close(); }
@Test public void propertiesOnlyNoAnnotationsWithPropertiesPayload() throws Exception { MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class); Properties payload = new Properties(); payload.setProperty("payload", "1"); Map<String, Object> headers = new HashMap<String, Object>(); Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build(); handler.handleMessage(message); assertEquals(payload, bean.lastPayload); assertNull(bean.lastHeaders); }
@Test public void propertiesOnlyNoAnnotationsWithMapPayload() throws Exception { MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class); Map<String, Object> payload = new HashMap<String, Object>(); payload.put("payload", 1); Map<String, Object> headers = new HashMap<String, Object>(); Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build(); handler.handleMessage(message); assertEquals(payload, bean.lastPayload); assertNull(bean.lastHeaders); }
@Test public void noDuplicateSubscription() { dispatcher = new BroadcastingDispatcher(taskExecutorMock); dispatcher.addHandler(targetMock1); dispatcher.addHandler(targetMock1); dispatcher.addHandler(targetMock1); dispatcher.dispatch(messageMock); verify(targetMock1).handleMessage(eq(messageMock)); }
@Test public void adviceChain() { MessageHandler handler = TestUtils.getPropertyValue(advisedAdapter, "handler", MessageHandler.class); handler.handleMessage(new GenericMessage<String>("foo")); assertEquals(1, adviceCalled); }
@Test public void advised() throws Exception { setUp("JpaMessageHandlerParserTests.xml", getClass()); EventDrivenConsumer consumer = this.context.getBean("advised", EventDrivenConsumer.class); final AbstractMessageChannel inputChannel = TestUtils.getPropertyValue(consumer, "inputChannel", AbstractMessageChannel.class); assertEquals("target", inputChannel.getComponentName()); final MessageHandler handler = TestUtils.getPropertyValue(consumer, "handler", MessageHandler.class); adviceCalled = 0; handler.handleMessage(new GenericMessage<String>("foo")); assertEquals(1, adviceCalled); }