![JAR search and dependency download from the Maven repository](/logo.png)
io.vertx.ext.stomp.impl.EventBusBridge Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vertx-stomp Show documentation
Show all versions of vertx-stomp Show documentation
Stomp support for Vert.x 3
/*
* Copyright (c) 2011-2015 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.vertx.ext.stomp.impl;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.eventbus.Message;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.stomp.*;
import io.vertx.ext.stomp.utils.Headers;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Clement Escoffier
*/
public class EventBusBridge extends Topic {
private final BridgeOptions options;
private final Map expressions = new HashMap<>();
private final Map> registry = new HashMap<>();
public EventBusBridge(Vertx vertx, BridgeOptions options) {
super(vertx, null);
this.options = options;
}
/**
* @return the destination address.
*/
@Override
public String destination() {
return "<>";
}
/**
* Handles a subscription request to the current {@link Destination}. All check about the frame format and unicity
* of the id should have been done beforehand.
*
* @param connection the connection
* @param frame the {@code SUBSCRIBE} frame
* @return the current instance of {@link Destination}
*/
@Override
public synchronized Destination subscribe(StompServerConnection connection, Frame frame) {
String address = frame.getDestination();
// Need to check whether the client can receive message from the event bus (outbound).
if (checkMatches(false, address, null)) {
// We need the subscription object to transform messages.
Subscription subscription = new Subscription(connection, frame);
subscriptions.add(subscription);
if (!registry.containsKey(address)) {
registry.put(address, vertx.eventBus().consumer(address, msg -> {
if (!checkMatches(false, address, msg.body())) {
return;
}
if (options.isPointToPoint()) {
Optional chosen = subscriptions.stream().filter(s -> s.destination.equals(address)).findAny();
if (chosen.isPresent()) {
Frame stompFrame = transform(msg, chosen.get());
chosen.get().connection.write(stompFrame);
}
} else {
subscriptions.stream().filter(s -> s.destination.equals(address)).forEach(s -> {
Frame stompFrame = transform(msg, s);
s.connection.write(stompFrame);
});
}
}));
}
return this;
}
return null;
}
/**
* Handles a un-subscription request to the current {@link Destination}.
*
* @param connection the connection
* @param frame the {@code UNSUBSCRIBE} frame
* @return {@code true} if the un-subscription has been handled, {@code false} otherwise.
*/
@Override
public synchronized boolean unsubscribe(StompServerConnection connection, Frame frame) {
for (Subscription subscription : new ArrayList<>(subscriptions)) {
if (subscription.connection.equals(connection)
&& subscription.id.equals(frame.getId())) {
boolean r = subscriptions.remove(subscription);
Optional any = subscriptions.stream().filter(s -> s.destination.equals(subscription.destination)).findAny();
// We unregister the event bus consumer if there are no subscription on this address anymore.
if (!any.isPresent()) {
MessageConsumer consumer = registry.remove(subscription.destination);
if (consumer != null) {
consumer.unregister();
}
}
return r;
}
}
return false;
}
/**
* Removes all subscriptions of the given connection
*
* @param connection the connection
* @return the current instance of {@link Destination}
*/
@Override
public synchronized Destination unsubscribeConnection(StompServerConnection connection) {
new ArrayList<>(subscriptions)
.stream()
.filter(subscription -> subscription.connection.equals(connection))
.forEach(s -> {
subscriptions.remove(s);
Optional any = subscriptions.stream().filter(s2 -> s2.destination.equals(s.destination))
.findAny();
// We unregister the event bus consumer if there are no subscription on this address anymore.
if (!any.isPresent()) {
MessageConsumer consumer = registry.remove(s.destination);
if (consumer != null) {
consumer.unregister();
}
}
});
return this;
}
private Frame transform(Message