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 eef1f7e92565d37d2be2fe853802f276d7530d69 Author: Rene Cordier <[email protected]> AuthorDate: Fri May 29 11:38:30 2020 +0700 JAMES-3171 JsError serialization --- .../org/apache/james/jmap/json/Serializer.scala | 64 +++++++++++---------- .../james/jmap/method/MailboxGetMethod.scala | 2 +- .../james/jmap/json/JsErrorSerializationTest.scala | 66 ++++++++++++++++++++++ 3 files changed, 100 insertions(+), 32 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 6d374ed..76c6863 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 @@ -34,6 +34,7 @@ import org.apache.james.mailbox.model.{MailboxACL, MailboxId} import play.api.libs.functional.syntax._ import play.api.libs.json._ +import scala.collection.{Seq => LegacySeq} import scala.util.Try class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { @@ -158,7 +159,7 @@ class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { private implicit val mailboxRightsWrites: Writes[MailboxRights] = Json.writes[MailboxRights] private implicit val mailboxNamespaceWrites: Writes[MailboxNamespace] = { - case personal: PersonalNamespace => JsString("Personal") + case _: PersonalNamespace => JsString("Personal") case delegated: DelegatedNamespace => JsString(s"Delegated[${delegated.owner.asString}]") } @@ -209,43 +210,44 @@ class Serializer @Inject() (mailboxIdFactory: MailboxId.Factory) { 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) - } + private implicit val jsonValidationErrorWrites: Writes[JsonValidationError] = error => JsString(error.message) - def serialize(requestObject: RequestObject): JsValue = { - Json.toJson(requestObject) - } + private implicit def jsonValidationErrorsWrites(implicit jsonValidationErrorWrites: Writes[JsonValidationError]): Writes[LegacySeq[JsonValidationError]] = + (errors: LegacySeq[JsonValidationError]) => { + JsArray(errors.map(error => jsonValidationErrorWrites.writes(error)).toArray[JsValue]) + } - def serialize(responseObject: ResponseObject): JsValue = { - Json.toJson(responseObject) - } + private implicit def errorsWrites(implicit jsonValidationErrorsWrites: Writes[LegacySeq[JsonValidationError]]): Writes[LegacySeq[(JsPath, LegacySeq[JsonValidationError])]] = + (errors: LegacySeq[(JsPath, LegacySeq[JsonValidationError])]) => { + errors.foldLeft(JsArray.empty)((jsArray, jsError) => { + val (path: JsPath, list: LegacySeq[JsonValidationError]) = jsError + jsArray:+ JsObject(Seq( + "path" -> JsString(path.toJsonString), + "messages" -> jsonValidationErrorsWrites.writes(list))) + }) + } - def serialize(mailbox: Mailbox): JsValue = { - Json.toJson(mailbox) - } + private implicit def jsErrorWrites: Writes[JsError] = Json.writes[JsError] - def serialize(mailboxGetResponse: MailboxGetResponse): JsValue = { - Json.toJson(mailboxGetResponse) - } + def serialize(session: Session): JsValue = Json.toJson(session) - def deserializeRequestObject(input: String): JsResult[RequestObject] = { - Json.parse(input).validate[RequestObject] - } + def serialize(requestObject: RequestObject): JsValue = Json.toJson(requestObject) - def deserializeRequestObject(input: InputStream): JsResult[RequestObject] = { - Json.parse(input).validate[RequestObject] - } + def serialize(responseObject: ResponseObject): JsValue = Json.toJson(responseObject) - def deserializeResponseObject(input: String): JsResult[ResponseObject] = { - Json.parse(input).validate[ResponseObject] - } + def serialize(mailbox: Mailbox): JsValue = Json.toJson(mailbox) - def deserializeMailboxGetRequest(input: String): JsResult[MailboxGetRequest] = { - Json.parse(input).validate[MailboxGetRequest] - } + def serialize(mailboxGetResponse: MailboxGetResponse): JsValue = Json.toJson(mailboxGetResponse) - def deserializeMailboxGetRequest(input: JsValue): JsResult[MailboxGetRequest] = { - Json.fromJson[MailboxGetRequest](input) - } + def serialize(errors: JsError): JsValue = Json.toJson(errors) + + def deserializeRequestObject(input: String): JsResult[RequestObject] = Json.parse(input).validate[RequestObject] + + def deserializeRequestObject(input: InputStream): JsResult[RequestObject] = Json.parse(input).validate[RequestObject] + + def deserializeResponseObject(input: String): JsResult[ResponseObject] = Json.parse(input).validate[ResponseObject] + + def deserializeMailboxGetRequest(input: String): JsResult[MailboxGetRequest] = Json.parse(input).validate[MailboxGetRequest] + + def deserializeMailboxGetRequest(input: JsValue): JsResult[MailboxGetRequest] = Json.fromJson[MailboxGetRequest](input) } \ No newline at end of file diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala index 1ccb921..22c38c6 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala @@ -63,7 +63,7 @@ class MailboxGetMethod @Inject() (serializer: Serializer, private def asMailboxGetRequest(arguments: Arguments): SMono[MailboxGetRequest] = { serializer.deserializeMailboxGetRequest(arguments.value) match { case JsSuccess(mailboxGetRequest, _) => SMono.just(mailboxGetRequest) - case JsError(errors) => SMono.raiseError(new IllegalArgumentException("Invalid MailboxGetRequest")) //FIXME MOB + case errors: JsError => SMono.raiseError(new IllegalArgumentException(serializer.serialize(errors).toString)) } } diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/JsErrorSerializationTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/JsErrorSerializationTest.scala new file mode 100644 index 0000000..cd980aa --- /dev/null +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/json/JsErrorSerializationTest.scala @@ -0,0 +1,66 @@ +/**************************************************************** + * 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 net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson +import org.apache.james.mailbox.model.TestId +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec +import play.api.libs.json.{JsError, JsPath, Json, JsonValidationError} + +object JsErrorSerializationTest { + private val SERIALIZER: Serializer = new Serializer(new TestId.Factory) +} + +class JsErrorSerializationTest extends AnyWordSpec with Matchers { + import JsErrorSerializationTest.SERIALIZER + + "Serialize JsError" should { + "succeed " in { + val errors: JsError = JsError(Seq( + ( + JsPath.\("name"), + Seq(JsonValidationError("validate.error.expected.jsstring"), JsonValidationError("error.maxLength")) + ), + ( + JsPath.\("id"), + Seq(JsonValidationError("error.path.missing")) + ))) + + val expectedJson: String = + """ + |{ + | "errors": [ + | { + | "path": "obj.name", + | "messages": ["validate.error.expected.jsstring", "error.maxLength"] + | }, + | { + | "path": "obj.id", + | "messages": ["error.path.missing"] + | } + | ] + |} + |""".stripMargin + + assertThatJson(Json.stringify(SERIALIZER.serialize(errors))).isEqualTo(expectedJson) + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
