You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/06/08 03:12:36 UTC
[james-project] 15/16: JAMES-3171 JsError serialization
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 <rc...@linagora.com>
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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org