From 7e045621c3bd3083a6805ce524dd52cae06a285b Mon Sep 17 00:00:00 2001 From: Rene Cordier Date: Tue, 23 Mar 2021 11:53:30 +0700 Subject: [PATCH 1/2] ISSUE-72 State implementation for Filter/get method --- .../LinagoraFilterGetMethodContract.scala | 6 ++++ .../LinagoraFilterSetMethodContract.scala | 1 + .../james/jmap/json/FilterSerializer.scala | 7 +++-- .../james/jmap/method/FilterGetMethod.scala | 28 ++++++++++--------- .../openpaas/james/jmap/model/FilterGet.scala | 7 ++++- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterGetMethodContract.scala b/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterGetMethodContract.scala index 26bbc28286..dedf07fb41 100644 --- a/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterGetMethodContract.scala +++ b/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterGetMethodContract.scala @@ -76,6 +76,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [ | { | "id": "singleton", @@ -135,6 +136,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "-1", | "list": [ | { | "id": "singleton", @@ -316,6 +318,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [ | { | "id": "singleton", @@ -384,6 +387,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [ | { | "id": "singleton", @@ -452,6 +456,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [ | | ], @@ -503,6 +508,7 @@ trait LinagoraFilterGetMethodContract { | "methodResponses": [[ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [], | "notFound": [] | }, "c1"]] diff --git a/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterSetMethodContract.scala b/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterSetMethodContract.scala index 99ce520096..bbe94e8e9a 100644 --- a/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterSetMethodContract.scala +++ b/openpaas-james/integration-tests/jmap/jmap-integration-tests-common/src/main/scala/com/linagora/openpaas/james/common/LinagoraFilterSetMethodContract.scala @@ -98,6 +98,7 @@ trait LinagoraFilterSetMethodContract { | [ | "Filter/get", { | "accountId": "$generateAccountIdAsString", + | "state": "0", | "list": [{ | "id": "singleton", | "rules": [{ diff --git a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/json/FilterSerializer.scala b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/json/FilterSerializer.scala index fb37012d39..8a2adc6576 100644 --- a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/json/FilterSerializer.scala +++ b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/json/FilterSerializer.scala @@ -1,6 +1,6 @@ package com.linagora.openpaas.james.jmap.json -import com.linagora.openpaas.james.jmap.model.{Action, AppendIn, Comparator, Condition, Field, Filter, FilterGetIds, FilterGetNotFound, FilterGetRequest, FilterGetResponse, FilterSetError, FilterSetRequest, FilterSetResponse, FilterSetUpdateResponse, Rule, RuleWithId, Update} +import com.linagora.openpaas.james.jmap.model.{Action, AppendIn, Comparator, Condition, Field, Filter, FilterGetIds, FilterGetNotFound, FilterGetRequest, FilterGetResponse, FilterSetError, FilterSetRequest, FilterSetResponse, FilterSetUpdateResponse, FilterState, Rule, RuleWithId, Update} import eu.timepit.refined.api.{RefType, Validate} import org.apache.james.jmap.core.SetError.SetErrorDescription import org.apache.james.jmap.core.{AccountId, State} @@ -43,6 +43,7 @@ case class FilterSerializer @Inject()(mailboxIdFactory: MailboxId.Factory) { implicit val ruleWrites: Writes[Rule] = Json.writes[Rule] implicit val filterWrites: Writes[Filter] = Json.writes[Filter] implicit val notFoundWrites: Writes[FilterGetNotFound] = Json.valueWrites[FilterGetNotFound] + implicit val filterState: Writes[FilterState] = Json.valueWrites[FilterState] implicit val filterGetResponseAccountId: Writes[AccountId] = Json.valueWrites[AccountId] implicit val filterGetResponseWrites: Writes[FilterGetResponse] = Json.writes[FilterGetResponse] @@ -60,14 +61,14 @@ case class FilterSerializer @Inject()(mailboxIdFactory: MailboxId.Factory) { implicit val updateReads: Reads[Update] = Json.valueReads[Update] implicit val filterSetRequestReads: Reads[FilterSetRequest] = Json.reads[FilterSetRequest] - def serialize(response: FilterGetResponse): JsValue = Json.toJson(response) - implicit val setErrorDescriptionWrites: Writes[SetErrorDescription] = Json.valueWrites[SetErrorDescription] implicit val filterSetErrorWrites: Writes[FilterSetError] = Json.writes[FilterSetError] implicit val filterSetUpdateResponseWrites: Writes[FilterSetUpdateResponse] = Json.valueWrites[FilterSetUpdateResponse] implicit val stateWrites: Writes[State] = Json.valueWrites[State] implicit val filterSetResponseWrites: Writes[FilterSetResponse] = Json.writes[FilterSetResponse] + def serializeFilterGetResponse(response: FilterGetResponse): JsValue = Json.toJson(response) + def serializeFilterSetResponse(response: FilterSetResponse): JsValue = Json.toJson(response) def deserializeFilterGetRequest(input: JsValue): JsResult[FilterGetRequest] = Json.fromJson[FilterGetRequest](input) diff --git a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/method/FilterGetMethod.scala b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/method/FilterGetMethod.scala index 3b32e7df6a..fdf32aa2a2 100644 --- a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/method/FilterGetMethod.scala +++ b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/method/FilterGetMethod.scala @@ -4,7 +4,7 @@ import com.google.inject.AbstractModule import com.google.inject.multibindings.{Multibinder, ProvidesIntoSet} import com.linagora.openpaas.james.jmap.json.FilterSerializer import com.linagora.openpaas.james.jmap.method.CapabilityIdentifier.LINAGORA_FILTER -import com.linagora.openpaas.james.jmap.model.{Filter, FilterGetNotFound, FilterGetRequest, FilterGetResponse, Rule} +import com.linagora.openpaas.james.jmap.model.{Filter, FilterGetNotFound, FilterGetRequest, FilterGetResponse, FilterState, FilterWithVersion, Rule} import eu.timepit.refined.auto._ import org.apache.james.core.Username import org.apache.james.jmap.api.filtering.FilteringManagement @@ -19,8 +19,10 @@ import org.apache.james.mailbox.model.MailboxId import org.apache.james.metrics.api.MetricFactory import org.reactivestreams.Publisher import play.api.libs.json.{JsError, JsObject, JsSuccess, Json} -import reactor.core.scala.publisher.{SFlux, SMono} +import reactor.core.scala.publisher.SMono + import javax.inject.Inject +import scala.jdk.CollectionConverters._ case object FilterCapabilityProperties extends CapabilityProperties { override def jsonify(): JsObject = Json.obj() @@ -58,7 +60,7 @@ class FilterGetMethod @Inject()(val metricFactory: MetricFactory, getFilterGetResponse(request, mailboxSession).map(response => InvocationWithContext( invocation = Invocation( methodName = methodName, - arguments = Arguments(FilterSerializer(mailboxIdFactory).serialize(response).as[JsObject]), + arguments = Arguments(FilterSerializer(mailboxIdFactory).serializeFilterGetResponse(response).as[JsObject]), methodCallId = invocation.invocation.methodCallId), processingContext = invocation.processingContext)) @@ -69,22 +71,22 @@ class FilterGetMethod @Inject()(val metricFactory: MetricFactory, case errors: JsError => Left(new IllegalArgumentException(ResponseSerializer.serialize(errors).toString)) } - private def retrieveFilters(username: Username) : SMono[Filter] = - SFlux.fromPublisher(filteringManagement.listRulesForUser(username)) - .map(javaRule => Rule.fromJava(javaRule, mailboxIdFactory)) - .collectSeq() - .map(rules => Filter("singleton", rules.toList)) + private def retrieveFiltersWithVersion(username: Username) : SMono[FilterWithVersion] = + SMono.fromPublisher(filteringManagement.listRulesForUser(username)) + .map(rulesWithVersion => FilterWithVersion(Filter("singleton", rulesWithVersion.getRules.asScala.toList.map(rule => Rule.fromJava(rule, mailboxIdFactory))), + rulesWithVersion.getVersion)) private def getFilterGetResponse(request: FilterGetRequest, mailboxSession: MailboxSession): SMono[FilterGetResponse] = request.ids match { - case None => retrieveFilters(mailboxSession.getUser) - .map(filter => FilterGetResponse(request.accountId, List(filter), FilterGetNotFound(List()))) + case None => retrieveFiltersWithVersion(mailboxSession.getUser) + .map(filterWithVersion => FilterGetResponse(request.accountId, FilterState(filterWithVersion.version.asString()), List(filterWithVersion.filter), FilterGetNotFound(List()))) case Some(ids) => if(ids.value.contains("singleton")) { - retrieveFilters(mailboxSession.getUser) - .map(filter => FilterGetResponse(request.accountId, List(filter), FilterGetNotFound(ids.value.filterNot(id => id.equals("singleton"))))) + retrieveFiltersWithVersion(mailboxSession.getUser) + .map(filterWithVersion => FilterGetResponse(request.accountId, FilterState(filterWithVersion.version.asString()), List(filterWithVersion.filter), FilterGetNotFound(ids.value.filterNot(id => id.equals("singleton"))))) } else { - SMono.just(FilterGetResponse(request.accountId, List(), FilterGetNotFound(ids.value))) + retrieveFiltersWithVersion(mailboxSession.getUser) + .map(filterWithVersion => FilterGetResponse(request.accountId, FilterState(filterWithVersion.version.asString()), List(), FilterGetNotFound(ids.value))) } } diff --git a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/model/FilterGet.scala b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/model/FilterGet.scala index afe14f4dec..a46a065232 100644 --- a/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/model/FilterGet.scala +++ b/openpaas-james/jmap/extensions/src/main/scala/com/linagora/openpaas/james/jmap/model/FilterGet.scala @@ -1,7 +1,7 @@ package com.linagora.openpaas.james.jmap.model import com.google.common.collect.ImmutableList -import org.apache.james.jmap.api.filtering.{Rule => JavaRule} +import org.apache.james.jmap.api.filtering.{Version, Rule => JavaRule} import org.apache.james.jmap.core.AccountId import org.apache.james.jmap.core.Id.Id import org.apache.james.jmap.mail.Name @@ -12,6 +12,7 @@ case class FilterGetRequest(accountId: AccountId, ids: Option[FilterGetIds]) extends WithAccountId case class FilterGetResponse(accountId: AccountId, + state: FilterState, list: List[Filter], notFound: FilterGetNotFound) @@ -31,6 +32,10 @@ case class Rule(name: Name, condition: Condition, action: Action) case class Filter(id: Id, rules: List[Rule]) +case class FilterWithVersion(filter: Filter, version: Version) + +case class FilterState(state: String) + case class FilterGetNotFound(value: List[String]) { def merge(other: FilterGetNotFound): FilterGetNotFound = FilterGetNotFound(this.value ++ other.value) } From aa9f47ddafc4de5e5b8e63cacdde7100e9be9cf4 Mon Sep 17 00:00:00 2001 From: Rene Cordier Date: Mon, 29 Mar 2021 15:45:22 +0700 Subject: [PATCH 2/2] Update james project SHA-1 --- james-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/james-project b/james-project index 14295d5a5e..afcb76d6b6 160000 --- a/james-project +++ b/james-project @@ -1 +1 @@ -Subproject commit 14295d5a5e2b72449b81847465e04ed3fed7bd60 +Subproject commit afcb76d6b6f7939b0726ba8fe6db2e9f6bb050fd