wildfire chat server source initial submit

This commit is contained in:
heavyrain2012
2019-03-16 17:04:23 +08:00
parent e59217bd10
commit cab3ca0916
1466 changed files with 528862 additions and 15919 deletions
@@ -1,64 +0,0 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception;
import io.moquette.interception.messages.InterceptAcknowledgedMessage;
import io.moquette.interception.messages.InterceptConnectMessage;
import io.moquette.interception.messages.InterceptConnectionLostMessage;
import io.moquette.interception.messages.InterceptDisconnectMessage;
import io.moquette.interception.messages.InterceptPublishMessage;
import io.moquette.interception.messages.InterceptSubscribeMessage;
import io.moquette.interception.messages.InterceptUnsubscribeMessage;
/**
* Basic abstract class usefull to avoid empty methods creation in subclasses.
*/
public abstract class AbstractInterceptHandler implements InterceptHandler {
@Override
public Class<?>[] getInterceptedMessageTypes() {
return InterceptHandler.ALL_MESSAGE_TYPES;
}
@Override
public void onConnect(InterceptConnectMessage msg) {
}
@Override
public void onDisconnect(InterceptDisconnectMessage msg) {
}
@Override
public void onConnectionLost(InterceptConnectionLostMessage msg) {
}
@Override
public void onPublish(InterceptPublishMessage msg) {
}
@Override
public void onSubscribe(InterceptSubscribeMessage msg) {
}
@Override
public void onUnsubscribe(InterceptUnsubscribeMessage msg) {
}
@Override
public void onMessageAcknowledged(InterceptAcknowledgedMessage msg) {
}
}
@@ -1,195 +0,0 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception;
import io.moquette.BrokerConstants;
import io.moquette.interception.messages.*;
import io.moquette.broker.config.IConfig;
import io.moquette.broker.subscriptions.Subscription;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static io.moquette.logging.LoggingUtils.getInterceptorIds;
/**
* An interceptor that execute the interception tasks asynchronously.
*/
public final class BrokerInterceptor implements Interceptor {
private static final Logger LOG = LoggerFactory.getLogger(BrokerInterceptor.class);
private final Map<Class<?>, List<InterceptHandler>> handlers;
private final ExecutorService executor;
private BrokerInterceptor(int poolSize, List<InterceptHandler> handlers) {
LOG.info("Initializing broker interceptor. InterceptorIds={}", getInterceptorIds(handlers));
this.handlers = new HashMap<>();
for (Class<?> messageType : InterceptHandler.ALL_MESSAGE_TYPES) {
this.handlers.put(messageType, new CopyOnWriteArrayList<InterceptHandler>());
}
for (InterceptHandler handler : handlers) {
this.addInterceptHandler(handler);
}
executor = Executors.newFixedThreadPool(poolSize);
}
/**
* Configures a broker interceptor, with a thread pool of one thread.
*
* @param handlers InterceptHandlers listeners.
*/
public BrokerInterceptor(List<InterceptHandler> handlers) {
this(1, handlers);
}
/**
* Configures a broker interceptor using the pool size specified in the IConfig argument.
* @param props configuration properties.
* @param handlers InterceptHandlers listeners.
*
*/
public BrokerInterceptor(IConfig props, List<InterceptHandler> handlers) {
this(Integer.parseInt(props.getProperty(BrokerConstants.BROKER_INTERCEPTOR_THREAD_POOL_SIZE, "1")), handlers);
}
/**
* Shutdown graciously the executor service
*/
void stop() {
LOG.info("Shutting down interceptor thread pool...");
executor.shutdown();
try {
LOG.info("Waiting for thread pool tasks to terminate...");
executor.awaitTermination(10L, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
if (!executor.isTerminated()) {
LOG.warn("Forcing shutdown of interceptor thread pool...");
executor.shutdownNow();
}
LOG.info("interceptors stopped");
}
@Override
public void notifyClientConnected(final MqttConnectMessage msg) {
for (final InterceptHandler handler : this.handlers.get(InterceptConnectMessage.class)) {
LOG.debug("Sending MQTT CONNECT message to interceptor. CId={}, interceptorId={}",
msg.payload().clientIdentifier(), handler.getID());
executor.execute(() -> handler.onConnect(new InterceptConnectMessage(msg)));
}
}
@Override
public void notifyClientDisconnected(final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptDisconnectMessage.class)) {
LOG.debug("Notifying MQTT client disconnection to interceptor. CId={}, username={}, interceptorId={}",
clientID, username, handler.getID());
executor.execute(() -> handler.onDisconnect(new InterceptDisconnectMessage(clientID, username)));
}
}
@Override
public void notifyClientConnectionLost(final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptConnectionLostMessage.class)) {
LOG.debug("Notifying unexpected MQTT client disconnection to interceptor CId={}, username={}, " +
"interceptorId={}", clientID, username, handler.getID());
executor.execute(() -> handler.onConnectionLost(new InterceptConnectionLostMessage(clientID, username)));
}
}
@Override
public void notifyTopicPublished(final MqttPublishMessage msg, final String clientID, final String username) {
msg.retain();
executor.execute(() -> {
try {
int messageId = msg.variableHeader().messageId();
String topic = msg.variableHeader().topicName();
for (InterceptHandler handler : handlers.get(InterceptPublishMessage.class)) {
LOG.debug("Notifying MQTT PUBLISH message to interceptor. CId={}, messageId={}, topic={}, "
+ "interceptorId={}", clientID, messageId, topic, handler.getID());
handler.onPublish(new InterceptPublishMessage(msg, clientID, username));
}
} finally {
ReferenceCountUtil.release(msg);
}
});
}
@Override
public void notifyTopicSubscribed(final Subscription sub, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptSubscribeMessage.class)) {
LOG.debug("Notifying MQTT SUBSCRIBE message to interceptor. CId={}, topicFilter={}, interceptorId={}",
sub.getClientId(), sub.getTopicFilter(), handler.getID());
executor.execute(() -> handler.onSubscribe(new InterceptSubscribeMessage(sub, username)));
}
}
@Override
public void notifyTopicUnsubscribed(final String topic, final String clientID, final String username) {
for (final InterceptHandler handler : this.handlers.get(InterceptUnsubscribeMessage.class)) {
LOG.debug("Notifying MQTT UNSUBSCRIBE message to interceptor. CId={}, topic={}, interceptorId={}", clientID,
topic, handler.getID());
executor.execute(() -> handler.onUnsubscribe(new InterceptUnsubscribeMessage(topic, clientID, username)));
}
}
@Override
public void notifyMessageAcknowledged(final InterceptAcknowledgedMessage msg) {
for (final InterceptHandler handler : this.handlers.get(InterceptAcknowledgedMessage.class)) {
LOG.debug("Notifying MQTT ACK message to interceptor. CId={}, messageId={}, topic={}, interceptorId={}",
msg.getMsg()/*.getClientID()*/, msg.getPacketID(), msg.getTopic(), handler.getID());
executor.execute(() -> handler.onMessageAcknowledged(msg));
}
}
@Override
public void addInterceptHandler(InterceptHandler interceptHandler) {
Class<?>[] interceptedMessageTypes = getInterceptedMessageTypes(interceptHandler);
LOG.info("Adding MQTT message interceptor. InterceptorId={}, handledMessageTypes={}",
interceptHandler.getID(), interceptedMessageTypes);
for (Class<?> interceptMessageType : interceptedMessageTypes) {
this.handlers.get(interceptMessageType).add(interceptHandler);
}
}
@Override
public void removeInterceptHandler(InterceptHandler interceptHandler) {
Class<?>[] interceptedMessageTypes = getInterceptedMessageTypes(interceptHandler);
LOG.info("Removing MQTT message interceptor. InterceptorId={}, handledMessageTypes={}",
interceptHandler.getID(), interceptedMessageTypes);
for (Class<?> interceptMessageType : interceptedMessageTypes) {
this.handlers.get(interceptMessageType).remove(interceptHandler);
}
}
private static Class<?>[] getInterceptedMessageTypes(InterceptHandler interceptHandler) {
Class<?>[] interceptedMessageTypes = interceptHandler.getInterceptedMessageTypes();
if (interceptedMessageTypes == null) {
return InterceptHandler.ALL_MESSAGE_TYPES;
}
return interceptedMessageTypes;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -17,7 +17,6 @@
package io.moquette.interception;
import io.moquette.interception.messages.*;
import io.moquette.broker.subscriptions.Subscription;
import io.netty.handler.codec.mqtt.MqttMessage;
/**
@@ -32,17 +31,20 @@ import io.netty.handler.codec.mqtt.MqttMessage;
public interface InterceptHandler {
Class<?>[] ALL_MESSAGE_TYPES = {InterceptConnectMessage.class, InterceptDisconnectMessage.class,
InterceptConnectionLostMessage.class, InterceptPublishMessage.class, InterceptSubscribeMessage.class,
InterceptUnsubscribeMessage.class, InterceptAcknowledgedMessage.class};
InterceptConnectionLostMessage.class, InterceptPublishMessage.class, InterceptAcknowledgedMessage.class};
/**
* @return the identifier of this intercept handler.
* Returns the identifier of this intercept handler.
*
* @return
*/
String getID();
/**
* @return the InterceptMessage subtypes that this handler can process. If the result is null or
* Returns the InterceptMessage subtypes that this handler can process. If the result is null or
* equal to ALL_MESSAGE_TYPES, all the message types will be processed.
*
* @return
*/
Class<?>[] getInterceptedMessageTypes();
@@ -54,9 +56,5 @@ public interface InterceptHandler {
void onPublish(InterceptPublishMessage msg);
void onSubscribe(InterceptSubscribeMessage msg);
void onUnsubscribe(InterceptUnsubscribeMessage msg);
void onMessageAcknowledged(InterceptAcknowledgedMessage msg);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -17,7 +17,6 @@
package io.moquette.interception;
import io.moquette.interception.messages.InterceptAcknowledgedMessage;
import io.moquette.broker.subscriptions.Subscription;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
@@ -39,12 +38,6 @@ public interface Interceptor {
void notifyClientConnectionLost(String clientID, String username);
void notifyTopicPublished(MqttPublishMessage msg, String clientID, String username);
void notifyTopicSubscribed(Subscription sub, String username);
void notifyTopicUnsubscribed(String topic, String clientID, String username);
void notifyMessageAcknowledged(InterceptAcknowledgedMessage msg);
void addInterceptHandler(InterceptHandler interceptHandler);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -16,68 +16,10 @@
package io.moquette.interception.messages;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.MqttQoS;
import java.io.Serializable;
import static io.moquette.spi.IMessagesStore.StoredMessage;
public class InterceptAcknowledgedMessage implements InterceptMessage {
class StoredMessage implements Serializable {
private static final long serialVersionUID = 1755296138639817304L;
private MqttQoS m_qos;
final byte[] m_payload;
final String m_topic;
private boolean m_retained;
private String m_clientID;
public StoredMessage(byte[] message, MqttQoS qos, String topic) {
m_qos = qos;
m_payload = message;
m_topic = topic;
}
public void setQos(MqttQoS qos) {
this.m_qos = qos;
}
public MqttQoS getQos() {
return m_qos;
}
public String getTopic() {
return m_topic;
}
public String getClientID() {
return m_clientID;
}
public void setClientID(String m_clientID) {
this.m_clientID = m_clientID;
}
public ByteBuf getPayload() {
return Unpooled.copiedBuffer(m_payload);
}
public void setRetained(boolean retained) {
this.m_retained = retained;
}
public boolean isRetained() {
return m_retained;
}
@Override
public String toString() {
return "PublishEvent{clientID='" + m_clientID + '\'' + ", m_retain="
+ m_retained + ", m_qos=" + m_qos + ", m_topic='" + m_topic + '\'' + '}';
}
}
private final StoredMessage msg;
private final String username;
private final String topic;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -18,8 +18,6 @@ package io.moquette.interception.messages;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
import java.nio.charset.StandardCharsets;
public class InterceptConnectMessage extends InterceptAbstractMessage {
private final MqttConnectMessage msg;
@@ -74,7 +72,7 @@ public class InterceptConnectMessage extends InterceptAbstractMessage {
}
public byte[] getPassword() {
return msg.payload().password().getBytes(StandardCharsets.UTF_8);
return msg.payload().password();
}
public String getWillTopic() {
@@ -82,6 +80,6 @@ public class InterceptConnectMessage extends InterceptAbstractMessage {
}
public byte[] getWillMessage() {
return msg.payload().willMessage().getBytes(StandardCharsets.UTF_8);
return msg.payload().willMessage().getBytes();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -1,36 +1,36 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception.messages;
public class InterceptDisconnectMessage implements InterceptMessage {
private final String clientID;
private final String username;
public InterceptDisconnectMessage(String clientID, String username) {
this.clientID = clientID;
this.username = username;
}
public String getClientID() {
return clientID;
}
public String getUsername() {
return username;
}
}
/*
* Copyright (c) 2012-2017 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.moquette.interception.messages;
public class InterceptDisconnectMessage implements InterceptMessage {
private final String clientID;
private final String username;
public InterceptDisconnectMessage(String clientID, String username) {
this.clientID = clientID;
this.username = username;
}
public String getClientID() {
return clientID;
}
public String getUsername() {
return username;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 The original author or authors
* Copyright (c) 2012-2017 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
@@ -1,50 +1,50 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception.messages;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
public class InterceptPublishMessage extends InterceptAbstractMessage {
private final MqttPublishMessage msg;
private final String clientID;
private final String username;
public InterceptPublishMessage(MqttPublishMessage msg, String clientID, String username) {
super(msg);
this.msg = msg;
this.clientID = clientID;
this.username = username;
}
public String getTopicName() {
return msg.variableHeader().topicName();
}
public ByteBuf getPayload() {
return msg.payload();
}
public String getClientID() {
return clientID;
}
public String getUsername() {
return username;
}
}
/*
* Copyright (c) 2012-2017 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.moquette.interception.messages;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
public class InterceptPublishMessage extends InterceptAbstractMessage {
private final MqttPublishMessage msg;
private final String clientID;
private final String username;
public InterceptPublishMessage(MqttPublishMessage msg, String clientID, String username) {
super(msg);
this.msg = msg;
this.clientID = clientID;
this.username = username;
}
public String getTopicName() {
return msg.variableHeader().topicName();
}
public ByteBuf getPayload() {
return msg.payload();
}
public String getClientID() {
return clientID;
}
public String getUsername() {
return username;
}
}
@@ -1,47 +0,0 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception.messages;
import io.moquette.broker.subscriptions.Subscription;
import io.netty.handler.codec.mqtt.MqttQoS;
public class InterceptSubscribeMessage implements InterceptMessage {
private final Subscription subscription;
private final String username;
public InterceptSubscribeMessage(Subscription subscription, String username) {
this.subscription = subscription;
this.username = username;
}
public String getClientID() {
return subscription.getClientId();
}
public MqttQoS getRequestedQos() {
return subscription.getRequestedQos();
}
public String getTopicFilter() {
return subscription.getTopicFilter().toString();
}
public String getUsername() {
return username;
}
}
@@ -1,42 +0,0 @@
/*
* Copyright (c) 2012-2018 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.moquette.interception.messages;
public class InterceptUnsubscribeMessage implements InterceptMessage {
private final String topicFilter;
private final String clientID;
private final String username;
public InterceptUnsubscribeMessage(String topicFilter, String clientID, String username) {
this.topicFilter = topicFilter;
this.clientID = clientID;
this.username = username;
}
public String getTopicFilter() {
return topicFilter;
}
public String getClientID() {
return clientID;
}
public String getUsername() {
return username;
}
}