/** * Install or remove an {@link ExecutorChannelInterceptor} that invokes a * completion task once the message is handled. * @param channel the channel to configure * @param preservePublishOrder whether preserve order is on or off based on * which an interceptor is either added or removed. */ static void configureOutboundChannel(MessageChannel channel, boolean preservePublishOrder) { if (preservePublishOrder) { Assert.isInstanceOf(ExecutorSubscribableChannel.class, channel, "An ExecutorSubscribableChannel is required for `preservePublishOrder`"); ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; if (execChannel.getInterceptors().stream().noneMatch(i -> i instanceof CallbackInterceptor)) { execChannel.addInterceptor(0, new CallbackInterceptor()); } } else if (channel instanceof ExecutorSubscribableChannel) { ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; execChannel.getInterceptors().stream().filter(i -> i instanceof CallbackInterceptor) .findFirst() .map(execChannel::removeInterceptor); } }
@Test public void postSendInterceptorMessageWasSent() { final AtomicBoolean preSendInvoked = new AtomicBoolean(false); final AtomicBoolean completionInvoked = new AtomicBoolean(false); this.channel.addInterceptor(new ChannelInterceptor() { @Override public void postSend(Message<?> message, MessageChannel channel, boolean sent) { assertInput(message, channel, sent); preSendInvoked.set(true); } @Override public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) { assertInput(message, channel, sent); completionInvoked.set(true); } private void assertInput(Message<?> message, MessageChannel channel, boolean sent) { assertNotNull(message); assertNotNull(channel); assertSame(ChannelInterceptorTests.this.channel, channel); assertTrue(sent); } }); this.channel.send(MessageBuilder.withPayload("test").build()); assertTrue(preSendInvoked.get()); assertTrue(completionInvoked.get()); }
@Test public void handleMessageFromClientWithImmutableMessageInterceptor() { AtomicReference<Boolean> mutable = new AtomicReference<>(); ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(); channel.addInterceptor(new ChannelInterceptor() { @Override public Message<?> preSend(Message<?> message, MessageChannel channel) { mutable.set(MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class).isMutable()); return message; } }); channel.addInterceptor(new ImmutableMessageChannelInterceptor()); StompSubProtocolHandler handler = new StompSubProtocolHandler(); handler.afterSessionStarted(this.session, channel); TextMessage message = StompTextMessageBuilder.create(StompCommand.CONNECT).build(); handler.handleMessageFromClient(this.session, message, channel); assertNotNull(mutable.get()); assertTrue(mutable.get()); }
@Test public void afterCompletionWithPreSendException() { PreSendInterceptor interceptor1 = new PreSendInterceptor(); PreSendInterceptor interceptor2 = new PreSendInterceptor(); interceptor2.setExceptionToRaise(new RuntimeException("Simulated exception")); this.channel.addInterceptor(interceptor1); this.channel.addInterceptor(interceptor2); try { this.channel.send(MessageBuilder.withPayload("test").build()); } catch (Exception ex) { assertEquals("Simulated exception", ex.getCause().getMessage()); } assertTrue(interceptor1.wasAfterCompletionInvoked()); assertFalse(interceptor2.wasAfterCompletionInvoked()); }
@Test public void interceptorWithNull() { BeforeHandleInterceptor interceptor1 = new BeforeHandleInterceptor(); NullReturningBeforeHandleInterceptor interceptor2 = new NullReturningBeforeHandleInterceptor(); this.channel.addInterceptor(interceptor1); this.channel.addInterceptor(interceptor2); this.channel.subscribe(this.handler); this.channel.send(this.message); verifyNoMoreInteractions(this.handler); assertEquals(1, interceptor1.getCounter().get()); assertEquals(1, interceptor2.getCounter().get()); assertTrue(interceptor1.wasAfterHandledInvoked()); }
@Test public void preSendInterceptorReturningNull() { PreSendInterceptor interceptor1 = new PreSendInterceptor(); NullReturningPreSendInterceptor interceptor2 = new NullReturningPreSendInterceptor(); this.channel.addInterceptor(interceptor1); this.channel.addInterceptor(interceptor2); Message<?> message = MessageBuilder.withPayload("test").build(); this.channel.send(message); assertEquals(1, interceptor1.getCounter().get()); assertEquals(1, interceptor2.getCounter().get()); assertEquals(0, this.messageHandler.getMessages().size()); assertTrue(interceptor1.wasAfterCompletionInvoked()); assertFalse(interceptor2.wasAfterCompletionInvoked()); }
@Test // SPR-14690 public void handleMessageFromClientWithTokenAuthentication() { ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(); channel.addInterceptor(new AuthenticationInterceptor("__pete__@gmail.com")); channel.addInterceptor(new ImmutableMessageChannelInterceptor()); TestMessageHandler messageHandler = new TestMessageHandler(); channel.subscribe(messageHandler); StompSubProtocolHandler handler = new StompSubProtocolHandler(); handler.afterSessionStarted(this.session, channel); TextMessage wsMessage = StompTextMessageBuilder.create(StompCommand.CONNECT).build(); handler.handleMessageFromClient(this.session, wsMessage, channel); assertEquals(1, messageHandler.getMessages().size()); Message<?> message = messageHandler.getMessages().get(0); Principal user = SimpMessageHeaderAccessor.getUser(message.getHeaders()); assertNotNull(user); assertEquals("__pete__@gmail.com", user.getName()); }
@Test public void handleMessageFromClientWithoutImmutableMessageInterceptor() { AtomicReference<Boolean> mutable = new AtomicReference<>(); ExecutorSubscribableChannel channel = new ExecutorSubscribableChannel(); channel.addInterceptor(new ChannelInterceptor() { @Override public Message<?> preSend(Message<?> message, MessageChannel channel) { mutable.set(MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class).isMutable()); return message; } }); StompSubProtocolHandler handler = new StompSubProtocolHandler(); handler.afterSessionStarted(this.session, channel); TextMessage message = StompTextMessageBuilder.create(StompCommand.CONNECT).build(); handler.handleMessageFromClient(this.session, message, channel); assertNotNull(mutable.get()); assertFalse(mutable.get()); }
@Test public void preSendInterceptorReturningModifiedMessage() { Message<?> expected = mock(Message.class); PreSendInterceptor interceptor = new PreSendInterceptor(); interceptor.setMessageToReturn(expected); this.channel.addInterceptor(interceptor); this.channel.send(MessageBuilder.withPayload("test").build()); assertEquals(1, this.messageHandler.getMessages().size()); Message<?> result = this.messageHandler.getMessages().get(0); assertNotNull(result); assertSame(expected, result); assertTrue(interceptor.wasAfterCompletionInvoked()); }
@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 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 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 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()); }
@VisibleForTesting public void addInterceptorForUnitTest(ChannelInterceptor theInterceptor) { mySubscribableChannel.addInterceptor(theInterceptor); }
/** * Install or remove an {@link ExecutorChannelInterceptor} that invokes a * completion task once the message is handled. * @param channel the channel to configure * @param preservePublishOrder whether preserve order is on or off based on * which an interceptor is either added or removed. */ static void configureOutboundChannel(MessageChannel channel, boolean preservePublishOrder) { if (preservePublishOrder) { Assert.isInstanceOf(ExecutorSubscribableChannel.class, channel, "An ExecutorSubscribableChannel is required for `preservePublishOrder`"); ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; if (execChannel.getInterceptors().stream().noneMatch(i -> i instanceof CallbackInterceptor)) { execChannel.addInterceptor(0, new CallbackInterceptor()); } } else if (channel instanceof ExecutorSubscribableChannel) { ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; execChannel.getInterceptors().stream().filter(i -> i instanceof CallbackInterceptor) .findFirst() .map(execChannel::removeInterceptor); } }
/** * Install or remove an {@link ExecutorChannelInterceptor} that invokes a * completion task once the message is handled. * @param channel the channel to configure * @param preservePublishOrder whether preserve order is on or off based on * which an interceptor is either added or removed. */ static void configureOutboundChannel(MessageChannel channel, boolean preservePublishOrder) { if (preservePublishOrder) { Assert.isInstanceOf(ExecutorSubscribableChannel.class, channel, "An ExecutorSubscribableChannel is required for `preservePublishOrder`"); ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; if (execChannel.getInterceptors().stream().noneMatch(i -> i instanceof CallbackInterceptor)) { execChannel.addInterceptor(0, new CallbackInterceptor()); } } else if (channel instanceof ExecutorSubscribableChannel) { ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; execChannel.getInterceptors().stream().filter(i -> i instanceof CallbackInterceptor) .findFirst() .map(execChannel::removeInterceptor); } }
/** * Install or remove an {@link ExecutorChannelInterceptor} that invokes a * completion task once the message is handled. * @param channel the channel to configure * @param preservePublishOrder whether preserve order is on or off based on * which an interceptor is either added or removed. */ static void configureOutboundChannel(MessageChannel channel, boolean preservePublishOrder) { if (preservePublishOrder) { Assert.isInstanceOf(ExecutorSubscribableChannel.class, channel, "An ExecutorSubscribableChannel is required for `preservePublishOrder`"); ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; if (execChannel.getInterceptors().stream().noneMatch(i -> i instanceof CallbackInterceptor)) { execChannel.addInterceptor(0, new CallbackInterceptor()); } } else if (channel instanceof ExecutorSubscribableChannel) { ExecutorSubscribableChannel execChannel = (ExecutorSubscribableChannel) channel; execChannel.getInterceptors().stream().filter(i -> i instanceof CallbackInterceptor) .findFirst() .map(execChannel::removeInterceptor); } }