Add ActiveMQ-based STOMP relay integration tests

This commit is contained in:
Rossen Stoyanchev
2013-08-15 17:29:10 -04:00
parent 3fb5ff2654
commit 94fefec0f9
8 changed files with 563 additions and 475 deletions

View File

@@ -376,13 +376,19 @@ public class StompBrokerRelayMessageHandler implements MessageHandler, SmartLife
}
private void brokerAvailable() {
if (this.brokerAvailable.compareAndSet(false, true)) {
if ((this.applicationEventPublisher != null) && this.brokerAvailable.compareAndSet(false, true)) {
if (logger.isTraceEnabled()) {
logger.trace("Publishing BrokerAvailabilityEvent (available)");
}
this.applicationEventPublisher.publishEvent(new BrokerAvailabilityEvent(true, this));
}
}
private void brokerUnavailable() {
if (this.brokerAvailable.compareAndSet(true, false)) {
if ((this.applicationEventPublisher != null) && this.brokerAvailable.compareAndSet(true, false)) {
if (logger.isTraceEnabled()) {
logger.trace("Publishing BrokerAvailabilityEvent (unavailable)");
}
this.applicationEventPublisher.publishEvent(new BrokerAvailabilityEvent(false, this));
}
}
@@ -518,52 +524,42 @@ public class StompBrokerRelayMessageHandler implements MessageHandler, SmartLife
private boolean forwardInternal(final Message<?> message) {
TcpConnection<String, String> localConnection = this.connection;
if (localConnection != null) {
if (logger.isTraceEnabled()) {
logger.trace("Forwarding message to STOMP broker, message id=" + message.getHeaders().getId());
}
byte[] bytes = stompMessageConverter.fromMessage(message);
final Deferred<Boolean, Promise<Boolean>> deferred = new DeferredPromiseSpec<Boolean>().get();
String payload = new String(bytes, Charset.forName("UTF-8"));
localConnection.send(payload, new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
if (!success && StompHeaderAccessor.wrap(message).getCommand() != StompCommand.DISCONNECT) {
deferred.accept(false);
} else {
deferred.accept(true);
}
}
});
Boolean success = null;
try {
success = deferred.compose().await();
if (success == null) {
sendError(sessionId, "Timed out waiting for message to be forwarded to the broker");
}
else if (!success) {
sendError(sessionId, "Failed to forward message to the broker");
}
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
sendError(sessionId, "Interrupted while forwarding message to the broker");
}
if (success == null) {
success = false;
}
return success;
} else {
if (localConnection == null) {
return false;
}
if (logger.isTraceEnabled()) {
logger.trace("Forwarding to STOMP broker, message: " + message);
}
byte[] bytes = stompMessageConverter.fromMessage(message);
String payload = new String(bytes, Charset.forName("UTF-8"));
final Deferred<Boolean, Promise<Boolean>> deferred = new DeferredPromiseSpec<Boolean>().get();
localConnection.send(payload, new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
deferred.accept(success);
}
});
Boolean success = null;
try {
success = deferred.compose().await();
if (success == null) {
sendError(sessionId, "Timed out waiting for message to be forwarded to the broker");
}
else if (!success) {
if (StompHeaderAccessor.wrap(message).getCommand() != StompCommand.DISCONNECT) {
sendError(sessionId, "Failed to forward message to the broker");
}
}
}
catch (InterruptedException ie) {
Thread.currentThread().interrupt();
sendError(sessionId, "Interrupted while forwarding message to the broker");
}
return (success != null) ? success : false;
}
private void flushMessages() {

View File

@@ -57,6 +57,9 @@ public enum StompCommand {
private static Set<StompCommand> destinationRequiredLookup =
new HashSet<StompCommand>(Arrays.asList(SEND, SUBSCRIBE, MESSAGE));
private static Set<StompCommand> subscriptionIdRequiredLookup =
new HashSet<StompCommand>(Arrays.asList(SUBSCRIBE, UNSUBSCRIBE, MESSAGE));
static {
messageTypeLookup.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
messageTypeLookup.put(StompCommand.STOMP, SimpMessageType.CONNECT);
@@ -76,4 +79,8 @@ public enum StompCommand {
return destinationRequiredLookup.contains(this);
}
public boolean requiresSubscriptionId() {
return subscriptionIdRequiredLookup.contains(this);
}
}

View File

@@ -54,7 +54,9 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
public static final String STOMP_MESSAGE_ID_HEADER = "message-id";
public static final String STOMP_RECEIPT_ID_HEADER = "receipt-id";
public static final String STOMP_RECEIPT_HEADER = "receipt"; // any client frame except CONNECT
public static final String STOMP_RECEIPT_ID_HEADER = "receipt-id"; // RECEIPT frame
public static final String STOMP_SUBSCRIPTION_HEADER = "subscription";
@@ -176,20 +178,22 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
result.put(STOMP_CONTENT_TYPE_HEADER, Arrays.asList(contentType.toString()));
}
if (StompCommand.MESSAGE.equals(getCommand())) {
if (getCommand().requiresSubscriptionId()) {
String subscriptionId = getSubscriptionId();
if (subscriptionId != null) {
result.put(STOMP_SUBSCRIPTION_HEADER, Arrays.asList(subscriptionId));
String name = StompCommand.MESSAGE.equals(getCommand()) ? STOMP_SUBSCRIPTION_HEADER : STOMP_ID_HEADER;
result.put(name, Arrays.asList(subscriptionId));
}
else {
logger.warn("STOMP MESSAGE frame should have a subscription: " + this.toString());
}
if ((getMessageId() == null)) {
String messageId = getSessionId() + "-" + messageIdCounter.getAndIncrement();
result.put(STOMP_MESSAGE_ID_HEADER, Arrays.asList(messageId));
logger.warn(getCommand() + " frame should have a subscription: " + this.toString());
}
}
if (StompCommand.MESSAGE.equals(getCommand()) && ((getMessageId() == null))) {
String messageId = getSessionId() + "-" + messageIdCounter.getAndIncrement();
result.put(STOMP_MESSAGE_ID_HEADER, Arrays.asList(messageId));
}
return result;
}
@@ -302,6 +306,14 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
return getFirstNativeHeader(STOMP_RECEIPT_ID_HEADER);
}
public void setReceipt(String receiptId) {
setNativeHeader(STOMP_RECEIPT_HEADER, receiptId);
}
public String getReceipt() {
return getFirstNativeHeader(STOMP_RECEIPT_HEADER);
}
public String getMessage() {
return getFirstNativeHeader(STOMP_MESSAGE_HEADER);
}