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/05/20 01:58:09 UTC

[james-project] branch master updated (80cdb69 -> c26bcfa)

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.


    from 80cdb69  JAMES-3168: distributed echomethod integration test
     new 86bd9d6  JAMES-3184 MessageFastViewProjectionCorrector concurrency control: RunningOptions
     new e33ce51  JAMES-3184 MessageFastViewProjectionCorrector: remove temporal coupling
     new 8696a09  JAMES-3184 Avoid direct access to progress fields
     new 7ec600d  JAMES-3184 RecomputeFastViewProjection task should take runningOptions as argument
     new 6a4a760  JAMES-3184 RecomputeFastViewProjection task runningOptions should be WebAdmin exposed
     new 18cab27  JAMES-3184 Include RunningOptions in additional information
     new b1a8f98  JAMES-3184 Documentation
     new 0f3584c  JAMES-3184 s/messageRatePerSecond/messagesPerSecond
     new 3d72b06  JAMES-3091 Mailbox/Get serialization
     new 691aae4  JAMES-3091 JsonAssert can't seem to evaluate correctly JsValue
     new c26bcfa  JAMES-3091: Add Serializer guice binding for jmap-rfc8621

The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../james/jmap/rfc8621/RFC8621MethodsModule.java   |   4 +
 .../org/apache/james/jmap/http/SessionRoutes.scala |   6 +-
 .../org/apache/james/jmap/json/Serializer.scala    |  34 +++-
 .../org/apache/james/jmap/mail/MailboxGet.scala    |   2 +-
 .../apache/james/jmap/routes/JMAPApiRoutes.scala   |   8 +-
 .../apache/james/jmap/http/SessionRoutesTest.scala |   5 +-
 .../jmap/json/MailboxGetSerializationTest.scala    | 211 +++++++++++++++++++++
 .../james/jmap/json/MailboxSerializationTest.scala |   8 +-
 .../jmap/json/RequestObjectSerializationTest.scala |  16 +-
 .../json/ResponseObjectSerializationTest.scala     |  12 +-
 .../james/jmap/json/SessionSerializationTest.scala |   4 +-
 .../james/jmap/routes/JMAPApiRoutesTest.scala      |   7 +-
 .../jmap/MessageFastViewProjectionCorrector.java   | 155 +++++++++++----
 ...uteAllFastViewProjectionItemsRequestToTask.java |   2 +-
 .../RecomputeAllFastViewProjectionItemsTask.java   |  51 +++--
 ...uteAllFastViewTaskAdditionalInformationDTO.java |  49 +++--
 ...teUserFastViewProjectionItemsRequestToTask.java |   2 +-
 .../RecomputeUserFastViewProjectionItemsTask.java  |  59 ++++--
 ...teUserFastViewTaskAdditionalInformationDTO.java |  45 +++--
 .../webadmin/data/jmap/RunningOptionsDTO.java}     |  25 ++-
 .../webadmin/data/jmap/RunningOptionsParser.java}  |  36 ++--
 ...llFastViewProjectionItemsRequestToTaskTest.java |  72 +++++++
 ...ctionItemsTaskAdditionalInformationDTOTest.java |  30 ++-
 ...stViewProjectionItemsTaskSerializationTest.java |  19 +-
 ...erFastViewProjectionItemsRequestToTaskTest.java |  72 +++++++
 ...ctionItemsTaskAdditionalInformationDTOTest.java |  22 +++
 ...stViewProjectionItemsTaskSerializationTest.java |  21 +-
 .../json/recomputeAll.additionalInformation.json   |   5 +-
 ...recomputeAll.additionalInformation.legacy.json} |   0
 .../src/test/resources/json/recomputeAll.task.json |   7 +-
 ...All.task.json => recomputeAll.task.legacy.json} |   0
 .../json/recomputeUser.additionalInformation.json  |   5 +-
 ...ecomputeUser.additionalInformation.legacy.json} |   0
 .../test/resources/json/recomputeUser.task.json    |   5 +-
 ...er.task.json => recomputeUser.task.legacy.json} |   0
 src/site/markdown/server/manage-webadmin.md        |  32 +++-
 36 files changed, 873 insertions(+), 158 deletions(-)
 create mode 100644 server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
 copy server/protocols/webadmin/{webadmin-mailqueue/src/main/java/org/apache/james/webadmin/dto/ForceDelivery.java => webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java} (62%)
 copy server/protocols/webadmin/{webadmin-cassandra/src/main/java/org/apache/james/webadmin/dto/CassandraVersionRequest.java => webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java} (59%)
 copy server/protocols/webadmin/webadmin-jmap/src/test/resources/json/{recomputeAll.additionalInformation.json => recomputeAll.additionalInformation.legacy.json} (100%)
 copy server/protocols/webadmin/webadmin-jmap/src/test/resources/json/{recomputeAll.task.json => recomputeAll.task.legacy.json} (100%)
 copy server/protocols/webadmin/webadmin-jmap/src/test/resources/json/{recomputeUser.additionalInformation.json => recomputeUser.additionalInformation.legacy.json} (100%)
 copy server/protocols/webadmin/webadmin-jmap/src/test/resources/json/{recomputeUser.task.json => recomputeUser.task.legacy.json} (100%)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 07/11: JAMES-3184 Documentation

Posted by rc...@apache.org.
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 b1a8f984cdbe333b248d4a4f41c40f3f2dd48357
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 13 17:25:21 2020 +0700

    JAMES-3184 Documentation
---
 src/site/markdown/server/manage-webadmin.md | 32 +++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/site/markdown/server/manage-webadmin.md b/src/site/markdown/server/manage-webadmin.md
index c480748..3cfd77e 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -520,6 +520,17 @@ Will schedule a task for recomputing the fast message view projection for all ma
 
 [More details about endpoints returning a task](#Endpoints_returning_a_task).
 
+An admin can specify the concurrency that should be used when running the task:
+
+ - `messageRatePerSecond` rate at which messages should be processed, per second. Defaults to 10.
+ 
+This optional parameter must have a strictly positive integer as a value and be passed as query parameters.
+
+Example:
+
+```
+curl -XPOST /mailboxes?task=recomputeFastViewProjectionItems&messageRatePerSecond=20
+```
 
 The scheduled task will have the following type `RecomputeAllPreviewsTask` and the following `additionalInformation`:
 
@@ -529,7 +540,10 @@ The scheduled task will have the following type `RecomputeAllPreviewsTask` and t
   "processedUserCount": 3,
   "processedMessageCount": 3,
   "failedUserCount": 2,
-  "failedMessageCount": 1
+  "failedMessageCount": 1,
+  "runningOptions": {
+    "messageRatePerSecond":20
+  }
 }
 ```
 
@@ -955,6 +969,17 @@ Will schedule a task for recomputing the fast message view projection for all ma
 
 [More details about endpoints returning a task](#Endpoints_returning_a_task).
 
+An admin can specify the concurrency that should be used when running the task:
+
+ - `messageRatePerSecond` rate at which messages should be processed, per second. Defaults to 10.
+ 
+This optional parameter must have a strictly positive integer as a value and be passed as query parameters.
+
+Example:
+
+```
+curl -XPOST /mailboxes?task=recomputeFastViewProjectionItems&messageRatePerSecond=20
+```
 
 The scheduled task will have the following type `RecomputeAllPreviewsTask` and the following `additionalInformation`:
 
@@ -963,7 +988,10 @@ The scheduled task will have the following type `RecomputeAllPreviewsTask` and t
   "type":"RecomputeAllPreviewsTask",
   "username": "{usernameToBeUsed}",
   "processedMessageCount": 3,
-  "failedMessageCount": 1
+  "failedMessageCount": 1,
+  "runningOptions": {
+    "messageRatePerSecond":20
+  }
 }
 ```
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 10/11: JAMES-3091 JsonAssert can't seem to evaluate correctly JsValue

Posted by rc...@apache.org.
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 691aae411b0170be99115ccee1b6b066caef33ad
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Fri May 15 11:19:02 2020 +0700

    JAMES-3091 JsonAssert can't seem to evaluate correctly JsValue
    
    When evaluating JsValue, JsonAssert seems to always say success, even if it should fail.
    Converting those values into String, could see that there was a serialization issue with MailboxNamespace and fix it
---
 .../src/main/scala/org/apache/james/jmap/json/Serializer.scala     | 7 ++++---
 .../org/apache/james/jmap/json/MailboxGetSerializationTest.scala   | 6 +++---
 .../org/apache/james/jmap/json/MailboxSerializationTest.scala      | 6 +++---
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
index 982ce1b..295e270 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
@@ -158,9 +158,10 @@ class Serializer(mailboxIdFactory: MailboxId.Factory) {
   private implicit val maySubmitWrites: Writes[MaySubmit] = Json.valueWrites[MaySubmit]
   private implicit val mailboxRightsWrites: Writes[MailboxRights] = Json.writes[MailboxRights]
 
-  private implicit val personalNamespaceWrites: Writes[PersonalNamespace] = namespace => JsString("Personal")
-  private implicit val delegatedNamespaceWrites: Writes[DelegatedNamespace] = namespace => JsString(s"Delegated[${namespace.owner.asString}]")
-  private implicit val mailboxNamespaceWrites: Writes[MailboxNamespace] = Json.writes[MailboxNamespace]
+  private implicit val mailboxNamespaceWrites: Writes[MailboxNamespace] = {
+    case personal: PersonalNamespace => JsString("Personal")
+    case delegated: DelegatedNamespace => JsString(s"Delegated[${delegated.owner.asString}]")
+  }
 
   private implicit val mailboxACLWrites: Writes[MailboxACL.Right] = right => JsString(right.asCharacter.toString)
 
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
index 44a1594..2449d6c 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
@@ -158,7 +158,7 @@ class MailboxGetSerializationTest extends AnyWordSpec with Matchers {
         list = List(MAILBOX),
         notFound = NotFound(List(MAILBOX_ID_1, MAILBOX_ID_2)))
 
-      val expectedJson = Json.parse(
+      val expectedJson: String =
         """
           |{
           |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
@@ -203,9 +203,9 @@ class MailboxGetSerializationTest extends AnyWordSpec with Matchers {
           |  }],
           |  "notFound": ["1", "2"]
           |}
-          |""".stripMargin)
+          |""".stripMargin
 
-      assertThatJson(SERIALIZER.serialize(actualValue)).isEqualTo(expectedJson)
+      assertThatJson(Json.stringify(SERIALIZER.serialize(actualValue))).isEqualTo(expectedJson)
     }
   }
 }
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
index 23c643d..940d29a 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
@@ -89,7 +89,7 @@ class MailboxSerializationTest extends AnyWordSpec with Matchers {
   "Serialize Mailbox" should {
     "succeed " in {
 
-      val expectedJson = Json.parse(
+      val expectedJson: String =
         """{
           |  "id":"2",
           |  "name":"inbox",
@@ -127,9 +127,9 @@ class MailboxSerializationTest extends AnyWordSpec with Matchers {
           |      "Storage":{"used":19}
           |    }
           |  }
-          |}""".stripMargin)
+          |}""".stripMargin
 
-      assertThatJson(new Serializer(new TestId.Factory).serialize(MAILBOX)).isEqualTo(expectedJson)
+      assertThatJson(Json.stringify(new Serializer(new TestId.Factory).serialize(MAILBOX))).isEqualTo(expectedJson)
     }
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 09/11: JAMES-3091 Mailbox/Get serialization

Posted by rc...@apache.org.
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 3d72b06fefad9606e71f075d2ea083fb21b790e5
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Tue May 12 17:25:29 2020 +0700

    JAMES-3091 Mailbox/Get serialization
---
 .../org/apache/james/jmap/http/SessionRoutes.scala |   6 +-
 .../org/apache/james/jmap/json/Serializer.scala    |  28 ++-
 .../org/apache/james/jmap/mail/MailboxGet.scala    |   2 +-
 .../apache/james/jmap/routes/JMAPApiRoutes.scala   |   8 +-
 .../apache/james/jmap/http/SessionRoutesTest.scala |   5 +-
 .../jmap/json/MailboxGetSerializationTest.scala    | 211 +++++++++++++++++++++
 .../james/jmap/json/MailboxSerializationTest.scala |   4 +-
 .../jmap/json/RequestObjectSerializationTest.scala |  16 +-
 .../json/ResponseObjectSerializationTest.scala     |  12 +-
 .../james/jmap/json/SessionSerializationTest.scala |   4 +-
 .../james/jmap/routes/JMAPApiRoutesTest.scala      |   7 +-
 11 files changed, 278 insertions(+), 25 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
index f262793..465c212 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/SessionRoutes.scala
@@ -46,9 +46,9 @@ object SessionRoutes {
 }
 
 @Inject
