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 7a50f92a38018f8cbd75698f27bbf0449a93949d Author: Benoit TELLIER <btell...@linagora.com> AuthorDate: Mon Nov 25 17:10:21 2024 +0100 JAMES-4091 Add JMAP Websockets and eventSource to connection descriptions --- .../james/jmap/rfc8621/RFC8621MethodsModule.java | 5 +++++ .../james/jmap/routes/EventSourceRoutes.scala | 25 +++++++++++++++++++--- .../apache/james/jmap/routes/WebSocketRoutes.scala | 25 +++++++++++++++++++--- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/rfc8621/RFC8621MethodsModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/rfc8621/RFC8621MethodsModule.java index 55a26bd215..71004190e3 100644 --- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/rfc8621/RFC8621MethodsModule.java +++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/rfc8621/RFC8621MethodsModule.java @@ -27,6 +27,7 @@ import java.util.Set; import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.ex.ConfigurationException; +import org.apache.james.core.ConnectionDescriptionSupplier; import org.apache.james.core.Disconnector; import org.apache.james.jmap.JMAPRoutes; import org.apache.james.jmap.JMAPRoutesHandler; @@ -206,6 +207,10 @@ public class RFC8621MethodsModule extends AbstractModule { disconnectorMultibinder.addBinding().to(WebSocketRoutes.class); disconnectorMultibinder.addBinding().to(EventSourceRoutes.class); disconnectorMultibinder.addBinding().to(PushSubscriptionDisconnector.class); + + Multibinder<ConnectionDescriptionSupplier> connectionDescriptionSupplierMultibinder = Multibinder.newSetBinder(binder(), ConnectionDescriptionSupplier.class); + connectionDescriptionSupplierMultibinder.addBinding().to(WebSocketRoutes.class); + connectionDescriptionSupplierMultibinder.addBinding().to(EventSourceRoutes.class); } @ProvidesIntoSet diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/EventSourceRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/EventSourceRoutes.scala index c67888bd24..544a94103f 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/EventSourceRoutes.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/EventSourceRoutes.scala @@ -22,16 +22,17 @@ package org.apache.james.jmap.routes import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicReference import java.util.function.Predicate -import java.util.stream +import java.util.{Optional, stream} import cats.implicits._ +import com.google.common.collect.ImmutableMap import eu.timepit.refined.api.Refined import eu.timepit.refined.numeric.Positive import eu.timepit.refined.refineV import io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE import io.netty.handler.codec.http.{HttpMethod, QueryStringDecoder} import jakarta.inject.{Inject, Named} -import org.apache.james.core.{Disconnector, Username} +import org.apache.james.core.{ConnectionDescription, ConnectionDescriptionSupplier, Disconnector, Username} import org.apache.james.events.{EventBus, Registration, RegistrationKey} import org.apache.james.jmap.HttpConstants.JSON_CONTENT_TYPE import org.apache.james.jmap.JMAPUrls.EVENT_SOURCE @@ -161,7 +162,7 @@ class EventSourceRoutes@Inject() (@Named(InjectionKeys.RFC_8621) val authenticat @Named(JMAPInjectionKeys.JMAP) eventBus: EventBus, pushSerializer: PushSerializer, typeStateFactory: TypeStateFactory, - delegationStore: DelegationStore) extends JMAPRoutes with Disconnector { + delegationStore: DelegationStore) extends JMAPRoutes with Disconnector with ConnectionDescriptionSupplier { private val connectedUsers: java.util.concurrent.ConcurrentHashMap[ClientContext, ClientContext] = new java.util.concurrent.ConcurrentHashMap[ClientContext, ClientContext] override def routes(): stream.Stream[JMAPRoute] = stream.Stream.of( @@ -250,4 +251,22 @@ class EventSourceRoutes@Inject() (@Named(InjectionKeys.RFC_8621) val authenticat connectedUsers.remove(context) }) } + + override def describeConnections(): stream.Stream[ConnectionDescription] = { + val writable = true + val encrypted = true + connectedUsers.values() + .stream() + .map(context => new ConnectionDescription( + "JMAP", + "EventSource", + Optional.empty(), + Optional.empty(), + context.pushRegistration.get() != null, + context.pushRegistration.get() != null, + writable, + !encrypted, + Optional.ofNullable(context.session.getUser), + ImmutableMap.of())) + } } diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala index 2471f79e97..6cd72f359c 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/WebSocketRoutes.scala @@ -22,13 +22,14 @@ package org.apache.james.jmap.routes import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicReference import java.util.function.Predicate -import java.util.stream +import java.util.{Optional, stream} +import com.google.common.collect.ImmutableMap import io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE import io.netty.handler.codec.http.websocketx.WebSocketFrame import io.netty.handler.codec.http.{HttpHeaderNames, HttpMethod} import jakarta.inject.{Inject, Named} -import org.apache.james.core.{Disconnector, Username} +import org.apache.james.core.{ConnectionDescription, ConnectionDescriptionSupplier, Disconnector, Username} import org.apache.james.events.{EventBus, Registration, RegistrationKey} import org.apache.james.jmap.HttpConstants.JSON_CONTENT_TYPE import org.apache.james.jmap.JMAPUrls.JMAP_WS @@ -82,7 +83,7 @@ class WebSocketRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticato pushSerializer: PushSerializer, typeStateFactory: TypeStateFactory, delegationStore: DelegationStore, - metricFactory: MetricFactory) extends JMAPRoutes with Disconnector { + metricFactory: MetricFactory) extends JMAPRoutes with Disconnector with ConnectionDescriptionSupplier { private val openingConnectionsMetric: Metric = metricFactory.generate("jmap_websocket_opening_connections_count") private val requestCountMetric: Metric = metricFactory.generate("jmap_websocket_requests_count") private val connectedUsers: java.util.concurrent.ConcurrentHashMap[ClientContext, ClientContext] = new java.util.concurrent.ConcurrentHashMap[ClientContext, ClientContext] @@ -209,4 +210,22 @@ class WebSocketRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticato connectedUsers.remove(context) }) } + + override def describeConnections(): stream.Stream[ConnectionDescription] = { + val writable = true + val encrypted = true + connectedUsers.values() + .stream() + .map(context => new ConnectionDescription( + "JMAP", + "WebSocket", + Optional.empty(), + Optional.empty(), + context.pushRegistration.get() != null, + context.pushRegistration.get() != null, + writable, + !encrypted, + Optional.ofNullable(context.session.getUser), + ImmutableMap.of())) + } } --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org