From 20090dc460e766fef0b80002ebf6500e631a7925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?= Date: Thu, 16 Nov 2023 15:08:15 +0100 Subject: [PATCH] refactor: Replace spray json with zio-json for FileMetadataSipiResponse (#2941) --- .../webapi/store/iiif/api/SipiService.scala | 18 +++++++++++------- .../store/iiif/impl/SipiServiceLive.scala | 7 ++++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/store/iiif/api/SipiService.scala b/webapi/src/main/scala/org/knora/webapi/store/iiif/api/SipiService.scala index 79072da61c..f7db7e776a 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/iiif/api/SipiService.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/iiif/api/SipiService.scala @@ -5,10 +5,9 @@ package org.knora.webapi.store.iiif.api -import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport -import spray.json.DefaultJsonProtocol -import spray.json.RootJsonFormat import zio.* +import zio.json.DeriveJsonDecoder +import zio.json.JsonDecoder import zio.macros.accessible import zio.nio.file.Path @@ -48,10 +47,15 @@ case class FileMetadataSipiResponse( } } -object FileMetadataSipiResponse extends SprayJsonSupport with DefaultJsonProtocol { - implicit val sipiKnoraJsonResponseFormat: RootJsonFormat[FileMetadataSipiResponse] = jsonFormat8( - FileMetadataSipiResponse.apply - ) +object FileMetadataSipiResponse { + // Because Sipi returns JSON Numbers which are whole numbers but not a valid Scala Int, e.g. `width: 1920.0`, we need to + // use a custom decoder for Int. See also https://github.com/zio/zio-json/issues/1049#issuecomment-1814108354 + implicit val anyWholeNumber: JsonDecoder[Int] = JsonDecoder[Double].mapOrFail { d => + val i = d.toInt + if (d == i.toDouble) { Right(i) } + else { Left("32-bit int expected") } + } + implicit val decoder: JsonDecoder[FileMetadataSipiResponse] = DeriveJsonDecoder.gen[FileMetadataSipiResponse] } @accessible diff --git a/webapi/src/main/scala/org/knora/webapi/store/iiif/impl/SipiServiceLive.scala b/webapi/src/main/scala/org/knora/webapi/store/iiif/impl/SipiServiceLive.scala index 934788a438..1c17ed960d 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/iiif/impl/SipiServiceLive.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/iiif/impl/SipiServiceLive.scala @@ -23,6 +23,7 @@ import org.apache.http.message.BasicNameValuePair import org.apache.http.util.EntityUtils import spray.json.* import zio.* +import zio.json.DecoderOps import zio.nio.file.Path import java.net.URI @@ -73,7 +74,11 @@ final case class SipiServiceLive( */ override def getFileMetadata(filePath: String): Task[FileMetadataSipiResponse] = doSipiRequest(new HttpGet(sipiConfig.internalBaseUrl + filePath + "/knora.json")) - .mapAttempt(_.parseJson.convertTo[FileMetadataSipiResponse]) + .flatMap(bodyStr => + ZIO + .fromEither(bodyStr.fromJson[FileMetadataSipiResponse]) + .mapError(e => SipiException(s"Invalid response from Sipi: $e, $bodyStr")) + ) /** * Asks Sipi to move a file from temporary storage to permanent storage.