From 58634181de360ca7845eb19d774620ed6736598f Mon Sep 17 00:00:00 2001 From: dantb Date: Wed, 20 Sep 2023 17:23:34 +0200 Subject: [PATCH] Refactor ArchiveRoutes, inline vals, remove zip extension val --- .../delta/plugins/archive/model/Zip.scala | 14 +++--- .../archive/routes/ArchiveRoutes.scala | 43 +++++++++---------- .../plugins/archive/ArchiveDownloadSpec.scala | 17 ++++---- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/model/Zip.scala b/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/model/Zip.scala index b09f21a5de..7477eb6a19 100644 --- a/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/model/Zip.scala +++ b/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/model/Zip.scala @@ -17,17 +17,13 @@ import ch.epfl.bluebrain.nexus.delta.sdk.utils.HeadersUtils object Zip { type WriteFlow[Metadata] = Flow[(Metadata, Source[ByteString, _]), ByteString, NotUsed] - def apply(req: HttpRequest): Option[Zip.type] = - if (HeadersUtils.matches(req.headers, Zip.contentType.mediaType)) Some(Zip) else None + lazy val contentType: ContentType = MediaTypes.`application/zip` - def contentType: ContentType = MediaTypes.`application/zip` + lazy val writeFlow: WriteFlow[ArchiveMetadata] = Archive.zip() - def fileExtension: String = "zip" + lazy val ordering: Ordering[ArchiveMetadata] = Ordering.by(md => md.filePath) - def metadata(filename: String): ArchiveMetadata = - ArchiveMetadata.create(filename) + def metadata(filename: String): ArchiveMetadata = ArchiveMetadata.create(filename) - def writeFlow: WriteFlow[ArchiveMetadata] = Archive.zip() - - def ordering: Ordering[ArchiveMetadata] = Ordering.by(md => md.filePath) + def checkHeader(req: HttpRequest): Boolean = HeadersUtils.matches(req.headers, Zip.contentType.mediaType) } diff --git a/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/routes/ArchiveRoutes.scala b/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/routes/ArchiveRoutes.scala index 960faab676..f4cba81633 100644 --- a/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/routes/ArchiveRoutes.scala +++ b/delta/plugins/archive/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/routes/ArchiveRoutes.scala @@ -2,7 +2,7 @@ package ch.epfl.bluebrain.nexus.delta.plugins.archive.routes import akka.http.scaladsl.model.StatusCodes.{Created, SeeOther} import akka.http.scaladsl.server.Directives._ -import akka.http.scaladsl.server.{Directive1, Route} +import akka.http.scaladsl.server.Route import ch.epfl.bluebrain.nexus.delta.plugins.archive.Archives import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.permissions import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.Zip @@ -54,10 +54,10 @@ class ArchiveRoutes( (post & entity(as[Json]) & pathEndOrSingleSlash) { json => operationName(s"$prefix/archives/{org}/{project}") { authorizeFor(ref, permissions.write).apply { - archiveResponse { - case Some(_) => emitRedirect(SeeOther, archives.create(ref, json).map(_.uris.accessUri)) - case None => emit(Created, archives.create(ref, json).mapValue(_.metadata)) - } + archiveResponse( + emitRedirect(SeeOther, archives.create(ref, json).map(_.uris.accessUri)), + emit(Created, archives.create(ref, json).mapValue(_.metadata)) + ) } } }, @@ -67,25 +67,24 @@ class ArchiveRoutes( // create an archive with an id (put & entity(as[Json]) & pathEndOrSingleSlash) { json => authorizeFor(ref, permissions.write).apply { - archiveResponse { - case Some(_) => emitRedirect(SeeOther, archives.create(id, ref, json).map(_.uris.accessUri)) - case None => emit(Created, archives.create(id, ref, json).mapValue(_.metadata)) - } + archiveResponse( + emitRedirect(SeeOther, archives.create(id, ref, json).map(_.uris.accessUri)), + emit(Created, archives.create(id, ref, json).mapValue(_.metadata)) + ) } }, // fetch or download an archive (get & pathEndOrSingleSlash) { authorizeFor(ref, permissions.read).apply { - archiveResponse { - case Some(_) => - parameter("ignoreNotFound".as[Boolean] ? false) { ignoreNotFound => - val response = archives.download(id, ref, ignoreNotFound).map { source => - sourceToFileResponse(source) - } - emit(response) + archiveResponse( + parameter("ignoreNotFound".as[Boolean] ? false) { ignoreNotFound => + val response = archives.download(id, ref, ignoreNotFound).map { source => + sourceToFileResponse(source) } - case None => emit(archives.fetch(id, ref)) - } + emit(response) + }, + emit(archives.fetch(id, ref)) + ) } } ) @@ -97,9 +96,9 @@ class ArchiveRoutes( } } - private def sourceToFileResponse(source: AkkaSource): FileResponse = - FileResponse(s"archive.${Zip.fileExtension}", Zip.contentType, 0L, source) + private def archiveResponse(validResp: Route, invalidResp: Route): Route = + extractRequest.map(Zip.checkHeader(_)).apply(valid => if (valid) validResp else invalidResp) - private def archiveResponse: Directive1[Option[Zip.type]] = - extractRequest.map(Zip(_)) + private def sourceToFileResponse(source: AkkaSource): FileResponse = + FileResponse(s"archive.zip", Zip.contentType, 0L, source) } diff --git a/delta/plugins/archive/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/ArchiveDownloadSpec.scala b/delta/plugins/archive/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/ArchiveDownloadSpec.scala index f9337095e4..3d75c62a63 100644 --- a/delta/plugins/archive/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/ArchiveDownloadSpec.scala +++ b/delta/plugins/archive/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/archive/ArchiveDownloadSpec.scala @@ -13,7 +13,6 @@ import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.ArchiveReference.{Fil import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.ArchiveRejection.{AuthorizationFailed, InvalidFileSelf, ResourceNotFound} import ch.epfl.bluebrain.nexus.delta.sdk.model.ResourceRepresentation.{CompactedJsonLd, Dot, ExpandedJsonLd, NQuads, NTriples, SourceJson} import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.{ArchiveRejection, ArchiveValue} -import ch.epfl.bluebrain.nexus.delta.plugins.archive.model.Zip import ch.epfl.bluebrain.nexus.delta.plugins.storage.RemoteContextResolutionFixture import ch.epfl.bluebrain.nexus.delta.plugins.storage.files.model.FileAttributes.FileAttributesOrigin.Client import ch.epfl.bluebrain.nexus.delta.plugins.storage.files.model.FileRejection.FileNotFound @@ -159,7 +158,7 @@ class ArchiveDownloadSpec .rejectedWith[AuthorizationFailed] } - s"provide a ${Zip.fileExtension} for both resources and files" in { + s"provide a zip for both resources and files" in { val value = ArchiveValue.unsafe( NonEmptySet.of( ResourceReference(Latest(id1), None, None, None), @@ -174,7 +173,7 @@ class ArchiveDownloadSpec result shouldEqual expected } - s"provide a ${Zip.fileExtension} for file selfs" in { + s"provide a zip for file selfs" in { val value = ArchiveValue.unsafe( NonEmptySet.of( FileSelfReference(file1Self, None) @@ -187,12 +186,12 @@ class ArchiveDownloadSpec result shouldEqual expected } - s"fail to provide a ${Zip.fileExtension} for file selfs which do not resolve" in { + s"fail to provide a zip for file selfs which do not resolve" in { val value = ArchiveValue.unsafe(NonEmptySet.of(FileSelfReference("http://wrong.file/self", None))) failToDownload[InvalidFileSelf](value, ignoreNotFound = false) } - s"provide a ${Zip.fileExtension} for both resources and files with different paths and formats" in { + s"provide a zip for both resources and files with different paths and formats" in { val list = List( SourceJson -> file1.value.asJson.sort.spaces2, CompactedJsonLd -> file1.toCompactedJsonLd.accepted.json.sort.spaces2, @@ -235,7 +234,7 @@ class ArchiveDownloadSpec downloadAndExtract(value, ignoreNotFound = false) should contain key file2Path } - s"fail to provide a ${Zip.fileExtension} when a resource is not found" in { + s"fail to provide a zip when a resource is not found" in { val value = ArchiveValue.unsafe( NonEmptySet.of( ResourceReference(Latest(iri"http://localhost/${genString()}"), None, None, None), @@ -245,7 +244,7 @@ class ArchiveDownloadSpec failToDownload[ResourceNotFound](value, ignoreNotFound = false) } - s"fail to provide a ${Zip.fileExtension} when a file is not found" in { + s"fail to provide a zip when a file is not found" in { val value = ArchiveValue.unsafe( NonEmptySet.of( ResourceReference(Latest(id1), None, None, None), @@ -283,14 +282,14 @@ class ArchiveDownloadSpec result shouldEqual expected } - s"fail to provide a ${Zip.fileExtension} when access to a resource is not found" in { + s"fail to provide a zip when access to a resource is not found" in { val value = ArchiveValue.unsafe( NonEmptySet.of(ResourceReference(Latest(id1), None, None, None)) ) rejectedAccess(value) } - s"fail to provide a ${Zip.fileExtension} when access to a file is not found" in { + s"fail to provide a zip when access to a file is not found" in { val value = ArchiveValue.unsafe( NonEmptySet.of(FileReference(Latest(id1), None, None)) )