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:
andrea
2015-08-08 18:37:32 +02:00
parent 9daff2b738
commit dc55ff4078
7 changed files with 94 additions and 86 deletions
@@ -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());
@@ -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;