You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2024/11/27 12:33:56 UTC
(james-project) 01/12: JAMES-4091 Allow describing opened IMAP channels
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0bd83e9f0e41342c9f2590b24163b67da44d1592
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Thu Nov 21 10:30:44 2024 +0100
JAMES-4091 Allow describing opened IMAP channels
---
.../apache/james/core/ConnectionDescription.java | 35 +++++++---------
.../james/core/ConnectionDescriptionSupplier.java | 40 +++++++++---------
.../james/imap/api/process/SelectedMailbox.java | 2 +
.../imap/processor/base/SelectedMailboxImpl.java | 5 +++
.../james/modules/protocols/IMAPServerModule.java | 2 +
.../james/modules/server/ServerRouteModule.java | 5 +++
.../apache/james/imapserver/netty/IMAPServer.java | 45 +++++++++++++++++++-
.../james/imapserver/netty/IMAPServerFactory.java | 13 +++++-
.../MemoryWebAdminServerIntegrationTest.java | 37 +++++++++++++++++
.../protocols/webadmin/webadmin-protocols/pom.xml | 4 ++
.../protocols/webadmin/ProtocolServerRoutes.java | 48 +++++++++++++++++++++-
11 files changed, 193 insertions(+), 43 deletions(-)
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java b/core/src/main/java/org/apache/james/core/ConnectionDescription.java
similarity index 55%
copy from server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
copy to core/src/main/java/org/apache/james/core/ConnectionDescription.java
index 5dbaa855c9..fc30273d82 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
+++ b/core/src/main/java/org/apache/james/core/ConnectionDescription.java
@@ -17,26 +17,19 @@
* under the License. *
****************************************************************/
-package org.apache.james.webadmin.integration.memory;
+package org.apache.james.core;
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
+import java.util.Map;
+import java.util.Optional;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
-import org.apache.james.webadmin.integration.WebAdminServerIntegrationTest;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class MemoryWebAdminServerIntegrationTest extends WebAdminServerIntegrationTest {
-
- @RegisterExtension
- static JamesServerExtension jamesServerExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
- MemoryJamesConfiguration.builder()
- .workingDirectory(tmpDir)
- .configurationFromClasspath()
- .usersRepository(DEFAULT)
- .build())
- .server(MemoryJamesServerMain::createServer)
- .build();
-}
\ No newline at end of file
+public record ConnectionDescription(
+ String protocol,
+ String endpoint,
+ Optional<String> remoteAddress,
+ boolean isActive,
+ boolean isOpen,
+ boolean isWritable,
+ boolean isEncrypted,
+ Optional<Username> username,
+ Map<String, String> protocolSpecificInformation) {
+}
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java b/core/src/main/java/org/apache/james/core/ConnectionDescriptionSupplier.java
similarity index 56%
copy from server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
copy to core/src/main/java/org/apache/james/core/ConnectionDescriptionSupplier.java
index 5dbaa855c9..16fa7ba6ae 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
+++ b/core/src/main/java/org/apache/james/core/ConnectionDescriptionSupplier.java
@@ -17,26 +17,28 @@
* under the License. *
****************************************************************/
-package org.apache.james.webadmin.integration.memory;
+package org.apache.james.core;
-import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
+import java.util.Set;
+import java.util.stream.Stream;
-import org.apache.james.JamesServerBuilder;
-import org.apache.james.JamesServerExtension;
-import org.apache.james.MemoryJamesConfiguration;
-import org.apache.james.MemoryJamesServerMain;
-import org.apache.james.webadmin.integration.WebAdminServerIntegrationTest;
-import org.junit.jupiter.api.extension.RegisterExtension;
+import jakarta.inject.Inject;
-class MemoryWebAdminServerIntegrationTest extends WebAdminServerIntegrationTest {
+public interface ConnectionDescriptionSupplier {
+ class CompositeConnectionDescriptionSupplier implements ConnectionDescriptionSupplier {
+ private final Set<ConnectionDescriptionSupplier> connectionDescriptionSupplierSet;
- @RegisterExtension
- static JamesServerExtension jamesServerExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
- MemoryJamesConfiguration.builder()
- .workingDirectory(tmpDir)
- .configurationFromClasspath()
- .usersRepository(DEFAULT)
- .build())
- .server(MemoryJamesServerMain::createServer)
- .build();
-}
\ No newline at end of file
+ @Inject
+ public CompositeConnectionDescriptionSupplier(Set<ConnectionDescriptionSupplier> connectionDescriptionSupplierSet) {
+ this.connectionDescriptionSupplierSet = connectionDescriptionSupplierSet;
+ }
+
+ @Override
+ public Stream<ConnectionDescription> describeConnections() {
+ return connectionDescriptionSupplierSet.stream()
+ .flatMap(ConnectionDescriptionSupplier::describeConnections);
+ }
+ }
+
+ Stream<ConnectionDescription> describeConnections();
+}
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/process/SelectedMailbox.java b/protocols/imap/src/main/java/org/apache/james/imap/api/process/SelectedMailbox.java
index 5aed0be304..241c27c9c5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/process/SelectedMailbox.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/process/SelectedMailbox.java
@@ -50,6 +50,8 @@ public interface SelectedMailbox {
void unregisterIdle();
+ boolean isIdling();
+
/**
* Return the msg index of the given uid or {@link NullableMessageSequenceNumber#noMessage()} instance if no
* message with the given uid was found
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
index 95af2d2ac2..6a94411c74 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
@@ -175,6 +175,11 @@ public class SelectedMailboxImpl implements SelectedMailbox, EventListener.React
idleEventListener.set(null);
}
+ @Override
+ public boolean isIdling() {
+ return idleEventListener.get() != null;
+ }
+
@Override
public Optional<MessageUid> getFirstUid() {
return uidMsnConverter.getFirstUid();
diff --git a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
index b79d43afa8..fcea6b9f6c 100644
--- a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
+++ b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
@@ -28,6 +28,7 @@ import org.apache.commons.configuration2.tree.ImmutableNode;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.ProtocolConfigurationSanitizer;
import org.apache.james.RunArguments;
+import org.apache.james.core.ConnectionDescriptionSupplier;
import org.apache.james.core.Disconnector;
import org.apache.james.core.healthcheck.HealthCheck;
import org.apache.james.filesystem.api.FileSystem;
@@ -119,6 +120,7 @@ public class IMAPServerModule extends AbstractModule {
Multibinder.newSetBinder(binder(), HealthCheck.class).addBinding().to(IMAPHealthCheck.class);
Multibinder.newSetBinder(binder(), Disconnector.class).addBinding().to(IMAPServerFactory.class);
+ Multibinder.newSetBinder(binder(), ConnectionDescriptionSupplier.class).addBinding().to(IMAPServerFactory.class);
}
@Provides
diff --git a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/ServerRouteModule.java b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/ServerRouteModule.java
index f3e3af0556..8ebf41e2e0 100644
--- a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/ServerRouteModule.java
+++ b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/ServerRouteModule.java
@@ -20,6 +20,7 @@
package org.apache.james.modules.server;
import org.apache.james.DisconnectorNotifier;
+import org.apache.james.core.ConnectionDescriptionSupplier;
import org.apache.james.core.Disconnector;
import org.apache.james.protocols.lib.netty.AbstractServerFactory;
import org.apache.james.protocols.webadmin.ProtocolServerRoutes;
@@ -39,10 +40,14 @@ public class ServerRouteModule extends AbstractModule {
.to(ProtocolServerRoutes.class);
Multibinder.newSetBinder(binder(), Disconnector.class);
+ Multibinder.newSetBinder(binder(), ConnectionDescriptionSupplier.class);
bind(Disconnector.class).to(Disconnector.CompositeDisconnector.class);
bind(Disconnector.CompositeDisconnector.class).in(Scopes.SINGLETON);
+ bind(ConnectionDescriptionSupplier.class).to(ConnectionDescriptionSupplier.CompositeConnectionDescriptionSupplier.class);
+ bind(ConnectionDescriptionSupplier.CompositeConnectionDescriptionSupplier.class).in(Scopes.SINGLETON);
+
bind(DisconnectorNotifier.class).to(DisconnectorNotifier.InVMDisconnectorNotifier.class);
bind(DisconnectorNotifier.InVMDisconnectorNotifier.class).in(Scopes.SINGLETON);
}
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
index f2e08114a6..a9bac1194a 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
@@ -18,7 +18,9 @@
****************************************************************/
package org.apache.james.imapserver.netty;
+import java.net.InetSocketAddress;
import java.net.MalformedURLException;
+import java.net.SocketAddress;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.LinkedHashMap;
@@ -26,18 +28,24 @@ import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
+import java.util.stream.Stream;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.apache.james.core.ConnectionDescription;
+import org.apache.james.core.ConnectionDescriptionSupplier;
import org.apache.james.core.Disconnector;
import org.apache.james.core.Username;
import org.apache.james.imap.api.ConnectionCheck;
import org.apache.james.imap.api.ImapConfiguration;
import org.apache.james.imap.api.ImapConstants;
import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.api.process.SelectedMailbox;
import org.apache.james.imap.decode.ImapDecoder;
import org.apache.james.imap.encode.ImapEncoder;
+import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.metrics.api.GaugeRegistry;
import org.apache.james.protocols.api.OidcSASLConfiguration;
import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
@@ -59,6 +67,7 @@ import com.google.common.collect.ImmutableSet;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.group.DefaultChannelGroup;
@@ -70,7 +79,8 @@ import io.netty.util.concurrent.GlobalEventExecutor;
/**
* NIO IMAP Server which use Netty.
*/
-public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapConstants, IMAPServerMBean, NettyConstants, Disconnector {
+public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapConstants, IMAPServerMBean, NettyConstants,
+ Disconnector, ConnectionDescriptionSupplier {
private static final Logger LOG = LoggerFactory.getLogger(IMAPServer.class);
public static class AuthenticationConfiguration {
@@ -356,4 +366,37 @@ public class IMAPServer extends AbstractConfigurableAsyncServer implements ImapC
ReactiveThrottler getReactiveThrottler() {
return reactiveThrottler;
}
+
+ @Override
+ public Stream<ConnectionDescription> describeConnections() {
+ return imapChannelGroup.stream()
+ .map(channel -> {
+ Optional<ImapSession> imapSession = Optional.ofNullable(channel.attr(IMAP_SESSION_ATTRIBUTE_KEY).get());
+ return new ConnectionDescription(
+ "IMAP",
+ jmxName,
+ Optional.ofNullable(channel.remoteAddress()).map(this::addressAsString),
+ channel.isActive(),
+ channel.isOpen(),
+ channel.isWritable(),
+ imapSession.map(ImapSession::isTLSActive).orElse(false),
+ imapSession.flatMap(session -> Optional.ofNullable(session.getUserName())),
+ ImmutableMap.of(
+ "isCompressed", Boolean.toString(imapSession.map(ImapSession::isCompressionActive).orElse(false)),
+ "selectedMailbox", imapSession.flatMap(session -> Optional.ofNullable(session.getSelected()))
+ .map(SelectedMailbox::getMailboxId)
+ .map(MailboxId::serialize)
+ .orElse(""),
+ "isIdling", Boolean.toString(imapSession.flatMap(session -> Optional.ofNullable(session.getSelected()))
+ .map(SelectedMailbox::isIdling)
+ .orElse(false))));
+ });
+ }
+
+ private String addressAsString(SocketAddress socketAddress) {
+ if (socketAddress instanceof InetSocketAddress address) {
+ return address.getAddress().getHostAddress();
+ }
+ return socketAddress.toString();
+ }
}
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
index 9ddcdb30b0..ab89490095 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServerFactory.java
@@ -21,11 +21,14 @@ package org.apache.james.imapserver.netty;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
+import java.util.stream.Stream;
import jakarta.inject.Inject;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.apache.james.core.ConnectionDescription;
+import org.apache.james.core.ConnectionDescriptionSupplier;
import org.apache.james.core.Disconnector;
import org.apache.james.core.Username;
import org.apache.james.filesystem.api.FileSystem;
@@ -41,7 +44,7 @@ import org.apache.james.protocols.lib.netty.AbstractServerFactory;
import com.github.fge.lambdas.functions.ThrowingFunction;
-public class IMAPServerFactory extends AbstractServerFactory implements Disconnector {
+public class IMAPServerFactory extends AbstractServerFactory implements Disconnector, ConnectionDescriptionSupplier {
protected final FileSystem fileSystem;
protected final ThrowingFunction<HierarchicalConfiguration<ImmutableNode>, ImapSuite> imapSuiteProvider;
@@ -105,4 +108,12 @@ public class IMAPServerFactory extends AbstractServerFactory implements Disconne
.map(server -> (IMAPServer) server)
.forEach(imapServer -> imapServer.disconnect(username));
}
+
+ @Override
+ public Stream<ConnectionDescription> describeConnections() {
+ return getServers()
+ .stream()
+ .map(server -> (IMAPServer) server)
+ .flatMap(IMAPServer::describeConnections);
+ }
}
diff --git a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
index 5dbaa855c9..3c7821de06 100644
--- a/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/memory-webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/memory/MemoryWebAdminServerIntegrationTest.java
@@ -19,16 +19,28 @@
package org.apache.james.webadmin.integration.memory;
+import static io.restassured.RestAssured.when;
import static org.apache.james.data.UsersRepositoryModuleChooser.Implementation.DEFAULT;
+import static org.apache.james.jmap.JMAPTestingConstants.LOCALHOST_IP;
+import static org.hamcrest.Matchers.is;
+import org.apache.james.GuiceJamesServer;
import org.apache.james.JamesServerBuilder;
import org.apache.james.JamesServerExtension;
import org.apache.james.MemoryJamesConfiguration;
import org.apache.james.MemoryJamesServerMain;
+import org.apache.james.modules.protocols.ImapGuiceProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.TestIMAPClient;
import org.apache.james.webadmin.integration.WebAdminServerIntegrationTest;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class MemoryWebAdminServerIntegrationTest extends WebAdminServerIntegrationTest {
+ private static final String DOMAIN = "domain";
+ private static final String USERNAME = "bob@" + DOMAIN;
+ private static final String PASSWORD = "password";
@RegisterExtension
static JamesServerExtension jamesServerExtension = new JamesServerBuilder<MemoryJamesConfiguration>(tmpDir ->
@@ -39,4 +51,29 @@ class MemoryWebAdminServerIntegrationTest extends WebAdminServerIntegrationTest
.build())
.server(MemoryJamesServerMain::createServer)
.build();
+
+ @RegisterExtension
+ TestIMAPClient testIMAPClient = new TestIMAPClient();
+
+ @Test
+ void shouldDescribeConnectedImapChannels(GuiceJamesServer server) throws Exception {
+ int imapPort = server.getProbe(ImapGuiceProbe.class).getImapPort();
+
+ server.getProbe(DataProbeImpl.class).addUser(USERNAME, PASSWORD);
+
+ testIMAPClient.connect(LOCALHOST_IP, imapPort)
+ .login(USERNAME, PASSWORD)
+ .select("INBOX");
+
+ when()
+ .get("/servers/channels/" + USERNAME)
+ .prettyPeek()
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .body("[0].protocol", is("IMAP"))
+ .body("[0].endpoint", is("imapserver"))
+ .body("[0].username", is("bob@domain"))
+ .body("[0].isEncrypted", is(false))
+ .body("[0].isEncrypted", is(false));
+ }
}
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-protocols/pom.xml b/server/protocols/webadmin/webadmin-protocols/pom.xml
index 6c29a73f63..c166a8c465 100644
--- a/server/protocols/webadmin/webadmin-protocols/pom.xml
+++ b/server/protocols/webadmin/webadmin-protocols/pom.xml
@@ -58,6 +58,10 @@
<artifactId>testing-base</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jdk8</artifactId>
+ </dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
diff --git a/server/protocols/webadmin/webadmin-protocols/src/main/java/org/apache/james/protocols/webadmin/ProtocolServerRoutes.java b/server/protocols/webadmin/webadmin-protocols/src/main/java/org/apache/james/protocols/webadmin/ProtocolServerRoutes.java
index c1901f7f15..d1ba81ee72 100644
--- a/server/protocols/webadmin/webadmin-protocols/src/main/java/org/apache/james/protocols/webadmin/ProtocolServerRoutes.java
+++ b/server/protocols/webadmin/webadmin-protocols/src/main/java/org/apache/james/protocols/webadmin/ProtocolServerRoutes.java
@@ -20,12 +20,16 @@
package org.apache.james.protocols.webadmin;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import jakarta.inject.Inject;
import org.apache.james.DisconnectorNotifier;
+import org.apache.james.core.ConnectionDescription;
+import org.apache.james.core.ConnectionDescriptionSupplier;
import org.apache.james.core.Username;
import org.apache.james.protocols.lib.netty.CertificateReloadable;
import org.apache.james.util.Port;
@@ -46,19 +50,49 @@ import spark.Request;
import spark.Service;
public class ProtocolServerRoutes implements Routes {
+ record ConnectionDescriptionDTO(
+ String protocol,
+ String endpoint,
+ Optional<String> remoteAddress,
+ boolean isActive,
+ boolean isOpen,
+ boolean isWritable,
+ boolean isEncrypted,
+ Optional<String> username,
+ Map<String, String> protocolSpecificInformation) {
+
+ static ConnectionDescriptionDTO from(ConnectionDescription domainObject) {
+ return new ConnectionDescriptionDTO(domainObject.protocol(),
+ domainObject.endpoint(),
+ domainObject.remoteAddress(),
+ domainObject.isActive(),
+ domainObject.isOpen(),
+ domainObject.isWritable(),
+ domainObject.isEncrypted(),
+ domainObject.username().map(Username::asString),
+ domainObject.protocolSpecificInformation());
+ }
+ }
+
public static final String SERVERS = "servers";
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static final TypeReference<List<String>> LIST_OF_STRING = new TypeReference<>() {
};
+ static {
+ OBJECT_MAPPER.registerModule(new Jdk8Module());
+ }
+
private final Set<CertificateReloadable.Factory> servers;
private final DisconnectorNotifier disconnector;
+ private final ConnectionDescriptionSupplier connectionDescriptionSupplier;
@Inject
- public ProtocolServerRoutes(Set<CertificateReloadable.Factory> servers, DisconnectorNotifier disconnector) {
+ public ProtocolServerRoutes(Set<CertificateReloadable.Factory> servers, DisconnectorNotifier disconnector, ConnectionDescriptionSupplier connectionDescriptionSupplier) {
this.servers = servers;
this.disconnector = disconnector;
+ this.connectionDescriptionSupplier = connectionDescriptionSupplier;
}
@Override
@@ -110,6 +144,18 @@ public class ProtocolServerRoutes implements Routes {
return Responses.returnNoContent(response);
});
+
+ service.get(SERVERS + "/channels", (request, response) -> OBJECT_MAPPER.writeValueAsString(connectionDescriptionSupplier.describeConnections()
+ .map(ConnectionDescriptionDTO::from)
+ .toList()));
+
+ service.get(SERVERS + "/channels/:user", (request, response) -> {
+ Username username = Username.of(request.params("user"));
+ return OBJECT_MAPPER.writeValueAsString(connectionDescriptionSupplier.describeConnections()
+ .filter(connectionDescription -> connectionDescription.username().map(username::equals).orElse(false))
+ .map(ConnectionDescriptionDTO::from)
+ .toList());
+ });
}
private Predicate<CertificateReloadable> filters(Request request) {
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org