-class SessionRoutes(val authenticator: Authenticator,
-                    val sessionSupplier: SessionSupplier = new SessionSupplier(),
-                    val serializer: Serializer = new Serializer()) extends JMAPRoutes {
+class SessionRoutes(val serializer: Serializer,
+                    val authenticator: Authenticator,
+                    val sessionSupplier: SessionSupplier = new SessionSupplier()) extends JMAPRoutes {
 
   private val generateSession: JMAPRoute.Action =
     (request, response) => SMono.fromPublisher(authenticator.authenticate(request))
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
index 87937a1..982ce1b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
@@ -22,8 +22,9 @@ package org.apache.james.jmap.json
 import java.io.InputStream
 import java.net.URL
 
+import javax.inject.Inject
 import org.apache.james.core.{Domain, Username}
-import org.apache.james.jmap.mail.{DelegatedNamespace, IsSubscribed, Mailbox, MailboxNamespace, MailboxRights, MayAddItems, MayCreateChild, MayDelete, MayReadItems, MayRemoveItems, MayRename, MaySetKeywords, MaySetSeen, MaySubmit, PersonalNamespace, Quota, QuotaId, QuotaRoot, Quotas, Right, Rights, SortOrder, TotalEmails, TotalThreads, UnreadEmails, UnreadThreads, Value}
+import org.apache.james.jmap.mail.{DelegatedNamespace, Ids, IsSubscribed, Mailbox, MailboxGetRequest, MailboxGetResponse, MailboxNamespace, MailboxRights, MayAddItems, MayCreateChild, MayDelete, MayReadItems, MayRemoveItems, MayRename, MaySetKeywords, MaySetSeen, MaySubmit, NotFound, PersonalNamespace, Properties, Quota, QuotaId, QuotaRoot, Quotas, Right, Rights, SortOrder, TotalEmails, TotalThreads, UnreadEmails, UnreadThreads, Value}
 import org.apache.james.jmap.model
 import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.model.Invocation.{Arguments, MethodCallId, MethodName}
@@ -33,7 +34,10 @@ import org.apache.james.mailbox.model.{MailboxACL, MailboxId}
 import play.api.libs.functional.syntax._
 import play.api.libs.json._
 
-class Serializer {
+import scala.util.Try
+
+@Inject
+class Serializer(mailboxIdFactory: MailboxId.Factory) {
   // CreateIds
   private implicit val clientIdFormat: Format[ClientId] = Json.valueFormat[ClientId]
   private implicit val serverIdFormat: Format[ServerId] = Json.valueFormat[ServerId]
@@ -130,6 +134,11 @@ class Serializer {
   private implicit val sessionWrites: Writes[Session] = Json.writes[Session]
 
   private implicit val mailboxIdWrites: Writes[MailboxId] = mailboxId => JsString(mailboxId.serialize)
+  private implicit val mailboxIdReads: Reads[MailboxId] = {
+    case JsString(serializedMailboxId) => Try(JsSuccess(mailboxIdFactory.fromString(serializedMailboxId))).getOrElse(JsError())
+    case _ => JsError()
+  }
+
   private implicit val roleWrites: Writes[Role] = role => JsString(role.serialize)
   private implicit val sortOrderWrites: Writes[SortOrder] = Json.valueWrites[SortOrder]
   private implicit val totalEmailsWrites: Writes[TotalEmails] = Json.valueWrites[TotalEmails]
@@ -193,6 +202,13 @@ class Serializer {
 
   private implicit val mailboxWrites: Writes[Mailbox] = Json.writes[Mailbox]
 
+  private implicit val idsRead: Reads[Ids] = Json.valueReads[Ids]
+  private implicit val propertiesRead: Reads[Properties] = Json.valueReads[Properties]
+  private implicit val mailboxGetRequest: Reads[MailboxGetRequest] = Json.reads[MailboxGetRequest]
+
+  private implicit val notFoundWrites: Writes[NotFound] = Json.valueWrites[NotFound]
+  private implicit val mailboxGetResponseWrites: Writes[MailboxGetResponse] = Json.writes[MailboxGetResponse]
+
   def serialize(session: Session): JsValue = {
     Json.toJson(session)
   }
@@ -209,6 +225,10 @@ class Serializer {
     Json.toJson(mailbox)
   }
 
+  def serialize(mailboxGetResponse: MailboxGetResponse): JsValue = {
+    Json.toJson(mailboxGetResponse)
+  }
+
   def deserializeRequestObject(input: String): JsResult[RequestObject] = {
     Json.parse(input).validate[RequestObject]
   }
@@ -220,4 +240,8 @@ class Serializer {
   def deserializeResponseObject(input: String): JsResult[ResponseObject] = {
     Json.parse(input).validate[ResponseObject]
   }
+
+  def deserializeMailboxGetRequest(input: String): JsResult[MailboxGetRequest] = {
+    Json.parse(input).validate[MailboxGetRequest]
+  }
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala
index ac2cc8a..f38a3a1 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxGet.scala
@@ -29,7 +29,7 @@ case class Ids(value: List[MailboxId])
 case class Properties(value: List[NonEmptyString])
 
 case class MailboxGetRequest(accountId: AccountId,
-                             ids: Ids,
+                             ids: Option[Ids],
                              properties: Option[Properties])
 
 case class NotFound(value: List[MailboxId])
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 7637fa1..8ea7002 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
@@ -27,6 +27,7 @@ import eu.timepit.refined.auto._
 import io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE
 import io.netty.handler.codec.http.HttpMethod
 import io.netty.handler.codec.http.HttpResponseStatus.OK
+import javax.inject.Inject
 import org.apache.http.HttpStatus.SC_BAD_REQUEST
 import org.apache.james.jmap.HttpConstants.JSON_CONTENT_TYPE
 import org.apache.james.jmap.JMAPUrls.JMAP
@@ -35,14 +36,13 @@ import org.apache.james.jmap.method.CoreEcho
 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.slf4j.{Logger, LoggerFactory}
 import play.api.libs.json.{JsError, JsSuccess, Json}
 import reactor.core.publisher.Mono
 import reactor.core.scala.publisher.{SFlux, SMono}
 import reactor.core.scheduler.Schedulers
 import reactor.netty.http.server.{HttpServerRequest, HttpServerResponse}
 
-class JMAPApiRoutes extends JMAPRoutes {
+class JMAPApiRoutes @Inject() (serializer: Serializer) extends JMAPRoutes {
   private val coreEcho = new CoreEcho
 
   override def routes(): stream.Stream[JMAPRoute] = Stream.of(
@@ -72,7 +72,7 @@ class JMAPApiRoutes extends JMAPRoutes {
   }
 
   private def parseRequestObject(inputStream: InputStream): SMono[RequestObject] =
-    new Serializer().deserializeRequestObject(inputStream) match {
+    serializer.deserializeRequestObject(inputStream) match {
       case JsSuccess(requestObject, _) => SMono.just(requestObject)
       case JsError(_) => SMono.raiseError(new IllegalArgumentException("Invalid RequestObject"))
     }
@@ -88,7 +88,7 @@ class JMAPApiRoutes extends JMAPRoutes {
           .header(CONTENT_TYPE, JSON_CONTENT_TYPE)
           .sendString(
             SMono.fromCallable(() =>
-              new Serializer().serialize(ResponseObject(ResponseObject.SESSION_STATE, invocations)).toString()),
+              serializer.serialize(ResponseObject(ResponseObject.SESSION_STATE, invocations)).toString),
             StandardCharsets.UTF_8
           ).`then`())
       )
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
index df01af4..dad6b10 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/http/SessionRoutesTest.scala
@@ -29,9 +29,11 @@ import io.restassured.config.RestAssuredConfig.newConfig
 import io.restassured.http.ContentType
 import org.apache.http.HttpStatus
 import org.apache.james.core.Username
-import org.apache.james.jmap.http.SessionRoutesTest.{BOB, TEST_CONFIGURATION}
 import org.apache.james.jmap._
+import org.apache.james.jmap.http.SessionRoutesTest.{BOB, TEST_CONFIGURATION}
+import org.apache.james.jmap.json.Serializer
 import org.apache.james.mailbox.MailboxSession
+import org.apache.james.mailbox.model.TestId
 import org.mockito.ArgumentMatchers.any
 import org.mockito.Mockito._
 import org.scalatest.BeforeAndAfter
@@ -62,6 +64,7 @@ class SessionRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
       .thenReturn(Mono.just(mockedSession))
 
     val sessionRoutes = new SessionRoutes(
+      serializer = new Serializer(new TestId.Factory),
       sessionSupplier = new SessionSupplier(),
       authenticator = mockedAuthFilter)
     jmapServer = new JMAPServer(
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
new file mode 100644
index 0000000..44a1594
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxGetSerializationTest.scala
@@ -0,0 +1,211 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap.json
+
+import eu.timepit.refined.auto._
+import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
+import org.apache.james.jmap.json.Fixture._
+import org.apache.james.jmap.json.MailboxGetSerializationTest._
+import org.apache.james.jmap.json.MailboxSerializationTest.MAILBOX
+import org.apache.james.jmap.mail._
+import org.apache.james.jmap.model.AccountId
+import org.apache.james.mailbox.model.{MailboxId, TestId}
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.wordspec.AnyWordSpec
+import play.api.libs.json.{JsError, JsSuccess, Json}
+
+object MailboxGetSerializationTest {
+  private val FACTORY: MailboxId.Factory = new TestId.Factory
+
+  private val SERIALIZER: Serializer = new Serializer(FACTORY)
+
+  private val ACCOUNT_ID: AccountId = AccountId(id)
+
+  private val MAILBOX_ID_1: MailboxId = FACTORY.fromString("1")
+  private val MAILBOX_ID_2: MailboxId = FACTORY.fromString("2")
+
+  private val PROPERTIES: Properties = Properties(List("name", "role"))
+}
+
+class MailboxGetSerializationTest extends AnyWordSpec with Matchers {
+  "Deserialize MailboxGetRequest" should {
+    "fail when MailboxId.Factory can't deserialize MailboxId" in {
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": ["ab#?"]
+          |}
+          |""".stripMargin) shouldBe a [JsError]
+    }
+
+    "succeed when properties are missing" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = Some(Ids(List(MAILBOX_ID_1))),
+        properties = None)
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": ["1"]
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+
+    "succeed when properties are null" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = Some(Ids(List(MAILBOX_ID_1))),
+        properties = None)
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": ["1"],
+          |  "properties": null
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+
+    "succeed when properties are empty" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = Some(Ids(List(MAILBOX_ID_1))),
+        properties = Some(Properties(Nil)))
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": ["1"],
+          |  "properties": []
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+
+    "succeed when ids is empty" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = Some(Ids(Nil)),
+        properties = None)
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": []
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+
+    "succeed when ids is null" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = None,
+        properties = None)
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": null
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+
+    "succeed" in {
+      val expectedRequestObject = MailboxGetRequest(
+        accountId = ACCOUNT_ID,
+        ids = Some(Ids(List(MAILBOX_ID_1, MAILBOX_ID_2))),
+        properties = Some(PROPERTIES))
+
+      SERIALIZER.deserializeMailboxGetRequest(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "ids": ["1", "2"],
+          |  "properties": ["name", "role"]
+          |}
+          |""".stripMargin) should equal(JsSuccess(expectedRequestObject))
+    }
+  }
+
+  "Serialize MailboxGetResponse" should {
+    "succeed" in {
+      val actualValue: MailboxGetResponse = MailboxGetResponse(
+        accountId = ACCOUNT_ID,
+        state = "75128aab4b1b",
+        list = List(MAILBOX),
+        notFound = NotFound(List(MAILBOX_ID_1, MAILBOX_ID_2)))
+
+      val expectedJson = Json.parse(
+        """
+          |{
+          |  "accountId": "aHR0cHM6Ly93d3cuYmFzZTY0ZW5jb2RlLm9yZy8",
+          |  "state": "75128aab4b1b",
+          |  "list": [{
+          |    "id":"2",
+          |    "name":"inbox",
+          |    "parentId":"1",
+          |    "role":"inbox",
+          |    "sortOrder":10,
+          |    "totalEmails":1234,
+          |    "unreadEmails":123,
+          |    "totalThreads":58,
+          |    "unreadThreads":22,
+          |    "myRights":{
+          |      "mayReadItems":false,
+          |      "mayAddItems":true,
+          |      "mayRemoveItems":false,
+          |      "maySetSeen":true,
+          |      "maySetKeywords":false,
+          |      "mayCreateChild":true,
+          |      "mayRename":true,
+          |      "mayDelete":false,
+          |      "maySubmit":false
+          |    },
+          |    "isSubscribed":true,
+          |    "namespace":"Personal",
+          |    "rights":{
+          |      "bob":["e","l"],
+          |      "alice":["r","w"]
+          |    },
+          |    "quotas":{
+          |      "quotaRoot":{
+          |        "Message":{"used":18,"max":42},
+          |        "Storage":{"used":12}
+          |      },
+          |      "quotaRoot2@localhost":{
+          |        "Message":{"used":14,"max":43},
+          |        "Storage":{"used":19}
+          |      }
+          |    }
+          |  }],
+          |  "notFound": ["1", "2"]
+          |}
+          |""".stripMargin)
+
+      assertThatJson(SERIALIZER.serialize(actualValue)).isEqualTo(expectedJson)
+    }
+  }
+}
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
index 5ab9690..23c643d 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/MailboxSerializationTest.scala
@@ -67,7 +67,7 @@ object MailboxSerializationTest {
       Quotas.Message -> Value(14L, Some(43L)),
       Quotas.Storage -> Value(19L, None)))))
 
-  private val MAILBOX: Mailbox = Mailbox(
+  val MAILBOX: Mailbox = Mailbox(
     id = MAILBOX_ID,
     name = MAILBOX_NAME,
     parentId = PARENT_ID,
@@ -129,7 +129,7 @@ class MailboxSerializationTest extends AnyWordSpec with Matchers {
           |  }
           |}""".stripMargin)
 
-      assertThatJson(new Serializer().serialize(MAILBOX)).isEqualTo(expectedJson)
+      assertThatJson(new Serializer(new TestId.Factory).serialize(MAILBOX)).isEqualTo(expectedJson)
     }
   }
 }
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/RequestObjectSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/RequestObjectSerializationTest.scala
index 4d1c5bd..47ce6f9 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/RequestObjectSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/RequestObjectSerializationTest.scala
@@ -20,11 +20,17 @@
 package org.apache.james.jmap.json
 
 import org.apache.james.jmap.json.Fixture._
+import org.apache.james.jmap.json.RequestObjectSerializationTest.SERIALIZER
 import org.apache.james.jmap.model.RequestObject
+import org.apache.james.mailbox.model.TestId
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.wordspec.AnyWordSpec
 import play.api.libs.json._
 
+object RequestObjectSerializationTest {
+  private val SERIALIZER: Serializer = new Serializer(new TestId.Factory)
+}
+
 class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
   "Deserialize RequestObject" should {
     "succeed when deserialize from JsString without CreatedIds" in {
@@ -33,7 +39,7 @@ class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
         methodCalls = Seq(invocation1),
         createdIds = Option.empty)
 
-      new Serializer()
+      SERIALIZER
         .deserializeRequestObject(
           """
             |{
@@ -54,7 +60,7 @@ class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
         methodCalls = Seq(invocation1),
         createdIds = Option(createdIds))
 
-      new Serializer()
+      SERIALIZER
         .deserializeRequestObject(
           """
             |{
@@ -76,7 +82,7 @@ class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
         methodCalls = Seq(invocation1, invocation2),
         createdIds = Option.empty)
 
-      new Serializer()
+      SERIALIZER
         .deserializeRequestObject(
           """
             |{
@@ -98,7 +104,7 @@ class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
 
   "Serialize RequestObject" should {
     "succeed when write to string without CreatedIds" in {
-      val actualValue = new Serializer().serialize(
+      val actualValue = SERIALIZER.serialize(
         RequestObject(
           using = Seq(coreIdentifier, mailIdentifier),
           methodCalls = Seq(invocation1),
@@ -121,7 +127,7 @@ class RequestObjectSerializationTest extends AnyWordSpec with Matchers {
     }
 
     "succeed when write to string with CreatedIds" in {
-      val actualValue = new Serializer().serialize(
+      val actualValue = SERIALIZER.serialize(
         RequestObject(
           using = Seq(coreIdentifier, mailIdentifier),
           methodCalls = Seq(invocation1),
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/ResponseObjectSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/ResponseObjectSerializationTest.scala
index 11c2504..100e4d4 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/ResponseObjectSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/ResponseObjectSerializationTest.scala
@@ -21,11 +21,17 @@ package org.apache.james.jmap.json
 
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.json.Fixture._
+import org.apache.james.jmap.json.ResponseObjectSerializationTest.SERIALIZER
 import org.apache.james.jmap.model.ResponseObject
+import org.apache.james.mailbox.model.TestId
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.wordspec.AnyWordSpec
 import play.api.libs.json._
 
+object ResponseObjectSerializationTest {
+  private val SERIALIZER: Serializer = new Serializer(new TestId.Factory)
+}
+
 class ResponseObjectSerializationTest extends AnyWordSpec with Matchers {
   "Deserialize ResponseObject" should {
     "succeed " in {
@@ -33,7 +39,7 @@ class ResponseObjectSerializationTest extends AnyWordSpec with Matchers {
         sessionState = "75128aab4b1b",
         methodResponses = Seq(invocation1))
 
-      new Serializer().deserializeResponseObject(
+      SERIALIZER.deserializeResponseObject(
         """
           |{
           |  "methodResponses": [
@@ -52,7 +58,7 @@ class ResponseObjectSerializationTest extends AnyWordSpec with Matchers {
         sessionState = "75128aab4b1b",
         methodResponses = Seq(invocation1, invocation2))
 
-      new Serializer().deserializeResponseObject(
+      SERIALIZER.deserializeResponseObject(
         """
           |{
           |  "sessionState": "75128aab4b1b",
@@ -90,7 +96,7 @@ class ResponseObjectSerializationTest extends AnyWordSpec with Matchers {
           |}
           |""".stripMargin))
 
-      new Serializer().serialize(responseObject) should be(Json.parse(expectedJson))
+      SERIALIZER.serialize(responseObject) should be(Json.parse(expectedJson))
     }
   }
 }
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
index 248c331..5a418d8 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/SessionSerializationTest.scala
@@ -26,10 +26,10 @@ import org.apache.james.core.Username
 import org.apache.james.jmap.json.SessionSerializationTest.SESSION
 import org.apache.james.jmap.model.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.model.CoreCapabilityProperties.CollationAlgorithm
-import org.apache.james.jmap.model.Id.Id
 import org.apache.james.jmap.model.MailCapability.EmailQuerySortOption
 import org.apache.james.jmap.model.State.State
 import org.apache.james.jmap.model._
+import org.apache.james.mailbox.model.TestId
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.wordspec.AnyWordSpec
 import play.api.libs.json.Json
@@ -205,7 +205,7 @@ class SessionSerializationTest extends AnyWordSpec with Matchers {
           |  "eventSourceUrl": "http://james.org",
           |  "state": "fda9342jcm"
           |}""".stripMargin)
-      new Serializer().serialize(SESSION) should equal(json)
+      new Serializer(new TestId.Factory).serialize(SESSION) should equal(json)
     }
   }
 }
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 004529b..9bf7ba8 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
@@ -30,19 +30,22 @@ import io.restassured.http.ContentType
 import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
 import org.apache.http.HttpStatus
 import org.apache.james.jmap.JMAPUrls.JMAP
-import org.apache.james.jmap.{JMAPConfiguration, JMAPRoutesHandler, JMAPServer, Version, VersionParser}
+import org.apache.james.jmap.json.Serializer
+import org.apache.james.jmap._
+import org.apache.james.mailbox.model.TestId
 import org.scalatest.BeforeAndAfter
 import org.scalatest.flatspec.AnyFlatSpec
 import org.scalatest.matchers.should.Matchers
 
 class JMAPApiRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
+  private val SERIALIZER: Serializer = new Serializer(new TestId.Factory)
 
   private val TEST_CONFIGURATION: JMAPConfiguration = JMAPConfiguration.builder().enable().randomPort().build()
   private val ACCEPT_JMAP_VERSION_HEADER = "application/json; jmapVersion="
   private val ACCEPT_DRAFT_VERSION_HEADER = ACCEPT_JMAP_VERSION_HEADER + Version.DRAFT.asString()
   private val ACCEPT_RFC8621_VERSION_HEADER = ACCEPT_JMAP_VERSION_HEADER + Version.RFC8621.asString()
 
-  private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes()
+  private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes(SERIALIZER)
   private val ROUTES_HANDLER: ImmutableSet[JMAPRoutesHandler] = ImmutableSet.of(new JMAPRoutesHandler(Version.RFC8621, JMAP_API_ROUTE))
 
   private val REQUEST_OBJECT: String =


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 04/11: JAMES-3184 RecomputeFastViewProjection task should take runningOptions as argument

Posted by rc...@apache.org.
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 7ec600de1a1237fafedc5816cc4b398a26398cd9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 13 14:36:50 2020 +0700

    JAMES-3184 RecomputeFastViewProjection task should take runningOptions as argument
    
    Handle deserialization for running options, and legacy tasks
    deserialization
---
 ...uteAllFastViewProjectionItemsRequestToTask.java |  4 ++-
 .../RecomputeAllFastViewProjectionItemsTask.java   | 30 +++++++++++++---
 ...teUserFastViewProjectionItemsRequestToTask.java |  3 +-
 .../RecomputeUserFastViewProjectionItemsTask.java  | 37 ++++++++++++++++----
 .../webadmin/data/jmap/RunningOptionsDTO.java}     | 40 +++++++++++++---------
 ...stViewProjectionItemsTaskSerializationTest.java | 19 +++++++++-
 ...stViewProjectionItemsTaskSerializationTest.java | 21 +++++++++++-
 .../src/test/resources/json/recomputeAll.task.json |  7 +++-
 ...All.task.json => recomputeAll.task.legacy.json} |  0
 .../test/resources/json/recomputeUser.task.json    |  5 ++-
 ...er.task.json => recomputeUser.task.legacy.json} |  0
 11 files changed, 131 insertions(+), 35 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
index e8d8a23..e81cf79 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
+
 import javax.inject.Inject;
 
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
@@ -27,6 +29,6 @@ public class RecomputeAllFastViewProjectionItemsRequestToTask extends TaskFromRe
     @Inject
     RecomputeAllFastViewProjectionItemsRequestToTask(MessageFastViewProjectionCorrector corrector) {
         super(Constants.TASK_REGISTRATION_KEY,
-            request -> new RecomputeAllFastViewProjectionItemsTask(corrector));
+            request -> new RecomputeAllFastViewProjectionItemsTask(corrector, RunningOptions.DEFAULT));
     }
 }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
index 6acba49..a34e412 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
@@ -86,38 +86,58 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
 
     public static class RecomputeAllFastViewTaskDTO implements TaskDTO {
         private final String type;
+        private final Optional<RunningOptionsDTO> runningOptions;
 
-        public RecomputeAllFastViewTaskDTO(@JsonProperty("type") String type) {
+        public RecomputeAllFastViewTaskDTO(@JsonProperty("type") String type,
+                                           @JsonProperty("runningOptions") Optional<RunningOptionsDTO> runningOptions) {
             this.type = type;
+            this.runningOptions = runningOptions;
         }
 
         @Override
         public String getType() {
             return type;
         }
+
+        public Optional<RunningOptionsDTO> getRunningOptions() {
+            return runningOptions;
+        }
     }
 
     public static TaskDTOModule<RecomputeAllFastViewProjectionItemsTask, RecomputeAllFastViewTaskDTO> module(MessageFastViewProjectionCorrector corrector) {
         return DTOModule
             .forDomainObject(RecomputeAllFastViewProjectionItemsTask.class)
             .convertToDTO(RecomputeAllFastViewTaskDTO.class)
-            .toDomainObjectConverter(dto -> new RecomputeAllFastViewProjectionItemsTask(corrector))
-            .toDTOConverter((task, type) -> new RecomputeAllFastViewTaskDTO(type))
+            .toDomainObjectConverter(dto -> asTask(corrector, dto))
+            .toDTOConverter(RecomputeAllFastViewProjectionItemsTask::asDTO)
             .typeName(TASK_TYPE.asString())
             .withFactory(TaskDTOModule::new);
     }
 
+    private static RecomputeAllFastViewTaskDTO asDTO(RecomputeAllFastViewProjectionItemsTask task, String type) {
+        return new RecomputeAllFastViewTaskDTO(type, Optional.of(RunningOptionsDTO.asDTO(task.runningOptions)));
+    }
+
+    private static RecomputeAllFastViewProjectionItemsTask asTask(MessageFastViewProjectionCorrector corrector, RecomputeAllFastViewTaskDTO dto) {
+        return new RecomputeAllFastViewProjectionItemsTask(corrector,
+            dto.getRunningOptions()
+                .map(RunningOptionsDTO::asDomainObject)
+                .orElse(RunningOptions.DEFAULT));
+    }
+
     private final MessageFastViewProjectionCorrector corrector;
     private final MessageFastViewProjectionCorrector.Progress progress;
+    private final RunningOptions runningOptions;
 
-    RecomputeAllFastViewProjectionItemsTask(MessageFastViewProjectionCorrector corrector) {
+    RecomputeAllFastViewProjectionItemsTask(MessageFastViewProjectionCorrector corrector, RunningOptions runningOptions) {
         this.corrector = corrector;
+        this.runningOptions = runningOptions;
         this.progress = new MessageFastViewProjectionCorrector.Progress();
     }
 
     @Override
     public Result run() {
-        return corrector.correctAllProjectionItems(progress, RunningOptions.DEFAULT)
+        return corrector.correctAllProjectionItems(progress, runningOptions)
             .subscribeOn(Schedulers.elastic())
             .block();
     }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
index c3a9f44..7b32ec6 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
@@ -25,6 +25,7 @@ import org.apache.james.core.Username;
 import org.apache.james.task.Task;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
 import org.apache.james.webadmin.utils.ErrorResponder;
 import org.eclipse.jetty.http.HttpStatus;
@@ -43,7 +44,7 @@ public class RecomputeUserFastViewProjectionItemsRequestToTask extends TaskFromR
     private static Task toTask(MessageFastViewProjectionCorrector corrector, UsersRepository usersRepository, Request request) throws UsersRepositoryException {
         Username username = Username.of(request.params("username"));
         if (usersRepository.contains(username)) {
-            return new RecomputeUserFastViewProjectionItemsTask(corrector, username);
+            return new RecomputeUserFastViewProjectionItemsTask(corrector, RunningOptions.DEFAULT, username);
         }
 
         throw ErrorResponder.builder()
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
index 3e44238..ca41a3f 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
@@ -82,12 +82,16 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
     public static class RecomputeUserFastViewTaskDTO implements TaskDTO {
         private final String type;
         private final String username;
+        private final Optional<RunningOptionsDTO> runningOptions;
 
         public RecomputeUserFastViewTaskDTO(
-            @JsonProperty("type") String type,
-            @JsonProperty("username") String username) {
+                @JsonProperty("type") String type,
+                @JsonProperty("username") String username,
+                @JsonProperty("runningOptions") Optional<RunningOptionsDTO> runningOptions) {
+
             this.type = type;
             this.username = username;
+            this.runningOptions = runningOptions;
         }
 
         @Override
@@ -98,31 +102,50 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
         public String getUsername() {
             return username;
         }
+
+        public Optional<RunningOptionsDTO> getRunningOptions() {
+            return runningOptions;
+        }
     }
 
     public static TaskDTOModule<RecomputeUserFastViewProjectionItemsTask, RecomputeUserFastViewTaskDTO> module(MessageFastViewProjectionCorrector corrector) {
         return DTOModule
             .forDomainObject(RecomputeUserFastViewProjectionItemsTask.class)
             .convertToDTO(RecomputeUserFastViewTaskDTO.class)
-            .toDomainObjectConverter(dto -> new RecomputeUserFastViewProjectionItemsTask(corrector, Username.of(dto.username)))
-            .toDTOConverter((task, type) -> new RecomputeUserFastViewTaskDTO(type, task.username.asString()))
+            .toDomainObjectConverter(dto -> asTask(corrector, dto))
+            .toDTOConverter(RecomputeUserFastViewProjectionItemsTask::asDTO)
             .typeName(TASK_TYPE.asString())
             .withFactory(TaskDTOModule::new);
     }
 
+    private static RecomputeUserFastViewTaskDTO asDTO(RecomputeUserFastViewProjectionItemsTask task, String type) {
+        return new RecomputeUserFastViewTaskDTO(type, task.username.asString(),
+            Optional.of(RunningOptionsDTO.asDTO(task.runningOptions)));
+    }
+
+    private static RecomputeUserFastViewProjectionItemsTask asTask(MessageFastViewProjectionCorrector corrector, RecomputeUserFastViewTaskDTO dto) {
+        return new RecomputeUserFastViewProjectionItemsTask(corrector,
+            dto.getRunningOptions()
+                .map(RunningOptionsDTO::asDomainObject)
+                .orElse(RunningOptions.DEFAULT),
+            Username.of(dto.username));
+    }
+
     private final MessageFastViewProjectionCorrector corrector;
-    private final MessageFastViewProjectionCorrector.Progress progress;
+    private final RunningOptions runningOptions;
+    private final Progress progress;
     private final Username username;
 
-    RecomputeUserFastViewProjectionItemsTask(MessageFastViewProjectionCorrector corrector, Username username) {
+    RecomputeUserFastViewProjectionItemsTask(MessageFastViewProjectionCorrector corrector, RunningOptions runningOptions, Username username) {
         this.corrector = corrector;
+        this.runningOptions = runningOptions;
         this.username = username;
         this.progress = new MessageFastViewProjectionCorrector.Progress();
     }
 
     @Override
     public Result run() {
-        return corrector.correctUsersProjectionItems(progress, username, RunningOptions.DEFAULT)
+        return corrector.correctUsersProjectionItems(progress, username, runningOptions)
             .subscribeOn(Schedulers.elastic())
             .block();
     }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
similarity index 56%
copy from server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java
copy to server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
index 3d1b949..5fae5b5 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
@@ -19,26 +19,32 @@
 
 package org.apache.james.webadmin.data.jmap;
 
-import static org.mockito.Mockito.mock;
+import java.util.Optional;
 
-import org.apache.james.JsonSerializationVerifier;
-import org.apache.james.util.ClassLoaderUtils;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 
-class RecomputeAllFastViewProjectionItemsTaskSerializationTest {
-    MessageFastViewProjectionCorrector corrector;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
-    @BeforeEach
-    void setUp() {
-        corrector = mock(MessageFastViewProjectionCorrector.class);
+public class RunningOptionsDTO {
+    public static RunningOptionsDTO asDTO(RunningOptions domainObject) {
+        return new RunningOptionsDTO(Optional.of(domainObject.getMessageRatePerSecond()));
     }
 
-    @Test
-    void shouldMatchJsonSerializationContract() throws Exception {
-        JsonSerializationVerifier.dtoModule(RecomputeAllFastViewProjectionItemsTask.module(corrector))
-            .bean(new RecomputeAllFastViewProjectionItemsTask(corrector))
-            .json(ClassLoaderUtils.getSystemResourceAsString("json/recomputeAll.task.json"))
-            .verify();
+    private final Optional<Integer> messageRatePerSecond;
+
+    @JsonCreator
+    public RunningOptionsDTO(
+            @JsonProperty("messageRatePerSecond") Optional<Integer> messageRatePerSecond) {
+        this.messageRatePerSecond = messageRatePerSecond;
+    }
+
+    public Optional<Integer> getMessageRatePerSecond() {
+        return messageRatePerSecond;
+    }
+
+    public RunningOptions asDomainObject() {
+        return messageRatePerSecond.map(RunningOptions::withMessageRatePerSecond)
+            .orElse(RunningOptions.DEFAULT);
     }
-}
\ No newline at end of file
+}
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java
index 3d1b949..fc9f89e 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskSerializationTest.java
@@ -19,10 +19,13 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.JsonSerializationVerifier;
+import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.util.ClassLoaderUtils;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -37,8 +40,22 @@ class RecomputeAllFastViewProjectionItemsTaskSerializationTest {
     @Test
     void shouldMatchJsonSerializationContract() throws Exception {
         JsonSerializationVerifier.dtoModule(RecomputeAllFastViewProjectionItemsTask.module(corrector))
-            .bean(new RecomputeAllFastViewProjectionItemsTask(corrector))
+            .bean(new RecomputeAllFastViewProjectionItemsTask(corrector,
+                RunningOptions.withMessageRatePerSecond(2)))
             .json(ClassLoaderUtils.getSystemResourceAsString("json/recomputeAll.task.json"))
             .verify();
     }
+
+    @Test
+    void shouldDeserializeLegacy() throws Exception {
+        RecomputeAllFastViewProjectionItemsTask legacyTask = JsonGenericSerializer.forModules(RecomputeAllFastViewProjectionItemsTask.module(corrector))
+            .withoutNestedType()
+            .deserialize(ClassLoaderUtils.getSystemResourceAsString("json/recomputeAll.task.legacy.json"));
+
+        RecomputeAllFastViewProjectionItemsTask expected = new RecomputeAllFastViewProjectionItemsTask(corrector,
+            RunningOptions.DEFAULT);
+
+        assertThat(legacyTask)
+            .isEqualToComparingFieldByFieldRecursively(expected);
+    }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskSerializationTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskSerializationTest.java
index 2d7d75d..b5796ba 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskSerializationTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskSerializationTest.java
@@ -19,11 +19,14 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.JsonSerializationVerifier;
 import org.apache.james.core.Username;
+import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.util.ClassLoaderUtils;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -38,8 +41,24 @@ class RecomputeUserFastViewProjectionItemsTaskSerializationTest {
     @Test
     void shouldMatchJsonSerializationContract() throws Exception {
         JsonSerializationVerifier.dtoModule(RecomputeUserFastViewProjectionItemsTask.module(corrector))
-            .bean(new RecomputeUserFastViewProjectionItemsTask(corrector, Username.of("bob")))
+            .bean(new RecomputeUserFastViewProjectionItemsTask(corrector,
+                RunningOptions.withMessageRatePerSecond(2),
+                Username.of("bob")))
             .json(ClassLoaderUtils.getSystemResourceAsString("json/recomputeUser.task.json"))
             .verify();
     }
+
+    @Test
+    void shouldDeserializeLegacy() throws Exception {
+        RecomputeUserFastViewProjectionItemsTask legacyTask = JsonGenericSerializer.forModules(RecomputeUserFastViewProjectionItemsTask.module(corrector))
+            .withoutNestedType()
+            .deserialize(ClassLoaderUtils.getSystemResourceAsString("json/recomputeUser.task.legacy.json"));
+
+        RecomputeUserFastViewProjectionItemsTask expected = new RecomputeUserFastViewProjectionItemsTask(corrector,
+            RunningOptions.DEFAULT,
+            Username.of("bob"));
+
+        assertThat(legacyTask)
+            .isEqualToComparingFieldByFieldRecursively(expected);
+    }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
index a76c799..0a61bed 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
@@ -1 +1,6 @@
-{"type":"RecomputeAllFastViewProjectionItemsTask"}
\ No newline at end of file
+{
+  "type":"RecomputeAllFastViewProjectionItemsTask",
+  "runningOptions": {
+    "messageRatePerSecond":2
+  }
+}
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.legacy.json
similarity index 100%
copy from server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
copy to server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.legacy.json
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
index fcd7712..2612c4c 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
@@ -1,4 +1,7 @@
 {
   "type":"RecomputeUserFastViewProjectionItemsTask",
-  "username": "bob"
+  "username": "bob",
+  "runningOptions": {
+    "messageRatePerSecond":2
+  }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.legacy.json
similarity index 100%
copy from server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
copy to server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.legacy.json


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 03/11: JAMES-3184 Avoid direct access to progress fields

Posted by rc...@apache.org.
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 8696a098d64983804587dffd08979f87da9388db
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon May 18 10:35:27 2020 +0700

    JAMES-3184 Avoid direct access to progress fields
---
 .../jmap/MessageFastViewProjectionCorrector.java   | 24 ++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
index a692aea..04d9407 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
@@ -118,6 +118,22 @@ public class MessageFastViewProjectionCorrector {
             failedMessageCount = new AtomicLong();
         }
 
+        private void incrementProcessedUserCount() {
+            processedUserCount.incrementAndGet();
+        }
+
+        private void incrementProcessedMessageCount() {
+            processedMessageCount.incrementAndGet();
+        }
+
+        private void incrementFailedUserCount() {
+            failedUserCount.incrementAndGet();
+        }
+
+        private void incrementFailedMessageCount() {
+            failedMessageCount.incrementAndGet();
+        }
+
         long getProcessedUserCount() {
             return processedUserCount.get();
         }
@@ -163,7 +179,7 @@ public class MessageFastViewProjectionCorrector {
         try {
             return Iterators.toFlux(usersRepository.list())
                 .map(mailboxManager::createSystemSession)
-                .doOnNext(any -> progress.processedUserCount.incrementAndGet())
+                .doOnNext(any -> progress.incrementProcessedUserCount())
                 .flatMap(session -> listUserMailboxMessages(progress, session));
         } catch (UsersRepositoryException e) {
             return Flux.error(e);
@@ -178,7 +194,7 @@ public class MessageFastViewProjectionCorrector {
                     .map(message -> new ProjectionEntry(messageManager, message.getUid(), session))));
         } catch (MailboxException e) {
             LOGGER.error("JMAP fastview re-computation aborted for {} as we failed listing user mailboxes", session.getUser(), e);
-            progress.failedUserCount.incrementAndGet();
+            progress.incrementFailedUserCount();
             return Flux.empty();
         }
     }
@@ -187,14 +203,14 @@ public class MessageFastViewProjectionCorrector {
         return retrieveContent(entry.getMessageManager(), entry.getSession(), entry.getUid())
             .map(this::computeProjectionEntry)
             .flatMap(this::storeProjectionEntry)
-            .doOnSuccess(any -> progress.processedMessageCount.incrementAndGet())
+            .doOnSuccess(any -> progress.incrementProcessedMessageCount())
             .thenReturn(Result.COMPLETED)
             .onErrorResume(e -> {
                 LOGGER.error("JMAP fastview re-computation aborted for {} - {} - {}",
                     entry.getSession().getUser(),
                     entry.getMessageManager().getId(),
                     entry.getUid(), e);
-                progress.failedMessageCount.incrementAndGet();
+                progress.incrementFailedMessageCount();
                 return Mono.just(Result.PARTIAL);
             });
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 11/11: JAMES-3091: Add Serializer guice binding for jmap-rfc8621

Posted by rc...@apache.org.
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 c26bcfa2a74c011a61a52cc46d5839e100202fce
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Mon May 18 10:34:18 2020 +0700

    JAMES-3091: Add Serializer guice binding for jmap-rfc8621
---
 .../main/java/org/apache/james/jmap/rfc8621/RFC8621MethodsModule.java | 4 ++++
 .../src/main/scala/org/apache/james/jmap/json/Serializer.scala        | 3 +--
 2 files changed, 5 insertions(+), 2 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 19fdbe4..2ee2c37 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
@@ -22,11 +22,13 @@ package org.apache.james.jmap.rfc8621;
 
 import org.apache.james.jmap.JMAPRoutesHandler;
 import org.apache.james.jmap.Version;
+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.routes.JMAPApiRoutes;
 
 import com.google.inject.AbstractModule;
+import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
 import com.google.inject.multibindings.ProvidesIntoSet;
 
@@ -34,6 +36,8 @@ public class RFC8621MethodsModule extends AbstractModule {
 
     @Override
     protected void configure() {
+        bind(Serializer.class).in(Scopes.SINGLETON);
+
         Multibinder<Method> methods = Multibinder.newSetBinder(binder(), Method.class);
         methods.addBinding().to(CoreEcho.class);
     }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
index 295e270..7e24a1a 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
@@ -36,8 +36,7 @@ import play.api.libs.json._
 
 import scala.util.Try
 
-@Inject
-class Serializer(mailboxIdFactory: MailboxId.Factory) {
+class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) {
   // CreateIds
   private implicit val clientIdFormat: Format[ClientId] = Json.valueFormat[ClientId]
   private implicit val serverIdFormat: Format[ServerId] = Json.valueFormat[ServerId]


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 01/11: JAMES-3184 MessageFastViewProjectionCorrector concurrency control: RunningOptions

Posted by rc...@apache.org.
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 86bd9d6a6143fa6e94c4e3f5617dc46a6b7d86c4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon May 18 10:30:23 2020 +0700

    JAMES-3184 MessageFastViewProjectionCorrector concurrency control: RunningOptions
    
    Fix message processing rate via throttling
---
 .../jmap/MessageFastViewProjectionCorrector.java   | 125 ++++++++++++++++-----
 .../RecomputeAllFastViewProjectionItemsTask.java   |   3 +-
 .../RecomputeUserFastViewProjectionItemsTask.java  |   7 +-
 3 files changed, 104 insertions(+), 31 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
index 2ba423c..27c65ab 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
@@ -20,6 +20,7 @@
 package org.apache.james.webadmin.data.jmap;
 
 import java.io.IOException;
+import java.time.Duration;
 import java.util.concurrent.atomic.AtomicLong;
 
 import javax.inject.Inject;
@@ -31,6 +32,7 @@ import org.apache.james.jmap.api.projections.MessageFastViewProjection;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MailboxMetaData;
@@ -45,13 +47,61 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
 
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
+import reactor.util.function.Tuple2;
 
 public class MessageFastViewProjectionCorrector {
-
     private static final Logger LOGGER = LoggerFactory.getLogger(MessageFastViewProjectionCorrector.class);
+    
+    private static final Duration DELAY = Duration.ZERO;
+    private static final Duration PERIOD = Duration.ofSeconds(1);
+
+    public static class RunningOptions {
+        public static RunningOptions withMessageRatePerSecond(int messageRatePerSecond) {
+            return new RunningOptions(messageRatePerSecond);
+        }
+
+        public static RunningOptions DEFAULT = new RunningOptions(10);
+
+        private final int messageRatePerSecond;
+
+        public RunningOptions(int messageRatePerSecond) {
+            Preconditions.checkArgument(messageRatePerSecond > 0, "'messageParallelism' must be strictly positive");
+
+            this.messageRatePerSecond = messageRatePerSecond;
+        }
+
+        public int getMessageRatePerSecond() {
+            return messageRatePerSecond;
+        }
+    }
+
+    private static class ProjectionEntry {
+        private final MessageManager messageManager;
+        private final MessageUid uid;
+        private final MailboxSession session;
+
+        private ProjectionEntry(MessageManager messageManager, MessageUid uid, MailboxSession session) {
+            this.messageManager = messageManager;
+            this.uid = uid;
+            this.session = session;
+        }
+
+        private MessageManager getMessageManager() {
+            return messageManager;
+        }
+
+        private MessageUid getUid() {
+            return uid;
+        }
+
+        private MailboxSession getSession() {
+            return session;
+        }
+    }
 
     static class Progress {
         private final AtomicLong processedUserCount;
@@ -102,48 +152,66 @@ public class MessageFastViewProjectionCorrector {
         this.projectionItemFactory = projectionItemFactory;
     }
 
-    Mono<Void> correctAllProjectionItems(Progress progress) {
+    Mono<Void> correctAllProjectionItems(Progress progress, RunningOptions runningOptions) {
+        return correctProjection(listAllMailboxMessages(progress), runningOptions, progress);
+    }
+
+    Mono<Void> correctUsersProjectionItems(Progress progress, Username username, RunningOptions runningOptions) {
+        MailboxSession session = mailboxManager.createSystemSession(username);
+        return correctProjection(listUserMailboxMessages(progress, session), runningOptions, progress);
+    }
+
+    private Flux<ProjectionEntry> listAllMailboxMessages(Progress progress) {
         try {
             return Iterators.toFlux(usersRepository.list())
-                .concatMap(username -> correctUsersProjectionItems(progress, username))
-                .then();
+                .map(mailboxManager::createSystemSession)
+                .doOnNext(any -> progress.processedUserCount.incrementAndGet())
+                .flatMap(session -> listUserMailboxMessages(progress, session));
         } catch (UsersRepositoryException e) {
-            return Mono.error(e);
+            return Flux.error(e);
         }
     }
 
-    Mono<Void> correctUsersProjectionItems(Progress progress, Username username) {
+    private Flux<ProjectionEntry> listUserMailboxMessages(Progress progress, MailboxSession session) {
         try {
-            MailboxSession session = mailboxManager.createSystemSession(username);
             return listUsersMailboxes(session)
-                .concatMap(mailboxMetadata -> retrieveMailbox(session, mailboxMetadata))
-                .concatMap(Throwing.function(messageManager -> correctMailboxProjectionItems(progress, messageManager, session)))
-                .doOnComplete(progress.processedUserCount::incrementAndGet)
-                .onErrorContinue((error, o) -> {
-                    LOGGER.error("JMAP fastview re-computation aborted for {}", username, error);
-                    progress.failedUserCount.incrementAndGet();
-                })
-                .then();
+                .flatMap(mailboxMetadata -> retrieveMailbox(session, mailboxMetadata))
+                .flatMap(Throwing.function(messageManager -> listAllMailboxMessages(messageManager, session)
+                    .map(message -> new ProjectionEntry(messageManager, message.getUid(), session))));
         } catch (MailboxException e) {
-            LOGGER.error("JMAP fastview re-computation aborted for {} as we failed listing user mailboxes", username, e);
+            LOGGER.error("JMAP fastview re-computation aborted for {} as we failed listing user mailboxes", session.getUser(), e);
             progress.failedUserCount.incrementAndGet();
-            return Mono.empty();
+            return Flux.empty();
         }
     }
 
-    private Mono<Void> correctMailboxProjectionItems(Progress progress, MessageManager messageManager, MailboxSession session) throws MailboxException {
-        return listAllMailboxMessages(messageManager, session)
-            .concatMap(messageResult -> retrieveContent(messageManager, session, messageResult))
+    private Mono<Void> correctProjection(ProjectionEntry entry, Progress progress) {
+        return retrieveContent(entry.getMessageManager(), entry.getSession(), entry.getUid())
             .map(this::computeProjectionEntry)
-            .concatMap(pair -> storeProjectionEntry(pair)
-                .doOnSuccess(any -> progress.processedMessageCount.incrementAndGet()))
-            .onErrorContinue((error, triggeringValue) -> {
-                LOGGER.error("JMAP fastview re-computation aborted for {} - {}", session.getUser(), triggeringValue, error);
+            .flatMap(this::storeProjectionEntry)
+            .doOnSuccess(any -> progress.processedMessageCount.incrementAndGet())
+            .onErrorResume(e -> {
+                LOGGER.error("JMAP fastview re-computation aborted for {} - {} - {}",
+                    entry.getSession().getUser(),
+                    entry.getMessageManager().getId(),
+                    entry.getUid(), e);
                 progress.failedMessageCount.incrementAndGet();
-            })
+                return Mono.empty();
+            });
+    }
+
+    private Mono<Void> correctProjection(Flux<ProjectionEntry> entries, RunningOptions runningOptions, Progress progress) {
+        return throttleWithRate(entries, runningOptions)
+            .flatMap(entry -> correctProjection(entry, progress))
             .then();
     }
 
+    private Flux<ProjectionEntry> throttleWithRate(Flux<ProjectionEntry> entries, RunningOptions runningOptions) {
+        return entries.windowTimeout(runningOptions.getMessageRatePerSecond(), Duration.ofSeconds(1))
+            .zipWith(Flux.interval(DELAY, PERIOD))
+            .flatMap(Tuple2::getT1);
+    }
+
     private Flux<MailboxMetaData> listUsersMailboxes(MailboxSession session) throws MailboxException {
         return Flux.fromIterable(mailboxManager.search(MailboxQuery.privateMailboxesBuilder(session).build(), session));
     }
@@ -156,11 +224,12 @@ public class MessageFastViewProjectionCorrector {
         return Iterators.toFlux(messageManager.getMessages(MessageRange.all(), FetchGroup.MINIMAL, session));
     }
 
-    private Flux<MessageResult> retrieveContent(MessageManager messageManager, MailboxSession session, MessageResult messageResult) {
+    private Mono<MessageResult> retrieveContent(MessageManager messageManager, MailboxSession session, MessageUid uid) {
         try {
-            return Iterators.toFlux(messageManager.getMessages(MessageRange.one(messageResult.getUid()), FetchGroup.FULL_CONTENT, session));
+            return Iterators.toFlux(messageManager.getMessages(MessageRange.one(uid), FetchGroup.FULL_CONTENT, session))
+                .next();
         } catch (MailboxException e) {
-            return Flux.error(e);
+            return Mono.error(e);
         }
     }
 
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
index 4ef9365..3556756 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
@@ -29,6 +29,7 @@ import org.apache.james.server.task.json.dto.TaskDTOModule;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskExecutionDetails;
 import org.apache.james.task.TaskType;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
@@ -116,7 +117,7 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
 
     @Override
     public Result run() {
-        corrector.correctAllProjectionItems(progress)
+        corrector.correctAllProjectionItems(progress, RunningOptions.DEFAULT)
             .subscribeOn(Schedulers.elastic())
             .block();
 
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
index d29435a..439f3df 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
@@ -19,6 +19,9 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.Progress;
+import static org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
+
 import java.time.Clock;
 import java.time.Instant;
 import java.util.Optional;
@@ -39,7 +42,7 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
     static final TaskType TASK_TYPE = TaskType.of("RecomputeUserFastViewProjectionItemsTask");
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private static AdditionalInformation from(MessageFastViewProjectionCorrector.Progress progress, Username username) {
+        private static AdditionalInformation from(Progress progress, Username username) {
             return new AdditionalInformation(username,
                 progress.getProcessedMessageCount(),
                 progress.getFailedMessageCount(),
@@ -119,7 +122,7 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
 
     @Override
     public Result run() {
-        corrector.correctUsersProjectionItems(progress, username)
+        corrector.correctUsersProjectionItems(progress, username, RunningOptions.DEFAULT)
             .subscribeOn(Schedulers.elastic())
             .block();
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 02/11: JAMES-3184 MessageFastViewProjectionCorrector: remove temporal coupling

Posted by rc...@apache.org.
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 e33ce51702eafba71082cf64ac186c91b0ef5a8d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon May 18 10:32:27 2020 +0700

    JAMES-3184 MessageFastViewProjectionCorrector: remove temporal coupling
    
    Tasks should not rely on the Progress (that
    could have been not yet updated) to know if
    a task succeeded or not.
---
 .../jmap/MessageFastViewProjectionCorrector.java     | 20 ++++++++++----------
 .../RecomputeAllFastViewProjectionItemsTask.java     |  7 +------
 .../RecomputeUserFastViewProjectionItemsTask.java    |  7 +------
 3 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
index 27c65ab..a692aea 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
@@ -40,6 +40,8 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.search.MailboxQuery;
+import org.apache.james.task.Task;
+import org.apache.james.task.Task.Result;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.util.streams.Iterators;
@@ -131,10 +133,6 @@ public class MessageFastViewProjectionCorrector {
         long getFailedMessageCount() {
             return failedMessageCount.get();
         }
-
-        boolean failed() {
-            return failedMessageCount.get() > 0 || failedUserCount.get() > 0;
-        }
     }
 
     private final UsersRepository usersRepository;
@@ -152,11 +150,11 @@ public class MessageFastViewProjectionCorrector {
         this.projectionItemFactory = projectionItemFactory;
     }
 
-    Mono<Void> correctAllProjectionItems(Progress progress, RunningOptions runningOptions) {
+    Mono<Result> correctAllProjectionItems(Progress progress, RunningOptions runningOptions) {
         return correctProjection(listAllMailboxMessages(progress), runningOptions, progress);
     }
 
-    Mono<Void> correctUsersProjectionItems(Progress progress, Username username, RunningOptions runningOptions) {
+    Mono<Result> correctUsersProjectionItems(Progress progress, Username username, RunningOptions runningOptions) {
         MailboxSession session = mailboxManager.createSystemSession(username);
         return correctProjection(listUserMailboxMessages(progress, session), runningOptions, progress);
     }
@@ -185,25 +183,27 @@ public class MessageFastViewProjectionCorrector {
         }
     }
 
-    private Mono<Void> correctProjection(ProjectionEntry entry, Progress progress) {
+    private Mono<Result> correctProjection(ProjectionEntry entry, Progress progress) {
         return retrieveContent(entry.getMessageManager(), entry.getSession(), entry.getUid())
             .map(this::computeProjectionEntry)
             .flatMap(this::storeProjectionEntry)
             .doOnSuccess(any -> progress.processedMessageCount.incrementAndGet())
+            .thenReturn(Result.COMPLETED)
             .onErrorResume(e -> {
                 LOGGER.error("JMAP fastview re-computation aborted for {} - {} - {}",
                     entry.getSession().getUser(),
                     entry.getMessageManager().getId(),
                     entry.getUid(), e);
                 progress.failedMessageCount.incrementAndGet();
-                return Mono.empty();
+                return Mono.just(Result.PARTIAL);
             });
     }
 
-    private Mono<Void> correctProjection(Flux<ProjectionEntry> entries, RunningOptions runningOptions, Progress progress) {
+    private Mono<Result> correctProjection(Flux<ProjectionEntry> entries, RunningOptions runningOptions, Progress progress) {
         return throttleWithRate(entries, runningOptions)
             .flatMap(entry -> correctProjection(entry, progress))
-            .then();
+            .reduce(Task::combine)
+            .switchIfEmpty(Mono.just(Result.COMPLETED));
     }
 
     private Flux<ProjectionEntry> throttleWithRate(Flux<ProjectionEntry> entries, RunningOptions runningOptions) {
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
index 3556756..6acba49 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
@@ -117,14 +117,9 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
 
     @Override
     public Result run() {
-        corrector.correctAllProjectionItems(progress, RunningOptions.DEFAULT)
+        return corrector.correctAllProjectionItems(progress, RunningOptions.DEFAULT)
             .subscribeOn(Schedulers.elastic())
             .block();
-
-        if (progress.failed()) {
-            return Result.PARTIAL;
-        }
-        return Result.COMPLETED;
     }
 
     @Override
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
index 439f3df..3e44238 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
@@ -122,14 +122,9 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
 
     @Override
     public Result run() {
-        corrector.correctUsersProjectionItems(progress, username, RunningOptions.DEFAULT)
+        return corrector.correctUsersProjectionItems(progress, username, RunningOptions.DEFAULT)
             .subscribeOn(Schedulers.elastic())
             .block();
-
-        if (progress.failed()) {
-            return Result.PARTIAL;
-        }
-        return Result.COMPLETED;
     }
 
     @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 06/11: JAMES-3184 Include RunningOptions in additional information

Posted by rc...@apache.org.
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 18cab271f21e5468eee6404fa446f9c065eefdb2
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 13 17:42:12 2020 +0700

    JAMES-3184 Include RunningOptions in additional information
    
    An admlin then can retrieve these parameters for a running task in webAdmin
---
 .../RecomputeAllFastViewProjectionItemsTask.java   | 15 +++++--
 ...uteAllFastViewTaskAdditionalInformationDTO.java | 49 +++++++++++++++-------
 .../RecomputeUserFastViewProjectionItemsTask.java  | 14 +++++--
 ...teUserFastViewTaskAdditionalInformationDTO.java | 45 ++++++++++++++------
 ...llFastViewProjectionItemsRequestToTaskTest.java |  2 +-
 ...ctionItemsTaskAdditionalInformationDTOTest.java | 30 ++++++++++++-
 ...ctionItemsTaskAdditionalInformationDTOTest.java | 22 ++++++++++
 .../json/recomputeAll.additionalInformation.json   |  5 ++-
 ...recomputeAll.additionalInformation.legacy.json} |  0
 .../json/recomputeUser.additionalInformation.json  |  5 ++-
 ...ecomputeUser.additionalInformation.legacy.json} |  0
 11 files changed, 149 insertions(+), 38 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
index a34e412..5ff9dc5 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTask.java
@@ -39,8 +39,9 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
     static final TaskType TASK_TYPE = TaskType.of("RecomputeAllFastViewProjectionItemsTask");
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private static AdditionalInformation from(MessageFastViewProjectionCorrector.Progress progress) {
-            return new AdditionalInformation(
+        private static AdditionalInformation from(MessageFastViewProjectionCorrector.Progress progress,
+                                                  RunningOptions runningOptions) {
+            return new AdditionalInformation(runningOptions,
                 progress.getProcessedUserCount(),
                 progress.getProcessedMessageCount(),
                 progress.getFailedUserCount(),
@@ -48,13 +49,15 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
                 Clock.systemUTC().instant());
         }
 
+        private final RunningOptions runningOptions;
         private final long processedUserCount;
         private final long processedMessageCount;
         private final long failedUserCount;
         private final long failedMessageCount;
         private final Instant timestamp;
 
-        public AdditionalInformation(long processedUserCount, long processedMessageCount, long failedUserCount, long failedMessageCount, Instant timestamp) {
+        public AdditionalInformation(RunningOptions runningOptions, long processedUserCount, long processedMessageCount, long failedUserCount, long failedMessageCount, Instant timestamp) {
+            this.runningOptions = runningOptions;
             this.processedUserCount = processedUserCount;
             this.processedMessageCount = processedMessageCount;
             this.failedUserCount = failedUserCount;
@@ -78,6 +81,10 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
             return failedMessageCount;
         }
 
+        public RunningOptions getRunningOptions() {
+            return runningOptions;
+        }
+
         @Override
         public Instant timestamp() {
             return timestamp;
@@ -149,6 +156,6 @@ public class RecomputeAllFastViewProjectionItemsTask implements Task {
 
     @Override
     public Optional<TaskExecutionDetails.AdditionalInformation> details() {
-        return Optional.of(AdditionalInformation.from(progress));
+        return Optional.of(AdditionalInformation.from(progress, runningOptions));
     }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewTaskAdditionalInformationDTO.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewTaskAdditionalInformationDTO.java
index 3c405d1..8e1461e 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewTaskAdditionalInformationDTO.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewTaskAdditionalInformationDTO.java
@@ -20,10 +20,12 @@
 package org.apache.james.webadmin.data.jmap;
 
 import java.time.Instant;
+import java.util.Optional;
 
 import org.apache.james.json.DTOModule;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.annotations.VisibleForTesting;
@@ -32,28 +34,41 @@ public class RecomputeAllFastViewTaskAdditionalInformationDTO implements Additio
     public static final AdditionalInformationDTOModule<RecomputeAllFastViewProjectionItemsTask.AdditionalInformation, RecomputeAllFastViewTaskAdditionalInformationDTO> SERIALIZATION_MODULE =
         DTOModule.forDomainObject(RecomputeAllFastViewProjectionItemsTask.AdditionalInformation.class)
             .convertToDTO(RecomputeAllFastViewTaskAdditionalInformationDTO.class)
-            .toDomainObjectConverter(dto -> new RecomputeAllFastViewProjectionItemsTask.AdditionalInformation(
-                dto.getProcessedUserCount(),
-                dto.getProcessedMessageCount(),
-                dto.getFailedUserCount(),
-                dto.getFailedMessageCount(),
-                dto.timestamp))
-            .toDTOConverter((details, type) -> new RecomputeAllFastViewTaskAdditionalInformationDTO(
-                type,
-                details.timestamp(),
-                details.getProcessedUserCount(),
-                details.getProcessedMessageCount(),
-                details.getFailedUserCount(),
-                details.getFailedMessageCount()))
+            .toDomainObjectConverter(RecomputeAllFastViewTaskAdditionalInformationDTO::toDomainObject)
+            .toDTOConverter(RecomputeAllFastViewTaskAdditionalInformationDTO::toDTO)
             .typeName(RecomputeAllFastViewProjectionItemsTask.TASK_TYPE.asString())
             .withFactory(AdditionalInformationDTOModule::new);
 
+    private static RecomputeAllFastViewProjectionItemsTask.AdditionalInformation toDomainObject(RecomputeAllFastViewTaskAdditionalInformationDTO dto) {
+        return new RecomputeAllFastViewProjectionItemsTask.AdditionalInformation(
+            dto.getRunningOptions()
+                .map(RunningOptionsDTO::asDomainObject)
+                .orElse(RunningOptions.DEFAULT),
+            dto.getProcessedUserCount(),
+            dto.getProcessedMessageCount(),
+            dto.getFailedUserCount(),
+            dto.getFailedMessageCount(),
+            dto.timestamp);
+    }
+
+    private static RecomputeAllFastViewTaskAdditionalInformationDTO toDTO(RecomputeAllFastViewProjectionItemsTask.AdditionalInformation details, String type) {
+        return new RecomputeAllFastViewTaskAdditionalInformationDTO(
+            type,
+            details.timestamp(),
+            details.getProcessedUserCount(),
+            details.getProcessedMessageCount(),
+            details.getFailedUserCount(),
+            details.getFailedMessageCount(),
+            Optional.of(RunningOptionsDTO.asDTO(details.getRunningOptions())));
+    }
+
     private final String type;
     private final Instant timestamp;
     private final long processedUserCount;
     private final long processedMessageCount;
     private final long failedUserCount;
     private final long failedMessageCount;
+    private final Optional<RunningOptionsDTO> runningOptions;
 
     @VisibleForTesting
     RecomputeAllFastViewTaskAdditionalInformationDTO(@JsonProperty("type") String type,
@@ -61,13 +76,15 @@ public class RecomputeAllFastViewTaskAdditionalInformationDTO implements Additio
                                                      @JsonProperty("processedUserCount") long processedUserCount,
                                                      @JsonProperty("processedMessageCount") long processedMessageCount,
                                                      @JsonProperty("failedUserCount") long failedUserCount,
-                                                     @JsonProperty("failedMessageCount") long failedMessageCount) {
+                                                     @JsonProperty("failedMessageCount") long failedMessageCount,
+                                                     @JsonProperty("runningOptions") Optional<RunningOptionsDTO> runningOptions) {
         this.type = type;
         this.timestamp = timestamp;
         this.processedUserCount = processedUserCount;
         this.processedMessageCount = processedMessageCount;
         this.failedUserCount = failedUserCount;
         this.failedMessageCount = failedMessageCount;
+        this.runningOptions = runningOptions;
     }
 
     @Override
@@ -95,4 +112,8 @@ public class RecomputeAllFastViewTaskAdditionalInformationDTO implements Additio
     public long getFailedMessageCount() {
         return failedMessageCount;
     }
+
+    public Optional<RunningOptionsDTO> getRunningOptions() {
+        return runningOptions;
+    }
 }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
index ca41a3f..3c4d90c 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTask.java
@@ -42,25 +42,31 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
     static final TaskType TASK_TYPE = TaskType.of("RecomputeUserFastViewProjectionItemsTask");
 
     public static class AdditionalInformation implements TaskExecutionDetails.AdditionalInformation {
-        private static AdditionalInformation from(Progress progress, Username username) {
-            return new AdditionalInformation(username,
+        private static AdditionalInformation from(Progress progress, RunningOptions runningOptions, Username username) {
+            return new AdditionalInformation(runningOptions, username,
                 progress.getProcessedMessageCount(),
                 progress.getFailedMessageCount(),
                 Clock.systemUTC().instant());
         }
 
+        private final RunningOptions runningOptions;
         private final Username username;
         private final long processedMessageCount;
         private final long failedMessageCount;
         private final Instant timestamp;
 
-        public AdditionalInformation(Username username, long processedMessageCount, long failedMessageCount, Instant timestamp) {
+        public AdditionalInformation(RunningOptions runningOptions, Username username, long processedMessageCount, long failedMessageCount, Instant timestamp) {
+            this.runningOptions = runningOptions;
             this.username = username;
             this.processedMessageCount = processedMessageCount;
             this.failedMessageCount = failedMessageCount;
             this.timestamp = timestamp;
         }
 
+        public RunningOptions getRunningOptions() {
+            return runningOptions;
+        }
+
         public long getProcessedMessageCount() {
             return processedMessageCount;
         }
@@ -157,6 +163,6 @@ public class RecomputeUserFastViewProjectionItemsTask implements Task {
 
     @Override
     public Optional<TaskExecutionDetails.AdditionalInformation> details() {
-        return Optional.of(AdditionalInformation.from(progress, username));
+        return Optional.of(AdditionalInformation.from(progress, runningOptions, username));
     }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewTaskAdditionalInformationDTO.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewTaskAdditionalInformationDTO.java
index f048a70..5a5c133 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewTaskAdditionalInformationDTO.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewTaskAdditionalInformationDTO.java
@@ -20,11 +20,13 @@
 package org.apache.james.webadmin.data.jmap;
 
 import java.time.Instant;
+import java.util.Optional;
 
 import org.apache.james.core.Username;
 import org.apache.james.json.DTOModule;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
 import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
@@ -32,36 +34,51 @@ public class RecomputeUserFastViewTaskAdditionalInformationDTO implements Additi
     public static final AdditionalInformationDTOModule<RecomputeUserFastViewProjectionItemsTask.AdditionalInformation, RecomputeUserFastViewTaskAdditionalInformationDTO> SERIALIZATION_MODULE =
         DTOModule.forDomainObject(RecomputeUserFastViewProjectionItemsTask.AdditionalInformation.class)
             .convertToDTO(RecomputeUserFastViewTaskAdditionalInformationDTO.class)
-            .toDomainObjectConverter(dto -> new RecomputeUserFastViewProjectionItemsTask.AdditionalInformation(
-                Username.of(dto.username),
-                dto.getProcessedMessageCount(),
-                dto.getFailedMessageCount(),
-                dto.timestamp))
-            .toDTOConverter((details, type) -> new RecomputeUserFastViewTaskAdditionalInformationDTO(
-                type,
-                details.timestamp(),
-                details.getUsername(),
-                details.getProcessedMessageCount(),
-                details.getFailedMessageCount()))
+            .toDomainObjectConverter(RecomputeUserFastViewTaskAdditionalInformationDTO::toDomainObject)
+            .toDTOConverter(RecomputeUserFastViewTaskAdditionalInformationDTO::toDTO)
             .typeName(RecomputeUserFastViewProjectionItemsTask.TASK_TYPE.asString())
             .withFactory(AdditionalInformationDTOModule::new);
 
+    private static RecomputeUserFastViewTaskAdditionalInformationDTO toDTO(RecomputeUserFastViewProjectionItemsTask.AdditionalInformation details, String type) {
+        return new RecomputeUserFastViewTaskAdditionalInformationDTO(
+            type,
+            details.timestamp(),
+            details.getUsername(),
+            details.getProcessedMessageCount(),
+            details.getFailedMessageCount(),
+            Optional.of(RunningOptionsDTO.asDTO(details.getRunningOptions())));
+    }
+
+    private static RecomputeUserFastViewProjectionItemsTask.AdditionalInformation toDomainObject(RecomputeUserFastViewTaskAdditionalInformationDTO dto) {
+        return new RecomputeUserFastViewProjectionItemsTask.AdditionalInformation(
+            dto.getRunningOptions()
+                .map(RunningOptionsDTO::asDomainObject)
+                .orElse(RunningOptions.DEFAULT),
+            Username.of(dto.username),
+            dto.getProcessedMessageCount(),
+            dto.getFailedMessageCount(),
+            dto.timestamp);
+    }
+
     private final String type;
     private final Instant timestamp;
     private final String username;
     private final long processedMessageCount;
     private final long failedMessageCount;
+    private final Optional<RunningOptionsDTO> runningOptions;
 
     private RecomputeUserFastViewTaskAdditionalInformationDTO(@JsonProperty("type") String type,
                                                               @JsonProperty("timestamp") Instant timestamp,
                                                               @JsonProperty("username") String username,
                                                               @JsonProperty("processedMessageCount") long processedMessageCount,
-                                                              @JsonProperty("failedMessageCount") long failedMessageCount) {
+                                                              @JsonProperty("failedMessageCount") long failedMessageCount,
+                                                              @JsonProperty("runningOptions") Optional<RunningOptionsDTO> runningOptionsDTO) {
         this.type = type;
         this.timestamp = timestamp;
         this.username = username;
         this.processedMessageCount = processedMessageCount;
         this.failedMessageCount = failedMessageCount;
+        this.runningOptions = runningOptionsDTO;
     }
 
     @Override
@@ -82,6 +99,10 @@ public class RecomputeUserFastViewTaskAdditionalInformationDTO implements Additi
         return failedMessageCount;
     }
 
+    public Optional<RunningOptionsDTO> getRunningOptions() {
+        return runningOptions;
+    }
+
     public String getUsername() {
         return username;
     }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
index 1e57577..85c3339 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
@@ -279,7 +279,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         .then()
             .body("taskId", is(taskId))
             .body("type", is("RecomputeAllFastViewProjectionItemsTask"))
-            .body("additionalInformation.runningOptions.messageParallelism", is(20));
+            .body("additionalInformation.runningOptions.messageRatePerSecond", is(20));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
index ad53227..15108e7 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
@@ -19,15 +19,25 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import java.time.Instant;
 
 import org.apache.james.JsonSerializationVerifier;
+import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.util.ClassLoaderUtils;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 import org.junit.jupiter.api.Test;
 
 class RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest {
     private static final Instant INSTANT = Instant.parse("2007-12-03T10:15:30.00Z");
-    private static final RecomputeAllFastViewProjectionItemsTask.AdditionalInformation DOMAIN_OBJECT = new RecomputeAllFastViewProjectionItemsTask.AdditionalInformation(1, 2, 3, 4, INSTANT);
+    private static final RecomputeAllFastViewProjectionItemsTask.AdditionalInformation DOMAIN_OBJECT = new RecomputeAllFastViewProjectionItemsTask.AdditionalInformation(
+        RunningOptions.withMessageRatePerSecond(20),
+        1,
+        2,
+        3,
+        4,
+        INSTANT);
 
     @Test
     void shouldMatchJsonSerializationContract() throws Exception {
@@ -36,4 +46,22 @@ class RecomputeAllFastViewProjectionItemsTaskAdditionalInformationDTOTest {
             .json(ClassLoaderUtils.getSystemResourceAsString("json/recomputeAll.additionalInformation.json"))
             .verify();
     }
+
+    @Test
+    void shouldDeserializeLegacy() throws Exception {
+        RecomputeAllFastViewProjectionItemsTask.AdditionalInformation legacyDetails = JsonGenericSerializer.forModules(RecomputeAllFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE)
+            .withoutNestedType()
+            .deserialize(ClassLoaderUtils.getSystemResourceAsString("json/recomputeAll.additionalInformation.legacy.json"));
+
+        RecomputeAllFastViewProjectionItemsTask.AdditionalInformation expected = new RecomputeAllFastViewProjectionItemsTask.AdditionalInformation(
+            RunningOptions.DEFAULT,
+            1,
+            2,
+            3,
+            4,
+            INSTANT);
+
+        assertThat(legacyDetails)
+            .isEqualToComparingFieldByFieldRecursively(expected);
+    }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
index 569b071..22355a9 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest.java
@@ -19,16 +19,20 @@
 
 package org.apache.james.webadmin.data.jmap;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import java.time.Instant;
 
 import org.apache.james.JsonSerializationVerifier;
 import org.apache.james.core.Username;
+import org.apache.james.json.JsonGenericSerializer;
 import org.apache.james.util.ClassLoaderUtils;
 import org.junit.jupiter.api.Test;
 
 class RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest {
     private static final Instant INSTANT = Instant.parse("2007-12-03T10:15:30.00Z");
     private static final RecomputeUserFastViewProjectionItemsTask.AdditionalInformation DOMAIN_OBJECT = new RecomputeUserFastViewProjectionItemsTask.AdditionalInformation(
+        MessageFastViewProjectionCorrector.RunningOptions.withMessageRatePerSecond(20),
         Username.of("bob"), 2, 3, INSTANT);
 
     @Test
@@ -38,4 +42,22 @@ class RecomputeUserFastViewProjectionItemsTaskAdditionalInformationDTOTest {
             .json(ClassLoaderUtils.getSystemResourceAsString("json/recomputeUser.additionalInformation.json"))
             .verify();
     }
+
+
+    @Test
+    void shouldDeserializeLegacy() throws Exception {
+        RecomputeUserFastViewProjectionItemsTask.AdditionalInformation legacyDetails = JsonGenericSerializer.forModules(RecomputeUserFastViewTaskAdditionalInformationDTO.SERIALIZATION_MODULE)
+            .withoutNestedType()
+            .deserialize(ClassLoaderUtils.getSystemResourceAsString("json/recomputeUser.additionalInformation.legacy.json"));
+
+        RecomputeUserFastViewProjectionItemsTask.AdditionalInformation expected = new RecomputeUserFastViewProjectionItemsTask.AdditionalInformation(
+            MessageFastViewProjectionCorrector.RunningOptions.DEFAULT,
+            Username.of("bob"),
+            2,
+            3,
+            INSTANT);
+
+        assertThat(legacyDetails)
+            .isEqualToComparingFieldByFieldRecursively(expected);
+    }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
index 6d130f9..6d9b476 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
@@ -4,5 +4,8 @@
   "processedUserCount":1,
   "processedMessageCount":2,
   "failedUserCount":3,
-  "failedMessageCount":4
+  "failedMessageCount":4,
+  "runningOptions": {
+    "messageRatePerSecond":20
+  }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.legacy.json
similarity index 100%
copy from server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
copy to server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.legacy.json
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
index 7e24f49..c4c7bd7 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
@@ -3,5 +3,8 @@
   "timestamp":"2007-12-03T10:15:30Z",
   "username": "bob",
   "processedMessageCount":2,
-  "failedMessageCount":3
+  "failedMessageCount":3,
+  "runningOptions": {
+    "messageRatePerSecond":20
+  }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.legacy.json
similarity index 100%
copy from server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
copy to server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.legacy.json


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 05/11: JAMES-3184 RecomputeFastViewProjection task runningOptions should be WebAdmin exposed

Posted by rc...@apache.org.
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 6a4a7605ce2c253fd7af40b2b241d78e96612e2d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 13 14:53:04 2020 +0700

    JAMES-3184 RecomputeFastViewProjection task runningOptions should be WebAdmin exposed
---
 ...uteAllFastViewProjectionItemsRequestToTask.java |  4 +-
 ...teUserFastViewProjectionItemsRequestToTask.java |  3 +-
 ...equestToTask.java => RunningOptionsParser.java} | 26 +++++---
 ...llFastViewProjectionItemsRequestToTaskTest.java | 72 ++++++++++++++++++++++
 ...erFastViewProjectionItemsRequestToTaskTest.java | 72 ++++++++++++++++++++++
 5 files changed, 164 insertions(+), 13 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
index e81cf79..5a6d55d 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
@@ -19,8 +19,6 @@
 
 package org.apache.james.webadmin.data.jmap;
 
-import static org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
-
 import javax.inject.Inject;
 
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
@@ -29,6 +27,6 @@ public class RecomputeAllFastViewProjectionItemsRequestToTask extends TaskFromRe
     @Inject
     RecomputeAllFastViewProjectionItemsRequestToTask(MessageFastViewProjectionCorrector corrector) {
         super(Constants.TASK_REGISTRATION_KEY,
-            request -> new RecomputeAllFastViewProjectionItemsTask(corrector, RunningOptions.DEFAULT));
+            request -> new RecomputeAllFastViewProjectionItemsTask(corrector, RunningOptionsParser.parse(request)));
     }
 }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
index 7b32ec6..47500a6 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTask.java
@@ -25,7 +25,6 @@ import org.apache.james.core.Username;
 import org.apache.james.task.Task;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
-import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
 import org.apache.james.webadmin.utils.ErrorResponder;
 import org.eclipse.jetty.http.HttpStatus;
@@ -44,7 +43,7 @@ public class RecomputeUserFastViewProjectionItemsRequestToTask extends TaskFromR
     private static Task toTask(MessageFastViewProjectionCorrector corrector, UsersRepository usersRepository, Request request) throws UsersRepositoryException {
         Username username = Username.of(request.params("username"));
         if (usersRepository.contains(username)) {
-            return new RecomputeUserFastViewProjectionItemsTask(corrector, RunningOptions.DEFAULT, username);
+            return new RecomputeUserFastViewProjectionItemsTask(corrector, RunningOptionsParser.parse(request), username);
         }
 
         throw ErrorResponder.builder()
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
similarity index 58%
copy from server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
copy to server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
index e81cf79..ca43bb9 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTask.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
@@ -19,16 +19,26 @@
 
 package org.apache.james.webadmin.data.jmap;
 
-import static org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
+import java.util.Optional;
 
-import javax.inject.Inject;
+import org.apache.james.webadmin.data.jmap.MessageFastViewProjectionCorrector.RunningOptions;
 
-import org.apache.james.webadmin.tasks.TaskFromRequestRegistry;
+import spark.Request;
 
-public class RecomputeAllFastViewProjectionItemsRequestToTask extends TaskFromRequestRegistry.TaskRegistration {
-    @Inject
-    RecomputeAllFastViewProjectionItemsRequestToTask(MessageFastViewProjectionCorrector corrector) {
-        super(Constants.TASK_REGISTRATION_KEY,
-            request -> new RecomputeAllFastViewProjectionItemsTask(corrector, RunningOptions.DEFAULT));
+public class RunningOptionsParser {
+    public static RunningOptions parse(Request request) {
+        return intQueryParameter(request, "messageRatePerSecond")
+            .map(RunningOptions::withMessageRatePerSecond)
+            .orElse(RunningOptions.DEFAULT);
+    }
+
+    public static Optional<Integer> intQueryParameter(Request request, String queryParameter) {
+        try {
+            return Optional.ofNullable(request.queryParams(queryParameter))
+                .map(Integer::parseInt);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(String.format("Illegal value supplied for query parameter '%s', expecting a " +
+                "strictly positive optional integer", queryParameter), e);
+        }
     }
 }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
index efb642b..1e57577 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
@@ -176,6 +176,48 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void postShouldFailWhenMessageRatePerSecondIsNotAnInt() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "abc")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("Illegal value supplied for query parameter 'messageRatePerSecond', expecting a strictly positive optional integer"));
+    }
+
+    @Test
+    void postShouldFailWhenMessageRatePerSecondIsNegative() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "-1")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("'messageParallelism' must be strictly positive"));
+    }
+
+    @Test
+    void postShouldFailWhenMessageRatePerSecondIsZero() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "0")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("'messageParallelism' must be strictly positive"));
+    }
+
+    @Test
     void postShouldCreateANewTask() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -186,6 +228,17 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void postShouldCreateANewTaskWhenConcurrencyParametersSpecified() {
+        given()
+            .queryParam("messageRatePerSecond", "1")
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .post()
+        .then()
+            .statusCode(HttpStatus.CREATED_201)
+            .body("taskId", notNullValue());
+    }
+
+    @Test
     void recomputeAllShouldCompleteWhenNoUser() {
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -211,6 +264,25 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void runningOptionsShouldBePartOfTaskDetails() {
+        String taskId = with()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "20")
+            .post()
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("taskId", is(taskId))
+            .body("type", is("RecomputeAllFastViewProjectionItemsTask"))
+            .body("additionalInformation.runningOptions.messageParallelism", is(20));
+    }
+
+    @Test
     void recomputeAllShouldCompleteWhenUserWithNoMailbox() throws Exception {
         usersRepository.addUser(BOB, "pass");
 
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
index 41b1291..886c38b 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
@@ -177,6 +177,48 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void postShouldFailWhenMessageRatePerSecondIsNotAnInt() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "abc")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("Illegal value supplied for query parameter 'messageRatePerSecond', expecting a strictly positive optional integer"));
+    }
+
+    @Test
+    void postShouldFailWhenMessageRatePerSecondIsNegative() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "-1")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("'messageParallelism' must be strictly positive"));
+    }
+
+    @Test
+    void postShouldFailWhenMessageRatePerSecondIsZero() {
+        given()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "0")
+            .post()
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("Invalid arguments supplied in the user request"))
+            .body("details", is("'messageParallelism' must be strictly positive"));
+    }
+
+    @Test
     void postShouldFailUponInvalidAction() {
         given()
             .queryParam("action", "invalid")
@@ -227,6 +269,17 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void postShouldCreateANewTaskWhenConcurrencyParametersSpecified() {
+        given()
+            .queryParam("messageRatePerSecond", "1")
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .post()
+        .then()
+            .statusCode(HttpStatus.CREATED_201)
+            .body("taskId", notNullValue());
+    }
+
+    @Test
     void recomputeUserShouldCompleteWhenUserWithNoMailbox() throws Exception {
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -251,6 +304,25 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
+    void runningOptionsShouldBePartOfTaskDetails() {
+        String taskId = with()
+            .queryParam("action", "recomputeFastViewProjectionItems")
+            .queryParam("messageRatePerSecond", "20")
+            .post()
+            .jsonPath()
+            .get("taskId");
+
+        given()
+            .basePath(TasksRoutes.BASE)
+        .when()
+            .get(taskId + "/await")
+        .then()
+            .body("taskId", is(taskId))
+            .body("type", is("RecomputeUserFastViewProjectionItemsTask"))
+            .body("additionalInformation.runningOptions.messageRatePerSecond", is(20));
+    }
+
+    @Test
     void recomputeUserShouldCompleteWhenUserWithNoMessage() throws Exception {
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 08/11: JAMES-3184 s/messageRatePerSecond/messagesPerSecond

Posted by rc...@apache.org.
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 0f3584c79e19d2722552994780bc279ece0b4494
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 19 09:05:28 2020 +0700

    JAMES-3184 s/messageRatePerSecond/messagesPerSecond
---
 .../jmap/MessageFastViewProjectionCorrector.java   | 14 ++++++-------
 .../webadmin/data/jmap/RunningOptionsDTO.java      | 14 ++++++-------
 .../webadmin/data/jmap/RunningOptionsParser.java   |  2 +-
 ...llFastViewProjectionItemsRequestToTaskTest.java | 24 +++++++++++-----------
 ...erFastViewProjectionItemsRequestToTaskTest.java | 24 +++++++++++-----------
 .../json/recomputeAll.additionalInformation.json   |  2 +-
 .../src/test/resources/json/recomputeAll.task.json |  2 +-
 .../json/recomputeUser.additionalInformation.json  |  2 +-
 .../test/resources/json/recomputeUser.task.json    |  2 +-
 9 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
index 04d9407..95767f5 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/MessageFastViewProjectionCorrector.java
@@ -68,16 +68,16 @@ public class MessageFastViewProjectionCorrector {
 
         public static RunningOptions DEFAULT = new RunningOptions(10);
 
-        private final int messageRatePerSecond;
+        private final int messagesPerSecond;
 
-        public RunningOptions(int messageRatePerSecond) {
-            Preconditions.checkArgument(messageRatePerSecond > 0, "'messageParallelism' must be strictly positive");
+        public RunningOptions(int messagesPerSecond) {
+            Preconditions.checkArgument(messagesPerSecond > 0, "'messagesPerSecond' must be strictly positive");
 
-            this.messageRatePerSecond = messageRatePerSecond;
+            this.messagesPerSecond = messagesPerSecond;
         }
 
-        public int getMessageRatePerSecond() {
-            return messageRatePerSecond;
+        public int getMessagesPerSecond() {
+            return messagesPerSecond;
         }
     }
 
@@ -223,7 +223,7 @@ public class MessageFastViewProjectionCorrector {
     }
 
     private Flux<ProjectionEntry> throttleWithRate(Flux<ProjectionEntry> entries, RunningOptions runningOptions) {
-        return entries.windowTimeout(runningOptions.getMessageRatePerSecond(), Duration.ofSeconds(1))
+        return entries.windowTimeout(runningOptions.getMessagesPerSecond(), Duration.ofSeconds(1))
             .zipWith(Flux.interval(DELAY, PERIOD))
             .flatMap(Tuple2::getT1);
     }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
index 5fae5b5..c8efe03 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsDTO.java
@@ -28,23 +28,23 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class RunningOptionsDTO {
     public static RunningOptionsDTO asDTO(RunningOptions domainObject) {
-        return new RunningOptionsDTO(Optional.of(domainObject.getMessageRatePerSecond()));
+        return new RunningOptionsDTO(Optional.of(domainObject.getMessagesPerSecond()));
     }
 
-    private final Optional<Integer> messageRatePerSecond;
+    private final Optional<Integer> messagesPerSecond;
 
     @JsonCreator
     public RunningOptionsDTO(
-            @JsonProperty("messageRatePerSecond") Optional<Integer> messageRatePerSecond) {
-        this.messageRatePerSecond = messageRatePerSecond;
+            @JsonProperty("messagesPerSecond") Optional<Integer> messagesPerSecond) {
+        this.messagesPerSecond = messagesPerSecond;
     }
 
-    public Optional<Integer> getMessageRatePerSecond() {
-        return messageRatePerSecond;
+    public Optional<Integer> getMessagesPerSecond() {
+        return messagesPerSecond;
     }
 
     public RunningOptions asDomainObject() {
-        return messageRatePerSecond.map(RunningOptions::withMessageRatePerSecond)
+        return messagesPerSecond.map(RunningOptions::withMessageRatePerSecond)
             .orElse(RunningOptions.DEFAULT);
     }
 }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
index ca43bb9..8aebd6e 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/main/java/org/apache/james/webadmin/data/jmap/RunningOptionsParser.java
@@ -27,7 +27,7 @@ import spark.Request;
 
 public class RunningOptionsParser {
     public static RunningOptions parse(Request request) {
-        return intQueryParameter(request, "messageRatePerSecond")
+        return intQueryParameter(request, "messagesPerSecond")
             .map(RunningOptions::withMessageRatePerSecond)
             .orElse(RunningOptions.DEFAULT);
     }
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
index 85c3339..0a8a2e6 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
@@ -176,45 +176,45 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsNotAnInt() {
+    void postShouldFailWhenMessagesPerSecondIsNotAnInt() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "abc")
+            .queryParam("messagesPerSecond", "abc")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("Illegal value supplied for query parameter 'messageRatePerSecond', expecting a strictly positive optional integer"));
+            .body("details", is("Illegal value supplied for query parameter 'messagesPerSecond', expecting a strictly positive optional integer"));
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsNegative() {
+    void postShouldFailWhenMessagesPerSecondIsNegative() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "-1")
+            .queryParam("messagesPerSecond", "-1")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("'messageParallelism' must be strictly positive"));
+            .body("details", is("'messagesPerSecond' must be strictly positive"));
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsZero() {
+    void postShouldFailWhenMessagesPerSecondIsZero() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "0")
+            .queryParam("messagesPerSecond", "0")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("'messageParallelism' must be strictly positive"));
+            .body("details", is("'messagesPerSecond' must be strictly positive"));
     }
 
     @Test
@@ -230,7 +230,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     @Test
     void postShouldCreateANewTaskWhenConcurrencyParametersSpecified() {
         given()
-            .queryParam("messageRatePerSecond", "1")
+            .queryParam("messagesPerSecond", "1")
             .queryParam("action", "recomputeFastViewProjectionItems")
             .post()
         .then()
@@ -267,7 +267,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
     void runningOptionsShouldBePartOfTaskDetails() {
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "20")
+            .queryParam("messagesPerSecond", "20")
             .post()
             .jsonPath()
             .get("taskId");
@@ -279,7 +279,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         .then()
             .body("taskId", is(taskId))
             .body("type", is("RecomputeAllFastViewProjectionItemsTask"))
-            .body("additionalInformation.runningOptions.messageRatePerSecond", is(20));
+            .body("additionalInformation.runningOptions.messagesPerSecond", is(20));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
index 886c38b..5a4d74a 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
@@ -177,45 +177,45 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsNotAnInt() {
+    void postShouldFailWhenMessagesPerSecondIsNotAnInt() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "abc")
+            .queryParam("messagesPerSecond", "abc")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("Illegal value supplied for query parameter 'messageRatePerSecond', expecting a strictly positive optional integer"));
+            .body("details", is("Illegal value supplied for query parameter 'messagesPerSecond', expecting a strictly positive optional integer"));
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsNegative() {
+    void postShouldFailWhenMessagesPerSecondIsNegative() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "-1")
+            .queryParam("messagesPerSecond", "-1")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("'messageParallelism' must be strictly positive"));
+            .body("details", is("'messagesPerSecond' must be strictly positive"));
     }
 
     @Test
-    void postShouldFailWhenMessageRatePerSecondIsZero() {
+    void postShouldFailWhenMessagesPerSecondIsZero() {
         given()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "0")
+            .queryParam("messagesPerSecond", "0")
             .post()
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("statusCode", is(400))
             .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
             .body("message", is("Invalid arguments supplied in the user request"))
-            .body("details", is("'messageParallelism' must be strictly positive"));
+            .body("details", is("'messagesPerSecond' must be strictly positive"));
     }
 
     @Test
@@ -271,7 +271,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     @Test
     void postShouldCreateANewTaskWhenConcurrencyParametersSpecified() {
         given()
-            .queryParam("messageRatePerSecond", "1")
+            .queryParam("messagesPerSecond", "1")
             .queryParam("action", "recomputeFastViewProjectionItems")
             .post()
         .then()
@@ -307,7 +307,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     void runningOptionsShouldBePartOfTaskDetails() {
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
-            .queryParam("messageRatePerSecond", "20")
+            .queryParam("messagesPerSecond", "20")
             .post()
             .jsonPath()
             .get("taskId");
@@ -319,7 +319,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
         .then()
             .body("taskId", is(taskId))
             .body("type", is("RecomputeUserFastViewProjectionItemsTask"))
-            .body("additionalInformation.runningOptions.messageRatePerSecond", is(20));
+            .body("additionalInformation.runningOptions.messagesPerSecond", is(20));
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
index 6d9b476..7c13044 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.additionalInformation.json
@@ -6,6 +6,6 @@
   "failedUserCount":3,
   "failedMessageCount":4,
   "runningOptions": {
-    "messageRatePerSecond":20
+    "messagesPerSecond":20
   }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
index 0a61bed..c1e3685 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeAll.task.json
@@ -1,6 +1,6 @@
 {
   "type":"RecomputeAllFastViewProjectionItemsTask",
   "runningOptions": {
-    "messageRatePerSecond":2
+    "messagesPerSecond":2
   }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
index c4c7bd7..7559a8d 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.additionalInformation.json
@@ -5,6 +5,6 @@
   "processedMessageCount":2,
   "failedMessageCount":3,
   "runningOptions": {
-    "messageRatePerSecond":20
+    "messagesPerSecond":20
   }
 }
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
index 2612c4c..e99409e 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/resources/json/recomputeUser.task.json
@@ -2,6 +2,6 @@
   "type":"RecomputeUserFastViewProjectionItemsTask",
   "username": "bob",
   "runningOptions": {
-    "messageRatePerSecond":2
+    "messagesPerSecond":2
   }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org