Skip to content

Commit

Permalink
Patching distribution under hasPart (#5062)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Dumas <simon.dumas@epfl.ch>
  • Loading branch information
imsdu and Simon Dumas authored Jul 10, 2024
1 parent 94b1423 commit 767cc38
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,19 @@ final class DistributionPatcher(
fetchFileAttributes: (ProjectRef, ResourceRef) => IO[FileAttributes]
) {

def patchAll: Json => IO[Json] = patchInRoot(_).flatMap(patchInHasPart)

private def patchInHasPart: Json => IO[Json] = root.hasPart.json.modifyA { json =>
json.asArray match {
case Some(array) => array.parTraverse(patchInRoot).map(Json.arr(_: _*))
case None => patchInRoot(json)
}
}(_)

/**
* Distribution may be defined as an object or as an array in original payloads
*/
def singleOrArray: Json => IO[Json] = root.distribution.json.modifyA { json =>
private def patchInRoot: Json => IO[Json] = root.distribution.json.modifyA { json =>
json.asArray match {
case Some(array) => array.parTraverse(single).map(Json.arr(_: _*))
case None => single(json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ final class SourcePatcher(distributionPatcher: DistributionPatcher, iriPatcher:

def apply(json: Json): IO[Json] =
distributionPatcher
.singleOrArray(json)
.patchAll(json)
.map(removeEmptyIds)
.map(patchIris(_, iriPatcher))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,69 +97,73 @@ class DistributionPatcherSuite extends NexusSuite {

test("Do nothing on a distribution payload without fields to patch") {
val input = json"""{ "anotherField": "XXX" }"""
patcher.single(input).assertEquals(input)
patcher.patchAll(input).assertEquals(input)
}

test("Patch location on a distribution to point to the new unique S3 storage") {
val input =
json"""{
"atLocation": {
"store": {
"@id": "https://bbp.epfl.ch/remote-disk-storage",
"@type": "RemoteDiskStorage",
"_rev": 3
"distribution": {
"atLocation": {
"store": {
"@id": "https://bbp.epfl.ch/remote-disk-storage",
"@type": "RemoteDiskStorage",
"_rev": 3
}
}
}
}"""
val expected =
json"""{
"atLocation": {
"store": {
"@id": "https://bluebrain.github.io/nexus/vocabulary/defaultS3Storage",
"@type": "S3Storage",
"_rev": 1
}
}
}"""
patcher.single(input).assertEquals(expected)
"distribution": {
"atLocation": {
"store": {
"@id": "https://bluebrain.github.io/nexus/vocabulary/defaultS3Storage",
"@type": "S3Storage",
"_rev": 1
}
}
}
}"""
patcher.patchAll(input).assertEquals(expected)
}

test("Patching an invalid file self should preserve the initial value") {
val input = json"""{ "contentUrl": "xxx" }"""
patcher.single(input).assertEquals(input)
val input = json"""{ "distribution": { "contentUrl": "xxx" } }"""
patcher.patchAll(input).assertEquals(input)
}

test("Patch a valid file self on a distribution without project mapping") {
val input = json"""{ "contentUrl": "${sourceFileSelf(projectNoMapping, resource1)}" }"""
val expected = json"""{ "contentUrl": "${destinationFileSelf(projectNoMapping, patchedResource1)}" }"""
patcher.single(input).assertEquals(expected)
val input = json"""{ "distribution": { "contentUrl": "${sourceFileSelf(projectNoMapping, resource1)}" } }"""
val expected =
json"""{ "distribution": { "contentUrl": "${destinationFileSelf(projectNoMapping, patchedResource1)}" } }"""
patcher.patchAll(input).assertEquals(expected)
}

test("Patch a valid file self on a distribution with project mapping") {
val input = json"""{ "contentUrl": "${sourceFileSelf(projectWithMapping, resource1)}" }"""
val input = json"""{ "distribution": { "contentUrl": "${sourceFileSelf(projectWithMapping, resource1)}" } }"""
val expectedContentUri = destinationFileSelf(mappedProject, patchedResource1).toString()
patcher.single(input).map(contentUrl).assertEquals(expectedContentUri)
patcher.patchAll(input).map(distributionContentUrl).assertEquals(expectedContentUri)
}

test("Patch an invalid distribution self should preserve the initial value") {
val input = json"""{ "distribution":"xxx" }"""
patcher.singleOrArray(input).assertEquals(input)
patcher.patchAll(input).assertEquals(input)
}

test("Patch a valid file self on a distribution as an object") {
val input = json"""{ "distribution": { "contentUrl": "${sourceFileSelf(projectWithMapping, resource1)}" } }"""
patcher
.singleOrArray(input)
.map(distribution)
.map(contentUrl)
.patchAll(input)
.map(distributionContentUrl)
.assertEquals(destinationFileSelf(mappedProject, patchedResource1).toString())
}

test("Patch a valid file self on a distribution as an array") {
val input = json"""{ "distribution": [{ "contentUrl": "${sourceFileSelf(projectNoMapping, resource2)}" }] }"""
val expected =
json"""{ "distribution": [{ "contentUrl": "${destinationFileSelf(projectNoMapping, patchedResource2)}" }] }"""
patcher.singleOrArray(input).assertEquals(expected)
patcher.patchAll(input).assertEquals(expected)
}

test("Patch a file location based on what the resource says") {
Expand All @@ -174,7 +178,7 @@ class DistributionPatcherSuite extends NexusSuite {
}"""

patcher
.singleOrArray(input)
.patchAll(input)
.map(distributionLocation)
.assertEquals("/actual/path/file.txt")
}
Expand All @@ -188,7 +192,7 @@ class DistributionPatcherSuite extends NexusSuite {
}"""

patcher
.singleOrArray(input)
.patchAll(input)
.map(distributionLocation)
.assertEquals("/actual/path/file.txt")
}
Expand All @@ -202,8 +206,8 @@ class DistributionPatcherSuite extends NexusSuite {
}"""

patcher
.singleOrArray(input)
.map(distrubutionContentSize)
.patchAll(input)
.map(distributionContentSize)
.assertEquals(jobj"""{"unitCode": "bytes", "value": $size}""")
}

Expand All @@ -216,15 +220,30 @@ class DistributionPatcherSuite extends NexusSuite {
}"""

patcher
.singleOrArray(input)
.patchAll(input)
.map(distrubutionDigest)
.assertEquals(jobj"""{
"algorithm": "SHA-256",
"value": "${digest}"
}""")
}

private def distrubutionContentSize(json: Json): JsonObject = {
test("Patch a hasPart without distribution should preserve the initial value") {
val input = json"""{ "hasPart": [{ "@id":"xxx" }] }"""
patcher.patchAll(input).assertEquals(input)
}

test("Patch a hasPart without distribution with a valid self should preserve the initial value") {
val input =
json"""{ "hasPart": [{ "distribution": { "contentUrl": "${sourceFileSelf(projectNoMapping, resource1)}" } }] }"""
val expected = json"""{ "hasPart": [{ "distribution": { "contentUrl": "${destinationFileSelf(
projectNoMapping,
patchedResource1
)}" } }] }"""
patcher.patchAll(input).assertEquals(expected)
}

private def distributionContentSize(json: Json): JsonObject = {
json.hcursor
.downField("distribution")
.downField("contentSize")
Expand All @@ -249,19 +268,12 @@ class DistributionPatcherSuite extends NexusSuite {
.getOrElse(fail("location was not present"))
}

private def contentUrl(json: Json): String = {
private def distributionContentUrl(json: Json): String = {
json.hcursor
.downField("distribution")
.downField("contentUrl")
.as[String]
.getOrElse(fail("contentUrl was not present"))
}

private def distribution(json: Json): Json = {
json.hcursor
.downField("distribution")
.as[JsonObject]
.getOrElse(fail("distribution was not present"))
.toJson
}

}

0 comments on commit 767cc38

Please sign in to comment.