You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/06/08 03:12:32 UTC
[james-project] 11/16: JAMES-3171 Add MailboxSession in Method and
do a better handling of method processing in JMAPApiRoutes
This is an automated email from the ASF dual-hosted git repository.
rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 10e46aa3e8a43eef367360dac0bc313e8e1978fc
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Fri May 22 16:37:26 2020 +0700
JAMES-3171 Add MailboxSession in Method and do a better handling of method processing in JMAPApiRoutes
---
.../james/jmap/rfc8621/RFC8621MethodsModule.java | 4 +-
.../{CoreEcho.scala => CoreEchoMethod.scala} | 5 ++-
.../org/apache/james/jmap/method/Method.scala | 3 +-
.../apache/james/jmap/routes/JMAPApiRoutes.scala | 45 ++++++++++++++--------
...CoreEchoTest.scala => CoreEchoMethodTest.scala} | 11 ++++--
.../james/jmap/routes/JMAPApiRoutesTest.scala | 6 ++-
6 files changed, 49 insertions(+), 25 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 f085137..8d855de 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,7 +27,7 @@ import org.apache.james.jmap.http.BasicAuthenticationStrategy;
import org.apache.james.jmap.http.rfc8621.InjectionKeys;
import org.apache.james.jmap.json.Serializer;
import org.apache.james.jmap.jwt.JWTAuthenticationStrategy;
-import org.apache.james.jmap.method.CoreEcho;
+import org.apache.james.jmap.method.CoreEchoMethod;
import org.apache.james.jmap.method.Method;
import org.apache.james.jmap.routes.JMAPApiRoutes;
import org.apache.james.metrics.api.MetricFactory;
@@ -47,7 +47,7 @@ public class RFC8621MethodsModule extends AbstractModule {
bind(Serializer.class).in(Scopes.SINGLETON);
Multibinder<Method> methods = Multibinder.newSetBinder(binder(), Method.class);
- methods.addBinding().to(CoreEcho.class);
+ methods.addBinding().to(CoreEchoMethod.class);
}
@ProvidesIntoSet
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEcho.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEchoMethod.scala
similarity index 86%
rename from server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEcho.scala
rename to server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEchoMethod.scala
index efeb0e7..fad57d8 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEcho.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/CoreEchoMethod.scala
@@ -22,11 +22,12 @@ package org.apache.james.jmap.method
import eu.timepit.refined.auto._
import org.apache.james.jmap.model.Invocation
import org.apache.james.jmap.model.Invocation.MethodName
+import org.apache.james.mailbox.MailboxSession
import org.reactivestreams.Publisher
import reactor.core.scala.publisher.SMono
-class CoreEcho extends Method {
+class CoreEchoMethod extends Method {
override val methodName = MethodName("Core/echo")
- override def process(invocation: Invocation): Publisher[Invocation] = SMono.just(invocation)
+ override def process(invocation: Invocation, mailboxSession: MailboxSession): Publisher[Invocation] = SMono.just(invocation)
}
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
index 8ff5b6d..21b33b5 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
@@ -21,11 +21,12 @@ package org.apache.james.jmap.method
import org.apache.james.jmap.model.Invocation
import org.apache.james.jmap.model.Invocation.MethodName
+import org.apache.james.mailbox.MailboxSession
import org.reactivestreams.Publisher
trait Method {
val methodName: MethodName
- def process(invocation: Invocation): Publisher[Invocation]
+ def process(invocation: Invocation, mailboxSession: MailboxSession): Publisher[Invocation]
}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
index 410ad77..478cdcc 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
@@ -35,10 +35,11 @@ import org.apache.james.jmap.exceptions.UnauthorizedException
import org.apache.james.jmap.http.Authenticator
import org.apache.james.jmap.http.rfc8621.InjectionKeys
import org.apache.james.jmap.json.Serializer
-import org.apache.james.jmap.method.CoreEcho
+import org.apache.james.jmap.method.Method
import org.apache.james.jmap.model.Invocation.{Arguments, MethodName}
import org.apache.james.jmap.model.{Invocation, RequestObject, ResponseObject}
import org.apache.james.jmap.{Endpoint, JMAPRoute, JMAPRoutes}
+import org.apache.james.mailbox.MailboxSession
import org.slf4j.{Logger, LoggerFactory}
import play.api.libs.json.{JsError, JsSuccess, Json}
import reactor.core.publisher.Mono
@@ -46,13 +47,25 @@ import reactor.core.scala.publisher.{SFlux, SMono}
import reactor.core.scheduler.Schedulers
import reactor.netty.http.server.{HttpServerRequest, HttpServerResponse}
+import scala.collection.mutable
+import scala.jdk.CollectionConverters._
+
object JMAPApiRoutes {
val LOGGER: Logger = LoggerFactory.getLogger(classOf[JMAPApiRoutes])
}
-class JMAPApiRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator: Authenticator,
- val serializer: Serializer) extends JMAPRoutes {
- private val coreEcho = new CoreEcho
+class JMAPApiRoutes (val authenticator: Authenticator,
+ serializer: Serializer,
+ methods: Set[Method]) extends JMAPRoutes {
+
+ private val methodsByName: Map[MethodName, Method] = methods.map(method => method.methodName -> method).toMap
+
+ @Inject
+ def this(@Named(InjectionKeys.RFC_8621) authenticator: Authenticator,
+ serializer: Serializer,
+ javaMethods: java.util.Set[Method]) {
+ this(authenticator, serializer, javaMethods.asScala.toSet)
+ }
override def routes(): stream.Stream[JMAPRoute] = Stream.of(
JMAPRoute.builder
@@ -66,8 +79,8 @@ class JMAPApiRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
private def post(httpServerRequest: HttpServerRequest, httpServerResponse: HttpServerResponse): Mono[Void] =
SMono(authenticator.authenticate(httpServerRequest))
- .flatMap(_ => this.requestAsJsonStream(httpServerRequest)
- .flatMap(requestObject => this.process(requestObject, httpServerResponse)))
+ .flatMap((mailboxSession: MailboxSession) => this.requestAsJsonStream(httpServerRequest)
+ .flatMap(requestObject => this.process(requestObject, httpServerResponse, mailboxSession)))
.onErrorResume(throwable => handleError(throwable, httpServerResponse))
.subscribeOn(Schedulers.elastic)
.asJava()
@@ -87,10 +100,12 @@ class JMAPApiRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
case JsError(_) => SMono.raiseError(new IllegalArgumentException("Invalid RequestObject"))
}
- private def process(requestObject: RequestObject, httpServerResponse: HttpServerResponse): SMono[Void] =
+ private def process(requestObject: RequestObject,
+ httpServerResponse: HttpServerResponse,
+ mailboxSession: MailboxSession): SMono[Void] =
requestObject
.methodCalls
- .map(this.processMethodWithMatchName)
+ .map(invocation => this.processMethodWithMatchName(invocation, mailboxSession))
.foldLeft(SFlux.empty[Invocation]) { (flux: SFlux[Invocation], mono: SMono[Invocation]) => flux.mergeWith(mono) }
.collectSeq()
.flatMap((invocations: Seq[Invocation]) =>
@@ -103,13 +118,13 @@ class JMAPApiRoutes @Inject() (@Named(InjectionKeys.RFC_8621) val authenticator:
).`then`())
)
- private def processMethodWithMatchName(invocation: Invocation): SMono[Invocation] = invocation.methodName match {
- case coreEcho.methodName => SMono.fromPublisher(coreEcho.process(invocation))
- case _ => SMono.just(new Invocation(
- MethodName("error"),
- Arguments(Json.obj("type" -> "Not implemented")),
- invocation.methodCallId))
- }
+ private def processMethodWithMatchName(invocation: Invocation, mailboxSession: MailboxSession): SMono[Invocation] =
+ SMono.justOrEmpty(methodsByName.get(invocation.methodName))
+ .flatMap(method => SMono.fromPublisher(method.process(invocation, mailboxSession)))
+ .switchIfEmpty(SMono.just(new Invocation(
+ MethodName("error"),
+ Arguments(Json.obj("type" -> "Not implemented")),
+ invocation.methodCallId)))
private def handleError(throwable: Throwable, httpServerResponse: HttpServerResponse): SMono[Void] = throwable match {
case exception: IllegalArgumentException => SMono.fromPublisher(httpServerResponse.status(SC_BAD_REQUEST)
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoMethodTest.scala
similarity index 84%
rename from server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoTest.scala
rename to server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoMethodTest.scala
index 2d78e5f..583e832 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/method/CoreEchoMethodTest.scala
@@ -20,25 +20,28 @@ package org.apache.james.jmap.method
import org.apache.james.jmap.json.Fixture.{invocation1, invocation2}
import org.apache.james.jmap.model.Invocation
+import org.apache.james.mailbox.MailboxSession
+import org.mockito.Mockito.mock
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import reactor.core.scala.publisher.SMono
-class CoreEchoTest extends AnyWordSpec with Matchers {
- private val echoMethod: CoreEcho = new CoreEcho()
+class CoreEchoMethodTest extends AnyWordSpec with Matchers {
+ private val echoMethod: CoreEchoMethod = new CoreEchoMethod()
+ private val mockedSession: MailboxSession = mock(classOf[MailboxSession])
"CoreEcho" should {
"Process" should {
"success and return the same with parameters as the invocation request" in {
val expectedResponse: Invocation = invocation1
- val dataResponse = SMono.fromPublisher(echoMethod.process(invocation1)).block()
+ val dataResponse = SMono.fromPublisher(echoMethod.process(invocation1, mockedSession)).block()
dataResponse shouldBe expectedResponse
}
"success and not return anything else different than the original invocation" in {
val wrongExpected: Invocation = invocation2
- val dataResponse = SMono.fromPublisher(echoMethod.process(invocation1)).block()
+ val dataResponse = SMono.fromPublisher(echoMethod.process(invocation1, mockedSession)).block()
dataResponse should not be(wrongExpected)
}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
index f23e835..37ffb9a 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
@@ -37,6 +37,7 @@ import org.apache.james.jmap.JMAPUrls.JMAP
import org.apache.james.jmap._
import org.apache.james.jmap.http.{Authenticator, BasicAuthenticationStrategy}
import org.apache.james.jmap.json.Serializer
+import org.apache.james.jmap.method.{CoreEchoMethod, Method}
import org.apache.james.jmap.routes.JMAPApiRoutesTest._
import org.apache.james.mailbox.MailboxManager
import org.apache.james.mailbox.extension.PreDeletionHook
@@ -67,7 +68,10 @@ object JMAPApiRoutesTest {
private val mailboxManager: MailboxManager = MemoryMailboxManagerProvider.provideMailboxManager(empty_set)
private val authenticationStrategy: BasicAuthenticationStrategy = new BasicAuthenticationStrategy(usersRepository, mailboxManager)
private val AUTHENTICATOR: Authenticator = Authenticator.of(new RecordingMetricFactory, authenticationStrategy)
- private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, SERIALIZER)
+
+ private val JMAP_METHODS: Set[Method] = Set(new CoreEchoMethod)
+
+ private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, SERIALIZER, JMAP_METHODS)
private val ROUTES_HANDLER: ImmutableSet[JMAPRoutesHandler] = ImmutableSet.of(new JMAPRoutesHandler(Version.RFC8621, JMAP_API_ROUTE))
private val userBase64String: String = Base64.getEncoder.encodeToString("user1:password".getBytes(StandardCharsets.UTF_8))
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org