Refine BrokerAvailabilityEvent behavior
Add accessor for brokerAvailable in AbstractBrokerMessageHandler Ensure brokerAvailable is set even if eventPublisher is not Add tests BrokerMessageHandlerTests Turn off brokerAvailable when StompBrokerRelayMessageHandler stops Actually stop message handling when brokerAvailable=false Improve log messages Issue: SPR-11563
This commit is contained in:
parent
14a8f19670
commit
6bcbb94aba
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -30,9 +30,10 @@ import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.MessageHandler;
|
import org.springframework.messaging.MessageHandler;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for a {@link MessageHandler} that manages subscriptions and
|
* Abstract base class for a {@link MessageHandler} that broker messages to
|
||||||
* propagates messages to subscribers.
|
* registered subscribers.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
|
|
@ -42,7 +43,7 @@ public abstract class AbstractBrokerMessageHandler
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private Collection<String> destinationPrefixes;
|
private final Collection<String> destinationPrefixes;
|
||||||
|
|
||||||
private ApplicationEventPublisher eventPublisher;
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
|
|
@ -55,9 +56,13 @@ public abstract class AbstractBrokerMessageHandler
|
||||||
private volatile boolean running = false;
|
private volatile boolean running = false;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractBrokerMessageHandler() {
|
||||||
|
this(Collections.<String>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
public AbstractBrokerMessageHandler(Collection<String> destinationPrefixes) {
|
public AbstractBrokerMessageHandler(Collection<String> destinationPrefixes) {
|
||||||
this.destinationPrefixes = (destinationPrefixes != null)
|
destinationPrefixes = (destinationPrefixes != null) ? destinationPrefixes : Collections.<String>emptyList();
|
||||||
? destinationPrefixes : Collections.<String>emptyList();
|
this.destinationPrefixes = Collections.unmodifiableCollection(destinationPrefixes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -88,6 +93,13 @@ public abstract class AbstractBrokerMessageHandler
|
||||||
return Integer.MAX_VALUE;
|
return Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this message handler is currently running.
|
||||||
|
*
|
||||||
|
* <p>Note that even when this message handler is running the
|
||||||
|
* {@link #isBrokerAvailable()} flag may still independently alternate between
|
||||||
|
* being on and off depending on the concrete sub-class implementation.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean isRunning() {
|
public final boolean isRunning() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
|
|
@ -95,6 +107,23 @@ public abstract class AbstractBrokerMessageHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the message broker is currently available and able to process messages.
|
||||||
|
*
|
||||||
|
* <p>Note that this is in addition to the {@link #isRunning()} flag, which
|
||||||
|
* indicates whether this message handler is running. In other words the message
|
||||||
|
* handler must first be running and then the {@link #isBrokerAvailable()} flag
|
||||||
|
* may still independently alternate between being on and off depending on the
|
||||||
|
* concrete sub-class implementation.
|
||||||
|
*
|
||||||
|
* <p>Application components may implement
|
||||||
|
* {@link org.springframework.context.ApplicationListener<BrokerAvailabilityEvent>>}
|
||||||
|
* to receive notifications when broker becomes available and unavailable.
|
||||||
|
*/
|
||||||
|
public boolean isBrokerAvailable() {
|
||||||
|
return this.brokerAvailable.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void start() {
|
public final void start() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
|
|
@ -157,18 +186,20 @@ public abstract class AbstractBrokerMessageHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void publishBrokerAvailableEvent() {
|
protected void publishBrokerAvailableEvent() {
|
||||||
if ((this.eventPublisher != null) && this.brokerAvailable.compareAndSet(false, true)) {
|
boolean shouldPublish = this.brokerAvailable.compareAndSet(false, true);
|
||||||
if (logger.isTraceEnabled()) {
|
if (this.eventPublisher != null && shouldPublish) {
|
||||||
logger.trace("Publishing BrokerAvailabilityEvent (available)");
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Publishing BrokerAvailabilityEvent (available)");
|
||||||
}
|
}
|
||||||
this.eventPublisher.publishEvent(new BrokerAvailabilityEvent(true, this));
|
this.eventPublisher.publishEvent(new BrokerAvailabilityEvent(true, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void publishBrokerUnavailableEvent() {
|
protected void publishBrokerUnavailableEvent() {
|
||||||
if ((this.eventPublisher != null) && this.brokerAvailable.compareAndSet(true, false)) {
|
boolean shouldPublish = this.brokerAvailable.compareAndSet(true, false);
|
||||||
if (logger.isTraceEnabled()) {
|
if (this.eventPublisher != null && shouldPublish) {
|
||||||
logger.trace("Publishing BrokerAvailabilityEvent (unavailable)");
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Publishing BrokerAvailabilityEvent (unavailable)");
|
||||||
}
|
}
|
||||||
this.eventPublisher.publishEvent(new BrokerAvailabilityEvent(false, this));
|
this.eventPublisher.publishEvent(new BrokerAvailabilityEvent(false, this));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final AbstractBrokerMessageHandler noopBroker = new AbstractBrokerMessageHandler(null) {
|
private static final AbstractBrokerMessageHandler noopBroker = new AbstractBrokerMessageHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startInternal() {
|
protected void startInternal() {
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
Assert.notNull(clientOutChannel, "'clientOutChannel' must not be null");
|
Assert.notNull(clientOutChannel, "'clientOutChannel' must not be null");
|
||||||
Assert.notNull(brokerChannel, "'brokerChannel' must not be null");
|
Assert.notNull(brokerChannel, "'brokerChannel' must not be null");
|
||||||
|
|
||||||
|
|
||||||
this.clientInboundChannel = clientInChannel;
|
this.clientInboundChannel = clientInChannel;
|
||||||
this.clientOutboundChannel = clientOutChannel;
|
this.clientOutboundChannel = clientOutChannel;
|
||||||
this.brokerChannel = brokerChannel;
|
this.brokerChannel = brokerChannel;
|
||||||
|
|
@ -328,7 +327,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Initializing \"system\" TCP connection");
|
logger.debug("Initializing \"system\" connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||||
|
|
@ -347,6 +346,8 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
@Override
|
@Override
|
||||||
protected void stopInternal() {
|
protected void stopInternal() {
|
||||||
|
|
||||||
|
publishBrokerUnavailableEvent();
|
||||||
|
|
||||||
this.clientInboundChannel.unsubscribe(this);
|
this.clientInboundChannel.unsubscribe(this);
|
||||||
this.brokerChannel.unsubscribe(this);
|
this.brokerChannel.unsubscribe(this);
|
||||||
|
|
||||||
|
|
@ -358,6 +359,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
logger.error("Failed to close connection in session " + handler.getSessionId() + ": " + t.getMessage());
|
logger.error("Failed to close connection in session " + handler.getSessionId() + ": " + t.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.tcpClient.shutdown();
|
this.tcpClient.shutdown();
|
||||||
}
|
}
|
||||||
|
|
@ -371,6 +373,17 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
|
||||||
String sessionId = headers.getSessionId();
|
String sessionId = headers.getSessionId();
|
||||||
|
|
||||||
|
if (!isBrokerAvailable()) {
|
||||||
|
if (sessionId == null || sessionId == SystemStompConnectionHandler.SESSION_ID) {
|
||||||
|
throw new MessageDeliveryException("Message broker is not active.");
|
||||||
|
}
|
||||||
|
if (logger.isTraceEnabled()) {
|
||||||
|
logger.trace("Message broker is not active. Ignoring message id=" + message.getHeaders().getId());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String destination = headers.getDestination();
|
String destination = headers.getDestination();
|
||||||
StompCommand command = headers.getCommand();
|
StompCommand command = headers.getCommand();
|
||||||
SimpMessageType messageType = headers.getMessageType();
|
SimpMessageType messageType = headers.getMessageType();
|
||||||
|
|
@ -396,9 +409,14 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled()) {
|
||||||
|
logger.trace("Processing message=" + message);
|
||||||
|
}
|
||||||
|
|
||||||
if (SimpMessageType.CONNECT.equals(messageType)) {
|
if (SimpMessageType.CONNECT.equals(messageType)) {
|
||||||
logger.debug("Processing CONNECT in session=" + sessionId +
|
if (logger.isDebugEnabled()) {
|
||||||
", number of connections=" + this.connectionHandlers.size());
|
logger.debug("Processing CONNECT (total connected=" + this.connectionHandlers.size() + ")");
|
||||||
|
}
|
||||||
headers.setLogin(this.clientLogin);
|
headers.setLogin(this.clientLogin);
|
||||||
headers.setPasscode(this.clientPasscode);
|
headers.setPasscode(this.clientPasscode);
|
||||||
if (getVirtualHost() != null) {
|
if (getVirtualHost() != null) {
|
||||||
|
|
@ -412,7 +430,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
StompConnectionHandler handler = this.connectionHandlers.get(sessionId);
|
StompConnectionHandler handler = this.connectionHandlers.get(sessionId);
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Connection already removed for sessionId=" + sessionId);
|
logger.trace("Connection already removed for sessionId '" + sessionId + "'");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +440,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
StompConnectionHandler handler = this.connectionHandlers.get(sessionId);
|
StompConnectionHandler handler = this.connectionHandlers.get(sessionId);
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
logger.warn("Connection for sessionId=" + sessionId + " not found. Ignoring message");
|
logger.warn("Connection for sessionId '" + sessionId + "' not found. Ignoring message");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -466,7 +484,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
@Override
|
@Override
|
||||||
public void afterConnected(TcpConnection<byte[]> connection) {
|
public void afterConnected(TcpConnection<byte[]> connection) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Established TCP connection to broker in session=" + this.sessionId);
|
logger.debug("Established TCP connection to broker in session '" + this.sessionId + "'");
|
||||||
}
|
}
|
||||||
this.tcpConnection = connection;
|
this.tcpConnection = connection;
|
||||||
connection.send(MessageBuilder.withPayload(EMPTY_PAYLOAD).setHeaders(this.connectHeaders).build());
|
connection.send(MessageBuilder.withPayload(EMPTY_PAYLOAD).setHeaders(this.connectHeaders).build());
|
||||||
|
|
@ -483,7 +501,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
*/
|
*/
|
||||||
protected void handleTcpConnectionFailure(String errorMessage, Throwable ex) {
|
protected void handleTcpConnectionFailure(String errorMessage, Throwable ex) {
|
||||||
if (logger.isErrorEnabled()) {
|
if (logger.isErrorEnabled()) {
|
||||||
logger.error(errorMessage + ", sessionId=" + this.sessionId, ex);
|
logger.error(errorMessage + ", sessionId '" + this.sessionId + "'", ex);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
sendStompErrorToClient(errorMessage);
|
sendStompErrorToClient(errorMessage);
|
||||||
|
|
@ -524,7 +542,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
logger.trace("Received broker heartbeat");
|
logger.trace("Received broker heartbeat");
|
||||||
}
|
}
|
||||||
else if (logger.isDebugEnabled()) {
|
else if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Received broker message in session=" + this.sessionId);
|
logger.debug("Received message from broker in session '" + this.sessionId + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StompCommand.CONNECTED == headers.getCommand()) {
|
if (StompCommand.CONNECTED == headers.getCommand()) {
|
||||||
|
|
@ -595,6 +613,9 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("TCP connection to broker closed in session '" + this.sessionId + "'");
|
||||||
|
}
|
||||||
sendStompErrorToClient("Connection to broker closed");
|
sendStompErrorToClient("Connection to broker closed");
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
@ -678,6 +699,10 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (this.isRemoteClientSession) {
|
if (this.isRemoteClientSession) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Removing session '" + sessionId + "' (total remaining=" +
|
||||||
|
(StompBrokerRelayMessageHandler.this.connectionHandlers.size() - 1) + ")");
|
||||||
|
}
|
||||||
StompBrokerRelayMessageHandler.this.connectionHandlers.remove(this.sessionId);
|
StompBrokerRelayMessageHandler.this.connectionHandlers.remove(this.sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2014 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.messaging.simp.broker;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
import org.springframework.messaging.support.GenericMessage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class BrokerMessageHandlerTests {
|
||||||
|
|
||||||
|
private TestBrokerMesageHandler handler;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
this.handler = new TestBrokerMesageHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void startShouldUpdateIsRunning() {
|
||||||
|
assertFalse(this.handler.isRunning());
|
||||||
|
this.handler.start();
|
||||||
|
assertTrue(this.handler.isRunning());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stopShouldUpdateIsRunning() {
|
||||||
|
|
||||||
|
this.handler.start();
|
||||||
|
assertTrue(this.handler.isRunning());
|
||||||
|
|
||||||
|
this.handler.stop();
|
||||||
|
assertFalse(this.handler.isRunning());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stopShouldPublishBrokerAvailabilityEvent() {
|
||||||
|
this.handler.start();
|
||||||
|
this.handler.stop();
|
||||||
|
assertEquals(Arrays.asList(true, false), this.handler.availabilityEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleMessageWhenBrokerNotRunning() {
|
||||||
|
this.handler.handleMessage(new GenericMessage<Object>("payload"));
|
||||||
|
assertEquals(Collections.emptyList(), this.handler.messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishBrokerAvailableEvent() {
|
||||||
|
|
||||||
|
assertFalse(this.handler.isBrokerAvailable());
|
||||||
|
assertEquals(Collections.emptyList(), this.handler.availabilityEvents);
|
||||||
|
|
||||||
|
this.handler.publishBrokerAvailableEvent();
|
||||||
|
|
||||||
|
assertTrue(this.handler.isBrokerAvailable());
|
||||||
|
assertEquals(Arrays.asList(true), this.handler.availabilityEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishBrokerAvailableEventWhenAlreadyAvailable() {
|
||||||
|
|
||||||
|
this.handler.publishBrokerAvailableEvent();
|
||||||
|
this.handler.publishBrokerAvailableEvent();
|
||||||
|
|
||||||
|
assertEquals(Arrays.asList(true), this.handler.availabilityEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishBrokerUnavailableEvent() {
|
||||||
|
|
||||||
|
this.handler.publishBrokerAvailableEvent();
|
||||||
|
assertTrue(this.handler.isBrokerAvailable());
|
||||||
|
|
||||||
|
this.handler.publishBrokerUnavailableEvent();
|
||||||
|
assertFalse(this.handler.isBrokerAvailable());
|
||||||
|
|
||||||
|
assertEquals(Arrays.asList(true, false), this.handler.availabilityEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishBrokerUnavailableEventWhenAlreadyUnvailable() {
|
||||||
|
|
||||||
|
this.handler.publishBrokerAvailableEvent();
|
||||||
|
this.handler.publishBrokerUnavailableEvent();
|
||||||
|
this.handler.publishBrokerUnavailableEvent();
|
||||||
|
|
||||||
|
assertEquals(Arrays.asList(true, false), this.handler.availabilityEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class TestBrokerMesageHandler extends AbstractBrokerMessageHandler
|
||||||
|
implements ApplicationEventPublisher {
|
||||||
|
|
||||||
|
private final List<Message<?>> messages = new ArrayList<>();
|
||||||
|
|
||||||
|
private final List<Boolean> availabilityEvents = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
private TestBrokerMesageHandler() {
|
||||||
|
setApplicationEventPublisher(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startInternal() {
|
||||||
|
publishBrokerAvailableEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleMessageInternal(Message<?> message) {
|
||||||
|
this.messages.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishEvent(ApplicationEvent event) {
|
||||||
|
if (event instanceof BrokerAvailabilityEvent) {
|
||||||
|
this.availabilityEvents.add(((BrokerAvailabilityEvent) event).isBrokerAvailable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -36,6 +36,7 @@ import static org.junit.Assert.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Unit tests for SimpleBrokerMessageHandler.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import org.springframework.messaging.StubMessageChannel;
|
||||||
import org.springframework.messaging.SubscribableChannel;
|
import org.springframework.messaging.SubscribableChannel;
|
||||||
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
|
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
@ -57,7 +58,9 @@ public class StompBrokerRelayRegistrationTests {
|
||||||
|
|
||||||
StompBrokerRelayMessageHandler relayMessageHandler = registration.getMessageHandler(brokerChannel);
|
StompBrokerRelayMessageHandler relayMessageHandler = registration.getMessageHandler(brokerChannel);
|
||||||
|
|
||||||
assertEquals(Arrays.asList(destinationPrefixes), relayMessageHandler.getDestinationPrefixes());
|
assertEquals(Arrays.asList(destinationPrefixes),
|
||||||
|
new ArrayList<String>(relayMessageHandler.getDestinationPrefixes()));
|
||||||
|
|
||||||
assertEquals("clientlogin", relayMessageHandler.getClientLogin());
|
assertEquals("clientlogin", relayMessageHandler.getClientLogin());
|
||||||
assertEquals("clientpasscode", relayMessageHandler.getClientPasscode());
|
assertEquals("clientpasscode", relayMessageHandler.getClientPasscode());
|
||||||
assertEquals("syslogin", relayMessageHandler.getSystemLogin());
|
assertEquals("syslogin", relayMessageHandler.getSystemLogin());
|
||||||
|
|
|
||||||
|
|
@ -164,18 +164,6 @@ public class StompBrokerRelayMessageHandlerIntegrationTests {
|
||||||
this.responseHandler.awaitAndAssert();
|
this.responseHandler.awaitAndAssert();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void brokerUnvailableErrorFrameOnConnect() throws Exception {
|
|
||||||
|
|
||||||
stopActiveMqBrokerAndAwait();
|
|
||||||
|
|
||||||
MessageExchange connect = MessageExchangeBuilder.connectWithError("sess1").build();
|
|
||||||
this.responseHandler.expect(connect);
|
|
||||||
|
|
||||||
this.relay.handleMessage(connect.message);
|
|
||||||
this.responseHandler.awaitAndAssert();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=MessageDeliveryException.class)
|
@Test(expected=MessageDeliveryException.class)
|
||||||
public void messageDeliverExceptionIfSystemSessionForwardFails() throws Exception {
|
public void messageDeliverExceptionIfSystemSessionForwardFails() throws Exception {
|
||||||
stopActiveMqBrokerAndAwait();
|
stopActiveMqBrokerAndAwait();
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,18 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.messaging.Message;
|
import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.StubMessageChannel;
|
import org.springframework.messaging.StubMessageChannel;
|
||||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||||
import org.springframework.messaging.simp.SimpMessageType;
|
import org.springframework.messaging.simp.SimpMessageType;
|
||||||
|
import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
|
||||||
import org.springframework.messaging.support.MessageBuilder;
|
import org.springframework.messaging.support.MessageBuilder;
|
||||||
import org.springframework.messaging.tcp.ReconnectStrategy;
|
import org.springframework.messaging.tcp.ReconnectStrategy;
|
||||||
import org.springframework.messaging.tcp.TcpConnection;
|
import org.springframework.messaging.tcp.TcpConnection;
|
||||||
|
|
@ -50,24 +55,33 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
|
||||||
this.tcpClient = new StubTcpOperations();
|
this.tcpClient = new StubTcpOperations();
|
||||||
|
|
||||||
this.brokerRelay = new StompBrokerRelayMessageHandler(new StubMessageChannel(),
|
this.brokerRelay = new StompBrokerRelayMessageHandler(new StubMessageChannel(),
|
||||||
new StubMessageChannel(), new StubMessageChannel(), Arrays.asList("/topic"));
|
new StubMessageChannel(), new StubMessageChannel(), Arrays.asList("/topic")) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startInternal() {
|
||||||
|
publishBrokerAvailableEvent(); // Force this, since we'll never actually connect
|
||||||
|
super.startInternal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.brokerRelay.setTcpClient(this.tcpClient);
|
this.brokerRelay.setTcpClient(this.tcpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVirtualHostHeader() {
|
public void testVirtualHostHeader() throws Exception {
|
||||||
|
|
||||||
String virtualHost = "ABC";
|
String virtualHost = "ABC";
|
||||||
String sessionId = "sess1";
|
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
|
||||||
headers.setSessionId(sessionId);
|
|
||||||
|
|
||||||
this.brokerRelay.setVirtualHost(virtualHost);
|
this.brokerRelay.setVirtualHost(virtualHost);
|
||||||
this.brokerRelay.start();
|
this.brokerRelay.start();
|
||||||
|
|
||||||
|
String sessionId = "sess1";
|
||||||
|
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||||
|
headers.setSessionId(sessionId);
|
||||||
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
||||||
|
|
||||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||||
|
|
@ -82,12 +96,7 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoginPasscode() {
|
public void testLoginPasscode() throws Exception {
|
||||||
|
|
||||||
String sessionId = "sess1";
|
|
||||||
|
|
||||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
|
||||||
headers.setSessionId(sessionId);
|
|
||||||
|
|
||||||
this.brokerRelay.setClientLogin("clientlogin");
|
this.brokerRelay.setClientLogin("clientlogin");
|
||||||
this.brokerRelay.setClientPasscode("clientpasscode");
|
this.brokerRelay.setClientPasscode("clientpasscode");
|
||||||
|
|
@ -96,6 +105,10 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||||
this.brokerRelay.setSystemPasscode("syspasscode");
|
this.brokerRelay.setSystemPasscode("syspasscode");
|
||||||
|
|
||||||
this.brokerRelay.start();
|
this.brokerRelay.start();
|
||||||
|
|
||||||
|
String sessionId = "sess1";
|
||||||
|
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
|
||||||
|
headers.setSessionId(sessionId);
|
||||||
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
||||||
|
|
||||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||||
|
|
@ -111,13 +124,13 @@ public class StompBrokerRelayMessageHandlerTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDestinationExcluded() {
|
public void testDestinationExcluded() throws Exception {
|
||||||
|
|
||||||
|
this.brokerRelay.start();
|
||||||
|
|
||||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
|
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
|
||||||
headers.setSessionId("sess1");
|
headers.setSessionId("sess1");
|
||||||
headers.setDestination("/user/daisy/foo");
|
headers.setDestination("/user/daisy/foo");
|
||||||
|
|
||||||
this.brokerRelay.start();
|
|
||||||
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
this.brokerRelay.handleMessage(MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build());
|
||||||
|
|
||||||
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
List<Message<byte[]>> sent = this.tcpClient.connection.messages;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.web.socket.config;
|
package org.springframework.web.socket.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
|
@ -127,7 +129,8 @@ public class MessageBrokerBeanDefinitionParserTests {
|
||||||
|
|
||||||
SimpleBrokerMessageHandler brokerMessageHandler = this.appContext.getBean(SimpleBrokerMessageHandler.class);
|
SimpleBrokerMessageHandler brokerMessageHandler = this.appContext.getBean(SimpleBrokerMessageHandler.class);
|
||||||
assertNotNull(brokerMessageHandler);
|
assertNotNull(brokerMessageHandler);
|
||||||
assertEquals(Arrays.asList("/topic", "/queue"), brokerMessageHandler.getDestinationPrefixes());
|
assertEquals(Arrays.asList("/topic", "/queue"),
|
||||||
|
new ArrayList<String>(brokerMessageHandler.getDestinationPrefixes()));
|
||||||
|
|
||||||
List<Class<? extends MessageHandler>> subscriberTypes =
|
List<Class<? extends MessageHandler>> subscriberTypes =
|
||||||
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
|
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue