diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityPayloadService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityPayloadService.kt index f54655a8c..2179d79b3 100644 --- a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityPayloadService.kt +++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityPayloadService.kt @@ -417,58 +417,46 @@ class EntityPayloadService( newTypes: List, modifiedAt: ZonedDateTime, allowEmptyListOfTypes: Boolean = true - ): Either = - 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 = 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( diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityPayloadServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityPayloadServiceTests.kt index 99347b993..0264dc0bd 100644 --- a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityPayloadServiceTests.kt +++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityPayloadServiceTests.kt @@ -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 { @@ -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] ) } }