Skip to content

Commit

Permalink
fix(core): do not force existing types to be present in payload when …
Browse files Browse the repository at this point in the history
…updating or appending types (#1115)

Co-authored-by: Benoit Orihuela <[email protected]>
  • Loading branch information
ranim-n and bobeal authored Mar 23, 2024
1 parent af498c5 commit 9a23d4d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -417,58 +417,46 @@ class EntityPayloadService(
newTypes: List<ExpandedTerm>,
modifiedAt: ZonedDateTime,
allowEmptyListOfTypes: Boolean = true
): Either<APIException, UpdateResult> =
either {
val entityPayload = retrieve(entityId).bind()
val currentTypes = entityPayload.types
// when dealing with an entity update, list of types can be empty if no change of type is requested
if (currentTypes.sorted() == newTypes.sorted() || newTypes.isEmpty() && allowEmptyListOfTypes)
return@either UpdateResult(emptyList(), emptyList())
if (!newTypes.containsAll(currentTypes)) {
val removedTypes = currentTypes.minus(newTypes)
return@either updateResultFromDetailedResult(
): Either<APIException, UpdateResult> = either {
val entityPayload = retrieve(entityId).bind()
val currentTypes = entityPayload.types
// when dealing with an entity update, list of types can be empty if no change of type is requested
if (currentTypes.sorted() == newTypes.sorted() || newTypes.isEmpty() && allowEmptyListOfTypes)
return@either UpdateResult(emptyList(), emptyList())

val updatedTypes = currentTypes.union(newTypes)
val updatedPayload = entityPayload.payload.deserializeExpandedPayload()
.mapValues {
if (it.key == JSONLD_TYPE)
updatedTypes
else it
}

databaseClient.sql(
"""
UPDATE entity_payload
SET types = :types,
modified_at = :modified_at,
payload = :payload
WHERE entity_id = :entity_id
""".trimIndent()
)
.bind("entity_id", entityId)
.bind("modified_at", modifiedAt)
.bind("types", updatedTypes.toTypedArray())
.bind("payload", Json.of(serializeObject(updatedPayload)))
.execute()
.map {
updateResultFromDetailedResult(
listOf(
UpdateAttributeResult(
attributeName = JSONLD_TYPE,
updateOperationResult = UpdateOperationResult.FAILED,
errorMessage = "A type cannot be removed from an entity: $removedTypes have been removed"
updateOperationResult = UpdateOperationResult.APPENDED
)
)
)
}

val updatedPayload = entityPayload.payload.deserializeExpandedPayload()
.mapValues {
if (it.key == JSONLD_TYPE)
newTypes
else it
}

databaseClient.sql(
"""
UPDATE entity_payload
SET types = :types,
modified_at = :modified_at,
payload = :payload
WHERE entity_id = :entity_id
""".trimIndent()
)
.bind("entity_id", entityId)
.bind("types", newTypes.toTypedArray())
.bind("modified_at", modifiedAt)
.bind("payload", Json.of(serializeObject(updatedPayload)))
.execute()
.map {
updateResultFromDetailedResult(
listOf(
UpdateAttributeResult(
attributeName = JSONLD_TYPE,
updateOperationResult = UpdateOperationResult.APPENDED
)
)
)
}.bind()
}
}.bind()
}

@Transactional
suspend fun appendAttributes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
}

@Test
fun `it should not add a type if existing types are not in the list of types to add`() = runTest {
fun `it should add a type to an entity even if existing types are not in the list of types to add`() = runTest {
loadMinimalEntity(entity01Uri, setOf(BEEHIVE_TYPE))
.sampleDataToNgsiLdEntity()
.map {
Expand All @@ -586,16 +586,15 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
now
)
}

entityPayloadService.updateTypes(entity01Uri, listOf(APIARY_TYPE), ngsiLdDateTime(), false)
.shouldSucceed()

entityPayloadService.retrieve(entity01Uri)
.shouldSucceedWith {
assertFalse(it.isSuccessful())
assertEquals(1, it.notUpdated.size)
val notUpdatedDetails = it.notUpdated[0]
assertEquals(JSONLD_TYPE, notUpdatedDetails.attributeName)
assertEquals(listOf(BEEHIVE_TYPE, APIARY_TYPE), it.types)
assertEquals(
"A type cannot be removed from an entity: [$BEEHIVE_TYPE] have been removed",
notUpdatedDetails.reason
listOf(BEEHIVE_TYPE, APIARY_TYPE),
it.payload.asString().deserializeExpandedPayload()[JSONLD_TYPE]
)
}
}
Expand Down

0 comments on commit 9a23d4d

Please sign in to comment.