Removed never used and unsufull no-op interceptor, forced usage of BrokerInterceptor, changed BrokerInterceptor to work on a list of InterceptHandler
This commit is contained in:
@@ -23,8 +23,7 @@ import org.eclipse.moquette.spi.impl.subscriptions.Subscription;
|
||||
* This interface is to be used internally by the broker components.
|
||||
* <p>
|
||||
* An interface is used instead of a class to allow more flexibility in changing
|
||||
* an implementation. For instance, this interface provide a lightweight
|
||||
* no-handler interceptor.
|
||||
* an implementation.
|
||||
* <p>
|
||||
* Interceptor implementations forward notifications to a <code>InterceptHandler</code>,
|
||||
* that is normally a field. So, the implementations should act as a proxy to a custom
|
||||
@@ -34,9 +33,6 @@ import org.eclipse.moquette.spi.impl.subscriptions.Subscription;
|
||||
* @author Wagner Macedo
|
||||
*/
|
||||
public interface Interceptor {
|
||||
/**
|
||||
* When no custom handler is provided, this interceptor should be used.
|
||||
*/
|
||||
|
||||
void notifyClientConnected(ConnectMessage msg);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.eclipse.moquette.proto.messages.ConnectMessage;
|
||||
import org.eclipse.moquette.proto.messages.PublishMessage;
|
||||
import org.eclipse.moquette.spi.impl.subscriptions.Subscription;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -30,11 +31,11 @@ import java.util.concurrent.Executors;
|
||||
* @author Wagner Macedo
|
||||
*/
|
||||
final class BrokerInterceptor implements Interceptor {
|
||||
private final InterceptHandler handler;
|
||||
private final List<InterceptHandler> handlers;
|
||||
private final ExecutorService executor;
|
||||
|
||||
BrokerInterceptor(InterceptHandler handler) {
|
||||
this.handler = handler;
|
||||
BrokerInterceptor(List<InterceptHandler> handlers) {
|
||||
this.handlers = handlers;
|
||||
executor = Executors.newFixedThreadPool(1);
|
||||
}
|
||||
|
||||
@@ -47,51 +48,61 @@ final class BrokerInterceptor implements Interceptor {
|
||||
|
||||
@Override
|
||||
public void notifyClientConnected(final ConnectMessage msg) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onConnect(msg.readOnlyClone());
|
||||
}
|
||||
});
|
||||
for (final InterceptHandler handler : this.handlers) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onConnect(msg.readOnlyClone());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyClientDisconnected(final String clientID) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onDisconnect(clientID);
|
||||
}
|
||||
});
|
||||
for (final InterceptHandler handler : this.handlers) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onDisconnect(clientID);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyTopicPublished(final PublishMessage msg) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onPublish(msg.readOnlyClone());
|
||||
}
|
||||
});
|
||||
for (final InterceptHandler handler : this.handlers) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onPublish(msg.readOnlyClone());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyTopicSubscribed(final Subscription sub) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onSubscribe(sub.clone());
|
||||
}
|
||||
});
|
||||
for (final InterceptHandler handler : this.handlers) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onSubscribe(sub);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyTopicUnsubscribed(final String sub) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onUnsubscribe(sub);
|
||||
}
|
||||
});
|
||||
for (final InterceptHandler handler : this.handlers) {
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.onUnsubscribe(sub);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@ import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.apache.commons.codec.binary.StringUtils;
|
||||
import org.eclipse.moquette.interception.Interceptor;
|
||||
import org.eclipse.moquette.server.netty.NettyChannel;
|
||||
import org.eclipse.moquette.spi.IMatchingCondition;
|
||||
import org.eclipse.moquette.spi.IMessagesStore;
|
||||
@@ -106,7 +103,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
private IMessagesStore m_messagesStore;
|
||||
private ISessionsStore m_sessionsStore;
|
||||
private IAuthenticator m_authenticator;
|
||||
private Interceptor interceptor = null;
|
||||
private BrokerInterceptor m_interceptor;
|
||||
|
||||
//maps clientID to Will testament, if specified on CONNECT
|
||||
private Map<String, WillMessage> m_willStore = new HashMap<>();
|
||||
@@ -116,13 +113,6 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
|
||||
ProtocolProcessor() {}
|
||||
|
||||
void init(SubscriptionsStore subscriptions, IMessagesStore storageService,
|
||||
ISessionsStore sessionsStore,
|
||||
IAuthenticator authenticator,
|
||||
boolean allowAnonymous, IAuthorizator authorizator) {
|
||||
init(subscriptions, storageService, sessionsStore, authenticator, allowAnonymous, authorizator, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param subscriptions the subscription store where are stored all the existing
|
||||
* clients subscriptions.
|
||||
@@ -137,11 +127,9 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
void init(SubscriptionsStore subscriptions, IMessagesStore storageService,
|
||||
ISessionsStore sessionsStore,
|
||||
IAuthenticator authenticator,
|
||||
boolean allowAnonymous, IAuthorizator authorizator, Interceptor interceptor) {
|
||||
boolean allowAnonymous, IAuthorizator authorizator, BrokerInterceptor interceptor) {
|
||||
//m_clientIDs = clientIDs;
|
||||
if (interceptor != null) {
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
this.m_interceptor = interceptor;
|
||||
this.subscriptions = subscriptions;
|
||||
this.allowAnonymous = allowAnonymous;
|
||||
m_authorizator = authorizator;
|
||||
@@ -177,7 +165,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
ConnAckMessage okResp = new ConnAckMessage();
|
||||
okResp.setReturnCode(ConnAckMessage.IDENTIFIER_REJECTED);
|
||||
session.write(okResp);
|
||||
interceptor.notifyClientConnected(msg);
|
||||
m_interceptor.notifyClientConnected(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,7 +221,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
AbstractMessage.QOSType willQos = AbstractMessage.QOSType.values()[msg.getWillQos()];
|
||||
byte[] willPayload = msg.getWillMessage().getBytes();
|
||||
ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(willPayload.length).put(willPayload).flip();
|
||||
//save the will testment in the clientID store
|
||||
//save the will testament in the clientID store
|
||||
WillMessage will = new WillMessage(msg.getWillTopic(), bb, msg.isWillRetain(),willQos );
|
||||
m_willStore.put(msg.getClientID(), will);
|
||||
}
|
||||
@@ -253,7 +241,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
okResp.setSessionPresent(true);
|
||||
}
|
||||
session.write(okResp);
|
||||
interceptor.notifyClientConnected(msg);
|
||||
m_interceptor.notifyClientConnected(msg);
|
||||
|
||||
LOG.info("Create persistent session for clientID <{}>", msg.getClientID());
|
||||
m_sessionsStore.addNewSubscription(Subscription.createEmptySubscription(msg.getClientID(), true)); //null means EmptySubscription
|
||||
@@ -317,7 +305,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
String user = (String) session.getAttribute(NettyChannel.ATTR_KEY_USERNAME);
|
||||
if (m_authorizator.canWrite(topic, user, clientID)) {
|
||||
executePublish(clientID, msg);
|
||||
interceptor.notifyTopicPublished(msg);
|
||||
m_interceptor.notifyTopicPublished(msg);
|
||||
} else {
|
||||
LOG.debug("topic {} doesn't have write credentials", topic);
|
||||
}
|
||||
@@ -576,7 +564,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
m_willStore.remove(clientID);
|
||||
|
||||
LOG.info("DISCONNECT client <{}> with clean session {}", clientID, cleanSession);
|
||||
interceptor.notifyClientDisconnected(clientID);
|
||||
m_interceptor.notifyClientDisconnected(clientID);
|
||||
}
|
||||
|
||||
void processConnectionLost(LostConnectionEvent evt) {
|
||||
@@ -610,7 +598,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
for (String topic : topics) {
|
||||
subscriptions.removeSubscription(topic, clientID);
|
||||
m_sessionsStore.removeSubscription(topic, clientID);
|
||||
interceptor.notifyTopicUnsubscribed(topic);
|
||||
m_interceptor.notifyTopicUnsubscribed(topic);
|
||||
}
|
||||
|
||||
//ack the client
|
||||
@@ -655,7 +643,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
subscriptions.add(newSubscription);
|
||||
|
||||
//notify the Observables
|
||||
interceptor.notifyTopicSubscribed(newSubscription);
|
||||
m_interceptor.notifyTopicSubscribed(newSubscription);
|
||||
|
||||
//scans retained messages to be published to the new subscription
|
||||
Collection<IMessagesStore.StoredMessage> messages = m_messagesStore.searchMatching(new IMatchingCondition() {
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.eclipse.moquette.spi.impl;
|
||||
import com.lmax.disruptor.EventHandler;
|
||||
import com.lmax.disruptor.RingBuffer;
|
||||
import com.lmax.disruptor.dsl.Disruptor;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.HdrHistogram.Histogram;
|
||||
import org.eclipse.moquette.interception.InterceptHandler;
|
||||
import org.eclipse.moquette.interception.Interceptor;
|
||||
import org.eclipse.moquette.proto.messages.AbstractMessage;
|
||||
import org.eclipse.moquette.spi.impl.security.*;
|
||||
import org.eclipse.moquette.server.ServerChannel;
|
||||
@@ -40,6 +40,8 @@ import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -75,7 +77,7 @@ public class SimpleMessaging implements IMessaging, EventHandler<ValueEvent> {
|
||||
|
||||
private ExecutorService m_executor;
|
||||
private Disruptor<ValueEvent> m_disruptor;
|
||||
private Interceptor interceptor;
|
||||
private BrokerInterceptor m_interceptor;
|
||||
|
||||
private static SimpleMessaging INSTANCE;
|
||||
|
||||
@@ -194,14 +196,18 @@ public class SimpleMessaging implements IMessaging, EventHandler<ValueEvent> {
|
||||
m_sessionsStore = mapStorage;
|
||||
|
||||
m_storageService.initStore();
|
||||
|
||||
try {
|
||||
final InterceptHandler handler = Class.forName(props.getProperty("intercept.handler"))
|
||||
.asSubclass(InterceptHandler.class).newInstance();
|
||||
interceptor = new BrokerInterceptor(handler);
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("Can't load the intercept handler {}", ex);
|
||||
|
||||
List<InterceptHandler> observers = new ArrayList<>();
|
||||
String interceptorClassName = props.getProperty("intercept.handler");
|
||||
if (interceptorClassName != null && !interceptorClassName.isEmpty()) {
|
||||
try {
|
||||
InterceptHandler handler = Class.forName(interceptorClassName).asSubclass(InterceptHandler.class).newInstance();
|
||||
observers.add(handler);
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("Can't load the intercept handler {}", ex);
|
||||
}
|
||||
}
|
||||
m_interceptor = new BrokerInterceptor(observers);
|
||||
|
||||
//List<Subscription> storedSubscriptions = m_sessionsStore.listAllSubscriptions();
|
||||
//subscriptions.init(storedSubscriptions);
|
||||
@@ -251,7 +257,7 @@ public class SimpleMessaging implements IMessaging, EventHandler<ValueEvent> {
|
||||
}
|
||||
|
||||
boolean allowAnonymous = Boolean.parseBoolean(props.getProperty(ALLOW_ANONYMOUS_PROPERTY_NAME, "true"));
|
||||
m_processor.init(subscriptions, m_storageService, m_sessionsStore, authenticator, allowAnonymous, authorizator, interceptor);
|
||||
m_processor.init(subscriptions, m_storageService, m_sessionsStore, authenticator, allowAnonymous, authorizator, m_interceptor);
|
||||
}
|
||||
|
||||
private Object loadClass(String className, Class<?> cls) {
|
||||
@@ -291,8 +297,8 @@ public class SimpleMessaging implements IMessaging, EventHandler<ValueEvent> {
|
||||
|
||||
private void processStop() {
|
||||
LOG.debug("processStop invoked");
|
||||
if (interceptor != null) {
|
||||
((BrokerInterceptor) interceptor).stop();
|
||||
if (m_interceptor != null) {
|
||||
this.m_interceptor.stop();
|
||||
}
|
||||
m_storageService.close();
|
||||
LOG.debug("subscription tree {}", subscriptions.dumpTree());
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ import java.text.ParseException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import org.eclipse.moquette.interception.Interceptor;
|
||||
import org.eclipse.moquette.spi.ISessionsStore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
Reference in New Issue
Block a user