Polishing

This commit is contained in:
Juergen Hoeller
2018-07-24 22:10:07 +02:00
parent 4f9a18f5aa
commit 0b5c099de2
8 changed files with 64 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -28,6 +28,8 @@ import org.springframework.messaging.MessageChannel;
* @author Mark Fisher
* @author Rossen Stoyanchev
* @since 4.0
* @see Message
* @see MessageChannel
*/
public interface ChannelInterceptor {
@@ -56,8 +58,8 @@ public interface ChannelInterceptor {
* completed and returned a Message, i.e. it did not return {@code null}.
* @since 4.1
*/
default void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent,
@Nullable Exception ex) {
default void afterSendCompletion(
Message<?> message, MessageChannel channel, boolean sent, @Nullable Exception ex) {
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -26,10 +26,13 @@ import org.springframework.messaging.MessageHandler;
* asynchronous sending of a {@link org.springframework.messaging.Message} to
* a specific subscriber through an {@link java.util.concurrent.Executor}.
* Supported on {@link org.springframework.messaging.MessageChannel}
* implementations that can be configured with an Executor.
* implementations that can be configured with an {@code Executor}.
*
* @author Rossen Stoyanchev
* @since 4.1
* @see Message
* @see MessageChannel
* @see MessageHandler
*/
public interface ExecutorChannelInterceptor extends ChannelInterceptor {
@@ -44,7 +47,9 @@ public interface ExecutorChannelInterceptor extends ChannelInterceptor {
* @return the input message, or a new instance, or {@code null}
*/
@Nullable
Message<?> beforeHandle(Message<?> message, MessageChannel channel, MessageHandler handler);
default Message<?> beforeHandle(Message<?> message, MessageChannel channel, MessageHandler handler) {
return message;
}
/**
* Invoked inside the {@link Runnable} submitted to the Executor after calling
@@ -57,6 +62,8 @@ public interface ExecutorChannelInterceptor extends ChannelInterceptor {
* @param handler the target handler that handled the message
* @param ex any exception that may been raised by the handler
*/
void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler, @Nullable Exception ex);
default void afterMessageHandled(
Message<?> message, MessageChannel channel, MessageHandler handler, @Nullable Exception ex) {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -38,23 +38,11 @@ import org.springframework.messaging.simp.TestPrincipal;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.TaskScheduler;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* Unit tests for SimpleBrokerMessageHandler.
* Unit tests for {@link SimpleBrokerMessageHandler}.
*
* @author Rossen Stoyanchev
* @since 4.0
@@ -89,8 +77,7 @@ public class SimpleBrokerMessageHandlerTests {
@Test
public void subcribePublish() {
public void subscribePublish() {
this.messageHandler.start();
this.messageHandler.handleMessage(createSubscriptionMessage("sess1", "sub1", "/foo"));
@@ -114,8 +101,7 @@ public class SimpleBrokerMessageHandlerTests {
}
@Test
public void subcribeDisconnectPublish() {
public void subscribeDisconnectPublish() {
String sess1 = "sess1";
String sess2 = "sess2";
@@ -153,7 +139,6 @@ public class SimpleBrokerMessageHandlerTests {
@Test
public void connect() {
this.messageHandler.start();
String id = "sess1";
@@ -173,10 +158,8 @@ public class SimpleBrokerMessageHandlerTests {
}
@Test
public void heartbeatValueWithAndWithoutTaskScheduler() throws Exception {
public void heartbeatValueWithAndWithoutTaskScheduler() {
assertNull(this.messageHandler.getHeartbeatValue());
this.messageHandler.setTaskScheduler(this.taskScheduler);
assertNotNull(this.messageHandler.getHeartbeatValue());
@@ -184,15 +167,14 @@ public class SimpleBrokerMessageHandlerTests {
}
@Test(expected = IllegalArgumentException.class)
public void startWithHeartbeatValueWithoutTaskScheduler() throws Exception {
public void startWithHeartbeatValueWithoutTaskScheduler() {
this.messageHandler.setHeartbeatValue(new long[] {10000, 10000});
this.messageHandler.start();
}
@SuppressWarnings("unchecked")
@Test
public void startAndStopWithHeartbeatValue() throws Exception {
public void startAndStopWithHeartbeatValue() {
ScheduledFuture future = mock(ScheduledFuture.class);
when(this.taskScheduler.scheduleWithFixedDelay(any(Runnable.class), eq(15000L))).thenReturn(future);
@@ -211,8 +193,7 @@ public class SimpleBrokerMessageHandlerTests {
@SuppressWarnings("unchecked")
@Test
public void startWithOneZeroHeartbeatValue() throws Exception {
public void startWithOneZeroHeartbeatValue() {
this.messageHandler.setTaskScheduler(this.taskScheduler);
this.messageHandler.setHeartbeatValue(new long[] {0, 10000});
this.messageHandler.start();
@@ -222,7 +203,6 @@ public class SimpleBrokerMessageHandlerTests {
@Test
public void readInactivity() throws Exception {
this.messageHandler.setHeartbeatValue(new long[] {0, 1});
this.messageHandler.setTaskScheduler(this.taskScheduler);
this.messageHandler.start();
@@ -254,7 +234,6 @@ public class SimpleBrokerMessageHandlerTests {
@Test
public void writeInactivity() throws Exception {
this.messageHandler.setHeartbeatValue(new long[] {1, 0});
this.messageHandler.setTaskScheduler(this.taskScheduler);
this.messageHandler.start();
@@ -286,7 +265,6 @@ public class SimpleBrokerMessageHandlerTests {
@Test
public void readWriteIntervalCalculation() throws Exception {
this.messageHandler.setHeartbeatValue(new long[] {1, 1});
this.messageHandler.setTaskScheduler(this.taskScheduler);
this.messageHandler.start();
@@ -311,9 +289,10 @@ public class SimpleBrokerMessageHandlerTests {
messages.get(0).getHeaders().get(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER));
}
private Message<String> createSubscriptionMessage(String sessionId, String subcriptionId, String destination) {
private Message<String> createSubscriptionMessage(String sessionId, String subscriptionId, String destination) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.SUBSCRIBE);
headers.setSubscriptionId(subcriptionId);
headers.setSubscriptionId(subscriptionId);
headers.setDestination(destination);
headers.setSessionId(sessionId);
return MessageBuilder.createMessage("", headers.getMessageHeaders());
@@ -333,11 +312,11 @@ public class SimpleBrokerMessageHandlerTests {
return MessageBuilder.createMessage(payload, headers.getMessageHeaders());
}
private boolean messageCaptured(String sessionId, String subcriptionId, String destination) {
private boolean messageCaptured(String sessionId, String subscriptionId, String destination) {
for (Message<?> message : this.messageCaptor.getAllValues()) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
if (sessionId.equals(headers.getSessionId())) {
if (subcriptionId.equals(headers.getSubscriptionId())) {
if (subscriptionId.equals(headers.getSubscriptionId())) {
if (destination.equals(headers.getDestination())) {
return true;
}

View File

@@ -117,12 +117,10 @@ public class MessageBrokerConfigurationTests {
AbstractSubscribableChannel channel = context.getBean(
"clientInboundChannel", AbstractSubscribableChannel.class);
assertEquals(3, channel.getInterceptors().size());
CustomThreadPoolTaskExecutor taskExecutor = context.getBean(
"clientInboundChannelExecutor", CustomThreadPoolTaskExecutor.class);
assertEquals(11, taskExecutor.getCorePoolSize());
assertEquals(12, taskExecutor.getMaxPoolSize());
assertEquals(13, taskExecutor.getKeepAliveSeconds());
@@ -480,7 +478,6 @@ public class MessageBrokerConfigurationTests {
TestChannel outChannel = context.getBean("clientOutboundChannel", TestChannel.class);
MessageChannel brokerChannel = context.getBean("brokerChannel", MessageChannel.class);
// 1. Subscribe to user destination
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE);
@@ -506,7 +503,6 @@ public class MessageBrokerConfigurationTests {
assertEquals(expectLeadingSlash ? "/queue.q1-usersess1" : "queue.q1-usersess1", headers.getDestination());
assertEquals("123", new String((byte[]) outputMessage.getPayload()));
// 3. Send message via broker channel
SimpMessagingTemplate template = new SimpMessagingTemplate(brokerChannel);

View File

@@ -49,9 +49,7 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.util.SocketUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
/**
* Integration tests for {@link StompBrokerRelayMessageHandler} running against ActiveMQ.
@@ -79,7 +77,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
@Before
public void setUp() throws Exception {
public void setup() throws Exception {
logger.debug("Setting up before '" + this.testName.getMethodName() + "'");
this.port = SocketUtils.findAvailableTcpPort(61613);
this.responseChannel = new ExecutorSubscribableChannel();
@@ -114,7 +112,7 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
}
@After
public void tearDown() throws Exception {
public void stop() throws Exception {
try {
logger.debug("STOMP broker relay stats: " + this.relay.getStatsInfo());
this.relay.stop();
@@ -168,7 +166,6 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
@Test(expected = MessageDeliveryException.class)
public void messageDeliveryExceptionIfSystemSessionForwardFails() throws Exception {
logger.debug("Starting test messageDeliveryExceptionIfSystemSessionForwardFails()");
stopActiveMqBrokerAndAwait();
@@ -179,8 +176,8 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
}
@Test
public void brokerBecomingUnvailableTriggersErrorFrame() throws Exception {
logger.debug("Starting test brokerBecomingUnvailableTriggersErrorFrame()");
public void brokerBecomingUnavailableTriggersErrorFrame() throws Exception {
logger.debug("Starting test brokerBecomingUnavailableTriggersErrorFrame()");
String sess1 = "sess1";
MessageExchange connect = MessageExchangeBuilder.connect(sess1).build();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2018 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.
@@ -65,8 +65,9 @@ public class ExecutorSubscribableChannelTests {
MockitoAnnotations.initMocks(this);
}
@Test
public void messageMustNotBeNull() throws Exception {
public void messageMustNotBeNull() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Message must not be null");
this.channel.send(null);
@@ -84,7 +85,7 @@ public class ExecutorSubscribableChannelTests {
}
@Test
public void sendWithExecutor() throws Exception {
public void sendWithExecutor() {
BeforeHandleInterceptor interceptor = new BeforeHandleInterceptor();
TaskExecutor executor = mock(TaskExecutor.class);
ExecutorSubscribableChannel testChannel = new ExecutorSubscribableChannel(executor);
@@ -100,7 +101,7 @@ public class ExecutorSubscribableChannelTests {
}
@Test
public void subscribeTwice() throws Exception {
public void subscribeTwice() {
assertThat(this.channel.subscribe(this.handler), equalTo(true));
assertThat(this.channel.subscribe(this.handler), equalTo(false));
this.channel.send(this.message);
@@ -108,7 +109,7 @@ public class ExecutorSubscribableChannelTests {
}
@Test
public void unsubscribeTwice() throws Exception {
public void unsubscribeTwice() {
this.channel.subscribe(this.handler);
assertThat(this.channel.unsubscribe(this.handler), equalTo(true));
assertThat(this.channel.unsubscribe(this.handler), equalTo(false));
@@ -117,7 +118,7 @@ public class ExecutorSubscribableChannelTests {
}
@Test
public void failurePropagates() throws Exception {
public void failurePropagates() {
RuntimeException ex = new RuntimeException();
willThrow(ex).given(this.handler).handleMessage(this.message);
MessageHandler secondHandler = mock(MessageHandler.class);
@@ -133,7 +134,7 @@ public class ExecutorSubscribableChannelTests {
}
@Test
public void concurrentModification() throws Exception {
public void concurrentModification() {
this.channel.subscribe(message1 -> channel.unsubscribe(handler));
this.channel.subscribe(this.handler);
this.channel.send(this.message);
@@ -208,8 +209,8 @@ public class ExecutorSubscribableChannelTests {
}
@Override
public void afterMessageHandled(Message<?> message, MessageChannel channel, MessageHandler handler,
Exception ex) {
public void afterMessageHandled(
Message<?> message, MessageChannel channel, MessageHandler handler, Exception ex) {
this.afterHandledInvoked = true;
}

View File

@@ -94,8 +94,8 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* Test fixture for MessageBrokerBeanDefinitionParser.
* See test configuration files websocket-config-broker-*.xml.
* Test fixture for {@link MessageBrokerBeanDefinitionParser}.
* Also see test configuration files websocket-config-broker-*.xml.
*
* @author Brian Clozel
* @author Artem Bilan
@@ -208,8 +208,7 @@ public class MessageBrokerBeanDefinitionParserTests {
assertNotNull(brokerMessageHandler.getTaskScheduler());
assertArrayEquals(new long[] {15000, 15000}, brokerMessageHandler.getHeartbeatValue());
List<Class<? extends MessageHandler>> subscriberTypes =
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
List<Class<? extends MessageHandler>> subscriberTypes = Arrays.asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
testChannel("clientInboundChannel", subscriberTypes, 2);
testExecutor("clientInboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
@@ -218,8 +217,7 @@ public class MessageBrokerBeanDefinitionParserTests {
testChannel("clientOutboundChannel", subscriberTypes, 1);
testExecutor("clientOutboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(
SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
subscriberTypes = Arrays.asList(SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
testChannel("brokerChannel", subscriberTypes, 1);
try {
this.appContext.getBean("brokerChannelExecutor", ThreadPoolTaskExecutor.class);
@@ -278,9 +276,8 @@ public class MessageBrokerBeanDefinitionParserTests {
assertEquals(5000, messageBroker.getSystemHeartbeatSendInterval());
assertThat(messageBroker.getDestinationPrefixes(), Matchers.containsInAnyOrder("/topic","/queue"));
List<Class<? extends MessageHandler>> subscriberTypes = Arrays.asList(
SimpAnnotationMethodMessageHandler.class, UserDestinationMessageHandler.class,
StompBrokerRelayMessageHandler.class);
List<Class<? extends MessageHandler>> subscriberTypes = Arrays.asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, StompBrokerRelayMessageHandler.class);
testChannel("clientInboundChannel", subscriberTypes, 2);
testExecutor("clientInboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
@@ -379,9 +376,8 @@ public class MessageBrokerBeanDefinitionParserTests {
assertSame(this.appContext.getBean("myValidator"), validator);
assertThat(validator, Matchers.instanceOf(TestValidator.class));
List<Class<? extends MessageHandler>> subscriberTypes =
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
List<Class<? extends MessageHandler>> subscriberTypes = Arrays.asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
testChannel("clientInboundChannel", subscriberTypes, 3);
testExecutor("clientInboundChannel", 100, 200, 600);
@@ -391,16 +387,13 @@ public class MessageBrokerBeanDefinitionParserTests {
testChannel("clientOutboundChannel", subscriberTypes, 3);
testExecutor("clientOutboundChannel", 101, 201, 601);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(SimpleBrokerMessageHandler.class,
UserDestinationMessageHandler.class);
subscriberTypes = Arrays.asList(SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
testChannel("brokerChannel", subscriberTypes, 1);
testExecutor("brokerChannel", 102, 202, 602);
}
// SPR-11623
@Test
@Test // SPR-11623
public void customChannelsWithDefaultExecutor() {
loadBeanDefinitions("websocket-config-broker-customchannels-default-executor.xml");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -57,8 +57,8 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.server.HandshakeHandler;
import static org.junit.Assert.assertTrue;
import static org.springframework.web.socket.messaging.StompTextMessageBuilder.create;
import static org.junit.Assert.*;
import static org.springframework.web.socket.messaging.StompTextMessageBuilder.*;
/**
* Integration tests with annotated message-handling methods.
@@ -70,6 +70,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration
private static final long TIMEOUT = 10;
@Parameters(name = "server [{0}], client [{1}]")
public static Object[][] arguments() {
return new Object[][] {
@@ -261,7 +262,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration
}
static interface ScopedBean {
interface ScopedBean {
String getValue();
}
@@ -315,9 +316,9 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration
@Configuration
@ComponentScan(
basePackageClasses=StompWebSocketIntegrationTests.class,
useDefaultFilters=false,
includeFilters=@ComponentScan.Filter(IntegrationTestController.class))
basePackageClasses = StompWebSocketIntegrationTests.class,
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(IntegrationTestController.class))
static class TestMessageBrokerConfigurer implements WebSocketMessageBrokerConfigurer {
@Autowired