Exposed method to retrieve the list of Server's connected clients (issue #448)
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package io.moquette.broker;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ClientDescriptor {
|
||||
|
||||
private final String clientID;
|
||||
private final String address;
|
||||
private final int port;
|
||||
|
||||
ClientDescriptor(String clientID, String address, int port) {
|
||||
this.clientID = clientID;
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getClientID() {
|
||||
return clientID;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ClientDescriptor that = (ClientDescriptor) o;
|
||||
return port == that.port &&
|
||||
Objects.equals(clientID, that.clientID) &&
|
||||
Objects.equals(address, that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(clientID, address, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClientDescriptor{" +
|
||||
"clientID='" + clientID + '\'' +
|
||||
", address='" + address + '\'' +
|
||||
", port=" + port +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -488,4 +489,8 @@ final class MQTTConnection {
|
||||
public String toString() {
|
||||
return "MQTTConnection{channel=" + channel + ", connected=" + connected + '}';
|
||||
}
|
||||
|
||||
InetSocketAddress remoteAddress() {
|
||||
return (InetSocketAddress) channel.remoteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class MQTTConnectionFactory {
|
||||
this.postOffice = postOffice;
|
||||
}
|
||||
|
||||
public MQTTConnection create(Channel channel) {
|
||||
MQTTConnection create(Channel channel) {
|
||||
return new MQTTConnection(channel, brokerConfig, authenticator, sessionRegistry, postOffice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
@@ -53,6 +50,7 @@ public class Server {
|
||||
private PostOffice dispatcher;
|
||||
private BrokerInterceptor interceptor;
|
||||
private H2Builder h2Builder;
|
||||
private SessionRegistry sessions;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
final Server server = new Server();
|
||||
@@ -136,7 +134,7 @@ public class Server {
|
||||
}
|
||||
|
||||
public void startServer(IConfig config, List<? extends InterceptHandler> handlers, ISslContextCreator sslCtxCreator,
|
||||
IAuthenticator authenticator, IAuthorizatorPolicy authorizatorPolicy) throws IOException {
|
||||
IAuthenticator authenticator, IAuthorizatorPolicy authorizatorPolicy) {
|
||||
final long start = System.currentTimeMillis();
|
||||
if (handlers == null) {
|
||||
handlers = Collections.emptyList();
|
||||
@@ -179,7 +177,7 @@ public class Server {
|
||||
ISubscriptionsDirectory subscriptions = new CTrieSubscriptionDirectory();
|
||||
subscriptions.init(subscriptionsRepository);
|
||||
final Authorizator authorizator = new Authorizator(authorizatorPolicy);
|
||||
SessionRegistry sessions = new SessionRegistry(subscriptions, queueRepository, authorizator);
|
||||
sessions = new SessionRegistry(subscriptions, queueRepository, authorizator);
|
||||
dispatcher = new PostOffice(subscriptions, retainedRepository, sessions, interceptor, authorizator);
|
||||
final BrokerConfiguration brokerConfig = new BrokerConfiguration(config);
|
||||
MQTTConnectionFactory connectionFactory = new MQTTConnectionFactory(brokerConfig, authenticator, sessions,
|
||||
@@ -195,11 +193,6 @@ public class Server {
|
||||
}
|
||||
|
||||
private IAuthorizatorPolicy initializeAuthorizatorPolicy(IAuthorizatorPolicy authorizatorPolicy, IConfig props) {
|
||||
// if (authorizatorPolicy == null) {
|
||||
// authorizatorPolicy = new PermitAllAuthorizatorPolicy();
|
||||
// }
|
||||
// return authorizatorPolicy;
|
||||
|
||||
LOG.debug("Configuring MQTT authorizator policy");
|
||||
String authorizatorClassName = props.getProperty(BrokerConstants.AUTHORIZATOR_CLASS_NAME, "");
|
||||
if (authorizatorPolicy == null && !authorizatorClassName.isEmpty()) {
|
||||
@@ -215,7 +208,7 @@ public class Server {
|
||||
IResourceLoader resourceLoader = props.getResourceLoader();
|
||||
authorizatorPolicy = ACLFileParser.parse(resourceLoader.loadResource(aclFilePath));
|
||||
} catch (ParseException pex) {
|
||||
LOG.error("Unable to parse ACL file. path=" + aclFilePath, pex);
|
||||
LOG.error("Unable to parse ACL file. path = {}", aclFilePath, pex);
|
||||
}
|
||||
} else {
|
||||
authorizatorPolicy = new PermitAllAuthorizatorPolicy();
|
||||
@@ -226,11 +219,6 @@ public class Server {
|
||||
}
|
||||
|
||||
private IAuthenticator initializeAuthenticator(IAuthenticator authenticator, IConfig props) {
|
||||
// if (authenticator == null) {
|
||||
// authenticator = new AcceptAllAuthenticator();
|
||||
// }
|
||||
// return authenticator;
|
||||
|
||||
LOG.debug("Configuring MQTT authenticator");
|
||||
String authenticatorClassName = props.getProperty(BrokerConstants.AUTHENTICATOR_CLASS_NAME, "");
|
||||
|
||||
@@ -391,4 +379,11 @@ public class Server {
|
||||
LOG.info("Removing MQTT message interceptor. InterceptorId={}", interceptHandler.getID());
|
||||
interceptor.removeInterceptHandler(interceptHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of descriptors of connected clients.
|
||||
* */
|
||||
public Collection<ClientDescriptor> listConnectedClients() {
|
||||
return sessions.listConnectedClients();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.netty.util.ReferenceCountUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.DelayQueue;
|
||||
import java.util.concurrent.Delayed;
|
||||
@@ -368,6 +369,13 @@ class Session {
|
||||
ReferenceCountUtil.release(removedMsg);
|
||||
}
|
||||
|
||||
Optional<InetSocketAddress> remoteAddress() {
|
||||
if (connected()) {
|
||||
return Optional.of(mqttConnection.remoteAddress());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Session{" +
|
||||
|
||||
@@ -26,9 +26,13 @@ import io.netty.handler.codec.mqtt.MqttQoS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SessionRegistry {
|
||||
|
||||
@@ -245,4 +249,19 @@ public class SessionRegistry {
|
||||
private void dropQueuesForClient(String clientId) {
|
||||
queues.remove(clientId);
|
||||
}
|
||||
|
||||
Collection<ClientDescriptor> listConnectedClients() {
|
||||
return pool.values().stream()
|
||||
.filter(Session::connected)
|
||||
.map(this::createClientDescriptor)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Optional<ClientDescriptor> createClientDescriptor(Session s) {
|
||||
final String clientID = s.getClientID();
|
||||
final Optional<InetSocketAddress> remoteAddressOpt = s.remoteAddress();
|
||||
return remoteAddressOpt.map(r -> new ClientDescriptor(clientID, r.getHostString(), r.getPort()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user