From 823d072f735c6831b7c2a7136de22a3c7a395b33 Mon Sep 17 00:00:00 2001 From: Samuel Kerrien Date: Tue, 3 Sep 2024 11:57:31 +0200 Subject: [PATCH 1/4] =?UTF-8?q?Added=20delegation=20process=20illustration?= =?UTF-8?q?,=20reference=20to=20configuration,=20mu=E2=80=A6=20(#5129)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added delegation process illustration, reference to configuration, multipart upload tutorials. * missing empty line --- docs/src/main/draw.io/delta/Nexus-1.8.drawio | 1106 +++++++++++++++++ .../src/main/draw.io/delta/files/files.drawio | 111 ++ .../api/assets/files/multipart-upload.png | Bin 0 -> 104428 bytes .../main/paradox/docs/delta/api/files-api.md | 16 +- 4 files changed, 1230 insertions(+), 3 deletions(-) create mode 100644 docs/src/main/draw.io/delta/Nexus-1.8.drawio create mode 100644 docs/src/main/draw.io/delta/files/files.drawio create mode 100644 docs/src/main/paradox/docs/delta/api/assets/files/multipart-upload.png diff --git a/docs/src/main/draw.io/delta/Nexus-1.8.drawio b/docs/src/main/draw.io/delta/Nexus-1.8.drawio new file mode 100644 index 0000000000..ba6b9c3f74 --- /dev/null +++ b/docs/src/main/draw.io/delta/Nexus-1.8.drawio @@ -0,0 +1,1106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/main/draw.io/delta/files/files.drawio b/docs/src/main/draw.io/delta/files/files.drawio new file mode 100644 index 0000000000..39a24d126e --- /dev/null +++ b/docs/src/main/draw.io/delta/files/files.drawio @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/main/paradox/docs/delta/api/assets/files/multipart-upload.png b/docs/src/main/paradox/docs/delta/api/assets/files/multipart-upload.png new file mode 100644 index 0000000000000000000000000000000000000000..a691083355d3f637e941598f2c9f6c538be51fbe GIT binary patch literal 104428 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%0A19U>ytyW#8iq9n24O-(>Zy&jY=9gZtN zjIF<`c68Nkx&wuv*eHYA=E@&Q>{|#Z)tcK`h|=tC+q=-&RJ}` zdJA{hBBPAyZj8eS>)e3Nj}uEc=dX1)H+H11choC&q_ejy7B2FUu@!cyJI^_;y%N8Z z7;oIEW+oA93oHXeFrT43_4!x|pV^{x;3rJ2I__>=YB25iN(A)&&n&eMkM_i$Qu5)ZVY8 z;)&quE2zC&V9A!BQlAHN7!pvBDdO_a{E|=K4Rrqmg*{234vyfvoNA+O)AfrPEMr#TvXj+%`YU z@_i(tZvEo9jBIZnZ)*W`7n}HI^xG?~+AWajYC65i@3iZZy@DRtWRQM0qusD|Jb%rC zle57p%ue!W6ozD}u417Fe_LNM8l^_!DBsTK=EMBba(m3KeQwZ;qqn*wuBRDTs~-lg z+nf6N8+-9LcDSb&R4Q0EAN4z;T^1kpv z^sc#YeVRo&-hEgwBwnIk5&@=X#OJm4|3{4)Y3Pa@4&u3RlOQ$fQRw=x0V@Svdx>5e z;!PgUlkOqxDbF#pN=%X~N?V?kyv%90RTD_Sm#ouILQjavK2Umlg*ZeVJkEUs2ZOajp(X=#e&tYw5#wit2f-}79k*x-aFVny zS9$Vy3pqp$OFT)(a5OgLO4qaW&m>l`;0xXNEt0 zsI4CKRGCX4UofEd?HFv^t=qf=*csI`d)ZZoi1{%)LzYN&8h^m{Ra$0(6&9iwnXWr9 z4=NJ;Iudpb7rRV0ndLVurV>&@4AE3tP6K-6i`o%&LbIO=V|M$6Pc*1>y?9b;zt*GE zDSX_iq?OgIMPO(II^-fBgR*yOpd-;aX0!fUE&G`Va~xfJ$LHq(_9Tk^Hy32Ylc%m_ zXgcj$e8?5ja4--|&;PaFYmn}xy;V3`cZX&Fx#Ok^4Zv z%IF~4zVA{J@DiF8le>2E4)&1wc3&DNT{bG(I=&ev`tftDlVH`k>JH~X(wr>saANO& zcCwrWn4oQMklcW1G|C(wxF;!ojZVJh>*=kTQde@O6Hyix^Z|J9$$2^(F%>Q*(8y-> z*WxmMmNu=xRqPN6Sxpb_!?n)lb$6W-^CAvb6d^LhJV5txMKr``G$a z1@m|+BcG?k*A;DxiZ(_(*NTbJ4ERcPQ-R^YFs>s0CKbsy5RwM82`+{DaGtI|J$K7O zW>O~TsdA;yo?^0yJ|<@n!sy(d*NOFUZ+Dxshtr?7U2!%0A-h(QYOWE-(b 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 L#Y-s{^gaIvyDUYf literal 0 HcmV?d00001 diff --git a/docs/src/main/paradox/docs/delta/api/files-api.md b/docs/src/main/paradox/docs/delta/api/files-api.md index 6006ac2ab0..71485f54dc 100644 --- a/docs/src/main/paradox/docs/delta/api/files-api.md +++ b/docs/src/main/paradox/docs/delta/api/files-api.md @@ -215,6 +215,13 @@ Response Clients can use delegation for files that cannot be uploaded through Delta (e.g. large files which may benefit from multipart upload from S3). Here Delta will provide bucket and path details for the upload. Users are then expected to upload the file using other methods, and call back to Delta to register this file with the same metadata that was initially validated. The three steps are outlined in detail below. +The following diagram illustrates the process of uploading a large file using the delegation method: +![delegation](assets/files/multipart-upload.png "Multipart upload process") + +There is Delta @link:[configuration](https://github.com/BlueBrain/nexus/blob/master/delta/app/src/main/resources/app.conf){ open=new } to be done prior to using this feature, in particular setting up the necessary RSA key to support secure communication between Delta and AWS and signing payloads. + +The configuration can be found under the following key `app.jws`. Please note that the allowed duration of the process is configured there with a default of 3h. Check the configuration key `app.jws.ttl` to change this value. + #### 1. Validate and generate path for file delegation Delta accepts and validates the following payload. @@ -298,7 +305,7 @@ This payload is then signed using the [flattened JWS serialization format](https } ``` -The `payload` field can be base64 decoded to access the generated file details. Note that `protected` contains an expiry field `exp` with the datetime at which this signature will expire (in epoch seconds). To view this can also be base64 decoded. +The `payload` field can be base64 decoded to access the generated file details. Note that `protected` contains an expiry field `exp` with the datetime at which this `signature` will expire (in epoch seconds). To view this can also be base64 decoded. **Example** @@ -312,9 +319,12 @@ Response Using the bucket and path from the previous step, the file should be uploaded to S3 by whatever means are appropriate. The only restriction is that this must be finished before the expiry datetime of the signed payload. +Here are some tutorials in both @link:[Java with AWS SDK](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example_s3_Scenario_MultipartUpload_section.html){ open=new } and +@link:[Python with Boto3](https://medium.com/analytics-vidhya/aws-s3-multipart-upload-download-using-boto3-python-sdk-2dedb0945f11){ open=new } that illustrate the process of doing a multipart upload to S3. + #### 3. Create/update delegated file resource -Once the file has been uploaded to S3 at the specified path, the file resource can be created. The payload can be passed back exactly as it was returned in the previous step. +Once the file has been uploaded to S3 at the specified path, the file resource can be created in the knowledge graph. The payload can be passed back exactly as it was returned in the previous step. ``` POST /v1/delegate/files/submit @@ -325,7 +335,7 @@ POST /v1/delegate/files/submit } ``` -Delta will verify that the signature matches the payload and that the expiry date is not passed. Then the file will be registered as a resource. The usual file resource response will be returned with all the standard metadata and file location details. +Delta will verify that the `signature` matches the payload and that the expiry date is not passed. Then the file will be registered as a resource. The usual file resource response will be returned with all the standard metadata and file location details. **Example** From f3d3e34dc5d019d289f70a3a63c6175983a22c4c Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 4 Sep 2024 12:06:47 +0200 Subject: [PATCH 2/4] Do not set up the content type with it is already correctly set (#5131) Co-authored-by: Simon Dumas --- .../storages/operations/s3/CopyResult.scala | 11 ----- .../operations/s3/S3OperationResult.scala | 11 +++++ .../s3/client/S3StorageClient.scala | 8 ++-- .../s3/client/S3StorageClientDisabled.scala | 9 +++-- .../s3/client/S3StorageClientImpl.scala | 40 ++++++++++--------- .../s3/client/S3StorageClientSuite.scala | 30 ++++++++++---- .../nexus/ship/files/FileCopier.scala | 6 +-- 7 files changed, 67 insertions(+), 48 deletions(-) delete mode 100644 delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/CopyResult.scala create mode 100644 delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/S3OperationResult.scala diff --git a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/CopyResult.scala b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/CopyResult.scala deleted file mode 100644 index d3d2757a0d..0000000000 --- a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/CopyResult.scala +++ /dev/null @@ -1,11 +0,0 @@ -package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3 - -sealed trait CopyResult extends Product with Serializable - -object CopyResult { - - final case object Success extends CopyResult - - final case object AlreadyExists extends CopyResult - -} diff --git a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/S3OperationResult.scala b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/S3OperationResult.scala new file mode 100644 index 0000000000..39d42d43fb --- /dev/null +++ b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/S3OperationResult.scala @@ -0,0 +1,11 @@ +package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3 + +sealed trait S3OperationResult extends Product with Serializable + +object S3OperationResult { + + final case object Success extends S3OperationResult + + final case object AlreadyExists extends S3OperationResult + +} diff --git a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClient.scala b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClient.scala index 4c93f6acee..760ff9c8bc 100644 --- a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClient.scala +++ b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClient.scala @@ -3,7 +3,7 @@ package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.cli import akka.http.scaladsl.model.ContentType import cats.effect.{IO, Resource} import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.StoragesConfig.S3StorageConfig -import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, CopyResult, HeadObject, PutObjectRequest} +import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, HeadObject, PutObjectRequest, S3OperationResult} import fs2.Stream import io.laserdisc.pure.s3.tagless.{Interpreter, S3AsyncClientOp} import software.amazon.awssdk.auth.credentials.{AwsBasicCredentials, AwsCredentialsProvider, DefaultCredentialsProvider, StaticCredentialsProvider} @@ -35,7 +35,7 @@ trait S3StorageClient { destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] + ): IO[S3OperationResult] def copyObjectMultiPart( sourceBucket: String, @@ -43,14 +43,14 @@ trait S3StorageClient { destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] + ): IO[S3OperationResult] def uploadFile( put: PutObjectRequest, fileData: Stream[IO, ByteBuffer] ): IO[Unit] - def updateContentType(bucket: String, key: String, contentType: ContentType): IO[Unit] + def updateContentType(bucket: String, key: String, contentType: ContentType): IO[S3OperationResult] def objectExists(bucket: String, key: String): IO[Boolean] def bucketExists(bucket: String): IO[Boolean] diff --git a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientDisabled.scala b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientDisabled.scala index 0429ba8306..5c7900b7a6 100644 --- a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientDisabled.scala +++ b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientDisabled.scala @@ -2,7 +2,7 @@ package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.cli import akka.http.scaladsl.model.ContentType import cats.effect.IO -import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, CopyResult, HeadObject, PutObjectRequest} +import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, HeadObject, PutObjectRequest, S3OperationResult} import ch.epfl.bluebrain.nexus.delta.sdk.error.ServiceError.FeatureDisabled import fs2.Stream import software.amazon.awssdk.services.s3.model._ @@ -27,7 +27,7 @@ private[client] object S3StorageClientDisabled extends S3StorageClient { destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] = raiseDisabledErr + ): IO[S3OperationResult] = raiseDisabledErr override def objectExists(bucket: String, key: String): IO[Boolean] = raiseDisabledErr @@ -36,7 +36,8 @@ private[client] object S3StorageClientDisabled extends S3StorageClient { data: Stream[IO, ByteBuffer] ): IO[Unit] = raiseDisabledErr - override def updateContentType(bucket: String, key: String, contentType: ContentType): IO[Unit] = raiseDisabledErr + override def updateContentType(bucket: String, key: String, contentType: ContentType): IO[S3OperationResult] = + raiseDisabledErr override def bucketExists(bucket: String): IO[Boolean] = raiseDisabledErr @@ -46,7 +47,7 @@ private[client] object S3StorageClientDisabled extends S3StorageClient { destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] = raiseDisabledErr + ): IO[S3OperationResult] = raiseDisabledErr override def readFileMultipart(bucket: String, fileKey: String): Stream[IO, Byte] = throw disabledErr } diff --git a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientImpl.scala b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientImpl.scala index 58930547ec..6608701028 100644 --- a/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientImpl.scala +++ b/delta/plugins/storage/src/main/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientImpl.scala @@ -62,7 +62,7 @@ final private[client] class S3StorageClientImpl(client: S3AsyncClientOp[IO]) ext destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] = + ): IO[S3OperationResult] = approveCopy(destinationBucket, destinationKey, options.overwriteTarget).flatMap { approved => if (approved) { val requestBuilder = CopyObjectRequest @@ -77,8 +77,8 @@ final private[client] class S3StorageClientImpl(client: S3AsyncClientOp[IO]) ext .contentType(contentType.value) .metadataDirective(MetadataDirective.REPLACE) } - client.copyObject(requestWithOptions.build()).as(CopyResult.Success) - } else IO.pure(CopyResult.AlreadyExists) + client.copyObject(requestWithOptions.build()).as(S3OperationResult.Success) + } else IO.pure(S3OperationResult.AlreadyExists) } def copyObjectMultiPart( @@ -87,13 +87,13 @@ final private[client] class S3StorageClientImpl(client: S3AsyncClientOp[IO]) ext destinationBucket: String, destinationKey: String, options: CopyOptions - ): IO[CopyResult] = + ): IO[S3OperationResult] = approveCopy(destinationBucket, destinationKey, options.overwriteTarget).flatMap { approved => if (approved) { copyObjectMultiPart(sourceBucket, sourceKey, destinationBucket, destinationKey, options.newContentType).as( - CopyResult.Success + S3OperationResult.Success ) - } else IO.pure(CopyResult.AlreadyExists) + } else IO.pure(S3OperationResult.AlreadyExists) } private def copyObjectMultiPart( @@ -183,19 +183,21 @@ final private[client] class S3StorageClientImpl(client: S3AsyncClientOp[IO]) ext .compile .drain - override def updateContentType(bucket: String, key: String, contentType: ContentType): IO[Unit] = { - val requestBuilder = CopyObjectRequest - .builder() - .sourceBucket(bucket) - .sourceKey(key) - .destinationBucket(bucket) - .destinationKey(key) - .checksumAlgorithm(checksumAlgorithm) - .contentType(contentType.value) - .metadataDirective(MetadataDirective.REPLACE) - - client.copyObject(requestBuilder.build()).void - } + override def updateContentType(bucket: String, key: String, contentType: ContentType): IO[S3OperationResult] = + headObject(bucket, key).flatMap { + case head if head.contentType.contains(contentType) => IO.pure(S3OperationResult.AlreadyExists) + case _ => + val requestBuilder = CopyObjectRequest + .builder() + .sourceBucket(bucket) + .sourceKey(key) + .destinationBucket(bucket) + .destinationKey(key) + .checksumAlgorithm(checksumAlgorithm) + .contentType(contentType.value) + .metadataDirective(MetadataDirective.REPLACE) + client.copyObject(requestBuilder.build()).as(S3OperationResult.Success) + } override def bucketExists(bucket: String): IO[Boolean] = { listObjectsV2(bucket) diff --git a/delta/plugins/storage/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientSuite.scala b/delta/plugins/storage/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientSuite.scala index 6a90aeb9c6..d46153ee9c 100644 --- a/delta/plugins/storage/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientSuite.scala +++ b/delta/plugins/storage/src/test/scala/ch/epfl/bluebrain/nexus/delta/plugins/storage/storages/operations/s3/client/S3StorageClientSuite.scala @@ -3,7 +3,7 @@ package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.cli import akka.http.scaladsl.model.ContentTypes import cats.effect.IO import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.StoragesConfig.S3StorageConfig -import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, CopyResult, LocalStackS3StorageClient, S3Helpers} +import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, LocalStackS3StorageClient, S3Helpers, S3OperationResult} import ch.epfl.bluebrain.nexus.testkit.mu.NexusSuite import io.laserdisc.pure.s3.tagless.S3AsyncClientOp import munit.AnyFixture @@ -33,7 +33,7 @@ class S3StorageClientSuite extends NexusSuite with LocalStackS3StorageClient.Fix result <- s3StorageClient.copyObject(bucket, key, bucket, newKey, options) head <- s3StorageClient.headObject(bucket, newKey) } yield { - assertEquals(result, CopyResult.Success) + assertEquals(result, S3OperationResult.Success) assertEquals(head.fileSize, contentLength) assertEquals(head.contentType, Some(expectedContentType)) } @@ -50,7 +50,7 @@ class S3StorageClientSuite extends NexusSuite with LocalStackS3StorageClient.Fix result <- s3StorageClient.copyObject(bucket, key, bucket, newKey, options) head <- s3StorageClient.headObject(bucket, newKey) } yield { - assertEquals(result, CopyResult.Success) + assertEquals(result, S3OperationResult.Success) assertEquals(head.fileSize, contentLength) assertEquals(head.contentType, Some(contentType)) } @@ -67,7 +67,7 @@ class S3StorageClientSuite extends NexusSuite with LocalStackS3StorageClient.Fix head <- s3StorageClient.headObject(bucket, existingTargetKey) } yield { val clue = "The file should not have been overwritten" - assertEquals(result, CopyResult.AlreadyExists) + assertEquals(result, S3OperationResult.AlreadyExists) assertEquals(head.fileSize, anotherContentLength, clue) assertEquals(head.contentType, Some(expectedContentType), clue) } @@ -84,7 +84,7 @@ class S3StorageClientSuite extends NexusSuite with LocalStackS3StorageClient.Fix head <- s3StorageClient.headObject(bucket, existingTargetKey) } yield { val clue = "The file should have been overwritten" - assertEquals(result, CopyResult.Success) + assertEquals(result, S3OperationResult.Success) assertEquals(head.fileSize, contentLength, clue) assertEquals(head.contentType, Some(contentType), clue) } @@ -96,13 +96,29 @@ class S3StorageClientSuite extends NexusSuite with LocalStackS3StorageClient.Fix givenAnS3Bucket { bucket => givenAFileInABucket(bucket, fileContents) { key => for { - _ <- s3StorageClient.updateContentType(bucket, key, contentType) - head <- s3StorageClient.headObject(bucket, key) + result <- s3StorageClient.updateContentType(bucket, key, contentType) + head <- s3StorageClient.headObject(bucket, key) } yield { + assertEquals(result, S3OperationResult.Success) assertEquals(head.contentType, Some(contentType)) } } } } + test("Do not update the content type of an existing object if it is already set to this value") { + val originalContentType = ContentTypes.`text/plain(UTF-8)` + givenAnS3Bucket { bucket => + givenAFileInABucket(bucket, fileContents) { key => + for { + result <- s3StorageClient.updateContentType(bucket, key, originalContentType) + head <- s3StorageClient.headObject(bucket, key) + } yield { + assertEquals(result, S3OperationResult.AlreadyExists) + assertEquals(head.contentType, Some(originalContentType)) + } + } + } + } + } diff --git a/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/files/FileCopier.scala b/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/files/FileCopier.scala index 5e50cff369..00fc327414 100644 --- a/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/files/FileCopier.scala +++ b/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/files/FileCopier.scala @@ -8,7 +8,7 @@ import ch.epfl.bluebrain.nexus.delta.kernel.RetryStrategy.logError import ch.epfl.bluebrain.nexus.delta.kernel.{Logger, RetryStrategy} import ch.epfl.bluebrain.nexus.delta.kernel.utils.UrlUtils import ch.epfl.bluebrain.nexus.delta.plugins.storage.files.model.FileAttributes -import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, CopyResult, S3LocationGenerator} +import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.{CopyOptions, S3LocationGenerator, S3OperationResult} import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.operations.s3.client.S3StorageClient import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef import ch.epfl.bluebrain.nexus.ship.config.FileProcessingConfig @@ -74,8 +74,8 @@ object FileCopier { } else s3StorageClient.copyObject(importBucket, originKey, targetBucket, targetKey, copyOptions) }.flatMap { - case CopyResult.Success => IO.unit - case CopyResult.AlreadyExists => + case S3OperationResult.Success => IO.unit + case S3OperationResult.AlreadyExists => IO.whenA(forceContentType) { attributes.mediaType.traverse { mediaType => logger.info(s"Patching to content type $mediaType for file $patchedFileName") >> From 442e0777b700daf0ab5738dc410546d3695a7e2d Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 11 Sep 2024 11:19:58 +0200 Subject: [PATCH 3/4] Edit constraint on trace's encoding format (#5132) * edit constraint on trace's encoding format * add non-nwb distribution in trace --- tests/docker/config/construct-query.sparql | 11 ++++--- .../test/resources/kg/search/data/trace.json | 33 ++++++++++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/tests/docker/config/construct-query.sparql b/tests/docker/config/construct-query.sparql index dc48a777a3..0842a4d652 100644 --- a/tests/docker/config/construct-query.sparql +++ b/tests/docker/config/construct-query.sparql @@ -268,11 +268,12 @@ CONSTRUCT { FILTER (?type != prov:Entity) # for Traces, only consider ones that have the nwb encoding format - FILTER NOT EXISTS { - ?id a nsg:Trace ; - schema:distribution / schema:encodingFormat ?encodingFormat . - FILTER (?encodingFormat != "application/nwb") - } + OPTIONAL { + ?id a bmo:ExperimentalTrace ; + schema:distribution/schema:encodingFormat ?encodingFormat . + } . + + FILTER(!bound(?encodingFormat) || ?encodingFormat = "application/nwb") . ?id nxv:createdAt ?createdAt ; nxv:createdBy ?createdByNode ; diff --git a/tests/src/test/resources/kg/search/data/trace.json b/tests/src/test/resources/kg/search/data/trace.json index 4ce21ed2e5..879e10593b 100644 --- a/tests/src/test/resources/kg/search/data/trace.json +++ b/tests/src/test/resources/kg/search/data/trace.json @@ -78,11 +78,33 @@ "@value": "2021-05-18T18:59:02.602182+02:00" }, "description": "This dataset is about simulated electrophysiology traces for cell instance S1J_L6_IPC_cADpyr_2. The dataset contains one distribution of the traces in NWB file format.", - "distribution": { + "distribution": [ + { + "@type": "DataDownload", + "atLocation": { + "@type": "Location", + "location": "file:///gpfs/bbp.cscs.ch/data/project/proj109/nexus/public/sscx/e/1/0/5/5/9/1/c/S1J_L6_IPC_cADpyr_2.nwb", + "store": { + "@id": "https://bbp.epfl.ch/neurosciencegraph/data/4820323e-bee0-48d2-824f-9d9d404dbbee" + } + }, + "contentSize": { + "unitCode": "bytes", + "value": 1657656 + }, + "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/public/sscx/5b24efb8-ce68-4ce7-afa6-53b8d8ea9a01", + "digest": { + "algorithm": "SHA-256", + "value": "9dfe31ab52dd636987a610b9ac70f6ca28f03331d75a17624a4308a1d64266fc" + }, + "encodingFormat": "application/nwb", + "name": "S1J_L6_IPC_cADpyr_2.nwb" + }, + { "@type": "DataDownload", "atLocation": { "@type": "Location", - "location": "file:///gpfs/bbp.cscs.ch/data/project/proj109/nexus/public/sscx/e/1/0/5/5/9/1/c/S1J_L6_IPC_cADpyr_2.nwb", + "location": "file:///gpfs/bbp.cscs.ch/data/project/proj109/nexus/public/sscx/e/1/0/5/5/9/1/c/S1J_L6_IPC_cADpyr_2.abf", "store": { "@id": "https://bbp.epfl.ch/neurosciencegraph/data/4820323e-bee0-48d2-824f-9d9d404dbbee" } @@ -96,9 +118,10 @@ "algorithm": "SHA-256", "value": "9dfe31ab52dd636987a610b9ac70f6ca28f03331d75a17624a4308a1d64266fc" }, - "encodingFormat": "application/nwb", - "name": "S1J_L6_IPC_cADpyr_2.nwb" - }, + "encodingFormat": "application/abf", + "name": "S1J_L6_IPC_cADpyr_2.abf" + } + ], "image": [ { "@id": "https://bbp.epfl.ch/neurosciencegraph/data/58342dff-8034-4b53-933b-1c034cdc8180", From d8e5fe96ef6ced0deaf5bf19800ca8df83d46b31 Mon Sep 17 00:00:00 2001 From: Samuel Kerrien Date: Mon, 16 Sep 2024 12:01:08 +0200 Subject: [PATCH 4/4] Fixed validation errors raised by paradoxValidateLinks (#5133) --- docs/ignore-paths.txt | 1 + docs/src/main/paradox/docs/delta/api/resources-api.md | 2 +- docs/src/main/paradox/docs/faq.md | 2 +- docs/src/main/paradox/docs/fusion/architecture.md | 4 ++-- .../main/paradox/docs/getting-started/running-nexus/index.md | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/ignore-paths.txt b/docs/ignore-paths.txt index 64bee4c24f..8938817edd 100644 --- a/docs/ignore-paths.txt +++ b/docs/ignore-paths.txt @@ -10,6 +10,7 @@ https://github.com/BlueBrain/nexus-js/blob/main/packages/nexus-sdk/README.md https://github.com/BlueBrain/nexus-js/blob/main/packages/react-nexus/README.md https://github.com/BlueBrain/nexus-web/blob/main/README.md.* https://github.com/lightbend/config.* +https://github.com/BlueBrain/nexus/issues?.* https://www.janelia.org http://mouselight.janelia.org/ http://ml-neuronbrowser.janelia.org diff --git a/docs/src/main/paradox/docs/delta/api/resources-api.md b/docs/src/main/paradox/docs/delta/api/resources-api.md index f71068a55d..edd4653e14 100644 --- a/docs/src/main/paradox/docs/delta/api/resources-api.md +++ b/docs/src/main/paradox/docs/delta/api/resources-api.md @@ -30,7 +30,7 @@ That means that when those get updated, the resources importing them must be als @@@ note { .warning title="Reserved types and fields" } -A generic resource can not have a type belonging to the Nexus vocabulary (https://bluebrain.github.io/nexus/vocabulary/). +A generic resource can not have a type belonging to the Nexus vocabulary `https://bluebrain.github.io/nexus/vocabulary/`. Moreover it can not include any field starting with underscore (_) at the root level as these fields are reserved for Nexus metadata. @@@ diff --git a/docs/src/main/paradox/docs/faq.md b/docs/src/main/paradox/docs/faq.md index 226f4e1483..756a14120b 100644 --- a/docs/src/main/paradox/docs/faq.md +++ b/docs/src/main/paradox/docs/faq.md @@ -9,7 +9,7 @@ Knowledge Graph. You can find out more information on our @link:[product home pa ### Is Blue Brain Nexus free to use? -Yes, Nexus is a free, Open Source platform released under @link:[Apache Licence 2.0](https://opensource.org/license/apache-2-0/){ open=new } +Yes, Nexus is a free, Open Source platform released under @link:[Apache Licence 2.0](https://www.apache.org/licenses/LICENSE-2.0){ open=new } ### How do I run Blue Brain Nexus? diff --git a/docs/src/main/paradox/docs/fusion/architecture.md b/docs/src/main/paradox/docs/fusion/architecture.md index 4d120be96f..10ded18454 100644 --- a/docs/src/main/paradox/docs/fusion/architecture.md +++ b/docs/src/main/paradox/docs/fusion/architecture.md @@ -48,7 +48,7 @@ Customize the Nexus codebase appearance by setting environment variables. Defaul - `LOGO_IMG`: HTTPS URL for the application logo. Recommended: SVG format with transparent background. Ideal size: ~35 px height, max 250 px width. @link:[Click here for an example SVG](https://github.com/BlueBrain/nexus-web/blob/main/src/shared/images/EPFL_BBP_logo.svg){ open=new }. - `LOGO_LINK`: HTTPS URL redirecting from the logo. Example: -- `LANDING_VIDEO`: HTTPS URL for a landing page video. Requirements: MP4 format, H.264 codec, ~10MB, 1920×1080 resolution. @link:[Click here for an example video](https://github.com/BlueBrain/nexus-web/tree/main/src/videos/BrainRegionsNexusPage.mp4){ open=new }. Ensure that the video's main color is not too bright, as the text on top of it will be white. +- `LANDING_VIDEO`: HTTPS URL for a landing page video. Requirements: MP4 format, H.264 codec, ~10MB, 1920×1080 resolution. @link:[Click here for an example video](https://raw.githubusercontent.com/BlueBrain/nexus-web/main/src/shared/videos/BrainRegionsNexusPage.mp4){ open=new }. Ensure that the video's main color is not too bright, as the text on top of it will be white. - `LANDING_POSTER_IMG`: HTTPS URL for a loading image on the landing page, displayed while the video loads. @link:[Click here for an example poster image](https://github.com/BlueBrain/nexus-web/blob/main/src/shared/images/BrainRegionsNexusPage.jpg){ open=new }. Please use a PNG or JPG image that matches the size and color of the video. Aim for the image to have the same dimensions as the video. Ensure that the image size is kept under 200 KB to improve loading time and user experience. - `MAIN_COLOR`: Main background color in hex code. Example color: #062d68 @@ -64,6 +64,6 @@ Customize the Nexus codebase appearance by setting environment variables. Defaul #### Additional Options -- `FORGE_LINK`: HTTPS URL for the `Forge templates` button (only if using Nexus Forge). Example: +- `FORGE_LINK`: HTTPS URL for the `Forge templates` button (only if using Nexus Forge). Example: `https://some-url.com` For a comprehensive list of environment variables, see the @link:[Environment Variables List](https://github.com/BlueBrain/nexus-web/blob/main/README.md#env-variables-list){ open=new }. diff --git a/docs/src/main/paradox/docs/getting-started/running-nexus/index.md b/docs/src/main/paradox/docs/getting-started/running-nexus/index.md index fd01a17f55..8162b3fed3 100644 --- a/docs/src/main/paradox/docs/getting-started/running-nexus/index.md +++ b/docs/src/main/paradox/docs/getting-started/running-nexus/index.md @@ -143,7 +143,7 @@ This setup runs the Nexus ecosystem without an identity provider, and the anonym #### Administration To list running services or access logs, please refer to the official Docker -@link:[documentation](https://docs.docker.com/engine/reference/commandline/stack/){ open=new }. +@link:[documentation](https://docs.docker.com/reference/cli/docker/stack/){ open=new }. #### Stopping Nexus