Skip to content

Commit

Permalink
refactor: expandedEntity id is a uri.
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasBousselin committed Feb 10, 2025
1 parent c78b325 commit 454cb12
Show file tree
Hide file tree
Showing 16 changed files with 38 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.model.GatewayTimeoutException
import com.egm.stellio.shared.util.JSON_LD_CONTENT_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.compactEntity
import com.egm.stellio.shared.util.toUri
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.http.HttpHeaders
Expand All @@ -49,12 +48,12 @@ class DistributedEntityProvisionService(
): Pair<BatchOperationResult, ExpandedEntity?> {
val csrFilters =
CSRFilters(
ids = setOf(entity.id.toUri()),
ids = setOf(entity.id),
types = entity.types.toSet()
)
val result = BatchOperationResult()
val registrationInfoFilter =
RegistrationInfoFilter(ids = setOf(entity.id.toUri()), types = entity.types.toSet())
RegistrationInfoFilter(ids = setOf(entity.id), types = entity.types.toSet())

val matchingCSR = contextSourceRegistrationService.getContextSourceRegistrations(
filters = csrFilters,
Expand Down Expand Up @@ -115,7 +114,7 @@ class DistributedEntityProvisionService(
{
resultToUpdate.errors.add(
BatchEntityError(
entityId = entity.id.toUri(),
entityId = entity.id,
registrationId = csr.id,
error = it.toProblemDetail()
)
Expand All @@ -126,7 +125,7 @@ class DistributedEntityProvisionService(
} else if (csr.mode != Mode.INCLUSIVE) {
resultToUpdate.errors.add(
BatchEntityError(
entityId = entity.id.toUri(),
entityId = entity.id,
registrationId = csr.id,
error = ConflictException(
"The csr: ${csr.id} does not support the creation of entities"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class EntityHandler(

val expandedEntity = expandJsonLdEntity(body, contexts)
expandedEntity.toNgsiLdEntity().bind()
val entityId = expandedEntity.id.toUri()
val entityId = expandedEntity.id

val (result, remainingEntity) =
if (queryParams.getFirst(QP.LOCAL.key)?.toBoolean() != false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class TemporalQueryService(
val attributes = entityAttributeService.getForEntity(entityId, attrs, datasetIds, false).let {
if (it.isEmpty())
ResourceNotFoundException(
entityOrAttrsNotFoundMessage(entityId.toString(), temporalEntitiesQuery.entitiesQuery.attrs)
entityOrAttrsNotFoundMessage(entityId, temporalEntitiesQuery.entitiesQuery.attrs)
).left()
else it.right()
}.bind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class TemporalEntityHandler(
extractPayloadAndContexts(requestBody, httpHeaders, applicationProperties.contexts.core).bind()

val jsonLdTemporalEntity = expandJsonLdEntity(body, contexts)
val entityUri = jsonLdTemporalEntity.id.toUri()
val entityUri = jsonLdTemporalEntity.id

val jsonLdInstances = jsonLdTemporalEntity.getAttributes()
jsonLdInstances.checkTemporalAttributeInstance().bind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class EnabledAuthorizationServiceTests {
it.second.forEach { jsonLdEntity ->
assertEquals(1, jsonLdEntity.types.size)
assertEquals(GROUP_TYPE, jsonLdEntity.types[0])
assertTrue(jsonLdEntity.id.startsWith(GROUP_ENTITY_PREFIX))
assertTrue(jsonLdEntity.id.toString().startsWith(GROUP_ENTITY_PREFIX))
}
}
}
Expand All @@ -303,7 +303,7 @@ class EnabledAuthorizationServiceTests {
assertEquals(1, it.first)
assertEquals(1, it.second[0].types.size)
assertEquals(GROUP_TYPE, it.second[0].types[0])
assertTrue(it.second[0].id.startsWith(GROUP_ENTITY_PREFIX))
assertTrue(it.second[0].id.toString().startsWith(GROUP_ENTITY_PREFIX))
}

coVerify {
Expand Down Expand Up @@ -338,7 +338,7 @@ class EnabledAuthorizationServiceTests {
it.second.forEach { jsonLdEntity ->
assertEquals(1, jsonLdEntity.types.size)
assertEquals(USER_TYPE, jsonLdEntity.types[0])
assertTrue(jsonLdEntity.id.startsWith(USER_ENTITY_PREFIX))
assertTrue(jsonLdEntity.id.toString().startsWith(USER_ENTITY_PREFIX))
assertTrue(jsonLdEntity.members.containsKey(AUTH_PROP_USERNAME))
}
}
Expand Down Expand Up @@ -432,7 +432,7 @@ class EnabledAuthorizationServiceTests {
assertEquals(1, it.first)
assertEquals(2, it.second.size)

val expandedEntityWithOtherRights = it.second.find { it.id == entityId01.toString() }!!
val expandedEntityWithOtherRights = it.second.find { it.id == entityId01 }!!
assertEquals(4, expandedEntityWithOtherRights.members.size)
assertTrue(expandedEntityWithOtherRights.members.containsKey(AUTH_REL_CAN_WRITE))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ class ContextSourceRegistrationTests {
fun `getAssociatedAttributes should check properties and relationship separately`() = runTest {
val entity = expandJsonLdEntity(entityPayload)
val registrationInfoFilter = RegistrationInfoFilter(
ids = setOf(entity.id.toUri()),
ids = setOf(entity.id),
types = entity.types.toSet()
)
val entityInfo = ContextSourceRegistration.EntityInfo(entity.id.toUri(), types = entity.types)
val entityInfo = ContextSourceRegistration.EntityInfo(entity.id, types = entity.types)
val information = RegistrationInfo(
entities = listOf(entityInfo),
propertyNames = listOf(NGSILD_NAME_PROPERTY),
Expand Down Expand Up @@ -176,7 +176,7 @@ class ContextSourceRegistrationTests {
val entity = expandJsonLdEntity(entityPayload)

val registrationInfoFilter = RegistrationInfoFilter(
ids = setOf(entity.id.toUri()),
ids = setOf(entity.id),
types = entity.types.toSet()
)
val nonMatchingEntityInfo = ContextSourceRegistration.EntityInfo(types = listOf(BEEHIVE_TYPE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ class EntityOperationServiceTests {
@BeforeEach
fun initNgsiLdEntitiesMocks() {
firstExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true) {
every { id } returns firstEntityURI.toString()
every { id } returns firstEntityURI
every { members } returns emptyMap()
}
firstEntity = mockkClass(NgsiLdEntity::class, relaxed = true)
every { firstEntity.id } returns firstEntityURI
secondExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true) {
every { id } returns secondEntityURI.toString()
every { id } returns secondEntityURI
every { members } returns emptyMap()
}
secondEntity = mockkClass(NgsiLdEntity::class, relaxed = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer() {

entityQueryService.queryEntity(beehiveTestCId)
.shouldSucceedWith {
assertEquals(beehiveTestCId.toString(), it.id)
assertEquals(beehiveTestCId, it.id)
assertEquals(listOf(BEEHIVE_TYPE), it.types)
assertEquals(7, it.members.size)
}
Expand Down Expand Up @@ -111,7 +111,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer() {
entityQueryService.queryEntities(buildDefaultQueryParams().copy(ids = setOf(beehiveTestCId)))
.shouldSucceedWith {
assertEquals(1, it.second)
assertEquals(beehiveTestCId.toString(), it.first[0].id)
assertEquals(beehiveTestCId, it.first[0].id)
assertEquals(listOf(BEEHIVE_TYPE), it.first[0].types)
assertEquals(7, it.first[0].members.size)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ class EntityHandlerTests {
).right()

val expectedMessage = entityOrAttrsNotFoundMessage(
beehiveId.toString(),
beehiveId,
setOf("https://uri.etsi.org/ngsi-ld/default-context/attr2")
)
webClient.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,23 @@ class EntityOperationHandlerTests {
every { types } returns listOf(SENSOR_TYPE)
}
mockedTemperatureSensorExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns temperatureSensorUri.toString()
every { id } returns temperatureSensorUri
every { members } returns emptyMap()
}
mockedDissolvedOxygenSensorEntity = mockkClass(NgsiLdEntity::class) {
every { id } returns dissolvedOxygenSensorUri
every { types } returns listOf(SENSOR_TYPE)
}
mockedDissolvedOxygenSensorExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns dissolvedOxygenSensorUri.toString()
every { id } returns dissolvedOxygenSensorUri
every { members } returns emptyMap()
}
mockedDeviceEntity = mockkClass(NgsiLdEntity::class) {
every { id } returns deviceUri
every { types } returns listOf(DEVICE_TYPE)
}
mockedDeviceExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns deviceUri.toString()
every { id } returns deviceUri
every { members } returns emptyMap()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_NONE_TERM
import com.egm.stellio.shared.util.entityOrAttrsNotFoundMessage
import com.egm.stellio.shared.util.toUri
import java.net.URI
import java.time.ZonedDateTime

data class ExpandedEntity(
Expand Down Expand Up @@ -80,7 +82,11 @@ data class ExpandedEntity(
)

val id by lazy {
(members[JSONLD_ID] ?: throw BadRequestDataException("Could not extract id from JSON-LD entity")) as String
when (val id = members[JSONLD_ID]) {
is URI -> id
is String -> id.toUri()
else -> throw BadRequestDataException("Could not extract id from JSON-LD entity")
}
}

val types by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typealias ExpandedAttributeInstance = Map<String, List<Any>>
typealias ExpandedNonReifiedPropertyValue = List<Map<String, Any>>

fun ExpandedAttributes.addCoreMembers(
entityId: String,
entityId: URI,
entityTypes: List<ExpandedTerm>
): Map<String, Any> =
this.plus(listOf(JSONLD_ID to entityId, JSONLD_TYPE to entityTypes))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_UNIT_CODE_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_VOCABPROPERTY_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_VOCABPROPERTY_VALUE
import com.egm.stellio.shared.util.toUri
import java.net.URI
import java.time.ZonedDateTime
import java.util.Locale
Expand All @@ -43,12 +42,12 @@ class NgsiLdEntity private constructor(
) {
companion object {
suspend fun create(
parsedKeys: Map<String, Any>
expandedEntity: ExpandedEntity
): Either<APIException, NgsiLdEntity> = either {
val parsedKeys = expandedEntity.members
ensure(parsedKeys.containsKey(JSONLD_ID)) {
BadRequestDataException("The provided NGSI-LD entity does not contain an id property")
}
val id = (parsedKeys[JSONLD_ID]!! as String).toUri()

ensure(parsedKeys.containsKey(JSONLD_TYPE)) {
BadRequestDataException("The provided NGSI-LD entity does not contain a type property")
Expand All @@ -60,7 +59,7 @@ class NgsiLdEntity private constructor(
val rawAttributes = getNonCoreMembers(parsedKeys, NGSILD_ENTITY_CORE_MEMBERS)
val attributes = parseAttributes(rawAttributes).bind()

NgsiLdEntity(id, types, scopes, attributes)
NgsiLdEntity(expandedEntity.id, types, scopes, attributes)
}
}

Expand Down Expand Up @@ -588,7 +587,7 @@ suspend fun ExpandedAttributeInstances.toNgsiLdAttribute(
}

suspend fun ExpandedEntity.toNgsiLdEntity(): Either<APIException, NgsiLdEntity> =
NgsiLdEntity.create(this.members)
NgsiLdEntity.create(this)

fun List<NgsiLdAttribute>.flatOnInstances(): List<Pair<NgsiLdAttribute, NgsiLdAttributeInstance>> =
this.flatMap { ngsiLdAttribute ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fun entityAlreadyExistsMessage(entityId: String) = "Entity $entityId already exi
fun typeNotFoundMessage(type: String) = "Type $type was not found"

fun entityOrAttrsNotFoundMessage(
entityId: String,
entityId: URI,
attrs: Set<String>
) = "Entity $entityId does not exist or it has none of the requested attributes : $attrs"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.egm.stellio.shared.util.expandJsonLdEntity
import com.egm.stellio.shared.util.loadAndExpandSampleData
import com.egm.stellio.shared.util.ngsiLdDateTime
import com.egm.stellio.shared.util.parseAndExpandQueryParameter
import com.egm.stellio.shared.util.toUri
import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
Expand All @@ -38,7 +39,7 @@ class ExpandedEntityTests {
@Test
fun `it should not find an expanded attribute contained in the entity`() {
val expandedEntity = ExpandedEntity(
mapOf(INCOMING_PROPERTY to "", OUTGOING_PROPERTY to "", JSONLD_ID to "urn:ngsi-ld:Entity:01")
mapOf(INCOMING_PROPERTY to "", OUTGOING_PROPERTY to "", JSONLD_ID to "urn:ngsi-ld:Entity:01".toUri())
)

val checkResult = expandedEntity.checkContainsAnyOf(setOf(TEMPERATURE_PROPERTY, NGSILD_NAME_PROPERTY))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class NgsiLdEntityTests {

val ngsiLdEntity = expandJsonLdEntity(rawEntity, NGSILD_TEST_CORE_CONTEXTS)

assertEquals("urn:ngsi-ld:Device:01234", ngsiLdEntity.id)
assertEquals("urn:ngsi-ld:Device:01234".toUri(), ngsiLdEntity.id)
assertEquals(listOf("https://uri.etsi.org/ngsi-ld/default-context/Device"), ngsiLdEntity.types)
}

Expand Down

0 comments on commit 454cb12

Please sign in to comment.