diff --git a/build.gradle.kts b/build.gradle.kts
index 09c1ee862..2fdfdbe43 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -63,7 +63,9 @@ subprojects {
implementation("org.springframework.kafka:spring-kafka")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
- implementation("com.github.jsonld-java:jsonld-java:0.13.6")
+
+ implementation("com.apicatalog:titanium-json-ld:1.3.3")
+ implementation("org.glassfish:jakarta.json:2.0.1")
implementation("io.arrow-kt:arrow-fx-coroutines:1.2.1")
diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml
index 4d7881032..d94210013 100644
--- a/config/detekt/detekt.yml
+++ b/config/detekt/detekt.yml
@@ -168,10 +168,10 @@ complexity:
TooManyFunctions:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
- thresholdInFiles: 20
- thresholdInClasses: 20
- thresholdInInterfaces: 20
- thresholdInObjects: 20
+ thresholdInFiles: 30
+ thresholdInClasses: 30
+ thresholdInInterfaces: 30
+ thresholdInObjects: 30
thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
diff --git a/search-service/config/detekt/baseline.xml b/search-service/config/detekt/baseline.xml
index 5efad94c5..118a5dc3a 100644
--- a/search-service/config/detekt/baseline.xml
+++ b/search-service/config/detekt/baseline.xml
@@ -10,6 +10,7 @@
LongMethod:AttributeInstanceService.kt$AttributeInstanceService$@Transactional suspend fun create(attributeInstance: AttributeInstance): Either<APIException, Unit>
LongMethod:EntityAccessControlHandler.kt$EntityAccessControlHandler$@PostMapping("/{subjectId}/attrs", consumes = [MediaType.APPLICATION_JSON_VALUE, JSON_LD_CONTENT_TYPE]) suspend fun addRightsOnEntities( @RequestHeader httpHeaders: HttpHeaders, @PathVariable subjectId: String, @RequestBody requestBody: Mono<String> ): ResponseEntity<*>
LongMethod:QueryServiceTests.kt$QueryServiceTests$@Test fun `it should query temporal entities as requested by query params`()
+ LongMethod:QueryServiceTests.kt$QueryServiceTests$@Test fun `it should return an empty list for an attribute if it has no temporal values`()
LongMethod:TemporalEntityBuilderTests.kt$TemporalEntityBuilderTests$@Test fun `it should return a temporal entity with values aggregated`()
LongMethod:TemporalScopeBuilderTests.kt$TemporalScopeBuilderTests$@Test fun `it should build an aggregated temporal representation of scopes`()
LongMethod:V0_29__JsonLd_migration.kt$V0_29__JsonLd_migration$override fun migrate(context: Context)
@@ -28,6 +29,5 @@
ReturnCount:EntitiesQueryUtils.kt$fun buildTemporalQuery( params: MultiValueMap<String, String>, inQueryEntities: Boolean = false, withAggregatedValues: Boolean = false ): Either<APIException, TemporalQuery>
SwallowedException:EntitiesQueryUtils.kt$e: IllegalArgumentException
TooManyFunctions:EntityPayloadService.kt$EntityPayloadService
- TooManyFunctions:TemporalEntityAttributeService.kt$TemporalEntityAttributeService
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/AuthorizationService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/AuthorizationService.kt
index 98293e638..9ea94122a 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/AuthorizationService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/AuthorizationService.kt
@@ -4,7 +4,7 @@ import arrow.core.Either
import arrow.core.Option
import com.egm.stellio.search.model.EntitiesQuery
import com.egm.stellio.shared.model.APIException
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.util.Sub
import java.net.URI
@@ -23,20 +23,20 @@ interface AuthorizationService {
suspend fun getAuthorizedEntities(
entitiesQuery: EntitiesQuery,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>>
+ ): Either>>
suspend fun getGroupsMemberships(
offset: Int,
limit: Int,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>>
+ ): Either>>
suspend fun getUsers(
offset: Int,
limit: Int,
- contextLink: String,
- ): Either>>
+ contexts: List,
+ ): Either>>
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/DisabledAuthorizationService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/DisabledAuthorizationService.kt
index 1fc06275f..36928017e 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/DisabledAuthorizationService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/DisabledAuthorizationService.kt
@@ -5,7 +5,7 @@ import arrow.core.Option
import arrow.core.right
import com.egm.stellio.search.model.EntitiesQuery
import com.egm.stellio.shared.model.APIException
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.util.Sub
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Component
@@ -41,20 +41,20 @@ class DisabledAuthorizationService : AuthorizationService {
override suspend fun getAuthorizedEntities(
entitiesQuery: EntitiesQuery,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>> = Pair(-1, emptyList()).right()
+ ): Either>> = Pair(-1, emptyList()).right()
override suspend fun getGroupsMemberships(
offset: Int,
limit: Int,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>> = Pair(-1, emptyList()).right()
+ ): Either>> = Pair(-1, emptyList()).right()
override suspend fun getUsers(
offset: Int,
limit: Int,
- contextLink: String,
- ): Either>> = Pair(-1, emptyList()).right()
+ contexts: List,
+ ): Either>> = Pair(-1, emptyList()).right()
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationService.kt
index 12e5bf971..b0b910814 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationService.kt
@@ -6,7 +6,7 @@ import arrow.fx.coroutines.parMap
import com.egm.stellio.search.model.EntitiesQuery
import com.egm.stellio.shared.model.APIException
import com.egm.stellio.shared.model.AccessDeniedException
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.util.*
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
@@ -95,9 +95,9 @@ class EnabledAuthorizationService(
override suspend fun getAuthorizedEntities(
entitiesQuery: EntitiesQuery,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>> = either {
+ ): Either>> = either {
val accessRights = entitiesQuery.attrs.mapNotNull { AccessRight.forExpandedAttributeName(it).getOrNull() }
val entitiesAccessControl = entityAccessRightsService.getSubjectAccessRights(
sub,
@@ -127,8 +127,8 @@ class EnabledAuthorizationService(
)
} else entityAccessControl
}
- .map { it.serializeProperties(contextLink) }
- .map { JsonLdEntity(it, listOf(contextLink)) }
+ .map { it.serializeProperties(contexts) }
+ .map { ExpandedEntity(it, contexts) }
val count = entityAccessRightsService.getSubjectAccessRightsCount(
sub,
@@ -143,9 +143,9 @@ class EnabledAuthorizationService(
override suspend fun getGroupsMemberships(
offset: Int,
limit: Int,
- contextLink: String,
+ contexts: List,
sub: Option
- ): Either>> = either {
+ ): Either>> = either {
val groups =
when (userIsAdmin(sub)) {
is Either.Left -> {
@@ -162,10 +162,7 @@ class EnabledAuthorizationService(
}
val jsonLdEntities = groups.second.map {
- JsonLdEntity(
- it.serializeProperties(),
- listOf(contextLink)
- )
+ ExpandedEntity(it.serializeProperties(), contexts)
}
Pair(groups.first, jsonLdEntities)
@@ -174,16 +171,13 @@ class EnabledAuthorizationService(
override suspend fun getUsers(
offset: Int,
limit: Int,
- contextLink: String
- ): Either>> = either {
+ contexts: List,
+ ): Either>> = either {
val users = subjectReferentialService.getUsers(offset, limit)
val usersCount = subjectReferentialService.getUsersCount().bind()
val jsonLdEntities = users.map {
- JsonLdEntity(
- it.serializeProperties(contextLink),
- listOf(contextLink)
- )
+ ExpandedEntity(it.serializeProperties(contexts), contexts)
}
Pair(usersCount, jsonLdEntities)
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EntityAccessRights.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EntityAccessRights.kt
index ba53d4dd3..e6f3761dc 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EntityAccessRights.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/EntityAccessRights.kt
@@ -1,20 +1,26 @@
package com.egm.stellio.search.authorization
-import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.model.ExpandedAttributeInstances
+import com.egm.stellio.shared.model.ExpandedTerm
+import com.egm.stellio.shared.model.addNonReifiedProperty
+import com.egm.stellio.shared.model.addSubAttribute
+import com.egm.stellio.shared.util.AccessRight
+import com.egm.stellio.shared.util.AuthContextModel
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_RIGHT
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SAP
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SUBJECT_INFO
import com.egm.stellio.shared.util.AuthContextModel.AUTH_REL_CAN_ADMIN
import com.egm.stellio.shared.util.AuthContextModel.AUTH_REL_CAN_READ
import com.egm.stellio.shared.util.AuthContextModel.AUTH_REL_CAN_WRITE
-import com.egm.stellio.shared.util.JsonLdUtils.DATASET_ID_PREFIX
+import com.egm.stellio.shared.util.AuthContextModel.DATASET_ID_PREFIX
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyMapValue
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedRelationship
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedProperty
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedRelationshipValue
+import com.egm.stellio.shared.util.extractSub
+import com.egm.stellio.shared.util.toUri
import java.net.URI
data class EntityAccessRights(
@@ -33,39 +39,39 @@ data class EntityAccessRights(
) {
val datasetId: URI = (DATASET_ID_PREFIX + uri.extractSub()).toUri()
- suspend fun serializeProperties(contextLink: String): ExpandedAttributeInstances =
- buildExpandedRelationship(uri)
- .addSubAttribute(NGSILD_DATASET_ID_PROPERTY, buildNonReifiedProperty(datasetId.toString()))
+ suspend fun serializeProperties(contexts: List): ExpandedAttributeInstances =
+ buildExpandedRelationshipValue(uri)
+ .addNonReifiedProperty(NGSILD_DATASET_ID_PROPERTY, datasetId.toString())
.addSubAttribute(
AUTH_PROP_SUBJECT_INFO,
- buildExpandedPropertyMapValue(subjectInfo, listOf(contextLink))
+ buildExpandedPropertyMapValue(subjectInfo, contexts)
)
}
- suspend fun serializeProperties(contextLink: String): Map {
+ suspend fun serializeProperties(contexts: List): Map {
val resultEntity = mutableMapOf()
resultEntity[JSONLD_ID] = id.toString()
resultEntity[JSONLD_TYPE] = types
- resultEntity[AUTH_PROP_RIGHT] = buildExpandedProperty(right.attributeName)
+ resultEntity[AUTH_PROP_RIGHT] = buildExpandedPropertyValue(right.attributeName)
specificAccessPolicy?.run {
- resultEntity[AUTH_PROP_SAP] = buildExpandedProperty(this)
+ resultEntity[AUTH_PROP_SAP] = buildExpandedPropertyValue(this)
}
rCanAdminUsers?.run {
resultEntity[AUTH_REL_CAN_ADMIN] = this.map {
- it.serializeProperties(contextLink)
+ it.serializeProperties(contexts)
}.flatten()
}
rCanWriteUsers?.run {
resultEntity[AUTH_REL_CAN_WRITE] = this.map {
- it.serializeProperties(contextLink)
+ it.serializeProperties(contexts)
}.flatten()
}
rCanReadUsers?.run {
resultEntity[AUTH_REL_CAN_READ] = this.map {
- it.serializeProperties(contextLink)
+ it.serializeProperties(contexts)
}.flatten()
}
return resultEntity
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/Group.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/Group.kt
index 025b04988..a664c6bf1 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/Group.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/Group.kt
@@ -1,11 +1,11 @@
package com.egm.stellio.search.authorization
+import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_NAME
import com.egm.stellio.shared.util.AuthContextModel.AUTH_REL_IS_MEMBER_OF
import com.egm.stellio.shared.util.AuthContextModel.GROUP_ENTITY_PREFIX
import com.egm.stellio.shared.util.AuthContextModel.GROUP_TYPE
import com.egm.stellio.shared.util.JsonLdUtils
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_NAME_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
data class Group(
val id: String,
@@ -18,10 +18,10 @@ data class Group(
resultEntity[JsonLdUtils.JSONLD_ID] = GROUP_ENTITY_PREFIX + id
resultEntity[JsonLdUtils.JSONLD_TYPE] = listOf(type)
- resultEntity[NGSILD_NAME_PROPERTY] = buildExpandedProperty(name)
+ resultEntity[AUTH_PROP_NAME] = buildExpandedPropertyValue(name)
isMember.run {
- resultEntity[AUTH_REL_IS_MEMBER_OF] = buildExpandedProperty(isMember.toString())
+ resultEntity[AUTH_REL_IS_MEMBER_OF] = buildExpandedPropertyValue(isMember.toString())
}
return resultEntity
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/User.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/User.kt
index 756ccb9cf..8999a36fd 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/User.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/User.kt
@@ -12,8 +12,8 @@ import com.egm.stellio.shared.util.AuthContextModel.USER_ENTITY_PREFIX
import com.egm.stellio.shared.util.AuthContextModel.USER_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyMapValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
data class User(
val id: String,
@@ -23,19 +23,19 @@ data class User(
val familyName: String? = null,
val subjectInfo: Map
) {
- suspend fun serializeProperties(contextLink: String): Map {
+ suspend fun serializeProperties(contexts: List): Map {
val resultEntity = mutableMapOf()
resultEntity[JSONLD_ID] = USER_ENTITY_PREFIX + id
resultEntity[JSONLD_TYPE] = listOf(type)
- resultEntity[AUTH_PROP_USERNAME] = buildExpandedProperty(username)
+ resultEntity[AUTH_PROP_USERNAME] = buildExpandedPropertyValue(username)
givenName?.run {
- resultEntity[AUTH_PROP_GIVEN_NAME] = buildExpandedProperty(givenName)
+ resultEntity[AUTH_PROP_GIVEN_NAME] = buildExpandedPropertyValue(givenName)
}
familyName?.run {
- resultEntity[AUTH_PROP_FAMILY_NAME] = buildExpandedProperty(familyName)
+ resultEntity[AUTH_PROP_FAMILY_NAME] = buildExpandedPropertyValue(familyName)
}
subjectInfo.filterKeys {
@@ -43,7 +43,7 @@ data class User(
}.run {
if (this.isNotEmpty())
resultEntity[AUTH_PROP_SUBJECT_INFO] =
- buildExpandedPropertyMapValue(this, listOf(contextLink))
+ buildExpandedPropertyMapValue(this, contexts)
}
return resultEntity
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/listener/ObservationEventListener.kt b/search-service/src/main/kotlin/com/egm/stellio/search/listener/ObservationEventListener.kt
index 63d691b78..799881dbb 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/listener/ObservationEventListener.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/listener/ObservationEventListener.kt
@@ -7,9 +7,9 @@ import com.egm.stellio.search.service.EntityEventService
import com.egm.stellio.search.service.EntityPayloadService
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
+import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdEntity
import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdTerms
import com.egm.stellio.shared.util.JsonUtils.deserializeAs
-import com.egm.stellio.shared.util.toExpandedAttributes
import com.egm.stellio.shared.web.NGSILD_TENANT_HEADER
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -64,10 +64,16 @@ class ObservationEventListener(
tenantUri: URI,
observationEvent: EntityCreateEvent
): Either = either {
+ val expandedEntity = expandJsonLdEntity(
+ observationEvent.operationPayload,
+ observationEvent.contexts
+ )
+ val ngsiLdEntity = expandedEntity.toNgsiLdEntity().bind()
+
mono {
entityPayloadService.createEntity(
- observationEvent.operationPayload,
- observationEvent.contexts,
+ ngsiLdEntity,
+ expandedEntity,
observationEvent.sub
).map {
entityEventService.publishEntityCreateEvent(
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/model/AttributeInstance.kt b/search-service/src/main/kotlin/com/egm/stellio/search/model/AttributeInstance.kt
index 01a43440f..65ea363d8 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/model/AttributeInstance.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/model/AttributeInstance.kt
@@ -1,11 +1,11 @@
package com.egm.stellio.search.model
+import com.egm.stellio.shared.model.ExpandedAttributeInstance
import com.egm.stellio.shared.model.WKTCoordinates
-import com.egm.stellio.shared.util.ExpandedAttributeInstance
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_INSTANCE_ID_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedDateTime
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedProperty
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.util.toUri
import io.r2dbc.postgresql.codec.Json
@@ -72,10 +72,10 @@ data class AttributeInstance private constructor(
instanceId: URI,
modifiedAt: ZonedDateTime? = null
): ExpandedAttributeInstance =
- this.plus(NGSILD_INSTANCE_ID_PROPERTY to buildNonReifiedProperty(instanceId.toString()))
+ this.plus(NGSILD_INSTANCE_ID_PROPERTY to buildNonReifiedPropertyValue(instanceId.toString()))
.let {
if (modifiedAt != null)
- it.plus(NGSILD_MODIFIED_AT_PROPERTY to buildNonReifiedDateTime(modifiedAt))
+ it.plus(NGSILD_MODIFIED_AT_PROPERTY to buildNonReifiedTemporalValue(modifiedAt))
else it
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/model/EntitiesQuery.kt b/search-service/src/main/kotlin/com/egm/stellio/search/model/EntitiesQuery.kt
index 46ff3343a..1b650bf47 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/model/EntitiesQuery.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/model/EntitiesQuery.kt
@@ -1,9 +1,9 @@
package com.egm.stellio.search.model
import com.egm.stellio.shared.model.EntityTypeSelection
+import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.model.GeoQuery
import com.egm.stellio.shared.model.PaginationQuery
-import com.egm.stellio.shared.util.ExpandedTerm
import java.net.URI
data class EntitiesQuery(
@@ -15,5 +15,5 @@ data class EntitiesQuery(
val paginationQuery: PaginationQuery,
val attrs: Set = emptySet(),
val geoQuery: GeoQuery? = null,
- val context: String
+ val contexts: List
)
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/model/EntityPayload.kt b/search-service/src/main/kotlin/com/egm/stellio/search/model/EntityPayload.kt
index b36ffc818..3a182299e 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/model/EntityPayload.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/model/EntityPayload.kt
@@ -1,23 +1,16 @@
package com.egm.stellio.search.model
+import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.util.AuthContextModel
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy
-import com.egm.stellio.shared.util.ExpandedTerm
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID_TERM
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE_TERM
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_TERM
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedDateTime
-import com.egm.stellio.shared.util.JsonLdUtils.compactTerm
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
import io.r2dbc.postgresql.codec.Json
import java.net.URI
import java.time.ZonedDateTime
@@ -34,50 +27,22 @@ data class EntityPayload(
val payload: Json,
val specificAccessPolicy: SpecificAccessPolicy? = null
) {
- fun serializeProperties(
- withCompactTerms: Boolean = false,
- contexts: List = emptyList()
- ): Map {
+ fun serializeProperties(): Map {
val resultEntity = mutableMapOf()
- // "manual" compaction is used for temporal entities where temporalValues representation and aggregations
- // are badly handled by the normal JSON-LD compaction process (lists of lists are lost mainly)
- if (withCompactTerms) {
- resultEntity[JSONLD_ID_TERM] = entityId.toString()
- // as we are "manually" compacting the type, handle the case where there is just one of it
- // and convey it as a string (instead of a list of 1)
- resultEntity[JSONLD_TYPE_TERM] =
- types.map { compactTerm(it, contexts) }
- .let { if (it.size > 1) it else it.first() }
- scopes?.run {
- resultEntity[NGSILD_SCOPE_TERM] = this
- }
- specificAccessPolicy?.run {
- resultEntity[AuthContextModel.AUTH_TERM_SAP] = mapOf(
- JSONLD_TYPE_TERM to "Property",
- JSONLD_VALUE_TERM to this
- )
- }
-
- resultEntity[NGSILD_CREATED_AT_TERM] = createdAt
- modifiedAt?.run {
- resultEntity[NGSILD_MODIFIED_AT_TERM] = this
- }
- } else {
- resultEntity[JSONLD_ID] = entityId.toString()
- resultEntity[JSONLD_TYPE] = types
- scopes?.run {
- resultEntity[NGSILD_SCOPE_PROPERTY] = this.map {
- mapOf(JSONLD_VALUE to it)
- }
- }
- specificAccessPolicy?.run {
- resultEntity[AuthContextModel.AUTH_PROP_SAP] = buildExpandedProperty(this)
+ resultEntity[JSONLD_ID] = entityId.toString()
+ resultEntity[JSONLD_TYPE] = types
+ scopes?.run {
+ resultEntity[NGSILD_SCOPE_PROPERTY] = this.map {
+ mapOf(JSONLD_VALUE to it)
}
+ }
+ specificAccessPolicy?.run {
+ resultEntity[AuthContextModel.AUTH_PROP_SAP] = buildExpandedPropertyValue(this)
+ }
- resultEntity[NGSILD_CREATED_AT_PROPERTY] = buildNonReifiedDateTime(createdAt)
- modifiedAt?.run {
- resultEntity[NGSILD_MODIFIED_AT_PROPERTY] = buildNonReifiedDateTime(this)
- }
+ resultEntity[NGSILD_CREATED_AT_PROPERTY] = buildNonReifiedTemporalValue(createdAt)
+ modifiedAt?.run {
+ resultEntity[NGSILD_MODIFIED_AT_PROPERTY] = buildNonReifiedTemporalValue(this)
}
return resultEntity
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/model/TemporalEntityAttribute.kt b/search-service/src/main/kotlin/com/egm/stellio/search/model/TemporalEntityAttribute.kt
index 46e198142..189aec73b 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/model/TemporalEntityAttribute.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/model/TemporalEntityAttribute.kt
@@ -1,6 +1,9 @@
package com.egm.stellio.search.model
-import com.egm.stellio.shared.util.ExpandedTerm
+import com.egm.stellio.shared.model.ExpandedTerm
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_GEOPROPERTY_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_TYPE
import io.r2dbc.postgresql.codec.Json
import org.springframework.data.annotation.Id
import java.net.URI
@@ -35,6 +38,13 @@ data class TemporalEntityAttribute(
enum class AttributeType {
Property,
Relationship,
- GeoProperty
+ GeoProperty;
+
+ fun toExpandedName(): String =
+ when (this) {
+ Property -> NGSILD_PROPERTY_TYPE.uri
+ Relationship -> NGSILD_RELATIONSHIP_TYPE.uri
+ GeoProperty -> NGSILD_GEOPROPERTY_TYPE.uri
+ }
}
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/scope/ScopeService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/scope/ScopeService.kt
index 6badab4f6..e0449c352 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/scope/ScopeService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/scope/ScopeService.kt
@@ -9,10 +9,10 @@ import com.egm.stellio.search.model.AttributeInstance.TemporalProperty
import com.egm.stellio.search.model.TemporalEntityAttribute.AttributeValueType
import com.egm.stellio.search.util.*
import com.egm.stellio.shared.model.APIException
+import com.egm.stellio.shared.model.ExpandedAttributeInstances
import com.egm.stellio.shared.model.NgsiLdEntity
import com.egm.stellio.shared.model.OperationNotSupportedException
import com.egm.stellio.shared.model.getScopes
-import com.egm.stellio.shared.util.ExpandedAttributeInstances
import com.egm.stellio.shared.util.INCONSISTENT_VALUES_IN_AGGREGATION_MESSAGE
import com.egm.stellio.shared.util.JsonLdUtils
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilder.kt b/search-service/src/main/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilder.kt
index 5d1e8f346..f4f37d764 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilder.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilder.kt
@@ -3,9 +3,16 @@ package com.egm.stellio.search.scope
import com.egm.stellio.search.model.EntityPayload
import com.egm.stellio.search.model.TemporalEntitiesQuery
import com.egm.stellio.search.model.TemporalQuery
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE_TERM
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE_TERM
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_LIST
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PREFIX
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUES
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedTemporalValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
object TemporalScopeBuilder {
@@ -19,40 +26,23 @@ object TemporalScopeBuilder {
emptyMap()
// if no history but entity has a scope, add an empty scope list (no history in the given time range)
else if (scopeInstances.isEmpty())
- mapOf(NGSILD_SCOPE_TERM to emptyList())
+ mapOf(NGSILD_SCOPE_PROPERTY to emptyList())
else if (temporalEntitiesQuery.withAggregatedValues)
buildScopeAggregatedRepresentation(
scopeInstances,
temporalEntitiesQuery.temporalQuery.aggrMethods!!
)
else if (temporalEntitiesQuery.withTemporalValues)
- mapOf(
- NGSILD_SCOPE_TERM to mapOf(
- JSONLD_TYPE_TERM to "Property",
- "values" to scopeInstances.map {
- it as SimplifiedScopeInstanceResult
- listOf(it.scopes, it.time)
- }
- )
- )
+ buildScopeSimplifiedRepresentation(scopeInstances)
else
- mapOf(
- NGSILD_SCOPE_TERM to scopeInstances.map {
- it as FullScopeInstanceResult
- mapOf(
- JSONLD_TYPE_TERM to "Property",
- JSONLD_VALUE_TERM to it.scopes,
- it.timeproperty to it.time
- )
- }
- )
+ buildScopeFullRepresentation(scopeInstances)
private fun buildScopeAggregatedRepresentation(
scopeHistory: List,
aggrMethods: List
): Map {
val attributeInstance = mutableMapOf(
- JSONLD_TYPE_TERM to "Property"
+ JSONLD_TYPE to listOf(NGSILD_PROPERTY_TYPE.uri)
)
aggrMethods.forEach { aggregate ->
@@ -65,11 +55,51 @@ object TemporalScopeBuilder {
.filter { aggregateResult ->
aggregateResult.aggregate == aggregate
}
- attributeInstance[aggregate.method] = valuesForAggregate.map { aggregateResult ->
- listOf(aggregateResult.value, aggregateResult.startDateTime, aggregateResult.endDateTime)
- }
+ attributeInstance[NGSILD_PREFIX + aggregate.method] =
+ buildExpandedTemporalValue(valuesForAggregate) { aggregateResult ->
+ listOf(
+ mapOf(JSONLD_VALUE to aggregateResult.value),
+ mapOf(JSONLD_VALUE to aggregateResult.startDateTime),
+ mapOf(JSONLD_VALUE to aggregateResult.endDateTime)
+ )
+ }
}
- return mapOf(NGSILD_SCOPE_TERM to attributeInstance.toMap())
+ return mapOf(NGSILD_SCOPE_PROPERTY to attributeInstance.toMap())
+ }
+
+ private fun buildScopeSimplifiedRepresentation(
+ scopeHistory: List
+ ): Map {
+ val attributeInstance = mapOf(
+ JSONLD_TYPE to listOf(NGSILD_PROPERTY_TYPE.uri),
+ NGSILD_PROPERTY_VALUES to
+ buildExpandedTemporalValue(scopeHistory) { scopeInstanceResult ->
+ scopeInstanceResult as SimplifiedScopeInstanceResult
+ listOf(
+ mapOf(
+ JSONLD_LIST to scopeInstanceResult.scopes.map { mapOf(JSONLD_VALUE to it) }
+ ),
+ mapOf(JSONLD_VALUE to scopeInstanceResult.time)
+ )
+ }
+ )
+
+ return mapOf(NGSILD_SCOPE_PROPERTY to attributeInstance)
}
+
+ private fun buildScopeFullRepresentation(
+ scopeHistory: List
+ ): Map =
+ mapOf(
+ NGSILD_SCOPE_PROPERTY to scopeHistory.map { scopeInstanceResult ->
+ scopeInstanceResult as FullScopeInstanceResult
+ mapOf(
+ JSONLD_TYPE to listOf(NGSILD_PROPERTY_TYPE.uri),
+ NGSILD_PROPERTY_VALUE to scopeInstanceResult.scopes.map { mapOf(JSONLD_VALUE to it) },
+ NGSILD_PREFIX + scopeInstanceResult.timeproperty to
+ buildNonReifiedTemporalValue(scopeInstanceResult.time)
+ )
+ }
+ )
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeInstanceService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeInstanceService.kt
index f1d5831d1..378de78ee 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeInstanceService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeInstanceService.kt
@@ -8,10 +8,7 @@ import arrow.fx.coroutines.parMap
import com.egm.stellio.search.model.*
import com.egm.stellio.search.model.AggregatedAttributeInstanceResult.AggregateResult
import com.egm.stellio.search.util.*
-import com.egm.stellio.shared.model.APIException
-import com.egm.stellio.shared.model.OperationNotSupportedException
-import com.egm.stellio.shared.model.ResourceNotFoundException
-import com.egm.stellio.shared.model.toNgsiLdAttribute
+import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.r2dbc.core.bind
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeService.kt
index 95d122747..363cdf661 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/AttributeService.kt
@@ -13,8 +13,8 @@ import com.egm.stellio.search.util.toInt
import com.egm.stellio.search.util.toList
import com.egm.stellio.search.util.toUri
import com.egm.stellio.shared.model.APIException
+import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.model.ResourceNotFoundException
-import com.egm.stellio.shared.util.ExpandedTerm
import com.egm.stellio.shared.util.JsonLdUtils.compactTerm
import com.egm.stellio.shared.util.JsonLdUtils.compactTerms
import com.egm.stellio.shared.util.attributeNotFoundMessage
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityEventService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityEventService.kt
index 2fa67b034..81755d408 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityEventService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityEventService.kt
@@ -6,9 +6,7 @@ import com.egm.stellio.search.model.UpdateOperationResult
import com.egm.stellio.search.model.UpdateResult
import com.egm.stellio.search.model.UpdatedDetails
import com.egm.stellio.shared.model.*
-import com.egm.stellio.shared.util.ExpandedTerm
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.getAttributeFromExpandedAttributes
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.util.getTenantFromContext
import kotlinx.coroutines.CoroutineScope
@@ -254,7 +252,10 @@ class EntityEventService(
when (attributeName) {
JSONLD_TYPE -> Pair(JSONLD_TYPE, serializeObject(jsonLdAttributes[JSONLD_TYPE]!!))
else -> {
- val extractedPayload = getAttributeFromExpandedAttributes(jsonLdAttributes, attributeName, datasetId)!!
+ val extractedPayload = (jsonLdAttributes as ExpandedAttributes).getAttributeFromExpandedAttributes(
+ attributeName,
+ datasetId
+ )!!
Pair(attributeName, serializeObject(extractedPayload))
}
}
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 2f5f33552..a9b3e1cda 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
@@ -34,32 +34,20 @@ class EntityPayloadService(
) {
private val logger = LoggerFactory.getLogger(javaClass)
- @Transactional
- suspend fun createEntity(
- payload: String,
- contexts: List,
- sub: String? = null
- ): Either = either {
- val jsonLdEntity = JsonLdUtils.expandJsonLdEntity(payload, contexts)
- val ngsiLdEntity = jsonLdEntity.toNgsiLdEntity().bind()
-
- createEntity(ngsiLdEntity, jsonLdEntity, sub).bind()
- }
-
@Transactional
suspend fun createEntity(
ngsiLdEntity: NgsiLdEntity,
- jsonLdEntity: JsonLdEntity,
+ expandedEntity: ExpandedEntity,
sub: String? = null
): Either = either {
val createdAt = ZonedDateTime.now(ZoneOffset.UTC)
val attributesMetadata = ngsiLdEntity.prepareTemporalAttributes().bind()
logger.debug("Creating entity {}", ngsiLdEntity.id)
- createEntityPayload(ngsiLdEntity, jsonLdEntity, createdAt, sub = sub).bind()
+ createEntityPayload(ngsiLdEntity, expandedEntity, createdAt, sub = sub).bind()
temporalEntityAttributeService.createEntityTemporalReferences(
ngsiLdEntity,
- jsonLdEntity,
+ expandedEntity,
attributesMetadata,
createdAt,
sub
@@ -69,7 +57,7 @@ class EntityPayloadService(
@Transactional
suspend fun createEntityPayload(
ngsiLdEntity: NgsiLdEntity,
- jsonLdEntity: JsonLdEntity,
+ expandedEntity: ExpandedEntity,
createdAt: ZonedDateTime,
sub: Sub? = null
): Either = either {
@@ -84,7 +72,7 @@ class EntityPayloadService(
.bind("types", ngsiLdEntity.types.toTypedArray())
.bind("scopes", ngsiLdEntity.scopes?.toTypedArray())
.bind("created_at", createdAt)
- .bind("payload", Json.of(serializeObject(jsonLdEntity.populateCreationTimeDate(createdAt).members)))
+ .bind("payload", Json.of(serializeObject(expandedEntity.populateCreationTimeDate(createdAt).members)))
.bind("contexts", ngsiLdEntity.contexts.toTypedArray())
.bind("specific_access_policy", specificAccessPolicy?.toString())
.execute()
@@ -129,7 +117,7 @@ class EntityPayloadService(
suspend fun replaceEntity(
entityId: URI,
ngsiLdEntity: NgsiLdEntity,
- jsonLdEntity: JsonLdEntity,
+ expandedEntity: ExpandedEntity,
sub: String? = null
): Either = either {
val replacedAt = ngsiLdDateTime()
@@ -138,10 +126,10 @@ class EntityPayloadService(
temporalEntityAttributeService.deleteTemporalAttributesOfEntity(entityId)
- replaceEntityPayload(ngsiLdEntity, jsonLdEntity, replacedAt, sub).bind()
+ replaceEntityPayload(ngsiLdEntity, expandedEntity, replacedAt, sub).bind()
temporalEntityAttributeService.createEntityTemporalReferences(
ngsiLdEntity,
- jsonLdEntity,
+ expandedEntity,
attributesMetadata,
replacedAt,
sub
@@ -151,14 +139,14 @@ class EntityPayloadService(
@Transactional
suspend fun replaceEntityPayload(
ngsiLdEntity: NgsiLdEntity,
- jsonLdEntity: JsonLdEntity,
+ expandedEntity: ExpandedEntity,
replacedAt: ZonedDateTime,
sub: Sub? = null
): Either = either {
val specificAccessPolicy = ngsiLdEntity.getSpecificAccessPolicy()?.bind()
val createdAt = retrieveCreatedAt(ngsiLdEntity.id).bind()
val serializedPayload =
- serializeObject(jsonLdEntity.populateReplacementTimeDates(createdAt, replacedAt).members)
+ serializeObject(expandedEntity.populateReplacementTimeDates(createdAt, replacedAt).members)
databaseClient.sql(
"""
@@ -177,7 +165,7 @@ class EntityPayloadService(
.bind("scopes", ngsiLdEntity.scopes?.toTypedArray())
.bind("modified_at", replacedAt)
.bind("payload", Json.of(serializedPayload))
- .bind("contexts", jsonLdEntity.contexts.toTypedArray())
+ .bind("contexts", expandedEntity.contexts.toTypedArray())
.bind("specific_access_policy", specificAccessPolicy?.toString())
.execute()
.map {
@@ -307,7 +295,7 @@ class EntityPayloadService(
accessRightFilter
).let {
if (entitiesQuery.q != null)
- it.wrapToAndClause(buildQQuery(entitiesQuery.q, listOf(entitiesQuery.context)))
+ it.wrapToAndClause(buildQQuery(entitiesQuery.q, entitiesQuery.contexts))
else it
}.let {
if (entitiesQuery.scopeQ != null)
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityTypeService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityTypeService.kt
index 5508d6d40..b8369eda1 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityTypeService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/EntityTypeService.kt
@@ -8,8 +8,8 @@ import com.egm.stellio.search.util.allToMappedList
import com.egm.stellio.search.util.toInt
import com.egm.stellio.search.util.toUri
import com.egm.stellio.shared.model.APIException
+import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.model.ResourceNotFoundException
-import com.egm.stellio.shared.util.ExpandedTerm
import com.egm.stellio.shared.util.JsonLdUtils.compactTerm
import com.egm.stellio.shared.util.JsonLdUtils.compactTerms
import com.egm.stellio.shared.util.typeNotFoundMessage
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/QueryService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/QueryService.kt
index 3ee97c9af..16f04f396 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/QueryService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/QueryService.kt
@@ -9,7 +9,9 @@ import com.egm.stellio.search.model.*
import com.egm.stellio.search.scope.ScopeService
import com.egm.stellio.search.util.TemporalEntityBuilder
import com.egm.stellio.search.util.deserializeAsMap
-import com.egm.stellio.shared.model.*
+import com.egm.stellio.shared.model.APIException
+import com.egm.stellio.shared.model.ExpandedEntity
+import com.egm.stellio.shared.model.ResourceNotFoundException
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
import com.egm.stellio.shared.util.entityOrAttrsNotFoundMessage
import com.egm.stellio.shared.util.wktToGeoJson
@@ -27,7 +29,7 @@ class QueryService(
suspend fun queryEntity(
entityId: URI,
contexts: List
- ): Either =
+ ): Either =
either {
val entityPayload = entityPayloadService.retrieve(entityId).bind()
toJsonLdEntity(entityPayload, contexts)
@@ -36,17 +38,17 @@ class QueryService(
suspend fun queryEntities(
entitiesQuery: EntitiesQuery,
accessRightFilter: () -> String?
- ): Either, Int>> = either {
+ ): Either, Int>> = either {
val entitiesIds = entityPayloadService.queryEntities(entitiesQuery, accessRightFilter)
val count = entityPayloadService.queryEntitiesCount(entitiesQuery, accessRightFilter).bind()
// we can have an empty list of entities with a non-zero count (e.g., offset too high)
if (entitiesIds.isEmpty())
- return@either Pair, Int>(emptyList(), count)
+ return@either Pair, Int>(emptyList(), count)
val entitiesPayloads =
entityPayloadService.retrieve(entitiesIds)
- .map { toJsonLdEntity(it, listOf(entitiesQuery.context)) }
+ .map { toJsonLdEntity(it, entitiesQuery.contexts) }
Pair(entitiesPayloads, count).right().bind()
}
@@ -54,8 +56,8 @@ class QueryService(
suspend fun queryTemporalEntity(
entityId: URI,
temporalEntitiesQuery: TemporalEntitiesQuery,
- contextLink: String
- ): Either = either {
+ contexts: List
+ ): Either = either {
val attrs = temporalEntitiesQuery.entitiesQuery.attrs
val temporalEntityAttributes = temporalEntityAttributeService.getForEntity(entityId, attrs).let {
if (it.isEmpty())
@@ -82,7 +84,7 @@ class QueryService(
TemporalEntityBuilder.buildTemporalEntity(
EntityTemporalResult(entityPayload, scopeHistory, temporalEntityAttributesWithInstances),
temporalEntitiesQuery,
- listOf(contextLink)
+ contexts
)
}
@@ -124,7 +126,7 @@ class QueryService(
suspend fun queryTemporalEntities(
temporalEntitiesQuery: TemporalEntitiesQuery,
accessRightFilter: () -> String?
- ): Either, Int>> = either {
+ ): Either, Int>> = either {
val attrs = temporalEntitiesQuery.entitiesQuery.attrs
val entitiesIds = entityPayloadService.queryEntities(temporalEntitiesQuery.entitiesQuery, accessRightFilter)
val count = entityPayloadService.queryEntitiesCount(temporalEntitiesQuery.entitiesQuery, accessRightFilter)
@@ -132,7 +134,7 @@ class QueryService(
// we can have an empty list of entities with a non-zero count (e.g., offset too high)
if (entitiesIds.isEmpty())
- return@either Pair, Int>(emptyList(), count)
+ return@either Pair, Int>(emptyList(), count)
val temporalEntityAttributes = temporalEntityAttributeService.getForTemporalEntities(
entitiesIds,
@@ -174,7 +176,7 @@ class QueryService(
TemporalEntityBuilder.buildTemporalEntities(
attributeInstancesPerEntityAndAttribute,
temporalEntitiesQuery,
- listOf(temporalEntitiesQuery.entitiesQuery.context)
+ temporalEntitiesQuery.entitiesQuery.contexts
),
count
)
@@ -236,8 +238,8 @@ class QueryService(
private fun toJsonLdEntity(
entityPayload: EntityPayload,
contexts: List
- ): JsonLdEntity {
+ ): ExpandedEntity {
val deserializedEntity = entityPayload.payload.deserializeAsMap()
- return JsonLdEntity(deserializedEntity, contexts)
+ return ExpandedEntity(deserializedEntity, contexts)
}
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeService.kt
index 96a6e4130..2e3559ea9 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeService.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeService.kt
@@ -15,13 +15,9 @@ import com.egm.stellio.shared.util.AttributeType
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PREFIX
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_HAS_OBJECT
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedDateTime
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_OBJECT
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdEntity
-import com.egm.stellio.shared.util.JsonLdUtils.getAttributeFromExpandedAttributes
-import com.egm.stellio.shared.util.JsonLdUtils.getPropertyValueFromMap
-import com.egm.stellio.shared.util.JsonLdUtils.getPropertyValueFromMapAsDateTime
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.savvasdalkitsis.jsonmerger.JsonMerger
import io.r2dbc.postgresql.codec.Json
@@ -125,18 +121,18 @@ class TemporalEntityAttributeService(
sub: String? = null
): Either = either {
val createdAt = ZonedDateTime.now(ZoneOffset.UTC)
- val jsonLdEntity = expandJsonLdEntity(payload, contexts)
- val ngsiLdEntity = jsonLdEntity.toNgsiLdEntity().bind()
+ val expandedEntity = expandJsonLdEntity(payload, contexts)
+ val ngsiLdEntity = expandedEntity.toNgsiLdEntity().bind()
ngsiLdEntity.prepareTemporalAttributes()
.map {
- createEntityTemporalReferences(ngsiLdEntity, jsonLdEntity, it, createdAt, sub).bind()
+ createEntityTemporalReferences(ngsiLdEntity, expandedEntity, it, createdAt, sub).bind()
}.bind()
}
@Transactional
suspend fun createEntityTemporalReferences(
ngsiLdEntity: NgsiLdEntity,
- jsonLdEntity: JsonLdEntity,
+ expandedEntity: ExpandedEntity,
attributesMetadata: List>,
createdAt: ZonedDateTime,
sub: String? = null
@@ -149,8 +145,7 @@ class TemporalEntityAttributeService(
}
.forEach {
val (expandedAttributeName, attributeMetadata) = it
- val attributePayload = getAttributeFromExpandedAttributes(
- jsonLdEntity.members,
+ val attributePayload = expandedEntity.getAttributes().getAttributeFromExpandedAttributes(
expandedAttributeName,
attributeMetadata.datasetId
)!!
@@ -535,8 +530,7 @@ class TemporalEntityAttributeService(
getForEntityAndAttribute(entityUri, ngsiLdAttribute.name, ngsiLdAttributeInstance.datasetId)
.fold({ null }, { it })
val attributeMetadata = ngsiLdAttributeInstance.toTemporalAttributeMetadata().bind()
- val attributePayload = getAttributeFromExpandedAttributes(
- expandedAttributes,
+ val attributePayload = expandedAttributes.getAttributeFromExpandedAttributes(
ngsiLdAttribute.name,
ngsiLdAttributeInstance.datasetId
)!!
@@ -601,8 +595,7 @@ class TemporalEntityAttributeService(
.fold({ null }, { it })
if (currentTea != null) {
val attributeMetadata = ngsiLdAttributeInstance.toTemporalAttributeMetadata().bind()
- val attributePayload = getAttributeFromExpandedAttributes(
- expandedAttributes,
+ val attributePayload = expandedAttributes.getAttributeFromExpandedAttributes(
ngsiLdAttribute.name,
ngsiLdAttributeInstance.datasetId
)!!
@@ -711,8 +704,7 @@ class TemporalEntityAttributeService(
getForEntityAndAttribute(entityUri, ngsiLdAttribute.name, ngsiLdAttributeInstance.datasetId)
.fold({ null }, { it })
val attributeMetadata = ngsiLdAttributeInstance.toTemporalAttributeMetadata().bind()
- val attributePayload = getAttributeFromExpandedAttributes(
- expandedAttributes,
+ val attributePayload = expandedAttributes.getAttributeFromExpandedAttributes(
ngsiLdAttribute.name,
ngsiLdAttributeInstance.datasetId
)!!
@@ -757,8 +749,7 @@ class TemporalEntityAttributeService(
getForEntityAndAttribute(entityUri, ngsiLdAttribute.name, ngsiLdAttributeInstance.datasetId)
.fold({ null }, { it })
val attributeMetadata = ngsiLdAttributeInstance.toTemporalAttributeMetadata().bind()
- val attributePayload = getAttributeFromExpandedAttributes(
- expandedAttributes,
+ val attributePayload = expandedAttributes.getAttributeFromExpandedAttributes(
ngsiLdAttribute.name,
ngsiLdAttributeInstance.datasetId
)!!
@@ -850,13 +841,13 @@ class TemporalEntityAttributeService(
when (tea.attributeType) {
TemporalEntityAttribute.AttributeType.Property ->
Triple(
- valueToStringOrNull(getPropertyValueFromMap(attributePayload, NGSILD_PROPERTY_VALUE)!!),
- valueToDoubleOrNull(getPropertyValueFromMap(attributePayload, NGSILD_PROPERTY_VALUE)!!),
+ valueToStringOrNull(attributePayload.getPropertyValue()!!),
+ valueToDoubleOrNull(attributePayload.getPropertyValue()!!),
null
)
TemporalEntityAttribute.AttributeType.Relationship ->
Triple(
- getPropertyValueFromMap(attributePayload, NGSILD_RELATIONSHIP_HAS_OBJECT)!! as String,
+ attributePayload.getMemberValue(NGSILD_RELATIONSHIP_OBJECT)!! as String,
null,
null
)
@@ -864,7 +855,7 @@ class TemporalEntityAttributeService(
Triple(
null,
null,
- WKTCoordinates(getPropertyValueFromMap(attributePayload, NGSILD_PROPERTY_VALUE)!! as String)
+ WKTCoordinates(attributePayload.getPropertyValue()!! as String)
)
}
@@ -893,7 +884,7 @@ class TemporalEntityAttributeService(
val timeAndProperty =
if (expandedAttributeInstance.containsKey(NGSILD_OBSERVED_AT_PROPERTY))
Pair(
- getPropertyValueFromMapAsDateTime(expandedAttributeInstance, NGSILD_OBSERVED_AT_PROPERTY)!!,
+ expandedAttributeInstance.getMemberValueAsDateTime(NGSILD_OBSERVED_AT_PROPERTY)!!,
AttributeInstance.TemporalProperty.OBSERVED_AT
)
else
@@ -926,7 +917,7 @@ class TemporalEntityAttributeService(
!attributePayload.containsKey(NGSILD_OBSERVED_AT_PROPERTY)
) {
Pair(
- attributePayload.plus(NGSILD_OBSERVED_AT_PROPERTY to buildNonReifiedDateTime(observedAt)),
+ attributePayload.plus(NGSILD_OBSERVED_AT_PROPERTY to buildNonReifiedTemporalValue(observedAt)),
attributeMetadata.copy(observedAt = observedAt)
)
} else Pair(attributePayload, attributeMetadata)
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/util/AttributeInstanceUtils.kt b/search-service/src/main/kotlin/com/egm/stellio/search/util/AttributeInstanceUtils.kt
index 8de606905..a7252aa04 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/util/AttributeInstanceUtils.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/util/AttributeInstanceUtils.kt
@@ -8,10 +8,8 @@ import com.egm.stellio.search.model.AttributeMetadata
import com.egm.stellio.search.model.TemporalEntityAttribute
import com.egm.stellio.search.model.TemporalEntityAttribute.AttributeValueType
import com.egm.stellio.shared.model.*
-import com.egm.stellio.shared.util.ExpandedAttributeInstance
import com.egm.stellio.shared.util.JsonLdUtils.logger
import com.egm.stellio.shared.util.JsonUtils.serializeObject
-import java.net.URI
import java.time.LocalDate
import java.time.LocalTime
import java.time.ZonedDateTime
@@ -84,7 +82,7 @@ fun guessAttributeValueType(
): AttributeValueType =
when (attributeType) {
TemporalEntityAttribute.AttributeType.Property ->
- guessPropertyValueType(expandedAttributeInstance.getPropertyValue()).first
+ guessPropertyValueType(expandedAttributeInstance.getPropertyValue()!!).first
TemporalEntityAttribute.AttributeType.Relationship -> AttributeValueType.URI
TemporalEntityAttribute.AttributeType.GeoProperty -> AttributeValueType.GEOMETRY
}
@@ -107,6 +105,5 @@ fun guessPropertyValueType(
is LocalDate -> Pair(AttributeValueType.DATE, Triple(value.toString(), null, null))
is ZonedDateTime -> Pair(AttributeValueType.DATETIME, Triple(value.toString(), null, null))
is LocalTime -> Pair(AttributeValueType.TIME, Triple(value.toString(), null, null))
- is URI -> Pair(AttributeValueType.URI, Triple(value.toString(), null, null))
else -> Pair(AttributeValueType.STRING, Triple(value.toString(), null, null))
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/util/EntitiesQueryUtils.kt b/search-service/src/main/kotlin/com/egm/stellio/search/util/EntitiesQueryUtils.kt
index b0d2d10e3..f4d86e7a7 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/util/EntitiesQueryUtils.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/util/EntitiesQueryUtils.kt
@@ -15,10 +15,10 @@ import java.util.Optional
fun composeEntitiesQuery(
defaultPagination: ApplicationProperties.Pagination,
requestParams: MultiValueMap,
- contextLink: String
+ contexts: List
): Either = either {
val ids = requestParams.getFirst(QUERY_PARAM_ID)?.split(",").orEmpty().toListOfUri().toSet()
- val typeSelection = expandTypeSelection(requestParams.getFirst(QUERY_PARAM_TYPE), contextLink)
+ val typeSelection = expandTypeSelection(requestParams.getFirst(QUERY_PARAM_TYPE), contexts)
val idPattern = validateIdPattern(requestParams.getFirst(QUERY_PARAM_ID_PATTERN)).bind()
/**
@@ -27,14 +27,14 @@ fun composeEntitiesQuery(
*/
val q = requestParams.getFirst(QUERY_PARAM_Q)?.decode()
val scopeQ = requestParams.getFirst(QUERY_PARAM_SCOPEQ)
- val attrs = parseAndExpandRequestParameter(requestParams.getFirst(QUERY_PARAM_ATTRS), contextLink)
+ val attrs = parseAndExpandRequestParameter(requestParams.getFirst(QUERY_PARAM_ATTRS), contexts)
val paginationQuery = parsePaginationParameters(
requestParams,
defaultPagination.limitDefault,
defaultPagination.limitMax
).bind()
- val geoQuery = parseGeoQueryParameters(requestParams.toSingleValueMap(), contextLink).bind()
+ val geoQuery = parseGeoQueryParameters(requestParams.toSingleValueMap(), contexts).bind()
EntitiesQuery(
ids = ids,
@@ -45,7 +45,7 @@ fun composeEntitiesQuery(
paginationQuery = paginationQuery,
attrs = attrs,
geoQuery = geoQuery,
- context = contextLink
+ contexts = contexts
)
}
@@ -67,22 +67,22 @@ fun composeEntitiesQueryFromPostRequest(
defaultPagination: ApplicationProperties.Pagination,
requestBody: String,
requestParams: MultiValueMap,
- contextLink: String
+ contexts: List
): Either = either {
val query = Query(requestBody).bind()
- composeEntitiesQueryFromPostRequest(defaultPagination, query, requestParams, contextLink).bind()
+ composeEntitiesQueryFromPostRequest(defaultPagination, query, requestParams, contexts).bind()
}
fun composeEntitiesQueryFromPostRequest(
defaultPagination: ApplicationProperties.Pagination,
query: Query,
requestParams: MultiValueMap,
- contextLink: String
+ contexts: List
): Either = either {
val entitySelector = query.entities?.get(0)
- val typeSelection = expandTypeSelection(entitySelector?.typeSelection, contextLink)
+ val typeSelection = expandTypeSelection(entitySelector?.typeSelection, contexts)
val idPattern = validateIdPattern(entitySelector?.idPattern).bind()
- val attrs = parseAndExpandRequestParameter(query.attrs?.joinToString(","), contextLink)
+ val attrs = parseAndExpandRequestParameter(query.attrs?.joinToString(","), contexts)
val geoQuery = if (query.geoQ != null) {
val geoQueryElements = mapOf(
"geometry" to query.geoQ.geometry,
@@ -90,7 +90,7 @@ fun composeEntitiesQueryFromPostRequest(
"georel" to query.geoQ.georel,
"geoproperty" to query.geoQ.geoproperty
)
- parseGeoQueryParameters(geoQueryElements, contextLink).bind()
+ parseGeoQueryParameters(geoQueryElements, contexts).bind()
} else null
val paginationQuery = parsePaginationParameters(
@@ -108,20 +108,20 @@ fun composeEntitiesQueryFromPostRequest(
paginationQuery = paginationQuery,
attrs = attrs,
geoQuery = geoQuery,
- context = contextLink
+ contexts = contexts
)
}
fun composeTemporalEntitiesQuery(
defaultPagination: ApplicationProperties.Pagination,
requestParams: MultiValueMap,
- contextLink: String,
+ contexts: List,
inQueryEntities: Boolean = false
): Either = either {
val entitiesQuery = composeEntitiesQuery(
defaultPagination,
requestParams,
- contextLink
+ contexts
).bind()
if (inQueryEntities)
@@ -154,14 +154,14 @@ fun composeTemporalEntitiesQueryFromPostRequest(
defaultPagination: ApplicationProperties.Pagination,
requestBody: String,
requestParams: MultiValueMap,
- contextLink: String
+ contexts: List
): Either = either {
val query = Query(requestBody).bind()
val entitiesQuery = composeEntitiesQueryFromPostRequest(
defaultPagination,
query,
requestParams,
- contextLink
+ contexts
).bind()
.validateMinimalQueryEntitiesParameters().bind()
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/util/TemporalEntityBuilder.kt b/search-service/src/main/kotlin/com/egm/stellio/search/util/TemporalEntityBuilder.kt
index 524011dc0..f606d6ac6 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/util/TemporalEntityBuilder.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/util/TemporalEntityBuilder.kt
@@ -2,14 +2,24 @@ package com.egm.stellio.search.util
import com.egm.stellio.search.model.*
import com.egm.stellio.search.scope.TemporalScopeBuilder
-import com.egm.stellio.shared.model.CompactedJsonLdEntity
-import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_SUB
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_CONTEXT
+import com.egm.stellio.shared.model.ExpandedEntity
+import com.egm.stellio.shared.model.ExpandedTerm
+import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SUB
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE_TERM
-import com.egm.stellio.shared.util.JsonLdUtils.compactFragment
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_GEOPROPERTY_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_GEOPROPERTY_VALUES
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PREFIX
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUES
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_OBJECTS
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedTemporalValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
+import com.egm.stellio.shared.util.JsonUtils
+import com.egm.stellio.shared.util.wktToGeoJson
typealias SimplifiedTemporalAttribute = Map
typealias TemporalEntityAttributeInstancesResult = Map>
@@ -20,7 +30,7 @@ object TemporalEntityBuilder {
queryResult: List,
temporalEntitiesQuery: TemporalEntitiesQuery,
contexts: List
- ): List =
+ ): List =
queryResult.map {
buildTemporalEntity(it, temporalEntitiesQuery, contexts)
}
@@ -29,11 +39,10 @@ object TemporalEntityBuilder {
entityTemporalResult: EntityTemporalResult,
temporalEntitiesQuery: TemporalEntitiesQuery,
contexts: List
- ): CompactedJsonLdEntity {
+ ): ExpandedEntity {
val temporalAttributes = buildTemporalAttributes(
entityTemporalResult.teaInstancesResult,
- temporalEntitiesQuery,
- contexts
+ temporalEntitiesQuery
)
val scopeAttributeInstances = TemporalScopeBuilder.buildScopeAttributeInstances(
@@ -42,69 +51,47 @@ object TemporalEntityBuilder {
temporalEntitiesQuery
)
- return entityTemporalResult.entityPayload.serializeProperties(
- withCompactTerms = true,
- contexts
- ).plus(temporalAttributes)
+ val expandedTemporalEntity = entityTemporalResult.entityPayload.serializeProperties()
+ .plus(temporalAttributes)
.plus(scopeAttributeInstances)
+ return ExpandedEntity(expandedTemporalEntity, contexts)
}
private fun buildTemporalAttributes(
attributeAndResultsMap: TemporalEntityAttributeInstancesResult,
temporalEntitiesQuery: TemporalEntitiesQuery,
- contexts: List
): Map =
if (temporalEntitiesQuery.withTemporalValues) {
val attributes = buildAttributesSimplifiedRepresentation(attributeAndResultsMap)
mergeSimplifiedTemporalAttributesOnAttributeName(attributes)
- .mapKeys { JsonLdUtils.compactTerm(it.key, contexts) }
- .mapValues {
- if (it.value.size == 1) it.value.first()
- else it.value
- }
} else if (temporalEntitiesQuery.withAggregatedValues) {
val attributes = buildAttributesAggregatedRepresentation(
attributeAndResultsMap,
temporalEntitiesQuery.temporalQuery.aggrMethods!!
)
mergeSimplifiedTemporalAttributesOnAttributeName(attributes)
- .mapKeys { JsonLdUtils.compactTerm(it.key, contexts) }
- .mapValues {
- if (it.value.size == 1) it.value.first()
- else it.value
- }
} else {
mergeFullTemporalAttributesOnAttributeName(attributeAndResultsMap)
- .mapKeys { JsonLdUtils.compactTerm(it.key, contexts) }
.mapValues { (_, attributeInstanceResults) ->
attributeInstanceResults.map { attributeInstanceResult ->
JsonUtils.deserializeObject(attributeInstanceResult.payload)
.let { instancePayload ->
injectSub(temporalEntitiesQuery, attributeInstanceResult, instancePayload)
- }.let { instancePayload ->
- compactAttributeInstance(instancePayload, contexts)
}.let { instancePayload ->
convertGeoProperty(instancePayload)
}.plus(
- attributeInstanceResult.timeproperty to attributeInstanceResult.time.toNgsiLdFormat()
+ Pair(
+ NGSILD_PREFIX + attributeInstanceResult.timeproperty,
+ buildNonReifiedTemporalValue(attributeInstanceResult.time)
+ )
)
}
}
}
- // FIXME in the history of attributes, we have a mix of
- // - compacted fragments (before v2)
- // - expanded fragments (since v2)
- // to avoid un-necessary (expensive) compactions, quick check to see if the fragment
- // is already compacted
- private fun compactAttributeInstance(instancePayload: Map, contexts: List): Map =
- if (instancePayload.containsKey(JSONLD_TYPE))
- compactFragment(instancePayload, contexts).minus(JSONLD_CONTEXT)
- else instancePayload
-
private fun convertGeoProperty(instancePayload: Map): Map =
- if (instancePayload[JSONLD_TYPE_TERM] == "GeoProperty")
- instancePayload.plus(JSONLD_VALUE_TERM to wktToGeoJson(instancePayload[JSONLD_VALUE_TERM]!! as String))
+ if (instancePayload[JSONLD_TYPE] == NGSILD_GEOPROPERTY_TYPE.uri)
+ instancePayload.plus(JSONLD_VALUE to wktToGeoJson(instancePayload[JSONLD_VALUE_TERM]!! as String))
else instancePayload
private fun injectSub(
@@ -113,7 +100,7 @@ object TemporalEntityBuilder {
instancePayload: Map
): Map =
if (temporalEntitiesQuery.withAudit && attributeInstanceResult.sub != null)
- instancePayload.plus(Pair(AUTH_TERM_SUB, attributeInstanceResult.sub))
+ instancePayload.plus(Pair(AUTH_PROP_SUB, buildExpandedPropertyValue(attributeInstanceResult.sub)))
else instancePayload
/**
@@ -129,19 +116,25 @@ object TemporalEntityBuilder {
): Map {
return attributeAndResultsMap.mapValues {
val attributeInstance = mutableMapOf(
- JSONLD_TYPE_TERM to it.key.attributeType.toString()
+ JSONLD_TYPE to listOf(it.key.attributeType.toExpandedName())
)
- it.key.datasetId?.let { datasetId -> attributeInstance["datasetId"] = datasetId }
+ it.key.datasetId?.let { datasetId ->
+ attributeInstance[NGSILD_DATASET_ID_PROPERTY] = buildNonReifiedPropertyValue(datasetId.toString())
+ }
val valuesKey =
when (it.key.attributeType) {
- TemporalEntityAttribute.AttributeType.Property -> "values"
- TemporalEntityAttribute.AttributeType.Relationship -> "objects"
- TemporalEntityAttribute.AttributeType.GeoProperty -> "values"
+ TemporalEntityAttribute.AttributeType.Property -> NGSILD_PROPERTY_VALUES
+ TemporalEntityAttribute.AttributeType.Relationship -> NGSILD_RELATIONSHIP_OBJECTS
+ TemporalEntityAttribute.AttributeType.GeoProperty -> NGSILD_GEOPROPERTY_VALUES
+ }
+ attributeInstance[valuesKey] =
+ buildExpandedTemporalValue(it.value) { attributeInstanceResult ->
+ attributeInstanceResult as SimplifiedAttributeInstanceResult
+ listOf(
+ mapOf(JSONLD_VALUE to attributeInstanceResult.value),
+ mapOf(JSONLD_VALUE to attributeInstanceResult.time)
+ )
}
- attributeInstance[valuesKey] = it.value.map { attributeInstanceResult ->
- attributeInstanceResult as SimplifiedAttributeInstanceResult
- listOf(attributeInstanceResult.value, attributeInstanceResult.time)
- }
attributeInstance.toMap()
}
}
@@ -160,23 +153,31 @@ object TemporalEntityBuilder {
): Map {
return attributeAndResultsMap.mapValues {
val attributeInstance = mutableMapOf(
- JSONLD_TYPE_TERM to it.key.attributeType.toString()
+ JSONLD_TYPE to listOf(it.key.attributeType.toExpandedName())
)
- it.key.datasetId?.let { datasetId -> attributeInstance["datasetId"] = datasetId }
+ it.key.datasetId?.let { datasetId ->
+ attributeInstance[NGSILD_DATASET_ID_PROPERTY] = buildNonReifiedPropertyValue(datasetId.toString())
+ }
+
+ val aggregatedResultsForTEA = it.value
+ .map { attributeInstanceResult ->
+ attributeInstanceResult as AggregatedAttributeInstanceResult
+ attributeInstanceResult.values
+ }
+ .flatten()
aggrMethods.forEach { aggregate ->
- val valuesForAggregate = it.value
- .map { attributeInstanceResult ->
- attributeInstanceResult as AggregatedAttributeInstanceResult
- attributeInstanceResult.values
- }
- .flatten()
- .filter { aggregateResult ->
- aggregateResult.aggregate == aggregate
- }
- attributeInstance[aggregate.method] = valuesForAggregate.map { aggregateResult ->
- listOf(aggregateResult.value, aggregateResult.startDateTime, aggregateResult.endDateTime)
+ val resultsForAggregate = aggregatedResultsForTEA.filter { aggregateResult ->
+ aggregateResult.aggregate.method == aggregate.method
}
+ attributeInstance[NGSILD_PREFIX + aggregate.method] =
+ buildExpandedTemporalValue(resultsForAggregate) { aggregateResult ->
+ listOf(
+ mapOf(JSONLD_VALUE to aggregateResult.value),
+ mapOf(JSONLD_VALUE to aggregateResult.startDateTime),
+ mapOf(JSONLD_VALUE to aggregateResult.endDateTime)
+ )
+ }
}
attributeInstance.toMap()
@@ -221,15 +222,3 @@ object TemporalEntityBuilder {
}
}
}
-
-/**
- * A specific application of sysAttrs option to temporal entities, that only applies it to the entity and not to the
- * attributes. Currently, this is not clear what should be done for attributes who already convey specifically asked
- * temporal information.
- */
-fun CompactedJsonLdEntity.applySysAttrs(includeSysAttrs: Boolean) =
- this.let {
- if (!includeSysAttrs)
- it.minus(JsonLdUtils.NGSILD_SYSATTRS_TERMS)
- else it
- }
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/AttributeHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/AttributeHandler.kt
index 59b125b51..c4d70b75c 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/AttributeHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/AttributeHandler.kt
@@ -3,6 +3,7 @@ package com.egm.stellio.search.web
import arrow.core.raise.either
import com.egm.stellio.search.service.AttributeService
import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdTerm
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
@@ -22,16 +23,16 @@ class AttributeHandler(
@RequestHeader httpHeaders: HttpHeaders,
@RequestParam details: Optional
): ResponseEntity<*> = either {
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val detailedRepresentation = details.orElse(false)
val availableAttribute: Any = if (detailedRepresentation)
- attributeService.getAttributeDetails(listOf(contextLink))
+ attributeService.getAttributeDetails(contexts)
else
- attributeService.getAttributeList(listOf(contextLink))
+ attributeService.getAttributeList(contexts)
- prepareGetSuccessResponse(mediaType, contextLink).body(JsonUtils.serializeObject(availableAttribute))
+ prepareGetSuccessResponseHeaders(mediaType, contexts).body(JsonUtils.serializeObject(availableAttribute))
}.fold(
{ it.toErrorResponse() },
{ it }
@@ -45,14 +46,14 @@ class AttributeHandler(
@RequestHeader httpHeaders: HttpHeaders,
@PathVariable attrId: String
): ResponseEntity<*> = either {
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
- val expandedAttribute = JsonLdUtils.expandJsonLdTerm(attrId.decode(), contextLink)
+ val expandedAttribute = expandJsonLdTerm(attrId.decode(), contexts)
val attributeTypeInfo =
- attributeService.getAttributeTypeInfoByAttribute(expandedAttribute, listOf(contextLink)).bind()
+ attributeService.getAttributeTypeInfoByAttribute(expandedAttribute, contexts).bind()
- prepareGetSuccessResponse(mediaType, contextLink).body(JsonUtils.serializeObject(attributeTypeInfo))
+ prepareGetSuccessResponseHeaders(mediaType, contexts).body(JsonUtils.serializeObject(attributeTypeInfo))
}.fold(
{ it.toErrorResponse() },
{ it }
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/BatchAPIResponses.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/BatchAPIResponses.kt
index 552b52639..421b50bcc 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/BatchAPIResponses.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/BatchAPIResponses.kt
@@ -2,7 +2,7 @@ package com.egm.stellio.search.web
import com.egm.stellio.search.model.UpdateResult
import com.egm.stellio.shared.model.APIException
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.model.NgsiLdEntity
import com.egm.stellio.shared.util.toUri
import com.fasterxml.jackson.annotation.JsonIgnore
@@ -51,7 +51,7 @@ data class BatchEntityError(
val error: MutableList
)
-typealias JsonLdNgsiLdEntity = Pair
+typealias JsonLdNgsiLdEntity = Pair
fun List.extractNgsiLdEntities(): List = this.map { it.second }
fun JsonLdNgsiLdEntity.entityId(): URI = this.second.id
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityAccessControlHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityAccessControlHandler.kt
index 22973ec26..cc5c3b431 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityAccessControlHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityAccessControlHandler.kt
@@ -13,9 +13,10 @@ import com.egm.stellio.shared.util.AuthContextModel.ALL_IAM_RIGHTS
import com.egm.stellio.shared.util.AuthContextModel.ALL_IAM_RIGHTS_TERMS
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SAP
import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_SAP
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_CONTEXT
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntities
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
import com.egm.stellio.shared.util.JsonLdUtils.expandAttributes
-import com.egm.stellio.shared.util.JsonLdUtils.removeContextFromInput
import com.egm.stellio.shared.util.JsonUtils.deserializeAsMap
import com.egm.stellio.shared.web.BaseHandler
import kotlinx.coroutines.reactive.awaitFirst
@@ -45,13 +46,13 @@ class EntityAccessControlHandler(
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contextLink = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val entitiesQuery = composeEntitiesQuery(
applicationProperties.pagination,
params,
- contextLink
+ contexts
).bind()
if (!entitiesQuery.attrs.all { ALL_IAM_RIGHTS.contains(it) })
@@ -59,31 +60,27 @@ class EntityAccessControlHandler(
"The attrs parameter only accepts as a value one or more of $ALL_IAM_RIGHTS_TERMS"
).left().bind>()
- val countAndAuthorizedEntities = authorizationService.getAuthorizedEntities(
+ val (count, entities) = authorizationService.getAuthorizedEntities(
entitiesQuery,
- contextLink,
+ contexts,
sub
).bind()
- if (countAndAuthorizedEntities.first == -1) {
+ if (count == -1) {
return@either ResponseEntity.status(HttpStatus.NO_CONTENT).build()
}
- val compactedEntities = JsonLdUtils.compactEntities(
- countAndAuthorizedEntities.second,
- contextLink,
- mediaType
- )
+ val compactedEntities = compactEntities(entities, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
- countAndAuthorizedEntities.first,
+ count,
"/ngsi-ld/v1/entityAccessControl/entities",
entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -97,41 +94,37 @@ class EntityAccessControlHandler(
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contextLink = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val entitiesQuery = composeEntitiesQuery(
applicationProperties.pagination,
params,
- contextLink
+ contexts
).bind()
- val countAndGroupEntities =
+ val (count, entities) =
authorizationService.getGroupsMemberships(
entitiesQuery.paginationQuery.offset,
entitiesQuery.paginationQuery.limit,
- contextLink,
+ contexts,
sub
).bind()
- if (countAndGroupEntities.first == -1) {
+ if (count == -1) {
return@either ResponseEntity.status(HttpStatus.NO_CONTENT).build()
}
- val compactedEntities = JsonLdUtils.compactEntities(
- countAndGroupEntities.second,
- contextLink,
- mediaType
- )
+ val compactedEntities = compactEntities(entities, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
- countAndGroupEntities.first,
+ count,
"/ngsi-ld/v1/entityAccessControl/groups",
entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -147,40 +140,36 @@ class EntityAccessControlHandler(
authorizationService.userIsAdmin(sub).bind()
- val contextLink = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getAuthzContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val entitiesQuery = composeEntitiesQuery(
applicationProperties.pagination,
params,
- contextLink
+ contexts
).bind()
- val countAndUserEntities =
+ val (count, entities) =
authorizationService.getUsers(
entitiesQuery.paginationQuery.offset,
entitiesQuery.paginationQuery.limit,
- contextLink
+ contexts
).bind()
- if (countAndUserEntities.first == -1) {
+ if (count == -1) {
return@either ResponseEntity.status(HttpStatus.NO_CONTENT).build()
}
- val compactedEntities = JsonLdUtils.compactEntities(
- countAndUserEntities.second,
- contextLink,
- mediaType
- )
+ val compactedEntities = compactEntities(entities, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
- countAndUserEntities.first,
+ count,
"/ngsi-ld/v1/entityAccessControl/users",
entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -294,7 +283,7 @@ class EntityAccessControlHandler(
val body = requestBody.awaitFirst().deserializeAsMap()
val contexts = checkAndGetContext(httpHeaders, body).bind().replaceDefaultContextToAuthzContext()
- val expandedAttribute = expandAttribute(AUTH_TERM_SAP, removeContextFromInput(body), contexts)
+ val expandedAttribute = expandAttribute(AUTH_TERM_SAP, body.minus(JSONLD_CONTEXT), contexts)
if (expandedAttribute.first != AUTH_PROP_SAP)
BadRequestDataException("${expandedAttribute.first} is not authorized property name")
.left().bind>()
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityHandler.kt
index 5a3d8fe0e..161a45669 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityHandler.kt
@@ -13,10 +13,12 @@ import com.egm.stellio.search.util.validateMinimalQueryEntitiesParameters
import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntities
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntity
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
import com.egm.stellio.shared.util.JsonLdUtils.expandAttributes
import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdEntity
-import com.egm.stellio.shared.util.JsonLdUtils.removeContextFromInput
+import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdTerm
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.web.BaseHandler
import org.springframework.http.HttpHeaders
@@ -49,15 +51,15 @@ class EntityHandler(
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
val (body, contexts) = extractPayloadAndContexts(requestBody, httpHeaders).bind()
- val jsonLdEntity = expandJsonLdEntity(body, contexts)
- val ngsiLdEntity = jsonLdEntity.toNgsiLdEntity().bind()
+ val expandedEntity = expandJsonLdEntity(body, contexts)
+ val ngsiLdEntity = expandedEntity.toNgsiLdEntity().bind()
authorizationService.userCanCreateEntities(sub).bind()
entityPayloadService.checkEntityExistence(ngsiLdEntity.id, true).bind()
entityPayloadService.createEntity(
ngsiLdEntity,
- jsonLdEntity,
+ expandedEntity,
sub.getOrNull()
).bind()
authorizationService.createAdminRight(ngsiLdEntity.id, sub).bind()
@@ -143,8 +145,8 @@ class EntityHandler(
val sub = getSubFromSecurityContext()
val (body, contexts) = extractPayloadAndContexts(requestBody, httpHeaders).bind()
- val jsonLdEntity = expandJsonLdEntity(body, contexts)
- val ngsiLdEntity = jsonLdEntity.toNgsiLdEntity().bind()
+ val expandedEntity = expandJsonLdEntity(body, contexts)
+ val ngsiLdEntity = expandedEntity.toNgsiLdEntity().bind()
entityPayloadService.checkEntityExistence(entityId).bind()
authorizationService.userCanUpdateEntity(entityId, sub).bind()
@@ -156,7 +158,7 @@ class EntityHandler(
entityPayloadService.replaceEntity(
entityId,
ngsiLdEntity,
- jsonLdEntity,
+ expandedEntity,
sub.getOrNull()
).bind()
@@ -188,34 +190,30 @@ class EntityHandler(
val mediaType = getApplicableMediaType(httpHeaders).bind()
val sub = getSubFromSecurityContext()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val entitiesQuery = composeEntitiesQuery(
applicationProperties.pagination,
params,
- contextLink
+ contexts
).bind()
.validateMinimalQueryEntitiesParameters().bind()
val accessRightFilter = authorizationService.computeAccessRightFilter(sub)
- val countAndEntities = queryService.queryEntities(entitiesQuery, accessRightFilter).bind()
+ val (entities, count) = queryService.queryEntities(entitiesQuery, accessRightFilter).bind()
- val filteredEntities = JsonLdUtils.filterJsonLdEntitiesOnAttributes(countAndEntities.first, entitiesQuery.attrs)
+ val filteredEntities = entities.filterOnAttributes(entitiesQuery.attrs)
- val compactedEntities = JsonLdUtils.compactEntities(
- filteredEntities,
- contextLink,
- mediaType
- )
+ val compactedEntities = compactEntities(filteredEntities, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
- countAndEntities.second,
+ count,
"/ngsi-ld/v1/entities",
entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -234,29 +232,29 @@ class EntityHandler(
val mediaType = getApplicableMediaType(httpHeaders).bind()
val sub = getSubFromSecurityContext()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val queryParams = composeEntitiesQuery(
applicationProperties.pagination,
params,
- contextLink
+ contexts
).bind()
entityPayloadService.checkEntityExistence(entityId).bind()
authorizationService.userCanReadEntity(entityId, sub).bind()
- val jsonLdEntity = queryService.queryEntity(entityId, listOf(contextLink)).bind()
+ val expandedEntity = queryService.queryEntity(entityId, contexts).bind()
- jsonLdEntity.checkContainsAnyOf(queryParams.attrs).bind()
+ expandedEntity.checkContainsAnyOf(queryParams.attrs).bind()
- val filteredJsonLdEntity = JsonLdEntity(
- JsonLdUtils.filterJsonLdEntityOnAttributes(jsonLdEntity, queryParams.attrs),
- jsonLdEntity.contexts
+ val filteredExpandedEntity = ExpandedEntity(
+ expandedEntity.filterOnAttributes(queryParams.attrs),
+ expandedEntity.contexts
)
- val compactedEntity = JsonLdUtils.compactEntity(filteredJsonLdEntity, contextLink, mediaType).toMutableMap()
+ val compactedEntity = compactEntity(filteredExpandedEntity, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
- prepareGetSuccessResponse(mediaType, contextLink)
+ prepareGetSuccessResponseHeaders(mediaType, contexts)
.body(serializeObject(compactedEntity.toFinalRepresentation(ngsiLdDataRepresentation)))
}.fold(
{ it.toErrorResponse() },
@@ -411,7 +409,7 @@ class EntityHandler(
// We expect an NGSI-LD Attribute Fragment which should be a JSON-LD Object (see 5.4)
val (body, contexts) = extractPayloadAndContexts(requestBody, httpHeaders).bind()
- val expandedAttribute = expandAttribute(attrId, removeContextFromInput(body), contexts)
+ val expandedAttribute = expandAttribute(attrId, body, contexts)
entityPayloadService.partialUpdateAttribute(
entityId,
@@ -458,8 +456,8 @@ class EntityHandler(
val deleteAll = params.getFirst("deleteAll")?.toBoolean() ?: false
val datasetId = params.getFirst("datasetId")?.toUri()
- val contexts = listOf(getContextFromLinkHeaderOrDefault(httpHeaders).bind())
- val expandedAttrId = JsonLdUtils.expandJsonLdTerm(attrId, contexts)
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val expandedAttrId = expandJsonLdTerm(attrId, contexts)
authorizationService.userCanUpdateEntity(entityId, sub).bind()
@@ -504,7 +502,7 @@ class EntityHandler(
entityPayloadService.checkEntityExistence(entityId).bind()
authorizationService.userCanUpdateEntity(entityId, sub).bind()
- val expandedAttribute = expandAttribute(attrId, removeContextFromInput(body), contexts)
+ val expandedAttribute = expandAttribute(attrId, body, contexts)
entityPayloadService.replaceAttribute(entityId, expandedAttribute, sub.getOrNull()).bind()
.let {
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityOperationHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityOperationHandler.kt
index 06647c2c9..9b9bcb911 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityOperationHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityOperationHandler.kt
@@ -12,10 +12,11 @@ import com.egm.stellio.search.util.validateMinimalQueryEntitiesParameters
import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_CONTEXT
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID_TERM
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntities
import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdEntityF
-import com.egm.stellio.shared.util.JsonLdUtils.filterJsonLdEntitiesOnAttributes
import com.egm.stellio.shared.util.JsonUtils.deserializeAsList
import kotlinx.coroutines.reactive.awaitFirst
import org.springframework.http.HttpHeaders
@@ -53,7 +54,7 @@ class EntityOperationHandler(
.checkNamesAreNgsiLdSupported().bind()
.checkContentIsNgsiLdSupported().bind()
checkBatchRequestBody(body).bind()
- checkContext(httpHeaders, body).bind()
+ checkContentType(httpHeaders, body).bind()
val context = getContextFromLinkHeader(httpHeaders.getOrEmpty(HttpHeaders.LINK)).bind()
val (parsedEntities, unparsableEntities) =
expandAndPrepareBatchOfEntities(body, context, httpHeaders.contentType).bind()
@@ -93,7 +94,7 @@ class EntityOperationHandler(
.checkNamesAreNgsiLdSupported().bind()
.checkContentIsNgsiLdSupported().bind()
checkBatchRequestBody(body).bind()
- checkContext(httpHeaders, body).bind()
+ checkContentType(httpHeaders, body).bind()
val context = getContextFromLinkHeader(httpHeaders.getOrEmpty(HttpHeaders.LINK)).bind()
val (parsedEntities, unparsableEntities) =
@@ -158,7 +159,7 @@ class EntityOperationHandler(
.checkNamesAreNgsiLdSupported().bind()
.checkContentIsNgsiLdSupported().bind()
checkBatchRequestBody(body).bind()
- checkContext(httpHeaders, body).bind()
+ checkContentType(httpHeaders, body).bind()
val context = getContextFromLinkHeader(httpHeaders.getOrEmpty(HttpHeaders.LINK)).bind()
val disallowOverwrite = options.map { it == QUERY_PARAM_OPTIONS_NOOVERWRITE_VALUE }.orElse(false)
@@ -258,37 +259,33 @@ class EntityOperationHandler(
@RequestParam params: MultiValueMap
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val entitiesQuery = composeEntitiesQueryFromPostRequest(
applicationProperties.pagination,
requestBody.awaitFirst(),
params,
- contextLink
+ contexts
).bind()
.validateMinimalQueryEntitiesParameters().bind()
val accessRightFilter = authorizationService.computeAccessRightFilter(sub)
- val countAndEntities = queryService.queryEntities(entitiesQuery, accessRightFilter).bind()
+ val (entities, count) = queryService.queryEntities(entitiesQuery, accessRightFilter).bind()
- val filteredEntities = filterJsonLdEntitiesOnAttributes(countAndEntities.first, entitiesQuery.attrs)
+ val filteredEntities = entities.filterOnAttributes(entitiesQuery.attrs)
- val compactedEntities = JsonLdUtils.compactEntities(
- filteredEntities,
- contextLink,
- mediaType
- )
+ val compactedEntities = compactEntities(filteredEntities, contexts)
val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
- countAndEntities.second,
+ count,
"/ngsi-ld/v1/entities",
entitiesQuery.paginationQuery,
LinkedMultiValueMap(),
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -308,7 +305,7 @@ class EntityOperationHandler(
payload.map {
val jsonLdExpansionResult =
if (contentType == JSON_LD_MEDIA_TYPE)
- expandJsonLdEntityF(it)
+ expandJsonLdEntityF(it.minus(JSONLD_CONTEXT), it.extractContexts())
else
expandJsonLdEntityF(it, listOf(context ?: NGSILD_CORE_CONTEXT))
jsonLdExpansionResult
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityTypeHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityTypeHandler.kt
index a120d9e3b..25640601d 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityTypeHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/EntityTypeHandler.kt
@@ -24,16 +24,16 @@ class EntityTypeHandler(
@RequestHeader httpHeaders: HttpHeaders,
@RequestParam details: Optional
): ResponseEntity<*> = either {
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val detailedRepresentation = details.orElse(false)
val availableEntityTypes: Any = if (detailedRepresentation)
- entityTypeService.getEntityTypes(listOf(contextLink))
+ entityTypeService.getEntityTypes(contexts)
else
- entityTypeService.getEntityTypeList(listOf(contextLink))
+ entityTypeService.getEntityTypeList(contexts)
- prepareGetSuccessResponse(mediaType, contextLink)
+ prepareGetSuccessResponseHeaders(mediaType, contexts)
.body(JsonUtils.serializeObject(availableEntityTypes))
}.fold(
{ it.toErrorResponse() },
@@ -48,13 +48,13 @@ class EntityTypeHandler(
@RequestHeader httpHeaders: HttpHeaders,
@PathVariable type: String
): ResponseEntity<*> = either {
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
- val expandedType = expandJsonLdTerm(type.decode(), contextLink)
+ val expandedType = expandJsonLdTerm(type.decode(), contexts)
- val entityTypeInfo = entityTypeService.getEntityTypeInfoByType(expandedType, listOf(contextLink)).bind()
+ val entityTypeInfo = entityTypeService.getEntityTypeInfoByType(expandedType, contexts).bind()
- prepareGetSuccessResponse(mediaType, contextLink).body(JsonUtils.serializeObject(entityTypeInfo))
+ prepareGetSuccessResponseHeaders(mediaType, contexts).body(JsonUtils.serializeObject(entityTypeInfo))
}.fold(
{ it.toErrorResponse() },
{ it }
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityHandler.kt
index c8b636549..81223adf7 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityHandler.kt
@@ -1,21 +1,24 @@
package com.egm.stellio.search.web
+import arrow.core.Either
+import arrow.core.left
import arrow.core.raise.either
+import arrow.core.right
import com.egm.stellio.search.authorization.AuthorizationService
import com.egm.stellio.search.service.*
-import com.egm.stellio.search.util.applySysAttrs
import com.egm.stellio.search.util.composeTemporalEntitiesQuery
import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.addContextsToEntity
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntities
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntity
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
import com.egm.stellio.shared.util.JsonLdUtils.expandAttributes
import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdEntity
-import com.egm.stellio.shared.util.JsonUtils.deserializeAsList
+import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdTerm
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.web.BaseHandler
-import kotlinx.coroutines.reactive.awaitFirst
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
@@ -59,15 +62,15 @@ class TemporalEntityHandler(
authorizationService.userCanCreateEntities(sub).bind()
// create a view of the entity containing only the most recent instance of each attribute
- val jsonLdEntity = JsonLdEntity(
+ val expandedEntity = ExpandedEntity(
sortedJsonLdInstances
.keepFirstInstances()
.addCoreMembers(jsonLdTemporalEntity.id, jsonLdTemporalEntity.types),
contexts
)
- val ngsiLdEntity = jsonLdEntity.toNgsiLdEntity().bind()
+ val ngsiLdEntity = expandedEntity.toNgsiLdEntity().bind()
- entityPayloadService.createEntity(ngsiLdEntity, jsonLdEntity, sub.getOrNull()).bind()
+ entityPayloadService.createEntity(ngsiLdEntity, expandedEntity, sub.getOrNull()).bind()
entityPayloadService.upsertAttributes(
entityUri,
sortedJsonLdInstances.removeFirstInstances(),
@@ -137,30 +140,30 @@ class TemporalEntityHandler(
@RequestParam params: MultiValueMap
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val temporalEntitiesQuery =
- composeTemporalEntitiesQuery(applicationProperties.pagination, params, contextLink, true).bind()
+ composeTemporalEntitiesQuery(applicationProperties.pagination, params, contexts, true).bind()
val accessRightFilter = authorizationService.computeAccessRightFilter(sub)
- val includeSysAttrs = params.contains(QUERY_PARAM_OPTIONS_SYSATTRS_VALUE)
val (temporalEntities, total) = queryService.queryTemporalEntities(
temporalEntitiesQuery,
accessRightFilter
- ).bind().let {
- Pair(it.first.map { it.applySysAttrs(includeSysAttrs) }, it.second)
- }
+ ).bind()
+ val compactedEntities = compactEntities(temporalEntities, contexts)
+
+ val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
- serializeObject(temporalEntities.map { addContextsToEntity(it, listOf(contextLink), mediaType) }),
+ compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
total,
"/ngsi-ld/v1/temporal/entities",
temporalEntitiesQuery.entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
@@ -174,30 +177,31 @@ class TemporalEntityHandler(
suspend fun getForEntity(
@RequestHeader httpHeaders: HttpHeaders,
@PathVariable entityId: URI,
- @RequestParam requestParams: MultiValueMap
+ @RequestParam params: MultiValueMap
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
entityPayloadService.checkEntityExistence(entityId).bind()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
authorizationService.userCanReadEntity(entityId, sub).bind()
val temporalEntitiesQuery =
- composeTemporalEntitiesQuery(applicationProperties.pagination, requestParams, contextLink).bind()
+ composeTemporalEntitiesQuery(applicationProperties.pagination, params, contexts).bind()
- val includeSysAttrs = requestParams.contains(QUERY_PARAM_OPTIONS_SYSATTRS_VALUE)
val temporalEntity = queryService.queryTemporalEntity(
entityId,
temporalEntitiesQuery,
- contextLink
+ contexts
).bind()
- .applySysAttrs(includeSysAttrs)
- prepareGetSuccessResponse(mediaType, contextLink)
- .body(serializeObject(addContextsToEntity(temporalEntity, listOf(contextLink), mediaType)))
+ val compactedEntity = compactEntity(temporalEntity, contexts)
+
+ val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
+ prepareGetSuccessResponseHeaders(mediaType, contexts)
+ .body(serializeObject(compactedEntity.toFinalRepresentation(ngsiLdDataRepresentation)))
}.fold(
{ it.toErrorResponse() },
{ it }
@@ -219,17 +223,14 @@ class TemporalEntityHandler(
@RequestBody requestBody: Mono
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val body = requestBody.awaitFirst().deserializeAsList().first()
- .checkNamesAreNgsiLdSupported().bind()
- .checkContentIsNgsiLdSupported().bind()
- val contexts = checkAndGetContext(httpHeaders, body).bind()
+ val (body, contexts) = extractPayloadAndContexts(requestBody, httpHeaders).bind()
val instanceUri = instanceId.toUri()
attrId.checkNameIsNgsiLdSupported().bind()
entityPayloadService.checkEntityExistence(entityId).bind()
authorizationService.userCanUpdateEntity(entityId, sub).bind()
- val expandedAttribute = expandAttribute(attrId, JsonLdUtils.removeContextFromInput(body), contexts)
+ val expandedAttribute = expandAttribute(attrId, body, contexts)
expandedAttribute.toExpandedAttributes().checkTemporalAttributeInstance().bind()
attributeInstanceService.modifyAttributeInstance(
@@ -288,9 +289,9 @@ class TemporalEntityHandler(
val deleteAll = params.getFirst("deleteAll")?.toBoolean() ?: false
val datasetId = params.getFirst("datasetId")?.toUri()
- val contexts = listOf(getContextFromLinkHeaderOrDefault(httpHeaders).bind())
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
attrId.checkNameIsNgsiLdSupported().bind()
- val expandedAttrId = JsonLdUtils.expandJsonLdTerm(attrId, contexts)
+ val expandedAttrId = expandJsonLdTerm(attrId, contexts)
temporalEntityAttributeService.checkEntityAndAttributeExistence(
entityId,
@@ -328,9 +329,9 @@ class TemporalEntityHandler(
@PathVariable instanceId: URI
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contexts = listOf(getContextFromLinkHeaderOrDefault(httpHeaders).bind())
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
attrId.checkNameIsNgsiLdSupported().bind()
- val expandedAttrId = JsonLdUtils.expandJsonLdTerm(attrId, contexts)
+ val expandedAttrId = expandJsonLdTerm(attrId, contexts)
entityPayloadService.checkEntityExistence(entityId).bind()
@@ -349,4 +350,29 @@ class TemporalEntityHandler(
missingPathErrorResponse(
"Missing entity, attribute or instance id when trying to delete an attribute instance"
)
+
+ private fun ExpandedAttributes.checkTemporalAttributeInstance(): Either =
+ this.values.all { expandedInstances ->
+ expandedInstances.all { expandedAttributePayloadEntry ->
+ expandedAttributePayloadEntry.getMemberValueAsDateTime(NGSILD_OBSERVED_AT_PROPERTY) != null
+ }
+ }.let {
+ if (it) Unit.right()
+ else BadRequestDataException(invalidTemporalInstanceMessage()).left()
+ }
+
+ private fun ExpandedAttributes.sorted(): ExpandedAttributes =
+ this.mapValues {
+ it.value.sortedByDescending { expandedAttributePayloadEntry ->
+ expandedAttributePayloadEntry.getMemberValueAsDateTime(NGSILD_OBSERVED_AT_PROPERTY)
+ }
+ }
+
+ private fun ExpandedAttributes.keepFirstInstances(): ExpandedAttributes =
+ this.mapValues { listOf(it.value.first()) }
+
+ private fun ExpandedAttributes.removeFirstInstances(): ExpandedAttributes =
+ this.mapValues {
+ it.value.drop(1)
+ }
}
diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandler.kt b/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandler.kt
index d0b596ec4..a3675e2e1 100644
--- a/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandler.kt
+++ b/search-service/src/main/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandler.kt
@@ -3,12 +3,11 @@ package com.egm.stellio.search.web
import arrow.core.raise.either
import com.egm.stellio.search.authorization.AuthorizationService
import com.egm.stellio.search.service.QueryService
-import com.egm.stellio.search.util.applySysAttrs
import com.egm.stellio.search.util.composeTemporalEntitiesQueryFromPostRequest
import com.egm.stellio.shared.config.ApplicationProperties
+import com.egm.stellio.shared.model.toFinalRepresentation
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.addContextsToEntity
-import com.egm.stellio.shared.util.JsonUtils.serializeObject
+import com.egm.stellio.shared.util.JsonLdUtils.compactEntities
import kotlinx.coroutines.reactive.awaitFirst
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
@@ -35,7 +34,7 @@ class TemporalEntityOperationsHandler(
@RequestParam params: MultiValueMap
): ResponseEntity<*> = either {
val sub = getSubFromSecurityContext()
- val contextLink = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
+ val contexts = getContextFromLinkHeaderOrDefault(httpHeaders).bind()
val mediaType = getApplicableMediaType(httpHeaders).bind()
val temporalEntitiesQuery =
@@ -43,27 +42,28 @@ class TemporalEntityOperationsHandler(
applicationProperties.pagination,
requestBody.awaitFirst(),
params,
- contextLink
+ contexts
).bind()
val accessRightFilter = authorizationService.computeAccessRightFilter(sub)
- val includeSysAttrs = params.contains(QUERY_PARAM_OPTIONS_SYSATTRS_VALUE)
val (temporalEntities, total) = queryService.queryTemporalEntities(
temporalEntitiesQuery,
accessRightFilter
- ).bind().let {
- Pair(it.first.map { it.applySysAttrs(includeSysAttrs) }, it.second)
- }
+ ).bind()
+
+ val compactedEntities = compactEntities(temporalEntities, contexts)
+
+ val ngsiLdDataRepresentation = parseRepresentations(params, mediaType)
buildQueryResponse(
- serializeObject(temporalEntities.map { addContextsToEntity(it, listOf(contextLink), mediaType) }),
+ compactedEntities.toFinalRepresentation(ngsiLdDataRepresentation),
total,
"/ngsi-ld/v1/temporal/entities",
temporalEntitiesQuery.entitiesQuery.paginationQuery,
params,
mediaType,
- contextLink
+ contexts
)
}.fold(
{ it.toErrorResponse() },
diff --git a/search-service/src/main/kotlin/db/migration/V0_29__JsonLd_migration.kt b/search-service/src/main/kotlin/db/migration/V0_29__JsonLd_migration.kt
index c1be0aabf..bd1f1d7dc 100644
--- a/search-service/src/main/kotlin/db/migration/V0_29__JsonLd_migration.kt
+++ b/search-service/src/main/kotlin/db/migration/V0_29__JsonLd_migration.kt
@@ -8,21 +8,15 @@ import com.egm.stellio.search.util.toTemporalAttributeMetadata
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.AuthContextModel
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SAP
-import com.egm.stellio.shared.util.ExpandedAttributeInstance
-import com.egm.stellio.shared.util.ExpandedTerm
-import com.egm.stellio.shared.util.JsonLdUtils.EGM_BASE_CONTEXT_URL
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_EXPANDED_ENTITY_CORE_MEMBERS
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
import com.egm.stellio.shared.util.JsonLdUtils.expandDeserializedPayload
-import com.egm.stellio.shared.util.JsonLdUtils.extractContextFromInput
-import com.egm.stellio.shared.util.JsonLdUtils.getAttributeFromExpandedAttributes
-import com.egm.stellio.shared.util.JsonLdUtils.getPropertyValueFromMapAsDateTime
-import com.egm.stellio.shared.util.JsonLdUtils.getPropertyValueFromMapAsString
import com.egm.stellio.shared.util.JsonUtils.deserializeAsMap
import com.egm.stellio.shared.util.JsonUtils.serializeObject
+import com.egm.stellio.shared.util.extractContexts
import com.egm.stellio.shared.util.toUri
import kotlinx.coroutines.runBlocking
import org.flywaydb.core.api.migration.BaseJavaMigration
@@ -38,6 +32,8 @@ import java.util.UUID
const val EGM_NO_BRANCH_BASE_CONTEXT_URL =
"https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models"
+const val EGM_BASE_CONTEXT_URL = "https://dataflow.stellio.io/jsonld-contexts"
+
@Suppress("unused")
class V0_29__JsonLd_migration : BaseJavaMigration() {
@@ -77,7 +73,7 @@ class V0_29__JsonLd_migration : BaseJavaMigration() {
}.forEach { (entityId, payload) ->
logger.debug("Migrating entity {}", entityId)
val deserializedPayload = payload.deserializeAsMap()
- val contexts = extractContextFromInput(deserializedPayload)
+ val contexts = deserializedPayload.extractContexts()
.map {
if (contextsToTransform.containsKey(it)) {
contextsToTransform[it]!!
@@ -96,8 +92,11 @@ class V0_29__JsonLd_migration : BaseJavaMigration() {
// extract specific access policy (if any) from the payload to be able to store it in entity_payload
// then remove it from the expanded payload
val specificAccessPolicy =
- getAttributeFromExpandedAttributes(originalExpandedEntity, AUTH_PROP_SAP, null)?.let {
- getPropertyValueFromMapAsString(it, NGSILD_PROPERTY_VALUE)
+ (originalExpandedEntity as ExpandedAttributes).getAttributeFromExpandedAttributes(
+ AUTH_PROP_SAP,
+ null
+ )?.let {
+ it.getMemberValueAsString(NGSILD_PROPERTY_VALUE)
}?.let {
AuthContextModel.SpecificAccessPolicy.valueOf(it)
}
@@ -111,8 +110,7 @@ class V0_29__JsonLd_migration : BaseJavaMigration() {
// as a property of the entity node, so we give them the creation date of the entity
val entityCreationDate =
try {
- getPropertyValueFromMapAsDateTime(
- expandedEntity as Map>,
+ (expandedEntity as Map>).getMemberValueAsDateTime(
NGSILD_CREATED_AT_PROPERTY
) ?: defaultZonedDateTime
} catch (e: DateTimeParseException) {
@@ -135,7 +133,7 @@ class V0_29__JsonLd_migration : BaseJavaMigration() {
""".trimIndent()
)
- val jsonLdEntity = JsonLdEntity(expandedEntity, contexts)
+ val jsonLdEntity = ExpandedEntity(expandedEntity, contexts)
val ngsiLdEntity = runBlocking {
jsonLdEntity.toNgsiLdEntity()
}
@@ -147,8 +145,7 @@ class V0_29__JsonLd_migration : BaseJavaMigration() {
val attributeName = ngsiLdAttribute.name
ngsiLdAttribute.getAttributeInstances().forEach { ngsiLdAttributeInstance ->
val datasetId = ngsiLdAttributeInstance.datasetId
- val attributePayload = getAttributeFromExpandedAttributes(
- jsonLdEntity.members,
+ val attributePayload = jsonLdEntity.getAttributes().getAttributeFromExpandedAttributes(
attributeName,
datasetId
)!!
diff --git a/search-service/src/main/resources/db/migration/V0_38__update_uri_type_to_string_for_properties.sql b/search-service/src/main/resources/db/migration/V0_38__update_uri_type_to_string_for_properties.sql
new file mode 100644
index 000000000..b768a3cb7
--- /dev/null
+++ b/search-service/src/main/resources/db/migration/V0_38__update_uri_type_to_string_for_properties.sql
@@ -0,0 +1,4 @@
+update temporal_entity_attribute
+ set attribute_value_type = 'STRING'
+ where attribute_value_type = 'URI'
+ and attribute_type = 'Property';
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/AuthorizationServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/AuthorizationServiceTests.kt
index 3b2b68514..d99ac0758 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/AuthorizationServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/AuthorizationServiceTests.kt
@@ -3,8 +3,8 @@ package com.egm.stellio.search.authorization
import arrow.core.None
import com.egm.stellio.search.model.EntitiesQuery
import com.egm.stellio.shared.model.PaginationQuery
-import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_COMPOUND_CONTEXT
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
+import com.egm.stellio.shared.util.AUTHZ_TEST_COMPOUND_CONTEXTS
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXTS
import com.egm.stellio.shared.util.shouldSucceedWith
import com.egm.stellio.shared.util.toUri
import io.mockk.spyk
@@ -32,9 +32,9 @@ class AuthorizationServiceTests {
authorizationService.getAuthorizedEntities(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 0),
- context = NGSILD_CORE_CONTEXT
+ contexts = NGSILD_CORE_CONTEXTS
),
- NGSILD_CORE_CONTEXT,
+ NGSILD_CORE_CONTEXTS,
None
).shouldSucceedWith {
assertEquals(-1, it.first)
@@ -47,7 +47,7 @@ class AuthorizationServiceTests {
authorizationService.getGroupsMemberships(
0,
0,
- AUTHORIZATION_COMPOUND_CONTEXT,
+ AUTHZ_TEST_COMPOUND_CONTEXTS,
None
).shouldSucceedWith {
assertEquals(-1, it.first)
@@ -60,7 +60,7 @@ class AuthorizationServiceTests {
authorizationService.getUsers(
0,
0,
- AUTHORIZATION_COMPOUND_CONTEXT
+ AUTHZ_TEST_COMPOUND_CONTEXTS
).shouldSucceedWith {
assertEquals(-1, it.first)
assertEquals(0, it.second.size)
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationServiceTests.kt
index f1b3508c9..88596bef4 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EnabledAuthorizationServiceTests.kt
@@ -8,7 +8,6 @@ import com.egm.stellio.search.model.EntitiesQuery
import com.egm.stellio.shared.model.AccessDeniedException
import com.egm.stellio.shared.model.PaginationQuery
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_COMPOUND_CONTEXT
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_USERNAME
import com.egm.stellio.shared.util.AuthContextModel.AUTH_REL_CAN_WRITE
import com.egm.stellio.shared.util.AuthContextModel.GROUP_ENTITY_PREFIX
@@ -251,7 +250,7 @@ class EnabledAuthorizationServiceTests {
)
coEvery { subjectReferentialService.getCountAllGroups() } returns Either.Right(2)
- enabledAuthorizationService.getGroupsMemberships(0, 2, AUTHORIZATION_COMPOUND_CONTEXT, Some(subjectUuid))
+ enabledAuthorizationService.getGroupsMemberships(0, 2, AUTHZ_TEST_COMPOUND_CONTEXTS, Some(subjectUuid))
.shouldSucceedWith {
assertEquals(2, it.first)
it.second.forEach { jsonLdEntity ->
@@ -276,7 +275,7 @@ class EnabledAuthorizationServiceTests {
)
coEvery { subjectReferentialService.getCountGroups(any()) } returns Either.Right(1)
- enabledAuthorizationService.getGroupsMemberships(0, 2, AUTHORIZATION_COMPOUND_CONTEXT, Some(subjectUuid))
+ enabledAuthorizationService.getGroupsMemberships(0, 2, AUTHZ_TEST_COMPOUND_CONTEXTS, Some(subjectUuid))
.shouldSucceedWith {
assertEquals(1, it.first)
assertEquals(1, it.second[0].types.size)
@@ -310,7 +309,7 @@ class EnabledAuthorizationServiceTests {
)
coEvery { subjectReferentialService.getUsersCount() } returns Either.Right(2)
- enabledAuthorizationService.getUsers(0, 2, AUTHORIZATION_COMPOUND_CONTEXT)
+ enabledAuthorizationService.getUsers(0, 2, AUTHZ_TEST_COMPOUND_CONTEXTS)
.shouldSucceedWith {
assertEquals(2, it.first)
it.second.forEach { jsonLdEntity ->
@@ -344,9 +343,9 @@ class EnabledAuthorizationServiceTests {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 10, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
- contextLink = APIC_COMPOUND_CONTEXT,
+ contexts = APIC_COMPOUND_CONTEXTS,
sub = Some(subjectUuid)
).shouldSucceedWith {
assertEquals(1, it.first)
@@ -400,17 +399,17 @@ class EnabledAuthorizationServiceTests {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 10, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
- contextLink = APIC_COMPOUND_CONTEXT,
+ contexts = APIC_COMPOUND_CONTEXTS,
sub = Some(subjectUuid)
).shouldSucceedWith {
assertEquals(1, it.first)
assertEquals(2, it.second.size)
- val jsonLdEntityWithOtherRights = it.second.find { it.id == entityId01.toString() }!!
- assertEquals(4, jsonLdEntityWithOtherRights.members.size)
- assertTrue(jsonLdEntityWithOtherRights.members.containsKey(AUTH_REL_CAN_WRITE))
+ val expandedEntityWithOtherRights = it.second.find { it.id == entityId01.toString() }!!
+ assertEquals(4, expandedEntityWithOtherRights.members.size)
+ assertTrue(expandedEntityWithOtherRights.members.containsKey(AUTH_REL_CAN_WRITE))
}
coVerify {
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EntityAccessRightsServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EntityAccessRightsServiceTests.kt
index 83c03c1ea..6f88e1847 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EntityAccessRightsServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/EntityAccessRightsServiceTests.kt
@@ -6,14 +6,14 @@ import com.egm.stellio.search.model.EntityPayload
import com.egm.stellio.search.service.EntityPayloadService
import com.egm.stellio.search.support.WithTimescaleContainer
import com.egm.stellio.shared.model.AccessDeniedException
+import com.egm.stellio.shared.model.ExpandedTerm
import com.egm.stellio.shared.model.PaginationQuery
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_COMPOUND_CONTEXT
import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_NAME
import com.egm.stellio.shared.util.AuthContextModel.CLIENT_ENTITY_PREFIX
+import com.egm.stellio.shared.util.AuthContextModel.DATASET_ID_PREFIX
import com.egm.stellio.shared.util.AuthContextModel.GROUP_ENTITY_PREFIX
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy.AUTH_READ
-import com.egm.stellio.shared.util.JsonLdUtils.DATASET_ID_PREFIX
import com.ninjasquad.springmockk.SpykBean
import io.mockk.Called
import io.mockk.coEvery
@@ -544,12 +544,12 @@ class EntityAccessRightsServiceTests : WithTimescaleContainer {
) {
val rawEntity =
if (specificAccessPolicy != null)
- loadMinimalEntityWithSap(entityId, types, specificAccessPolicy, setOf(AUTHORIZATION_COMPOUND_CONTEXT))
+ loadMinimalEntityWithSap(entityId, types, specificAccessPolicy, AUTHZ_TEST_COMPOUND_CONTEXTS)
else loadMinimalEntity(entityId, types)
rawEntity.sampleDataToNgsiLdEntity().map {
entityPayloadService.createEntityPayload(
ngsiLdEntity = it.second,
- jsonLdEntity = it.first,
+ expandedEntity = it.first,
createdAt = ngsiLdDateTime()
)
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/listener/ObservationEventListenerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/listener/ObservationEventListenerTests.kt
index da6ca7edb..e7d289095 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/listener/ObservationEventListenerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/listener/ObservationEventListenerTests.kt
@@ -7,7 +7,8 @@ import com.egm.stellio.search.model.UpdateResult
import com.egm.stellio.search.model.UpdatedDetails
import com.egm.stellio.search.service.EntityEventService
import com.egm.stellio.search.service.EntityPayloadService
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
+import com.egm.stellio.shared.model.NgsiLdEntity
import com.egm.stellio.shared.util.*
import com.ninjasquad.springmockk.MockkBean
import io.mockk.*
@@ -40,7 +41,7 @@ class ObservationEventListenerTests {
val observationEvent = loadSampleData("events/entity/entityCreateEvent.json")
coEvery {
- entityPayloadService.createEntity(any(), any(), any())
+ entityPayloadService.createEntity(any(), any(), any())
} returns Unit.right()
coEvery { entityEventService.publishEntityCreateEvent(any(), any(), any(), any()) } returns Job()
@@ -48,8 +49,8 @@ class ObservationEventListenerTests {
coVerify {
entityPayloadService.createEntity(
+ any(),
any(),
- listOf(APIC_COMPOUND_CONTEXT),
eq("0123456789-1234-5678-987654321")
)
}
@@ -59,7 +60,7 @@ class ObservationEventListenerTests {
eq("0123456789-1234-5678-987654321"),
eq(expectedEntityId),
eq(listOf(BEEHIVE_TYPE)),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
@@ -106,7 +107,7 @@ class ObservationEventListenerTests {
it.updated[0].updateOperationResult == UpdateOperationResult.UPDATED
},
eq(false),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
@@ -143,8 +144,8 @@ class ObservationEventListenerTests {
),
emptyList()
).right()
- val mockedJsonLdEntity = mockkClass(JsonLdEntity::class, relaxed = true)
- every { mockedJsonLdEntity.types } returns listOf(BEEHIVE_TYPE)
+ val mockedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
+ every { mockedExpandedEntity.types } returns listOf(BEEHIVE_TYPE)
coEvery {
entityEventService.publishAttributeChangeEvents(any(), any(), any(), any(), any(), any())
} returns Job()
@@ -173,7 +174,7 @@ class ObservationEventListenerTests {
it.updated[0].datasetId == expectedTemperatureDatasetId
},
eq(true),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/model/EntityModelTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/model/EntityModelTests.kt
index 96729ba09..7ecf93b3f 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/model/EntityModelTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/model/EntityModelTests.kt
@@ -2,7 +2,8 @@ package com.egm.stellio.search.model
import com.egm.stellio.search.support.EMPTY_JSON_PAYLOAD
import com.egm.stellio.shared.util.*
-import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Assertions.assertFalse
+import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.Instant
import java.time.ZoneOffset
@@ -17,7 +18,7 @@ class EntityModelTests {
createdAt = now,
modifiedAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = DEFAULT_CONTEXTS
+ contexts = NGSILD_TEST_CORE_CONTEXTS
)
@Test
@@ -32,28 +33,7 @@ class EntityModelTests {
fun `it should serialize entityPayload with SAP if present`() {
val entityPayloadWithSAP =
entityPayload.copy(specificAccessPolicy = AuthContextModel.SpecificAccessPolicy.AUTH_WRITE)
- val serializedEntity = entityPayloadWithSAP.serializeProperties(false)
+ val serializedEntity = entityPayloadWithSAP.serializeProperties()
assertTrue(serializedEntity.contains(AuthContextModel.AUTH_PROP_SAP))
}
-
- @Test
- fun `it should serialize entityPayload with SAP if present and compact term if specified`() {
- val entityPayloadWithSAP =
- entityPayload.copy(specificAccessPolicy = AuthContextModel.SpecificAccessPolicy.AUTH_WRITE)
- val serializedEntity = entityPayloadWithSAP.serializeProperties(
- withCompactTerms = true,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
- )
- val specificAccessPolicy = mapOf(
- JsonLdUtils.JSONLD_TYPE_TERM to "Property",
- JsonLdUtils.JSONLD_VALUE_TERM to AuthContextModel.SpecificAccessPolicy.AUTH_WRITE
- )
- assertTrue(serializedEntity.contains(AuthContextModel.AUTH_TERM_SAP))
- assertEquals(specificAccessPolicy, serializedEntity[AuthContextModel.AUTH_TERM_SAP])
-
- assertTrue(serializedEntity.contains(JsonLdUtils.JSONLD_ID_TERM))
- assertTrue(serializedEntity.contains(JsonLdUtils.JSONLD_TYPE_TERM))
- assertEquals("urn:ngsi-ld:beehive:01", serializedEntity[JsonLdUtils.JSONLD_ID_TERM])
- assertEquals(BEEHIVE_COMPACT_TYPE, serializedEntity[JsonLdUtils.JSONLD_TYPE_TERM])
- }
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/scope/ScopeServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/scope/ScopeServiceTests.kt
index f343e1d02..119e6f445 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/scope/ScopeServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/scope/ScopeServiceTests.kt
@@ -6,6 +6,7 @@ import com.egm.stellio.search.service.EntityPayloadService
import com.egm.stellio.search.support.WithKafkaContainer
import com.egm.stellio.search.support.WithTimescaleContainer
import com.egm.stellio.search.util.deserializeAsMap
+import com.egm.stellio.shared.model.ExpandedAttributeInstance
import com.egm.stellio.shared.model.PaginationQuery
import com.egm.stellio.shared.model.getScopes
import com.egm.stellio.shared.util.*
@@ -97,7 +98,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
"scope": [${inputScopes.joinToString(",") { "\"$it\"" } }]
}
""".trimIndent(),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
scopeService.update(
@@ -136,7 +137,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(timeproperty = TemporalProperty.MODIFIED_AT),
withTemporalValues = false,
@@ -162,7 +163,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timeproperty = TemporalProperty.MODIFIED_AT,
@@ -192,7 +193,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timeproperty = TemporalProperty.MODIFIED_AT,
@@ -226,7 +227,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timeproperty = TemporalProperty.MODIFIED_AT,
@@ -261,7 +262,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timeproperty = TemporalProperty.MODIFIED_AT,
@@ -302,7 +303,7 @@ class ScopeServiceTests : WithTimescaleContainer, WithKafkaContainer {
TemporalEntitiesQuery(
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 100, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(),
withTemporalValues = false,
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilderTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilderTests.kt
index f5717cf86..c5467fd66 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilderTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/scope/TemporalScopeBuilderTests.kt
@@ -66,7 +66,7 @@ class TemporalScopeBuilderTests {
aggrMethods = listOf(TemporalQuery.Aggregate.SUM, TemporalQuery.Aggregate.AVG)
)
- val scopehHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
+ val scopeHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
entityPayload,
scopeInstances,
TemporalEntitiesQuery(
@@ -80,7 +80,7 @@ class TemporalScopeBuilderTests {
assertJsonPayloadsAreEqual(
loadSampleData("expectations/scope_aggregated_instances.json"),
- JsonUtils.serializeObject(scopehHistory)
+ JsonUtils.serializeObject(scopeHistory)
)
}
@@ -104,7 +104,7 @@ class TemporalScopeBuilderTests {
Instant.now().atZone(ZoneOffset.UTC).minusHours(1),
)
- val scopehHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
+ val scopeHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
entityPayload,
scopeInstances,
TemporalEntitiesQuery(
@@ -118,7 +118,7 @@ class TemporalScopeBuilderTests {
assertJsonPayloadsAreEqual(
loadSampleData("expectations/scope_temporal_values_instances.json"),
- JsonUtils.serializeObject(scopehHistory)
+ JsonUtils.serializeObject(scopeHistory)
)
}
@@ -144,7 +144,7 @@ class TemporalScopeBuilderTests {
Instant.now().atZone(ZoneOffset.UTC).minusHours(1),
)
- val scopehHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
+ val scopeHistory = TemporalScopeBuilder.buildScopeAttributeInstances(
entityPayload,
scopeInstances,
TemporalEntitiesQuery(
@@ -158,7 +158,7 @@ class TemporalScopeBuilderTests {
assertJsonPayloadsAreEqual(
loadSampleData("expectations/scope_full_instances.json"),
- JsonUtils.serializeObject(scopehHistory)
+ JsonUtils.serializeObject(scopeHistory)
)
}
@@ -168,6 +168,6 @@ class TemporalScopeBuilderTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
)
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeInstanceServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeInstanceServiceTests.kt
index 733d27c3a..ef46b42c5 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeInstanceServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeInstanceServiceTests.kt
@@ -2,7 +2,10 @@ package com.egm.stellio.search.service
import com.egm.stellio.search.model.*
import com.egm.stellio.search.support.*
+import com.egm.stellio.shared.model.ExpandedAttributes
import com.egm.stellio.shared.model.ResourceNotFoundException
+import com.egm.stellio.shared.model.addNonReifiedTemporalProperty
+import com.egm.stellio.shared.model.getSingleEntry
import com.egm.stellio.shared.util.*
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
@@ -11,9 +14,7 @@ import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_INSTANCE_ID_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
-import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedDateTime
-import com.egm.stellio.shared.util.JsonUtils.deserializeAsList
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
import com.egm.stellio.shared.util.JsonUtils.deserializeAsMap
import io.mockk.spyk
import io.mockk.verify
@@ -249,8 +250,8 @@ class AttributeInstanceServiceTests : WithTimescaleContainer, WithKafkaContainer
temporalEntityAttribute = temporalEntityAttribute2.id,
time = observedAt,
attributeMetadata = attributeMetadata,
- payload = buildExpandedProperty(attributeMetadata.value!!)
- .addSubAttribute(NGSILD_OBSERVED_AT_PROPERTY, buildNonReifiedDateTime(observedAt))
+ payload = buildExpandedPropertyValue(attributeMetadata.value!!)
+ .addNonReifiedTemporalProperty(NGSILD_OBSERVED_AT_PROPERTY, observedAt)
.getSingleEntry()
)
attributeInstanceService.create(attributeInstance)
@@ -546,10 +547,10 @@ class AttributeInstanceServiceTests : WithTimescaleContainer, WithKafkaContainer
val instanceTemporalFragment =
loadSampleData("fragments/temporal_instance_fragment.jsonld")
- val attributeInstancePayload = mapOf(INCOMING_COMPACT_PROPERTY to instanceTemporalFragment.deserializeAsList())
+ val attributeInstancePayload = mapOf(INCOMING_COMPACT_PROPERTY to instanceTemporalFragment.deserializeAsMap())
val jsonLdAttribute = JsonLdUtils.expandJsonLdFragment(
attributeInstancePayload,
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
) as ExpandedAttributes
val temporalEntitiesQuery = gimmeTemporalEntitiesQuery(
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeServiceTests.kt
index 16c039ffb..703e83ddd 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/AttributeServiceTests.kt
@@ -16,7 +16,8 @@ import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_LOCATION_TERM
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
@@ -42,13 +43,9 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
private val now = Instant.now().atZone(ZoneOffset.UTC)
- private val entityPayload1 = newEntityPayload(
- "urn:ngsi-ld:BeeHive:TESTA",
- listOf(BEEHIVE_TYPE, SENSOR_TYPE),
- DEVICE_COMPACT_TYPE
- )
- private val entityPayload2 = newEntityPayload("urn:ngsi-ld:Sensor:TESTB", listOf(SENSOR_TYPE), DEVICE_COMPACT_TYPE)
- private val entityPayload3 = newEntityPayload("urn:ngsi-ld:Apiary:TESTC", listOf(APIARY_TYPE), DEVICE_COMPACT_TYPE)
+ private val entityPayload1 = newEntityPayload("urn:ngsi-ld:BeeHive:TESTA", listOf(BEEHIVE_TYPE, SENSOR_TYPE))
+ private val entityPayload2 = newEntityPayload("urn:ngsi-ld:Sensor:TESTB", listOf(SENSOR_TYPE))
+ private val entityPayload3 = newEntityPayload("urn:ngsi-ld:Apiary:TESTC", listOf(APIARY_TYPE))
private val temporalEntityAttribute1 = newTemporalEntityAttribute(
"urn:ngsi-ld:BeeHive:TESTA",
INCOMING_PROPERTY,
@@ -97,7 +94,7 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should return an AttributeList`() = runTest {
- val attributeNames = attributeService.getAttributeList(listOf(APIC_COMPOUND_CONTEXT))
+ val attributeNames = attributeService.getAttributeList(APIC_COMPOUND_CONTEXTS)
assertTrue(
attributeNames.attributeList == listOf(
INCOMING_COMPACT_PROPERTY,
@@ -112,13 +109,13 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
fun `it should return an empty list of attributes if no attributes was found`() = runTest {
clearPreviousTemporalEntityAttributesAndObservations()
- val attributeNames = attributeService.getAttributeList(listOf(APIC_COMPOUND_CONTEXT))
+ val attributeNames = attributeService.getAttributeList(APIC_COMPOUND_CONTEXTS)
assert(attributeNames.attributeList.isEmpty())
}
@Test
fun `it should return a list of AttributeDetails`() = runTest {
- val attributeDetails = attributeService.getAttributeDetails(listOf(APIC_COMPOUND_CONTEXT))
+ val attributeDetails = attributeService.getAttributeDetails(APIC_COMPOUND_CONTEXTS)
assertEquals(4, attributeDetails.size)
assertTrue(
attributeDetails.containsAll(
@@ -152,14 +149,14 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
fun `it should return an empty list of AttributeDetails if no attribute was found`() = runTest {
clearPreviousTemporalEntityAttributesAndObservations()
- val attributeDetails = attributeService.getAttributeDetails(listOf(APIC_COMPOUND_CONTEXT))
+ val attributeDetails = attributeService.getAttributeDetails(APIC_COMPOUND_CONTEXTS)
assertTrue(attributeDetails.isEmpty())
}
@Test
fun `it should return an attribute Information by specific attribute`() = runTest {
val attributeTypeInfo =
- attributeService.getAttributeTypeInfoByAttribute(INCOMING_PROPERTY, listOf(APIC_COMPOUND_CONTEXT))
+ attributeService.getAttributeTypeInfoByAttribute(INCOMING_PROPERTY, APIC_COMPOUND_CONTEXTS)
attributeTypeInfo.shouldSucceedWith {
AttributeTypeInfo(
@@ -175,7 +172,7 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should error when type doesn't exist`() = runTest {
val attributeTypeInfo =
- attributeService.getAttributeTypeInfoByAttribute(TEMPERATURE_PROPERTY, listOf(APIC_COMPOUND_CONTEXT))
+ attributeService.getAttributeTypeInfoByAttribute(TEMPERATURE_PROPERTY, APIC_COMPOUND_CONTEXTS)
attributeTypeInfo.shouldFail {
assertEquals(ResourceNotFoundException(attributeNotFoundMessage(TEMPERATURE_PROPERTY)), it)
@@ -233,12 +230,16 @@ class AttributeServiceTests : WithTimescaleContainer, WithKafkaContainer {
.execute()
}
- private fun newEntityPayload(id: String, types: List, contexts: String): EntityPayload =
+ private fun newEntityPayload(
+ id: String,
+ types: List,
+ contexts: List = APIC_COMPOUND_CONTEXTS
+ ): EntityPayload =
EntityPayload(
entityId = toUri(id),
types = types,
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(contexts)
+ contexts = contexts
)
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityEventServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityEventServiceTests.kt
index 1dff12870..695a8e1a0 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityEventServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityEventServiceTests.kt
@@ -9,7 +9,7 @@ import com.egm.stellio.search.support.EMPTY_PAYLOAD
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
-import com.egm.stellio.shared.util.JsonLdUtils.expandJsonLdFragment
+import com.egm.stellio.shared.util.JsonLdUtils.expandAttributes
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.web.DEFAULT_TENANT_URI
import com.ninjasquad.springmockk.MockkBean
@@ -212,7 +212,7 @@ class EntityEventServiceTests {
"$fishNumberTerm": $fishNumberAttributeFragment
}
""".trimIndent()
- val jsonLdAttributes = expandJsonLdFragment(attributesPayload, listOf(AQUAC_COMPOUND_CONTEXT))
+ val jsonLdAttributes = expandAttributes(attributesPayload, listOf(AQUAC_COMPOUND_CONTEXT))
val appendResult = UpdateResult(
listOf(
UpdatedDetails(fishNumberProperty, null, UpdateOperationResult.APPENDED),
@@ -278,7 +278,7 @@ class EntityEventServiceTests {
"$fishNumberTerm": $fishNumberAttributeFragment
}
""".trimIndent()
- val jsonLdAttributes = expandJsonLdFragment(attributesPayload, listOf(AQUAC_COMPOUND_CONTEXT))
+ val jsonLdAttributes = expandAttributes(attributesPayload, listOf(AQUAC_COMPOUND_CONTEXT))
val updateResult = UpdateResult(
updated = arrayListOf(
UpdatedDetails(fishNameProperty, fishName1DatasetUri, UpdateOperationResult.REPLACED),
@@ -338,7 +338,7 @@ class EntityEventServiceTests {
"$fishNameTerm": [$fishNameAttributeFragment, $fishNameAttributeFragment2]
}
""".trimIndent()
- val jsonLdAttributes = expandJsonLdFragment(attributePayload, listOf(AQUAC_COMPOUND_CONTEXT))
+ val jsonLdAttributes = expandAttributes(attributePayload, listOf(AQUAC_COMPOUND_CONTEXT))
val updateResult = UpdateResult(
updated = arrayListOf(
UpdatedDetails(fishNameProperty, fishName1DatasetUri, UpdateOperationResult.REPLACED),
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityOperationServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityOperationServiceTests.kt
index fb0cc6bf6..27c217492 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityOperationServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityOperationServiceTests.kt
@@ -9,8 +9,8 @@ import com.egm.stellio.search.model.UpdateResult
import com.egm.stellio.search.web.BatchEntityError
import com.egm.stellio.search.web.BatchEntitySuccess
import com.egm.stellio.shared.model.BadRequestDataException
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.model.InternalErrorException
-import com.egm.stellio.shared.model.JsonLdEntity
import com.egm.stellio.shared.model.NgsiLdEntity
import com.egm.stellio.shared.util.Sub
import com.egm.stellio.shared.util.toUri
@@ -46,22 +46,22 @@ class EntityOperationServiceTests {
val firstEntityURI = "urn:ngsi-ld:Device:HCMR-AQUABOX1".toUri()
val secondEntityURI = "urn:ngsi-ld:Device:HCMR-AQUABOX2".toUri()
- private lateinit var firstJsonLdEntity: JsonLdEntity
+ private lateinit var firstExpandedEntity: ExpandedEntity
private lateinit var firstEntity: NgsiLdEntity
- private lateinit var secondJsonLdEntity: JsonLdEntity
+ private lateinit var secondExpandedEntity: ExpandedEntity
private lateinit var secondEntity: NgsiLdEntity
val sub: Sub = "60AAEBA3-C0C7-42B6-8CB0-0D30857F210E"
@BeforeEach
fun initNgsiLdEntitiesMocks() {
- firstJsonLdEntity = mockkClass(JsonLdEntity::class, relaxed = true) {
+ firstExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true) {
every { id } returns firstEntityURI.toString()
every { members } returns emptyMap()
}
firstEntity = mockkClass(NgsiLdEntity::class, relaxed = true)
every { firstEntity.id } returns firstEntityURI
- secondJsonLdEntity = mockkClass(JsonLdEntity::class, relaxed = true) {
+ secondExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true) {
every { id } returns secondEntityURI.toString()
every { members } returns emptyMap()
}
@@ -77,13 +77,13 @@ class EntityOperationServiceTests {
val (exist, doNotExist) = entityOperationService.splitEntitiesByExistence(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
)
)
- assertEquals(listOf(Pair(firstJsonLdEntity, firstEntity)), exist)
- assertEquals(listOf(Pair(secondJsonLdEntity, secondEntity)), doNotExist)
+ assertEquals(listOf(Pair(firstExpandedEntity, firstEntity)), exist)
+ assertEquals(listOf(Pair(secondExpandedEntity, secondEntity)), doNotExist)
}
@Test
@@ -105,8 +105,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.create(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
sub
)
@@ -118,10 +118,10 @@ class EntityOperationServiceTests {
assertTrue(batchOperationResult.errors.isEmpty())
coVerify {
- entityPayloadService.createEntity(firstEntity, firstJsonLdEntity, sub)
+ entityPayloadService.createEntity(firstEntity, firstExpandedEntity, sub)
}
coVerify {
- entityPayloadService.createEntity(secondEntity, secondJsonLdEntity, sub)
+ entityPayloadService.createEntity(secondEntity, secondExpandedEntity, sub)
}
}
@@ -134,8 +134,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.create(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
sub
)
@@ -157,8 +157,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.update(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
false,
sub
@@ -189,8 +189,8 @@ class EntityOperationServiceTests {
val batchOperationResult =
entityOperationService.update(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
false,
sub
@@ -224,8 +224,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.update(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
false,
sub
@@ -254,8 +254,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.replace(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
sub
)
@@ -288,8 +288,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.replace(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
sub
)
@@ -318,8 +318,8 @@ class EntityOperationServiceTests {
val batchOperationResult = entityOperationService.replace(
listOf(
- Pair(firstJsonLdEntity, firstEntity),
- Pair(secondJsonLdEntity, secondEntity)
+ Pair(firstExpandedEntity, firstEntity),
+ Pair(secondExpandedEntity, secondEntity)
),
sub
)
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 c5e6b83ca..b8b2a055e 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
@@ -10,11 +10,9 @@ import com.egm.stellio.search.util.deserializeAsMap
import com.egm.stellio.shared.model.AlreadyExistsException
import com.egm.stellio.shared.model.ResourceNotFoundException
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_COMPOUND_CONTEXT
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy.AUTH_READ
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy.AUTH_WRITE
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DEFAULT_VOCAB
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
@@ -84,7 +82,7 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should create an entity payload from string with specificAccessPolicy`() = runTest {
- loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, setOf(AUTHORIZATION_COMPOUND_CONTEXT))
+ loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, AUTHZ_TEST_COMPOUND_CONTEXTS)
.sampleDataToNgsiLdEntity()
.map {
entityPayloadService.createEntityPayload(
@@ -93,7 +91,7 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
now
)
}
- loadMinimalEntityWithSap(entity02Uri, setOf(BEEHIVE_TYPE), AUTH_WRITE, setOf(AUTHORIZATION_COMPOUND_CONTEXT))
+ loadMinimalEntityWithSap(entity02Uri, setOf(BEEHIVE_TYPE), AUTH_WRITE, AUTHZ_TEST_COMPOUND_CONTEXTS)
.sampleDataToNgsiLdEntity()
.map {
entityPayloadService.createEntityPayload(
@@ -148,17 +146,18 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
temporalEntityAttributeService.createEntityTemporalReferences(any(), any(), any(), any(), any())
} returns Unit.right()
- val rawEntity = loadSampleData("beehive_minimal.jsonld")
+ val (expandedEntity, ngsiLdEntity) =
+ loadAndPrepareSampleData("beehive_minimal.jsonld").shouldSucceedAndResult()
entityPayloadService.createEntity(
- rawEntity,
- listOf(APIC_COMPOUND_CONTEXT),
+ ngsiLdEntity,
+ expandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
entityPayloadService.retrieve(beehiveTestCId)
.shouldSucceedWith {
- assertEquals(listOf(APIC_COMPOUND_CONTEXT), it.contexts)
+ assertEquals(APIC_COMPOUND_CONTEXTS, it.contexts)
}
coVerify {
@@ -206,11 +205,12 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
temporalEntityAttributeService.getForEntity(any(), any())
} returns emptyList()
- val createEntityPayload = loadSampleData("beehive_minimal.jsonld")
+ val (expandedEntity, ngsiLdEntity) =
+ loadAndPrepareSampleData("beehive_minimal.jsonld").shouldSucceedAndResult()
entityPayloadService.createEntity(
- createEntityPayload,
- listOf(APIC_COMPOUND_CONTEXT),
+ ngsiLdEntity,
+ expandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
@@ -266,17 +266,18 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
temporalEntityAttributeService.getForEntity(any(), any())
} returns emptyList()
- val createEntityPayload = loadSampleData("beehive_minimal.jsonld")
+ val (expandedEntity, ngsiLdEntity) =
+ loadAndPrepareSampleData("beehive_minimal.jsonld").shouldSucceedAndResult()
entityPayloadService.createEntity(
- createEntityPayload,
- listOf(APIC_COMPOUND_CONTEXT),
+ ngsiLdEntity,
+ expandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
val expandedAttributes = expandAttributes(
loadSampleData("fragments/beehive_merge_entity_multiple_types.jsonld"),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
entityPayloadService.mergeEntity(
@@ -310,17 +311,18 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
temporalEntityAttributeService.getForEntity(any(), any())
} returns emptyList()
- val createEntityPayload = loadSampleData("beehive_minimal.jsonld")
+ val (expandedEntity, ngsiLdEntity) =
+ loadAndPrepareSampleData("beehive_minimal.jsonld").shouldSucceedAndResult()
entityPayloadService.createEntity(
- createEntityPayload,
- listOf(APIC_COMPOUND_CONTEXT),
+ ngsiLdEntity,
+ expandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
val expandedAttributes = expandAttributes(
loadSampleData("fragments/beehive_merge_entity_multiple_types_and_scopes.jsonld"),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
entityPayloadService.mergeEntity(
@@ -353,20 +355,21 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
} returns Unit.right()
coEvery { temporalEntityAttributeService.deleteTemporalAttributesOfEntity(any()) } returns Unit.right()
- val createEntityPayload = loadSampleData("beehive_minimal.jsonld")
+ val (expandedEntity, ngsiLdEntity) =
+ loadAndPrepareSampleData("beehive_minimal.jsonld").shouldSucceedAndResult()
entityPayloadService.createEntity(
- createEntityPayload,
- listOf(APIC_COMPOUND_CONTEXT),
+ ngsiLdEntity,
+ expandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
- val (jsonLdEntity, ngsiLdEntity) = loadSampleData().sampleDataToNgsiLdEntity().shouldSucceedAndResult()
+ val (newExpandedEntity, newNgsiLdEntity) = loadSampleData().sampleDataToNgsiLdEntity().shouldSucceedAndResult()
entityPayloadService.replaceEntity(
beehiveURI,
- ngsiLdEntity,
- jsonLdEntity,
+ newNgsiLdEntity,
+ newExpandedEntity,
"0123456789-1234-5678-987654321"
).shouldSucceed()
@@ -403,7 +406,7 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
val expandedAttribute = expandAttribute(
loadSampleData("fragments/beehive_new_incoming_property.json"),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
entityPayloadService.replaceAttribute(beehiveTestCId, expandedAttribute, "0123456789-1234-5678-987654321")
@@ -434,14 +437,14 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
.hasFieldOrPropertyWithValue("types", listOf(BEEHIVE_TYPE))
.hasFieldOrPropertyWithValue("createdAt", now)
.hasFieldOrPropertyWithValue("modifiedAt", null)
- .hasFieldOrPropertyWithValue("contexts", listOf(NGSILD_CORE_CONTEXT))
+ .hasFieldOrPropertyWithValue("contexts", listOf(NGSILD_TEST_CORE_CONTEXT))
.hasFieldOrPropertyWithValue("specificAccessPolicy", null)
}
}
@Test
fun `it should retrieve an entity payload with specificAccesPolicy`() = runTest {
- loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, setOf(AUTHORIZATION_COMPOUND_CONTEXT))
+ loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, AUTHZ_TEST_COMPOUND_CONTEXTS)
.sampleDataToNgsiLdEntity()
.map {
entityPayloadService.createEntityPayload(
@@ -712,7 +715,7 @@ class EntityPayloadServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should remove a specific access policy from a entity payload`() = runTest {
- loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, setOf(AUTHORIZATION_COMPOUND_CONTEXT))
+ loadMinimalEntityWithSap(entity01Uri, setOf(BEEHIVE_TYPE), AUTH_READ, AUTHZ_TEST_COMPOUND_CONTEXTS)
.sampleDataToNgsiLdEntity()
.map {
entityPayloadService.createEntityPayload(
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityQueryServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityQueryServiceTests.kt
index beee42708..8afce0713 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityQueryServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityQueryServiceTests.kt
@@ -8,7 +8,6 @@ import com.egm.stellio.search.support.WithTimescaleContainer
import com.egm.stellio.shared.model.GeoQuery
import com.egm.stellio.shared.model.PaginationQuery
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_NAME_PROPERTY
import com.ninjasquad.springmockk.MockkBean
import io.mockk.coEvery
import kotlinx.coroutines.runBlocking
@@ -59,11 +58,10 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
runBlocking {
- entityPayloadService.createEntity(firstRawEntity, listOf(APIC_COMPOUND_CONTEXT))
- entityPayloadService.createEntity(secondRawEntity, listOf(APIC_COMPOUND_CONTEXT))
- entityPayloadService.createEntity(thirdRawEntity, listOf(APIC_COMPOUND_CONTEXT))
- entityPayloadService.createEntity(fourthRawEntity, listOf(APIC_COMPOUND_CONTEXT))
- entityPayloadService.createEntity(fifthRawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ listOf(firstRawEntity, secondRawEntity, thirdRawEntity, fourthRawEntity, fifthRawEntity).forEach {
+ val (expandedEntity, ngsiLdEntity) = it.sampleDataToNgsiLdEntity().shouldSucceedAndResult()
+ entityPayloadService.createEntity(ngsiLdEntity, expandedEntity)
+ }
}
}
@@ -100,7 +98,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = types,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -129,7 +127,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
typeSelection = BEEHIVE_TYPE,
scopeQ = scopeQ,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -146,7 +144,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
ids = setOf(entity02Uri),
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 2, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -162,7 +160,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
ids = setOf(entity02Uri, entity05Uri),
typeSelection = "$APIARY_TYPE|$BEEHIVE_TYPE",
paginationQuery = PaginationQuery(limit = 2, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -178,7 +176,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 2, offset = 0),
attrs = setOf(NGSILD_NAME_PROPERTY),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -194,7 +192,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
ids = setOf(entity02Uri),
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 1, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -209,7 +207,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 1, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -224,7 +222,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
typeSelection = BEEHIVE_TYPE,
idPattern = ".*urn:ngsi-ld:BeeHive:01.*",
paginationQuery = PaginationQuery(limit = 1, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -282,7 +280,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
q = q,
paginationQuery = PaginationQuery(limit = 2, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -323,7 +321,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
coordinates
).getOrNull()!!
),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -337,7 +335,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) {
"""
@@ -362,7 +360,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) {
"""
@@ -389,7 +387,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) {
"""
@@ -413,7 +411,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
EntitiesQuery(
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }.shouldSucceedWith { assertEquals(2, it) }
}
@@ -425,7 +423,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
ids = setOf(entity02Uri, entity01Uri),
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 30, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { "entity_payload.entity_id IN ('urn:ngsi-ld:BeeHive:01')" }
.shouldSucceedWith { assertEquals(1, it) }
@@ -439,7 +437,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
ids = setOf(entity02Uri, entity01Uri),
typeSelection = "https://ontology.eglobalmark.com/apic#UnknownType",
paginationQuery = PaginationQuery(limit = 2, offset = 10),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
@@ -454,7 +452,7 @@ class EntityQueryServiceTests : WithTimescaleContainer, WithKafkaContainer {
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(limit = 2, offset = 10),
attrs = setOf("unknownAttribute"),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
) { null }
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityTypeServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityTypeServiceTests.kt
index 5e68807e3..fea6cb905 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityTypeServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/EntityTypeServiceTests.kt
@@ -43,13 +43,9 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
private val now = Instant.now().atZone(ZoneOffset.UTC)
- private val entityPayload1 = newEntityPayload(
- "urn:ngsi-ld:BeeHive:TESTA",
- listOf(BEEHIVE_TYPE, SENSOR_TYPE),
- DEVICE_COMPACT_TYPE
- )
- private val entityPayload2 = newEntityPayload("urn:ngsi-ld:Sensor:TESTB", listOf(SENSOR_TYPE), DEVICE_COMPACT_TYPE)
- private val entityPayload3 = newEntityPayload("urn:ngsi-ld:Apiary:TESTC", listOf(APIARY_TYPE), DEVICE_COMPACT_TYPE)
+ private val entityPayload1 = newEntityPayload("urn:ngsi-ld:BeeHive:TESTA", listOf(BEEHIVE_TYPE, SENSOR_TYPE))
+ private val entityPayload2 = newEntityPayload("urn:ngsi-ld:Sensor:TESTB", listOf(SENSOR_TYPE))
+ private val entityPayload3 = newEntityPayload("urn:ngsi-ld:Apiary:TESTC", listOf(APIARY_TYPE))
private val temporalEntityAttribute1 = newTemporalEntityAttribute(
"urn:ngsi-ld:BeeHive:TESTA",
INCOMING_PROPERTY,
@@ -98,7 +94,7 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should return an EntityTypeList`() = runTest {
- val entityTypes = entityTypeService.getEntityTypeList(listOf(APIC_COMPOUND_CONTEXT))
+ val entityTypes = entityTypeService.getEntityTypeList(APIC_COMPOUND_CONTEXTS)
assertTrue(
entityTypes.typeList == listOf(APIARY_COMPACT_TYPE, BEEHIVE_COMPACT_TYPE, SENSOR_COMPACT_TYPE)
@@ -115,7 +111,7 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should return a list of EntityType`() = runTest {
- val entityTypes = entityTypeService.getEntityTypes(listOf(APIC_COMPOUND_CONTEXT))
+ val entityTypes = entityTypeService.getEntityTypes(APIC_COMPOUND_CONTEXTS)
assertTrue(entityTypes.size == 3)
assertTrue(
@@ -157,7 +153,7 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
fun `it should return an EntityTypeInfo for a specific type`() = runTest {
val entityTypeInfo = entityTypeService.getEntityTypeInfoByType(
BEEHIVE_TYPE,
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
entityTypeInfo.shouldSucceedWith {
@@ -184,7 +180,7 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
@Test
fun `it should error when type doesn't exist`() = runTest {
val entityTypeInfo =
- entityTypeService.getEntityTypeInfoByType(TEMPERATURE_PROPERTY, listOf(APIC_COMPOUND_CONTEXT))
+ entityTypeService.getEntityTypeInfoByType(TEMPERATURE_PROPERTY, APIC_COMPOUND_CONTEXTS)
entityTypeInfo.shouldFail {
assertEquals(ResourceNotFoundException(typeNotFoundMessage(TEMPERATURE_PROPERTY)), it)
@@ -242,12 +238,16 @@ class EntityTypeServiceTests : WithTimescaleContainer, WithKafkaContainer {
.execute()
}
- private fun newEntityPayload(id: String, types: List, contexts: String): EntityPayload =
+ private fun newEntityPayload(
+ id: String,
+ types: List,
+ contexts: List = APIC_COMPOUND_CONTEXTS
+ ): EntityPayload =
EntityPayload(
entityId = toUri(id),
types = types,
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(contexts)
+ contexts = contexts
)
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/QueryServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/QueryServiceTests.kt
index 5e28a05ed..05eb66203 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/QueryServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/QueryServiceTests.kt
@@ -11,6 +11,7 @@ import com.egm.stellio.search.support.buildDefaultQueryParams
import com.egm.stellio.shared.model.PaginationQuery
import com.egm.stellio.shared.model.ResourceNotFoundException
import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_TERM
import com.ninjasquad.springmockk.MockkBean
import io.mockk.coEvery
@@ -55,7 +56,7 @@ class QueryServiceTests {
fun `it should return a JSON-LD entity when querying by id`() = runTest {
coEvery { entityPayloadService.retrieve(any()) } returns gimmeEntityPayload().right()
- queryService.queryEntity(entityUri, listOf(APIC_COMPOUND_CONTEXT))
+ queryService.queryEntity(entityUri, APIC_COMPOUND_CONTEXTS)
.shouldSucceedWith {
assertEquals(entityUri.toString(), it.id)
assertEquals(listOf(BEEHIVE_TYPE), it.types)
@@ -67,7 +68,7 @@ class QueryServiceTests {
fun `it should return an API exception if no entity exists with the given id`() = runTest {
coEvery { entityPayloadService.retrieve(any()) } returns ResourceNotFoundException("").left()
- queryService.queryEntity(entityUri, listOf(APIC_COMPOUND_CONTEXT))
+ queryService.queryEntity(entityUri, APIC_COMPOUND_CONTEXTS)
.shouldFail {
assertTrue(it is ResourceNotFoundException)
}
@@ -114,13 +115,13 @@ class QueryServiceTests {
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 50),
attrs = setOf(INCOMING_PROPERTY, OUTGOING_PROPERTY),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
withTemporalValues = false,
withAudit = false,
withAggregatedValues = false
),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).fold({
assertInstanceOf(ResourceNotFoundException::class.java, it)
assertEquals(
@@ -166,13 +167,13 @@ class QueryServiceTests {
),
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 50),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
withTemporalValues = false,
withAudit = false,
withAggregatedValues = false
),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
)
coVerify {
@@ -198,7 +199,7 @@ class QueryServiceTests {
temporalQuery = TemporalQuery(),
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 50),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
withTemporalValues = false,
withAudit = false,
@@ -221,7 +222,7 @@ class QueryServiceTests {
),
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 50),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
withTemporalValues = false,
withAudit = false,
@@ -249,7 +250,7 @@ class QueryServiceTests {
temporalQuery = TemporalQuery(),
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 0, offset = 50),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
withTemporalValues = false,
withAudit = false,
@@ -295,7 +296,7 @@ class QueryServiceTests {
EntitiesQuery(
typeSelection = "$BEEHIVE_TYPE,$APIARY_TYPE",
paginationQuery = PaginationQuery(limit = 2, offset = 2),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timerel = TemporalQuery.Timerel.BEFORE,
@@ -313,7 +314,7 @@ class QueryServiceTests {
EntitiesQuery(
typeSelection = "$BEEHIVE_TYPE,$APIARY_TYPE",
paginationQuery = PaginationQuery(limit = 2, offset = 2),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
)
attributeInstanceService.search(
@@ -329,7 +330,7 @@ class QueryServiceTests {
EntitiesQuery(
typeSelection = "$BEEHIVE_TYPE,$APIARY_TYPE",
paginationQuery = PaginationQuery(limit = 2, offset = 2),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
any()
)
@@ -363,7 +364,7 @@ class QueryServiceTests {
EntitiesQuery(
typeSelection = "$BEEHIVE_TYPE,$APIARY_TYPE",
paginationQuery = PaginationQuery(limit = 2, offset = 2),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
TemporalQuery(
timerel = TemporalQuery.Timerel.BEFORE,
@@ -382,17 +383,32 @@ class QueryServiceTests {
assertJsonPayloadsAreEqual(
"""
{
- "id": "urn:ngsi-ld:BeeHive:TESTC",
- "type": "BeeHive",
- "createdAt": "$now",
- "incoming": {
- "type": "Property",
- "avg": []
- }
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://uri.etsi.org/ngsi-ld/createdAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "$now"
+ }
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming":[
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/avg":[
+ {
+ "@list":[]
+ }
+ ]
+ }
+ ]
}
""".trimIndent(),
- JsonUtils.serializeObject(it.first[0]),
- setOf(NGSILD_CREATED_AT_TERM)
+ JsonUtils.serializeObject(it.first[0].members),
+ setOf(NGSILD_CREATED_AT_PROPERTY)
)
})
}
@@ -402,7 +418,7 @@ class QueryServiceTests {
entityId = entityUri,
types = listOf(BEEHIVE_TYPE),
createdAt = now,
- contexts = listOf(APIC_COMPOUND_CONTEXT),
+ contexts = APIC_COMPOUND_CONTEXTS,
payload = Json.of(loadSampleData("beehive_expanded.jsonld"))
)
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeServiceTests.kt
index c46bb84cc..b65534660 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeServiceTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityAttributeServiceTests.kt
@@ -56,7 +56,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
entityId = beehiveTestCId,
types = listOf(BEEHIVE_TYPE),
createdAt = Instant.now().atZone(UTC),
- contexts = listOf(APIC_COMPOUND_CONTEXT),
+ contexts = APIC_COMPOUND_CONTEXTS,
payload = EMPTY_JSON_PAYLOAD
)
).block()
@@ -66,7 +66,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
entityId = beehiveTestDId,
types = listOf(BEEHIVE_TYPE),
createdAt = Instant.now().atZone(UTC),
- contexts = listOf(APIC_COMPOUND_CONTEXT),
+ contexts = APIC_COMPOUND_CONTEXTS,
payload = EMPTY_JSON_PAYLOAD
)
).block()
@@ -93,7 +93,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
val temporalEntityAttributes =
temporalEntityAttributeService.getForEntity(
@@ -118,7 +118,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
temporalEntityAttributeService.createEntityTemporalReferences(
rawEntity,
- listOf(APIC_COMPOUND_CONTEXT),
+ APIC_COMPOUND_CONTEXTS,
"0123456789-1234-5678-987654321"
).shouldSucceed()
@@ -170,7 +170,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
temporalEntityAttributeService.createEntityTemporalReferences(
rawEntity,
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
).shouldSucceed()
val teas = temporalEntityAttributeService.getForEntity(beehiveTestCId, emptySet())
@@ -226,7 +226,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
assertThrows("it should have thrown a RuntimeException") {
temporalEntityAttributeService.createEntityTemporalReferences(
rawEntity,
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
).shouldSucceed()
}
@@ -240,7 +240,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val temporalEntityAttribute = temporalEntityAttributeService.getForEntityAndAttribute(
@@ -250,7 +250,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
val createdAt = ngsiLdDateTime()
val newProperty = loadSampleData("fragments/beehive_new_incoming_property.json")
- val expandedAttribute = expandAttribute(newProperty, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttribute = expandAttribute(newProperty, APIC_COMPOUND_CONTEXTS)
val newNgsiLdProperty = expandedAttribute.toNgsiLdAttribute().shouldSucceedAndResult()
temporalEntityAttributeService.replaceAttribute(
temporalEntityAttribute,
@@ -288,7 +288,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val temporalEntityAttribute = temporalEntityAttributeService.getForEntityAndAttribute(
@@ -298,7 +298,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
val mergedAt = ngsiLdDateTime()
val propertyToMerge = loadSampleData("fragments/beehive_mergeAttribute.json")
- val expandedAttribute = expandAttribute(propertyToMerge, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttribute = expandAttribute(propertyToMerge, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.mergeAttribute(
temporalEntityAttribute,
INCOMING_PROPERTY,
@@ -331,7 +331,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
}
}
""".trimIndent(),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
temporalEntityAttributeService.getForEntityAndAttribute(
@@ -352,12 +352,12 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val createdAt = ngsiLdDateTime()
val attributesToMerge = loadSampleData("fragments/beehive_mergeAttributes.json")
- val expandedAttributes = JsonLdUtils.expandAttributes(attributesToMerge, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttributes = JsonLdUtils.expandAttributes(attributesToMerge, APIC_COMPOUND_CONTEXTS)
val ngsiLdAttributes = expandedAttributes.toMap().toNgsiLdAttributes().shouldSucceedAndResult()
temporalEntityAttributeService.mergeEntityAttributes(
beehiveTestCId,
@@ -417,13 +417,13 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val createdAt = ngsiLdDateTime()
val observedAt = ZonedDateTime.parse("2019-12-04T12:00:00.00Z")
val propertyToMerge = loadSampleData("fragments/beehive_mergeAttribute_without_observedAt.json")
- val expandedAttributes = JsonLdUtils.expandAttributes(propertyToMerge, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttributes = JsonLdUtils.expandAttributes(propertyToMerge, APIC_COMPOUND_CONTEXTS)
val ngsiLdAttributes = expandedAttributes.toMap().toNgsiLdAttributes().shouldSucceedAndResult()
temporalEntityAttributeService.mergeEntityAttributes(
beehiveTestCId,
@@ -456,12 +456,12 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val replacedAt = ngsiLdDateTime()
val propertyToReplace = loadSampleData("fragments/beehive_new_incoming_property.json")
- val expandedAttribute = expandAttribute(propertyToReplace, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttribute = expandAttribute(propertyToReplace, APIC_COMPOUND_CONTEXTS)
val ngsiLdAttribute = expandedAttribute.toNgsiLdAttribute().shouldSucceedAndResult()
temporalEntityAttributeService.replaceEntityAttribute(
@@ -490,12 +490,12 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
.shouldSucceed()
val replacedAt = ngsiLdDateTime()
val propertyToReplace = loadSampleData("fragments/beehive_new_unknown_property.json")
- val expandedAttribute = expandAttribute(propertyToReplace, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedAttribute = expandAttribute(propertyToReplace, APIC_COMPOUND_CONTEXTS)
val ngsiLdAttribute = expandedAttribute.toNgsiLdAttribute().shouldSucceedAndResult()
temporalEntityAttributeService.replaceEntityAttribute(
@@ -518,7 +518,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.getForEntityAndAttribute(
beehiveTestCId,
@@ -532,7 +532,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.getForEntityAndAttribute(
beehiveTestCId,
@@ -547,7 +547,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.getForEntityAndAttribute(
beehiveTestCId,
@@ -565,7 +565,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
coEvery { attributeInstanceService.deleteInstancesOfAttribute(any(), any(), any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.deleteTemporalAttribute(
beehiveTestDId,
@@ -588,7 +588,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
coEvery { attributeInstanceService.deleteAllInstancesOfAttribute(any(), any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.deleteTemporalAttribute(
beehiveTestCId,
@@ -611,7 +611,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
temporalEntityAttributeService.checkEntityAndAttributeExistence(beehiveTestCId, INCOMING_PROPERTY)
.shouldSucceed()
@@ -623,7 +623,7 @@ class TemporalEntityAttributeServiceTests : WithTimescaleContainer, WithKafkaCon
coEvery { attributeInstanceService.create(any()) } returns Unit.right()
- temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, listOf(APIC_COMPOUND_CONTEXT))
+ temporalEntityAttributeService.createEntityTemporalReferences(rawEntity, APIC_COMPOUND_CONTEXTS)
val result = temporalEntityAttributeService.checkEntityAndAttributeExistence(beehiveTestCId, "speed")
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/support/BusinessObjectsFactory.kt b/search-service/src/test/kotlin/com/egm/stellio/search/support/BusinessObjectsFactory.kt
index a0b52fbcd..9c4cc2090 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/support/BusinessObjectsFactory.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/support/BusinessObjectsFactory.kt
@@ -2,7 +2,11 @@ package com.egm.stellio.search.support
import com.egm.stellio.search.model.*
import com.egm.stellio.shared.model.PaginationQuery
-import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.model.addNonReifiedTemporalProperty
+import com.egm.stellio.shared.model.getSingleEntry
+import com.egm.stellio.shared.util.APIC_COMPOUND_CONTEXTS
+import com.egm.stellio.shared.util.JsonLdUtils
+import com.egm.stellio.shared.util.ngsiLdDateTime
import java.util.UUID
import kotlin.random.Random
@@ -19,11 +23,8 @@ fun gimmeAttributeInstance(
type = TemporalEntityAttribute.AttributeType.Property,
observedAt = ngsiLdDateTime()
)
- val payload = JsonLdUtils.buildExpandedProperty(attributeMetadata.measuredValue!!)
- .addSubAttribute(
- JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY,
- JsonLdUtils.buildNonReifiedDateTime(attributeMetadata.observedAt!!)
- )
+ val payload = JsonLdUtils.buildExpandedPropertyValue(attributeMetadata.measuredValue!!)
+ .addNonReifiedTemporalProperty(JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY, attributeMetadata.observedAt!!)
.getSingleEntry()
return AttributeInstance(
@@ -44,7 +45,7 @@ fun gimmeTemporalEntitiesQuery(
TemporalEntitiesQuery(
entitiesQuery = EntitiesQuery(
paginationQuery = PaginationQuery(limit = 50, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
temporalQuery = temporalQuery,
withTemporalValues = withTemporalValues,
@@ -55,5 +56,5 @@ fun gimmeTemporalEntitiesQuery(
fun buildDefaultQueryParams(): EntitiesQuery =
EntitiesQuery(
paginationQuery = PaginationQuery(limit = 50, offset = 0),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
)
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/support/TestUtils.kt b/search-service/src/test/kotlin/com/egm/stellio/search/support/TestUtils.kt
index 7baad6380..518b59801 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/support/TestUtils.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/support/TestUtils.kt
@@ -2,10 +2,20 @@ package com.egm.stellio.search.support
import com.egm.stellio.search.model.TemporalEntityAttribute
import com.egm.stellio.shared.model.NgsiLdAttribute
-import com.egm.stellio.shared.model.toNgsiLdAttribute
+import com.egm.stellio.shared.model.toNgsiLdAttributes
import com.egm.stellio.shared.util.AuthContextModel
-import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_SAP
-import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
+import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SAP
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_INSTANCE_ID_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_OBSERVED_AT_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_OBJECT
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import com.egm.stellio.shared.util.shouldSucceedAndResult
import io.r2dbc.postgresql.codec.Json
@@ -16,35 +26,27 @@ fun buildAttributeInstancePayload(
value: Any,
observedAt: ZonedDateTime,
datasetId: URI? = null,
- instanceId: URI? = null,
+ instanceId: URI,
attributeType: TemporalEntityAttribute.AttributeType = TemporalEntityAttribute.AttributeType.Property
-) = serializeObject(
- mapOf(
- "type" to attributeType.toString(),
- "datasetId" to datasetId,
- "instanceId" to instanceId,
- "observedAt" to observedAt
- )
- .let {
- if (attributeType == TemporalEntityAttribute.AttributeType.Property)
- it.plus("value" to value)
- else
- it.plus("object" to value)
- }
+): String = serializeObject(
+ mutableMapOf(
+ JSONLD_TYPE to listOf(attributeType.toExpandedName()),
+ NGSILD_OBSERVED_AT_PROPERTY to buildNonReifiedTemporalValue(observedAt),
+ NGSILD_INSTANCE_ID_PROPERTY to buildNonReifiedPropertyValue(instanceId.toString())
+ ).apply {
+ if (datasetId != null)
+ put(NGSILD_DATASET_ID_PROPERTY, buildNonReifiedPropertyValue(datasetId.toString()))
+ if (attributeType == TemporalEntityAttribute.AttributeType.Property)
+ put(NGSILD_PROPERTY_VALUE, listOf(mapOf(JSONLD_VALUE to value)))
+ else
+ put(NGSILD_RELATIONSHIP_OBJECT, listOf(mapOf(JSONLD_ID to value.toString())))
+ }
)
-suspend fun buildSapAttribute(specificAccessPolicy: AuthContextModel.SpecificAccessPolicy): NgsiLdAttribute {
- val sapPropertyFragment =
- """
- {
- "type": "Property",
- "value": "$specificAccessPolicy"
- }
- """.trimIndent()
-
- return expandAttribute(AUTH_TERM_SAP, sapPropertyFragment, AuthContextModel.AUTHORIZATION_API_DEFAULT_CONTEXTS)
- .toNgsiLdAttribute().shouldSucceedAndResult()
-}
+suspend fun buildSapAttribute(specificAccessPolicy: AuthContextModel.SpecificAccessPolicy): NgsiLdAttribute =
+ mapOf(AUTH_PROP_SAP to buildExpandedPropertyValue(specificAccessPolicy))
+ .toNgsiLdAttributes()
+ .shouldSucceedAndResult()[0]
const val EMPTY_PAYLOAD = "{}"
val EMPTY_JSON_PAYLOAD = Json.of(EMPTY_PAYLOAD)
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/util/AttributeInstanceUtilsTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/util/AttributeInstanceUtilsTests.kt
index ebe8938aa..a44cb9e32 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/util/AttributeInstanceUtilsTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/util/AttributeInstanceUtilsTests.kt
@@ -1,8 +1,9 @@
package com.egm.stellio.search.util
import com.egm.stellio.search.model.TemporalEntityAttribute
-import com.egm.stellio.shared.util.DEFAULT_CONTEXTS
import com.egm.stellio.shared.util.JsonLdUtils.expandAttribute
+import com.egm.stellio.shared.util.NGSILD_TEST_CORE_CONTEXTS
+import com.egm.stellio.shared.util.ngsiLdDateTime
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -14,25 +15,106 @@ import java.time.LocalTime
class AttributeInstanceUtilsTests {
@Test
- fun `it should guess the value type of a property`() = runTest {
+ fun `it should guess the value type of a string property`() = runTest {
val expandedStringProperty = expandAttribute(
"property",
mapOf("type" to "Property", "value" to "A string"),
- DEFAULT_CONTEXTS
+ NGSILD_TEST_CORE_CONTEXTS
)
assertEquals(
- guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedStringProperty.second[0]),
- TemporalEntityAttribute.AttributeValueType.STRING
+ TemporalEntityAttribute.AttributeValueType.STRING,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedStringProperty.second[0])
)
+ }
+
+ @Test
+ fun `it should guess the value type of a double property`() = runTest {
+ val expandedBooleanProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to 20.0),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.NUMBER,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedBooleanProperty.second[0])
+ )
+ }
+
+ @Test
+ fun `it should guess the value type of an int property`() = runTest {
+ val expandedBooleanProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to 20),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.NUMBER,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedBooleanProperty.second[0])
+ )
+ }
+
+ @Test
+ fun `it should guess the value type of a boolean property`() = runTest {
+ val expandedBooleanProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to true),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.BOOLEAN,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedBooleanProperty.second[0])
+ )
+ }
+
+ @Test
+ fun `it should guess the value type of an object property`() = runTest {
+ val expandedListProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to mapOf("key1" to "value1", "key2" to "value3")),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.OBJECT,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedListProperty.second[0])
+ )
+ }
+ @Test
+ fun `it should guess the value type of an array property`() = runTest {
+ val expandedListProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to listOf("A", "B")),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.ARRAY,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedListProperty.second[0])
+ )
+ }
+
+ @Test
+ fun `it should guess the value type of a time property`() = runTest {
val expandedTimeProperty = expandAttribute(
"property",
- mapOf("type" to "Property", "value" to LocalTime.now()),
- DEFAULT_CONTEXTS
+ mapOf("type" to "Property", "value" to mapOf("@type" to "Time", "@value" to LocalTime.now())),
+ NGSILD_TEST_CORE_CONTEXTS
)
assertEquals(
- guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedTimeProperty.second[0]),
- TemporalEntityAttribute.AttributeValueType.TIME
+ TemporalEntityAttribute.AttributeValueType.TIME,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedTimeProperty.second[0])
+ )
+ }
+
+ @Test
+ fun `it should guess the value type of a datetime property`() = runTest {
+ val expandedTimeProperty = expandAttribute(
+ "property",
+ mapOf("type" to "Property", "value" to mapOf("@type" to "DateTime", "@value" to ngsiLdDateTime())),
+ NGSILD_TEST_CORE_CONTEXTS
+ )
+ assertEquals(
+ TemporalEntityAttribute.AttributeValueType.DATETIME,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.Property, expandedTimeProperty.second[0])
)
}
@@ -44,11 +126,11 @@ class AttributeInstanceUtilsTests {
"type" to "GeoProperty",
"value" to mapOf("type" to "Point", "coordinates" to listOf(0, 0))
),
- DEFAULT_CONTEXTS
+ NGSILD_TEST_CORE_CONTEXTS
)
assertEquals(
- guessAttributeValueType(TemporalEntityAttribute.AttributeType.GeoProperty, expandedGeoProperty.second[0]),
- TemporalEntityAttribute.AttributeValueType.GEOMETRY
+ TemporalEntityAttribute.AttributeValueType.GEOMETRY,
+ guessAttributeValueType(TemporalEntityAttribute.AttributeType.GeoProperty, expandedGeoProperty.second[0])
)
}
@@ -57,14 +139,14 @@ class AttributeInstanceUtilsTests {
val expandedGeoRelationship = expandAttribute(
"relationship",
mapOf("type" to "Relationship", "value" to URI("urn:ngsi-ld")),
- DEFAULT_CONTEXTS
+ NGSILD_TEST_CORE_CONTEXTS
)
assertEquals(
+ TemporalEntityAttribute.AttributeValueType.URI,
guessAttributeValueType(
TemporalEntityAttribute.AttributeType.Relationship,
expandedGeoRelationship.second[0]
- ),
- TemporalEntityAttribute.AttributeValueType.URI
+ )
)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/util/EntitiesQueryUtilsTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/util/EntitiesQueryUtilsTests.kt
index 6027f7b76..49698071e 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/util/EntitiesQueryUtilsTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/util/EntitiesQueryUtilsTests.kt
@@ -6,7 +6,6 @@ import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.BadRequestDataException
import com.egm.stellio.shared.model.GeoQuery
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DEFAULT_VOCAB
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_OBSERVATION_SPACE_PROPERTY
import io.mockk.every
@@ -28,7 +27,7 @@ class EntitiesQueryUtilsTests {
val entitiesQuery = composeEntitiesQuery(
ApplicationProperties.Pagination(1, 20),
requestParams,
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldSucceedAndResult()
assertEquals("$BEEHIVE_TYPE,$APIARY_TYPE", entitiesQuery.typeSelection)
@@ -51,7 +50,7 @@ class EntitiesQueryUtilsTests {
val entitiesQuery = composeEntitiesQuery(
ApplicationProperties.Pagination(30, 100),
requestParams,
- NGSILD_CORE_CONTEXT
+ NGSILD_TEST_CORE_CONTEXTS
).shouldSucceedAndResult()
assertEquals("speed>50;foodName==dietary fibres", entitiesQuery.q)
@@ -63,7 +62,7 @@ class EntitiesQueryUtilsTests {
val entitiesQuery = composeEntitiesQuery(
ApplicationProperties.Pagination(30, 100),
requestParams,
- NGSILD_CORE_CONTEXT
+ NGSILD_TEST_CORE_CONTEXTS
).shouldSucceedAndResult()
assertEquals(null, entitiesQuery.typeSelection)
@@ -123,7 +122,7 @@ class EntitiesQueryUtilsTests {
ApplicationProperties.Pagination(30, 100),
query,
LinkedMultiValueMap(),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldSucceedWith {
assertEquals(setOf("urn:ngsi-ld:BeeHive:TESTC".toUri()), it.ids)
assertEquals("urn:ngsi-ld:BeeHive:*", it.idPattern)
@@ -155,7 +154,7 @@ class EntitiesQueryUtilsTests {
ApplicationProperties.Pagination(30, 100),
query,
LinkedMultiValueMap(),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldSucceedWith {
assertEquals(BEEHIVE_TYPE, it.typeSelection)
assertEquals(setOf("${NGSILD_DEFAULT_VOCAB}attr1"), it.attrs)
@@ -176,7 +175,7 @@ class EntitiesQueryUtilsTests {
ApplicationProperties.Pagination(30, 100),
query,
LinkedMultiValueMap(),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldFailWith {
it is BadRequestDataException &&
it.message == "The type parameter should be equals to 'Query'"
@@ -196,7 +195,7 @@ class EntitiesQueryUtilsTests {
ApplicationProperties.Pagination(30, 100),
query,
LinkedMultiValueMap(),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldFailWith {
it is BadRequestDataException &&
it.message.startsWith("The supplied query could not be parsed")
@@ -216,7 +215,7 @@ class EntitiesQueryUtilsTests {
ApplicationProperties.Pagination(30, 100),
query,
LinkedMultiValueMap(),
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldFailWith {
it is BadRequestDataException &&
it.message.startsWith("The supplied query could not be parsed")
@@ -233,7 +232,7 @@ class EntitiesQueryUtilsTests {
composeTemporalEntitiesQuery(
pagination,
queryParams,
- APIC_COMPOUND_CONTEXT,
+ APIC_COMPOUND_CONTEXTS,
true
).shouldFail {
assertInstanceOf(BadRequestDataException::class.java, it)
@@ -253,7 +252,7 @@ class EntitiesQueryUtilsTests {
composeTemporalEntitiesQuery(
pagination,
queryParams,
- APIC_COMPOUND_CONTEXT
+ APIC_COMPOUND_CONTEXTS
).shouldFail {
assertInstanceOf(BadRequestDataException::class.java, it)
assertEquals("'timerel' and 'time' must be used in conjunction", it.message)
@@ -272,7 +271,7 @@ class EntitiesQueryUtilsTests {
composeTemporalEntitiesQuery(
pagination,
queryParams,
- APIC_COMPOUND_CONTEXT,
+ APIC_COMPOUND_CONTEXTS,
true
).shouldFail {
assertInstanceOf(BadRequestDataException::class.java, it)
@@ -289,7 +288,7 @@ class EntitiesQueryUtilsTests {
every { pagination.limitMax } returns 100
val temporalEntitiesQuery =
- composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXT).shouldSucceedAndResult()
+ composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXTS).shouldSucceedAndResult()
assertEquals(
setOf("urn:ngsi-ld:BeeHive:TESTC".toUri(), "urn:ngsi-ld:BeeHive:TESTB".toUri()),
@@ -322,7 +321,7 @@ class EntitiesQueryUtilsTests {
every { pagination.limitMax } returns 100
val temporalEntitiesQuery =
- composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXT).shouldSucceedAndResult()
+ composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXTS).shouldSucceedAndResult()
assertTrue(temporalEntitiesQuery.withAudit)
}
@@ -354,7 +353,7 @@ class EntitiesQueryUtilsTests {
queryParams.add("attrs", "outgoing")
val temporalQuery =
- composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXT).shouldSucceedAndResult()
+ composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXTS).shouldSucceedAndResult()
assertEquals(1, temporalQuery.entitiesQuery.attrs.size)
assertTrue(temporalQuery.entitiesQuery.attrs.contains(OUTGOING_PROPERTY))
@@ -372,7 +371,7 @@ class EntitiesQueryUtilsTests {
queryParams.add("attrs", "incoming,outgoing")
val temporalQuery =
- composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXT).shouldSucceedAndResult()
+ composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXTS).shouldSucceedAndResult()
assertEquals(2, temporalQuery.entitiesQuery.attrs.size)
assertIterableEquals(setOf(INCOMING_PROPERTY, OUTGOING_PROPERTY), temporalQuery.entitiesQuery.attrs)
@@ -389,7 +388,7 @@ class EntitiesQueryUtilsTests {
queryParams.add("timeAt", "2019-10-17T07:31:39Z")
val temporalQuery =
- composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXT).shouldSucceedAndResult()
+ composeTemporalEntitiesQuery(pagination, queryParams, APIC_COMPOUND_CONTEXTS).shouldSucceedAndResult()
assertTrue(temporalQuery.entitiesQuery.attrs.isEmpty())
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/util/QueryParameterizedTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntitiesParameterizedSource.kt
similarity index 96%
rename from search-service/src/test/kotlin/com/egm/stellio/search/util/QueryParameterizedTests.kt
rename to search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntitiesParameterizedSource.kt
index 765680e71..cb709ed23 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/util/QueryParameterizedTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntitiesParameterizedSource.kt
@@ -12,7 +12,7 @@ import java.util.UUID
import java.util.stream.Stream
@Suppress("unused", "UtilityClassWithPublicConstructor")
-class QueryParameterizedTests {
+class TemporalEntitiesParameterizedSource {
companion object {
private val now = Instant.now().atZone(ZoneOffset.UTC)
@@ -25,7 +25,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
@@ -50,7 +50,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
@@ -79,7 +79,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
@@ -111,7 +111,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
@@ -147,7 +147,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
@@ -186,7 +186,7 @@ class QueryParameterizedTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
),
emptyList(),
mapOf(
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityBuilderTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityBuilderTests.kt
similarity index 86%
rename from search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityBuilderTests.kt
rename to search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityBuilderTests.kt
index 82ccb979e..8c7651b4e 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/service/TemporalEntityBuilderTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityBuilderTests.kt
@@ -1,14 +1,12 @@
-package com.egm.stellio.search.service
+package com.egm.stellio.search.util
import com.egm.stellio.search.model.*
import com.egm.stellio.search.model.AggregatedAttributeInstanceResult.AggregateResult
import com.egm.stellio.search.scope.ScopeInstanceResult
import com.egm.stellio.search.support.EMPTY_JSON_PAYLOAD
import com.egm.stellio.search.support.buildDefaultQueryParams
-import com.egm.stellio.search.util.TemporalEntityAttributeInstancesResult
-import com.egm.stellio.search.util.TemporalEntityBuilder
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonUtils.serializeObject
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
@@ -40,7 +38,7 @@ class TemporalEntityBuilderTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
)
val temporalEntity = TemporalEntityBuilder.buildTemporalEntity(
EntityTemporalResult(entityPayload, emptyList(), attributeAndResultsMap),
@@ -51,17 +49,17 @@ class TemporalEntityBuilderTests {
withAudit = false,
withAggregatedValues = false
),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
assertJsonPayloadsAreEqual(
loadSampleData("expectations/beehive_empty_outgoing.jsonld"),
- serializeObject(temporalEntity),
- setOf(NGSILD_CREATED_AT_TERM)
+ serializeObject(temporalEntity.members),
+ setOf(NGSILD_CREATED_AT_PROPERTY)
)
}
@ParameterizedTest
- @MethodSource("com.egm.stellio.search.util.ParameterizedTests#rawResultsProvider")
+ @MethodSource("com.egm.stellio.search.util.TemporalEntityParameterizedSource#rawResultsProvider")
fun `it should correctly build a temporal entity`(
scopeHistory: List,
attributeAndResultsMap: TemporalEntityAttributeInstancesResult,
@@ -74,7 +72,7 @@ class TemporalEntityBuilderTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
)
val temporalEntity = TemporalEntityBuilder.buildTemporalEntity(
@@ -86,13 +84,17 @@ class TemporalEntityBuilderTests {
withAudit,
false
),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
+ )
+ assertJsonPayloadsAreEqual(
+ expectation,
+ serializeObject(temporalEntity.members),
+ setOf(NGSILD_CREATED_AT_PROPERTY)
)
- assertJsonPayloadsAreEqual(expectation, serializeObject(temporalEntity), setOf(NGSILD_CREATED_AT_TERM))
}
@ParameterizedTest
- @MethodSource("com.egm.stellio.search.util.QueryParameterizedTests#rawResultsProvider")
+ @MethodSource("com.egm.stellio.search.util.TemporalEntitiesParameterizedSource#rawResultsProvider")
fun `it should correctly build temporal entities`(
entityTemporalResults: List,
withTemporalValues: Boolean,
@@ -108,9 +110,13 @@ class TemporalEntityBuilderTests {
withAudit,
false
),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
+ )
+ assertJsonPayloadsAreEqual(
+ expectation,
+ serializeObject(temporalEntity.map { it.members }),
+ setOf(NGSILD_CREATED_AT_PROPERTY)
)
- assertJsonPayloadsAreEqual(expectation, serializeObject(temporalEntity), setOf(NGSILD_CREATED_AT_TERM))
}
@Test
@@ -172,7 +178,7 @@ class TemporalEntityBuilderTests {
types = listOf(BEEHIVE_TYPE),
createdAt = now,
payload = EMPTY_JSON_PAYLOAD,
- contexts = listOf(APIC_COMPOUND_CONTEXT)
+ contexts = APIC_COMPOUND_CONTEXTS
)
val temporalEntity = TemporalEntityBuilder.buildTemporalEntity(
@@ -184,13 +190,13 @@ class TemporalEntityBuilderTests {
withAudit = false,
withAggregatedValues = true
),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
assertJsonPayloadsAreEqual(
loadSampleData("expectations/beehive_aggregated_outgoing.jsonld"),
- serializeObject(temporalEntity),
- setOf(NGSILD_CREATED_AT_TERM)
+ serializeObject(temporalEntity.members),
+ setOf(NGSILD_CREATED_AT_PROPERTY)
)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/util/ParameterizedTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityParameterizedSource.kt
similarity index 99%
rename from search-service/src/test/kotlin/com/egm/stellio/search/util/ParameterizedTests.kt
rename to search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityParameterizedSource.kt
index e41519878..d617e2fd3 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/util/ParameterizedTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/util/TemporalEntityParameterizedSource.kt
@@ -17,7 +17,7 @@ import java.util.UUID
import java.util.stream.Stream
@Suppress("unused", "UtilityClassWithPublicConstructor")
-class ParameterizedTests {
+class TemporalEntityParameterizedSource {
companion object {
private val now = Instant.now().atZone(ZoneOffset.UTC)
@@ -552,6 +552,7 @@ class ParameterizedTests {
beehivePropertyMultiInstancesTemporalValues,
beehivePropertyMultiInstancesStringValuesTemporalValues,
beehivePropertyMultiInstancesWithoutDatasetIdStringValuesTemporalValues,
+ beehiveRelationshipMultiInstancesTemporalValues,
beehiveScopeMultiInstancesTemporalValues,
beehiveScopeMultiInstances
)
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/AnonymousUserHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/AnonymousUserHandlerTests.kt
index 82eed369e..12df2bd12 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/AnonymousUserHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/AnonymousUserHandlerTests.kt
@@ -8,8 +8,7 @@ import com.egm.stellio.search.service.EntityPayloadService
import com.egm.stellio.search.service.QueryService
import com.egm.stellio.search.service.TemporalEntityAttributeService
import com.egm.stellio.shared.config.ApplicationProperties
-import com.egm.stellio.shared.util.AQUAC_COMPOUND_CONTEXT
-import com.egm.stellio.shared.util.buildContextLinkHeader
+import com.egm.stellio.shared.util.AQUAC_HEADER_LINK
import com.ninjasquad.springmockk.MockkBean
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
@@ -28,8 +27,6 @@ import org.springframework.test.web.reactive.server.WebTestClient
@Import(WebSecurityTestConfig::class)
class AnonymousUserHandlerTests {
- private val aquacHeaderLink = buildContextLinkHeader(AQUAC_COMPOUND_CONTEXT)
-
@Autowired
private lateinit var webClient: WebTestClient
@@ -54,7 +51,7 @@ class AnonymousUserHandlerTests {
webClient
.get()
.uri("/ngsi-ld/v1/entities/urn:ngsi-ld:Sensor:0022CCC")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.exchange()
.expectStatus().isUnauthorized
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/AttributeHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/AttributeHandlerTests.kt
index 5e56e10fc..c687c4dea 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/AttributeHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/AttributeHandlerTests.kt
@@ -42,8 +42,6 @@ class AttributeHandlerTests {
@MockkBean
private lateinit var attributeService: AttributeService
- private val apicHeaderLink = buildContextLinkHeader(APIC_COMPOUND_CONTEXT)
-
private val expectedAttributeDetails =
"""
[
@@ -204,7 +202,7 @@ class AttributeHandlerTests {
@Test
fun `get attribute type information should correctly serialize an AttributeTypeInfo`() {
- coEvery { attributeService.getAttributeTypeInfoByAttribute(any(), listOf(APIC_COMPOUND_CONTEXT)) } returns
+ coEvery { attributeService.getAttributeTypeInfoByAttribute(any(), APIC_COMPOUND_CONTEXTS) } returns
AttributeTypeInfo(
id = TEMPERATURE_PROPERTY.toUri(),
type = "Attribute",
@@ -216,14 +214,14 @@ class AttributeHandlerTests {
webClient.get()
.uri("/ngsi-ld/v1/attributes/temperature")
- .header(HttpHeaders.LINK, apicHeaderLink)
+ .header(HttpHeaders.LINK, APIC_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.exchange()
.expectStatus().isOk
.expectBody().json(expectedAttributeTypeInfo)
coVerify {
- attributeService.getAttributeTypeInfoByAttribute(TEMPERATURE_PROPERTY, listOf(APIC_COMPOUND_CONTEXT))
+ attributeService.getAttributeTypeInfoByAttribute(TEMPERATURE_PROPERTY, APIC_COMPOUND_CONTEXTS)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityAccessControlHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityAccessControlHandlerTests.kt
index 92f195f6c..2267e1191 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityAccessControlHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityAccessControlHandlerTests.kt
@@ -13,7 +13,6 @@ import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_COMPOUND_CONTEXT
-import com.egm.stellio.shared.util.AuthContextModel.AUTHORIZATION_CONTEXT
import com.egm.stellio.shared.util.AuthContextModel.AUTH_PROP_SAP
import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_CAN_READ
import com.egm.stellio.shared.util.AuthContextModel.AUTH_TERM_FAMILY_NAME
@@ -28,9 +27,7 @@ import com.egm.stellio.shared.util.AuthContextModel.GROUP_TYPE
import com.egm.stellio.shared.util.AuthContextModel.SpecificAccessPolicy.AUTH_READ
import com.egm.stellio.shared.util.AuthContextModel.USER_COMPACT_TYPE
import com.egm.stellio.shared.util.AuthContextModel.USER_TYPE
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_NAME_PROPERTY
-import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedProperty
+import com.egm.stellio.shared.util.JsonLdUtils.buildExpandedPropertyValue
import com.ninjasquad.springmockk.MockkBean
import io.mockk.Called
import io.mockk.coEvery
@@ -58,8 +55,6 @@ import java.time.Duration
@Import(WebSecurityTestConfig::class)
class EntityAccessControlHandlerTests {
- private val authzHeaderLink = buildContextLinkHeader(AUTHORIZATION_CONTEXT)
-
@Autowired
private lateinit var webClient: WebTestClient
@@ -99,7 +94,7 @@ class EntityAccessControlHandlerTests {
"type": "Relationship",
"object": "$entityUri1"
},
- "@context": ["$AUTHORIZATION_CONTEXT", "$NGSILD_CORE_CONTEXT"]
+ "@context": ["$AUTHZ_TEST_CONTEXT", "$NGSILD_TEST_CORE_CONTEXT"]
}
""".trimIndent()
@@ -145,7 +140,7 @@ class EntityAccessControlHandlerTests {
"type": "Relationship",
"object": "$entityUri3"
},
- "@context": ["$AUTHORIZATION_CONTEXT", "$NGSILD_CORE_CONTEXT"]
+ "@context": ["$AUTHZ_TEST_CONTEXT", "$NGSILD_TEST_CORE_CONTEXT"]
}
""".trimIndent()
@@ -199,7 +194,7 @@ class EntityAccessControlHandlerTests {
"object": "$entityUri2",
"datasetId": "$entityUri2"
}],
- "@context": ["$AUTHORIZATION_CONTEXT", "$NGSILD_CORE_CONTEXT"]
+ "@context": ["$AUTHZ_TEST_CONTEXT", "$NGSILD_TEST_CORE_CONTEXT"]
}
""".trimIndent()
@@ -251,7 +246,7 @@ class EntityAccessControlHandlerTests {
"type": "Property",
"value": "$entityUri2"
},
- "@context": ["$AUTHORIZATION_CONTEXT", "$NGSILD_CORE_CONTEXT"]
+ "@context": ["$AUTHZ_TEST_CONTEXT", "$NGSILD_TEST_CORE_CONTEXT"]
}
""".trimIndent()
@@ -324,7 +319,7 @@ class EntityAccessControlHandlerTests {
webClient.delete()
.uri("/ngsi-ld/v1/entityAccessControl/$otherUserSub/attrs/$entityUri1")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.exchange()
.expectStatus().isNoContent
@@ -386,7 +381,7 @@ class EntityAccessControlHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entityAccessControl/$entityUri1/attrs/specificAccessPolicy")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.bodyValue(requestPayload)
.exchange()
@@ -414,7 +409,7 @@ class EntityAccessControlHandlerTests {
{
"type": "Property",
"value": "AUTH_READ",
- "@context": ["$AUTHORIZATION_CONTEXT"]
+ "@context": ["$AUTHZ_TEST_CONTEXT"]
}
""".trimIndent()
@@ -491,7 +486,7 @@ class EntityAccessControlHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entityAccessControl/$entityUri1/attrs/specificAccessPolicy")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.bodyValue(requestPayload)
.exchange()
@@ -514,7 +509,7 @@ class EntityAccessControlHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entityAccessControl/$entityUri1/attrs/specificAccessPolicy")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.bodyValue(requestPayload)
.exchange()
@@ -529,7 +524,7 @@ class EntityAccessControlHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entityAccessControl/$entityUri1/attrs/specificAccessPolicy")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.bodyValue("{}")
.exchange()
@@ -543,7 +538,7 @@ class EntityAccessControlHandlerTests {
webClient.delete()
.uri("/ngsi-ld/v1/entityAccessControl/$entityUri1/attrs/specificAccessPolicy")
- .header(HttpHeaders.LINK, buildContextLinkHeader(AUTHORIZATION_CONTEXT))
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
.exchange()
.expectStatus().isNoContent
@@ -558,7 +553,7 @@ class EntityAccessControlHandlerTests {
fun `get authorized entities should return 200 and the number of results if requested limit is 0`() {
coEvery {
authorizationService.getAuthorizedEntities(any(), any(), any())
- } returns Pair(3, emptyList()).right()
+ } returns Pair(3, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/entities?&limit=0&offset=1&count=true")
@@ -572,7 +567,7 @@ class EntityAccessControlHandlerTests {
fun `get authorized entities should return 200 and empty response if requested offset does not exist`() {
coEvery {
authorizationService.getAuthorizedEntities(any(), any(), any())
- } returns Pair(0, emptyList()).right()
+ } returns Pair(0, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/entities?limit=1&offset=9")
@@ -619,7 +614,7 @@ class EntityAccessControlHandlerTests {
"id": "urn:ngsi-ld:Beehive:TESTC",
"type": "$BEEHIVE_TYPE",
"$AUTH_TERM_RIGHT": {"type":"Property", "value": "rCanRead"},
- "@context": ["$AUTHORIZATION_COMPOUND_CONTEXT"]
+ "@context": "$AUTHORIZATION_COMPOUND_CONTEXT"
},
{
"id": "urn:ngsi-ld:Beehive:TESTD",
@@ -635,7 +630,7 @@ class EntityAccessControlHandlerTests {
"value": {"$AUTH_TERM_KIND": "User", "$AUTH_TERM_USERNAME": "stellio-user"}
}
},
- "@context": ["$AUTHORIZATION_COMPOUND_CONTEXT"]
+ "@context": "$AUTHORIZATION_COMPOUND_CONTEXT"
}]
""".trimMargin()
)
@@ -661,7 +656,7 @@ class EntityAccessControlHandlerTests {
fun `get authorized entities should return 204 if authentication is not enabled`() {
coEvery {
authorizationService.getAuthorizedEntities(any(), any(), any())
- } returns Pair(-1, emptyList()).right()
+ } returns Pair(-1, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/entities")
@@ -674,7 +669,7 @@ class EntityAccessControlHandlerTests {
fun `get groups memberships should return 200 and the number of results if requested limit is 0`() {
coEvery {
authorizationService.getGroupsMemberships(any(), any(), any(), any())
- } returns Pair(3, emptyList()).right()
+ } returns Pair(3, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/groups?&limit=0&offset=1&count=true")
@@ -691,13 +686,13 @@ class EntityAccessControlHandlerTests {
} returns Pair(
1,
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf(
"@id" to "urn:ngsi-ld:group:1",
"@type" to listOf(GROUP_TYPE),
- NGSILD_NAME_PROPERTY to buildExpandedProperty("egm")
+ NGSILD_NAME_PROPERTY to buildExpandedPropertyValue("egm")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
)
)
).right()
@@ -715,7 +710,7 @@ class EntityAccessControlHandlerTests {
"id": "urn:ngsi-ld:group:1",
"type": "$GROUP_COMPACT_TYPE",
"name" : {"type":"Property", "value": "egm"},
- "@context": ["$AUTHORIZATION_COMPOUND_CONTEXT"]
+ "@context": "$AUTHORIZATION_COMPOUND_CONTEXT"
}
]
""".trimMargin()
@@ -731,21 +726,22 @@ class EntityAccessControlHandlerTests {
} returns Pair(
1,
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf(
"@id" to "urn:ngsi-ld:group:01",
"@type" to listOf(GROUP_TYPE),
- NGSILD_NAME_PROPERTY to buildExpandedProperty("egm"),
- AuthContextModel.AUTH_REL_IS_MEMBER_OF to buildExpandedProperty("true")
+ NGSILD_NAME_PROPERTY to buildExpandedPropertyValue("egm"),
+ AuthContextModel.AUTH_REL_IS_MEMBER_OF to buildExpandedPropertyValue("true")
),
- listOf(AUTHORIZATION_CONTEXT)
+ listOf(AUTHZ_TEST_COMPOUND_CONTEXT)
)
)
).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/groups?count=true")
- .header(HttpHeaders.LINK, authzHeaderLink)
+ .header(HttpHeaders.LINK, AUTHZ_HEADER_LINK)
+ .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.exchange()
.expectStatus().isOk
.expectHeader().valueEquals(RESULTS_COUNT_HEADER, "1")
@@ -757,7 +753,10 @@ class EntityAccessControlHandlerTests {
"type": "Group",
"name": {"type":"Property", "value": "egm"},
"isMemberOf": {"type":"Property", "value": "true"},
- "@context": ["$AUTHORIZATION_CONTEXT", "$NGSILD_CORE_CONTEXT"]
+ "@context": [
+ "$AUTHZ_TEST_CONTEXT",
+ "$AUTHORIZATION_COMPOUND_CONTEXT"
+ ]
}
]
""".trimMargin()
@@ -770,7 +769,7 @@ class EntityAccessControlHandlerTests {
fun `get groups memberships should return 204 if authentication is not enabled`() {
coEvery {
authorizationService.getGroupsMemberships(any(), any(), any(), any())
- } returns Pair(-1, emptyList()).right()
+ } returns Pair(-1, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/groups")
@@ -797,7 +796,7 @@ class EntityAccessControlHandlerTests {
coEvery { authorizationService.userIsAdmin(any()) } returns Unit.right()
coEvery {
authorizationService.getUsers(any(), any(), any())
- } returns Pair(3, emptyList()).right()
+ } returns Pair(3, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/users?&limit=0&offset=1&count=true")
@@ -812,7 +811,7 @@ class EntityAccessControlHandlerTests {
coEvery { authorizationService.userIsAdmin(any()) } returns Unit.right()
coEvery {
authorizationService.getUsers(any(), any(), any())
- } returns Pair(-1, emptyList()).right()
+ } returns Pair(-1, emptyList()).right()
webClient.get()
.uri("/ngsi-ld/v1/entityAccessControl/users")
@@ -829,7 +828,7 @@ class EntityAccessControlHandlerTests {
} returns Pair(
1,
listOf(
- JsonLdEntity(
+ ExpandedEntity(
User(
"1",
USER_TYPE,
@@ -837,8 +836,8 @@ class EntityAccessControlHandlerTests {
"givenName",
"familyName",
mapOf("profile" to "stellio-user", "username" to "username")
- ).serializeProperties(AUTHORIZATION_COMPOUND_CONTEXT),
- listOf(NGSILD_CORE_CONTEXT)
+ ).serializeProperties(AUTHZ_TEST_COMPOUND_CONTEXTS),
+ listOf(NGSILD_TEST_CORE_CONTEXT)
)
)
).right()
@@ -859,7 +858,7 @@ class EntityAccessControlHandlerTests {
"$AUTH_TERM_GIVEN_NAME" : { "type":"Property", "value": "givenName" },
"$AUTH_TERM_FAMILY_NAME" : { "type":"Property", "value": "familyName" },
"$AUTH_TERM_SUBJECT_INFO": { "type":"Property","value":{ "profile": "stellio-user" } },
- "@context": ["$AUTHORIZATION_COMPOUND_CONTEXT"]
+ "@context": "$AUTHORIZATION_COMPOUND_CONTEXT"
}
]
""".trimMargin()
@@ -870,10 +869,10 @@ class EntityAccessControlHandlerTests {
private suspend fun createJsonLdEntity(
entityAccessRights: EntityAccessRights,
- context: String = NGSILD_CORE_CONTEXT
- ): JsonLdEntity {
- val earSerialized = entityAccessRights.serializeProperties(AUTHORIZATION_COMPOUND_CONTEXT)
- return JsonLdEntity(earSerialized, listOf(context))
+ context: String = NGSILD_TEST_CORE_CONTEXT
+ ): ExpandedEntity {
+ val earSerialized = entityAccessRights.serializeProperties(AUTHZ_TEST_COMPOUND_CONTEXTS)
+ return ExpandedEntity(earSerialized, listOf(context))
}
private fun createEntityAccessRight(
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityHandlerTests.kt
index ee690c6e7..989ef4144 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityHandlerTests.kt
@@ -16,6 +16,7 @@ import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXTS
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATE_TIME_TYPE
@@ -23,7 +24,7 @@ import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATE_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_HAS_OBJECT
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_OBJECT
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_TYPE
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_TIME_TYPE
import com.ninjasquad.springmockk.MockkBean
@@ -55,8 +56,6 @@ import java.time.*
@Import(WebSecurityTestConfig::class)
class EntityHandlerTests {
- private val aquacHeaderLink = buildContextLinkHeader(AQUAC_COMPOUND_CONTEXT)
-
@Autowired
private lateinit var webClient: WebTestClient
@@ -89,17 +88,10 @@ class EntityHandlerTests {
private val deadFishesType = "https://ontology.eglobalmark.com/aquac#DeadFishes"
private val fishNumberAttribute = "https://ontology.eglobalmark.com/aquac#fishNumber"
private val fishSizeAttribute = "https://ontology.eglobalmark.com/aquac#fishSize"
- private val hcmrContext = listOf(
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/" +
- "master/shared-jsonld-contexts/egm.jsonld",
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/" +
- "master/aquac/jsonld-contexts/aquac.jsonld",
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
- )
@Test
fun `create entity should return a 201 if JSON-LD payload is correct`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
val breedingServiceId = "urn:ngsi-ld:BreedingService:0214".toUri()
coEvery { authorizationService.userCanCreateEntities(sub) } returns Unit.right()
@@ -134,14 +126,14 @@ class EntityHandlerTests {
eq("60AAEBA3-C0C7-42B6-8CB0-0D30857F210E"),
eq(breedingServiceId),
eq(listOf(breedingServiceType)),
- eq(hcmrContext)
+ eq(listOf(AQUAC_COMPOUND_CONTEXT))
)
}
}
@Test
fun `create entity should return a 409 if the entity already exists`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
coEvery { authorizationService.userCanCreateEntities(sub) } returns Unit.right()
coEvery {
@@ -164,7 +156,7 @@ class EntityHandlerTests {
@Test
fun `create entity should return a 500 error if there is an internal server error`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
coEvery { authorizationService.userCanCreateEntities(sub) } returns Unit.right()
coEvery { entityPayloadService.checkEntityExistence(any(), any()) } returns Unit.right()
@@ -194,7 +186,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.bodyValue(jsonLdFile)
.exchange()
.expectStatus().isBadRequest
@@ -211,7 +203,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.bodyValue(entityWithoutId)
.exchange()
.expectStatus().isBadRequest
@@ -228,7 +220,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.bodyValue(entityWithoutType)
.exchange()
.expectStatus().isBadRequest
@@ -236,7 +228,7 @@ class EntityHandlerTests {
@Test
fun `create entity should return a 400 if creation unexpectedly fails`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
coEvery { authorizationService.userCanCreateEntities(sub) } returns Unit.right()
coEvery { entityPayloadService.checkEntityExistence(any(), any()) } returns Unit.right()
@@ -263,7 +255,7 @@ class EntityHandlerTests {
@Test
fun `create entity should return a 403 if user is not allowed to create entities`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
coEvery {
authorizationService.userCanCreateEntities(sub)
@@ -295,9 +287,9 @@ class EntityHandlerTests {
fun `get entity by id should return 200 when entity exists`() {
mockkDefaultBehaviorForGetEntityById()
- val returnedJsonLdEntity = mockkClass(JsonLdEntity::class, relaxed = true)
- coEvery { queryService.queryEntity(any(), any()) } returns returnedJsonLdEntity.right()
- every { returnedJsonLdEntity.checkContainsAnyOf(any()) } returns Unit.right()
+ val returnedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
+ coEvery { queryService.queryEntity(any(), any()) } returns returnedExpandedEntity.right()
+ every { returnedExpandedEntity.checkContainsAnyOf(any()) } returns Unit.right()
webClient.get()
.uri("/ngsi-ld/v1/entities/$beehiveId")
@@ -310,7 +302,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize temporal properties`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
NGSILD_CREATED_AT_PROPERTY to
mapOf(
@@ -320,7 +312,7 @@ class EntityHandlerTests {
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -332,7 +324,7 @@ class EntityHandlerTests {
"""
{
"createdAt": "2015-10-18T11:20:30.000001Z",
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -342,7 +334,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly filter the asked attributes`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive"),
@@ -359,7 +351,7 @@ class EntityHandlerTests {
)
)
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -376,7 +368,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly return the simplified representation of an entity`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive"),
@@ -388,12 +380,12 @@ class EntityHandlerTests {
),
"https://uri.etsi.org/ngsi-ld/default-context/rel1" to mapOf(
JSONLD_TYPE to NGSILD_RELATIONSHIP_TYPE.uri,
- NGSILD_RELATIONSHIP_HAS_OBJECT to mapOf(
+ NGSILD_RELATIONSHIP_OBJECT to mapOf(
JSONLD_ID to "urn:ngsi-ld:Entity:1234"
)
)
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -409,7 +401,7 @@ class EntityHandlerTests {
"type": "Beehive",
"prop1": "some value",
"rel1": "urn:ngsi-ld:Entity:1234",
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -419,12 +411,12 @@ class EntityHandlerTests {
fun `get entity by id should return 404 if the entity has none of the requested attributes`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf(BEEHIVE_TYPE)
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
val expectedMessage = entityOrAttrsNotFoundMessage(
@@ -451,12 +443,12 @@ class EntityHandlerTests {
fun `get entity by id should not include temporal properties if optional query param sysAttrs is not present`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -464,7 +456,7 @@ class EntityHandlerTests {
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.exchange()
.expectStatus().isOk
- .expectBody().json("""{"@context":["$NGSILD_CORE_CONTEXT"]}""")
+ .expectBody().json("""{"@context":"$NGSILD_CORE_CONTEXT"}""")
.jsonPath("$.createdAt").doesNotExist()
.jsonPath("$.modifiedAt").doesNotExist()
}
@@ -472,7 +464,7 @@ class EntityHandlerTests {
@Test
fun `get entity by id should correctly serialize properties of type DateTime and display sysAttrs asked`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
NGSILD_CREATED_AT_PROPERTY to
mapOf(
@@ -499,7 +491,7 @@ class EntityHandlerTests {
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -520,7 +512,7 @@ class EntityHandlerTests {
"createdAt":"2015-10-18T11:20:30.000001Z",
"modifiedAt":"2015-10-18T12:20:30.000001Z"
},
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -530,7 +522,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize properties of type Date`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/testedAt" to mapOf(
"@type" to "https://uri.etsi.org/ngsi-ld/Property",
@@ -542,7 +534,7 @@ class EntityHandlerTests {
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -560,7 +552,7 @@ class EntityHandlerTests {
"@value":"2015-10-18"
}
},
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -570,7 +562,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize properties of type Time`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/testedAt" to mapOf(
"@type" to "https://uri.etsi.org/ngsi-ld/Property",
@@ -582,7 +574,7 @@ class EntityHandlerTests {
"@id" to "urn:ngsi-ld:Beehive:4567",
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -600,7 +592,7 @@ class EntityHandlerTests {
"@value":"11:20:30"
}
},
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -610,7 +602,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize multi-attribute property having one instance`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/name" to
mapOf(
@@ -623,7 +615,7 @@ class EntityHandlerTests {
JSONLD_ID to "urn:ngsi-ld:Beehive:4567",
JSONLD_TYPE to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -637,7 +629,7 @@ class EntityHandlerTests {
"id":"urn:ngsi-ld:Beehive:4567",
"type":"Beehive",
"name":{"type":"Property","datasetId":"urn:ngsi-ld:Property:french-name","value":"ruche"},
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -647,7 +639,7 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize multi-attribute property having more than one instance`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/name" to
listOf(
@@ -669,7 +661,7 @@ class EntityHandlerTests {
JSONLD_ID to "urn:ngsi-ld:Beehive:4567",
JSONLD_TYPE to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -690,7 +682,7 @@ class EntityHandlerTests {
"type":"Property","datasetId":"urn:ngsi-ld:Property:french-name","value":"ruche"
}
],
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -700,12 +692,12 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize multi-attribute relationship having one instance`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/managedBy" to
mapOf(
JSONLD_TYPE to "https://uri.etsi.org/ngsi-ld/Relationship",
- NGSILD_RELATIONSHIP_HAS_OBJECT to mapOf(
+ NGSILD_RELATIONSHIP_OBJECT to mapOf(
JSONLD_ID to "urn:ngsi-ld:Beekeeper:1230"
),
NGSILD_DATASET_ID_PROPERTY to mapOf(
@@ -715,7 +707,7 @@ class EntityHandlerTests {
JSONLD_ID to "urn:ngsi-ld:Beehive:4567",
JSONLD_TYPE to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -733,7 +725,7 @@ class EntityHandlerTests {
"datasetId":"urn:ngsi-ld:Dataset:managedBy:0215",
"object":"urn:ngsi-ld:Beekeeper:1230"
},
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -743,12 +735,12 @@ class EntityHandlerTests {
fun `get entity by id should include createdAt & modifiedAt if query param sysAttrs is present`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/managedBy" to
mapOf(
JSONLD_TYPE to "https://uri.etsi.org/ngsi-ld/Relationship",
- NGSILD_RELATIONSHIP_HAS_OBJECT to mapOf(
+ NGSILD_RELATIONSHIP_OBJECT to mapOf(
JSONLD_ID to "urn:ngsi-ld:Beekeeper:1230"
),
NGSILD_DATASET_ID_PROPERTY to mapOf(
@@ -768,7 +760,7 @@ class EntityHandlerTests {
JSONLD_ID to "urn:ngsi-ld:Beehive:4567",
JSONLD_TYPE to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -785,19 +777,19 @@ class EntityHandlerTests {
fun `get entity by id should correctly serialize multi-attribute relationship having more than one instance`() {
mockkDefaultBehaviorForGetEntityById()
- coEvery { queryService.queryEntity(any(), any()) } returns JsonLdEntity(
+ coEvery { queryService.queryEntity(any(), any()) } returns ExpandedEntity(
mapOf(
"https://uri.etsi.org/ngsi-ld/default-context/managedBy" to
listOf(
mapOf(
JSONLD_TYPE to "https://uri.etsi.org/ngsi-ld/Relationship",
- NGSILD_RELATIONSHIP_HAS_OBJECT to mapOf(
+ NGSILD_RELATIONSHIP_OBJECT to mapOf(
JSONLD_ID to "urn:ngsi-ld:Beekeeper:1229"
)
),
mapOf(
JSONLD_TYPE to "https://uri.etsi.org/ngsi-ld/Relationship",
- NGSILD_RELATIONSHIP_HAS_OBJECT to mapOf(
+ NGSILD_RELATIONSHIP_OBJECT to mapOf(
JSONLD_ID to "urn:ngsi-ld:Beekeeper:1230"
),
NGSILD_DATASET_ID_PROPERTY to mapOf(
@@ -808,7 +800,7 @@ class EntityHandlerTests {
JSONLD_ID to "urn:ngsi-ld:Beehive:4567",
JSONLD_TYPE to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
).right()
webClient.get()
@@ -832,7 +824,7 @@ class EntityHandlerTests {
"object":"urn:ngsi-ld:Beekeeper:1230"
}
],
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
""".trimIndent()
)
@@ -866,7 +858,7 @@ class EntityHandlerTests {
webClient.get()
.uri("/ngsi-ld/v1/entities/urn:ngsi-ld:BeeHive:TEST")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.exchange()
.expectStatus().isForbidden
.expectBody().json(
@@ -884,12 +876,12 @@ class EntityHandlerTests {
fun `get entities by type should not include temporal properties if query param sysAttrs is not present`() {
coEvery { queryService.queryEntities(any(), any()) } returns Pair(
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
)
),
1
@@ -906,7 +898,7 @@ class EntityHandlerTests {
{
"id": "$beehiveId",
"type": "Beehive",
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
]
""".trimMargin()
@@ -922,13 +914,13 @@ class EntityHandlerTests {
EntitiesQuery(
typeSelection = "https://uri.etsi.org/ngsi-ld/default-context/Beehive",
paginationQuery = PaginationQuery(offset = 0, limit = 30),
- context = NGSILD_CORE_CONTEXT
+ contexts = NGSILD_CORE_CONTEXTS
),
any()
)
} returns Pair(
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf(
NGSILD_CREATED_AT_PROPERTY to
mapOf(
@@ -938,7 +930,7 @@ class EntityHandlerTests {
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
)
),
1
@@ -956,7 +948,7 @@ class EntityHandlerTests {
"id": "$beehiveId",
"type": "Beehive",
"createdAt":"2015-10-18T11:20:30.000001Z",
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
]
""".trimMargin()
@@ -967,9 +959,9 @@ class EntityHandlerTests {
fun `get entities should return 200 with prev and next link header if exists`() {
coEvery { queryService.queryEntities(any(), any()) } returns Pair(
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf("@id" to "urn:ngsi-ld:Beehive:TESTC", "@type" to listOf("Beehive")),
- listOf(NGSILD_CORE_CONTEXT)
+ listOf(NGSILD_TEST_CORE_CONTEXT)
)
),
3
@@ -995,7 +987,7 @@ class EntityHandlerTests {
{
"id": "urn:ngsi-ld:Beehive:TESTC",
"type": "Beehive",
- "@context": ["$NGSILD_CORE_CONTEXT"]
+ "@context": "$NGSILD_CORE_CONTEXT"
}
]
""".trimMargin()
@@ -1006,7 +998,7 @@ class EntityHandlerTests {
fun `get entities should return 200 and empty response if requested offset does not exists`() {
coEvery {
queryService.queryEntities(any(), any())
- } returns Pair(emptyList(), 0).right()
+ } returns Pair(emptyList(), 0).right()
webClient.get()
.uri("/ngsi-ld/v1/entities/?type=Beehive&limit=1&offset=9")
@@ -1057,18 +1049,18 @@ class EntityHandlerTests {
ids = setOf(beehiveId),
typeSelection = BEEHIVE_TYPE,
paginationQuery = PaginationQuery(offset = 0, limit = 30),
- context = APIC_COMPOUND_CONTEXT
+ contexts = APIC_COMPOUND_CONTEXTS
),
any()
)
} returns Pair(
listOf(
- JsonLdEntity(
+ ExpandedEntity(
mapOf(
"@id" to beehiveId.toString(),
"@type" to listOf("Beehive")
),
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
),
1
@@ -1086,7 +1078,7 @@ class EntityHandlerTests {
{
"id": "$beehiveId",
"type": "Beehive",
- "@context": ["$APIC_COMPOUND_CONTEXT"]
+ "@context": "$APIC_COMPOUND_CONTEXT"
}
]
""".trimMargin()
@@ -1095,7 +1087,7 @@ class EntityHandlerTests {
@Test
fun `get entities should return 200 and the number of results`() {
- coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 3).right()
+ coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 3).right()
webClient.get()
.uri("/ngsi-ld/v1/entities/?type=Beehive&limit=0&offset=1&count=true")
@@ -1124,7 +1116,7 @@ class EntityHandlerTests {
@Test
fun `get entities should allow a query not including a type request parameter`() {
- coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 0).right()
+ coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 0).right()
webClient.get()
.uri("/ngsi-ld/v1/entities/?attrs=myProp")
@@ -1153,7 +1145,7 @@ class EntityHandlerTests {
@Test
fun `replace entity should return a 201 if JSON-LD payload is correct`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
val breedingServiceId = "urn:ngsi-ld:BreedingService:0214".toUri()
coEvery { entityPayloadService.checkEntityExistence(breedingServiceId) } returns Unit.right()
@@ -1186,14 +1178,14 @@ class EntityHandlerTests {
eq("60AAEBA3-C0C7-42B6-8CB0-0D30857F210E"),
eq(breedingServiceId),
eq(listOf(breedingServiceType)),
- eq(hcmrContext)
+ eq(listOf(AQUAC_COMPOUND_CONTEXT))
)
}
}
@Test
fun `replace entity should return a 403 if user is not allowed to update the entity`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
val breedingServiceId = "urn:ngsi-ld:BreedingService:0214".toUri()
coEvery { entityPayloadService.checkEntityExistence(breedingServiceId) } returns Unit.right()
@@ -1219,7 +1211,7 @@ class EntityHandlerTests {
@Test
fun `replace entity should return a 404 if entity does not exist`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
val breedingServiceId = "urn:ngsi-ld:BreedingService:0214".toUri()
coEvery {
@@ -1236,7 +1228,7 @@ class EntityHandlerTests {
@Test
fun `replace entity should return a 400 if id contained in payload is different from the one in URL`() {
- val jsonLdFile = ClassPathResource("/ngsild/aquac/BreedingService.json")
+ val jsonLdFile = ClassPathResource("/ngsild/aquac/breedingService.jsonld")
val breedingServiceId = "urn:ngsi-ld:BreedingService:0215".toUri()
coEvery { entityPayloadService.checkEntityExistence(breedingServiceId) } returns Unit.right()
@@ -1308,7 +1300,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1358,7 +1350,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1409,7 +1401,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1456,7 +1448,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1496,7 +1488,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.bodyValue(jsonLdFile)
.exchange()
.expectStatus().isNotFound
@@ -1537,7 +1529,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(invalidPayload)
.exchange()
@@ -1566,7 +1558,7 @@ class EntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1612,7 +1604,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs/$attrId")
- .header("Link", aquacHeaderLink)
+ .header("Link", AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1647,7 +1639,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs/$attrId")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1677,7 +1669,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs/$attrId")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1702,7 +1694,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs/$attrId")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1757,7 +1749,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1811,7 +1803,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId?observedAt=2019-12-04T12:00:00.00Z")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1849,7 +1841,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId?observedAt=notDateTime")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1901,7 +1893,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1923,7 +1915,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -1964,7 +1956,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -2010,7 +2002,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -2037,7 +2029,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -2073,7 +2065,7 @@ class EntityHandlerTests {
{
"type": "https://uri.etsi.org/ngsi-ld/errors/LdContextNotAvailable",
"title": "A remote JSON-LD @context referenced in a request cannot be retrieved by the NGSI-LD Broker and expansion or compaction cannot be performed",
- "detail": "Unable to load remote context (cause was: com.github.jsonldjava.core.JsonLdError: loading remote context failed: https://easyglobalmarket.com/contexts/diat.jsonld)"
+ "detail": "Unable to load remote context (cause was: JsonLdError[code=There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED]., message=There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED].])"
}
""".trimIndent()
)
@@ -2120,7 +2112,7 @@ class EntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/entities/$entityId/attrs")
- .header(HttpHeaders.LINK, aquacHeaderLink)
+ .header(HttpHeaders.LINK, AQUAC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(jsonLdFile)
.exchange()
@@ -2143,7 +2135,7 @@ class EntityHandlerTests {
coEvery { entityPayloadService.checkEntityExistence(beehiveId) } returns Unit.right()
coEvery { entityPayloadService.retrieve(any()) } returns entity.right()
every { entity.types } returns listOf(BEEHIVE_TYPE)
- every { entity.contexts } returns listOf(APIC_COMPOUND_CONTEXT)
+ every { entity.contexts } returns APIC_COMPOUND_CONTEXTS
coEvery { authorizationService.userCanAdminEntity(beehiveId, sub) } returns Unit.right()
coEvery { entityPayloadService.deleteEntity(any()) } returns Unit.right()
coEvery { authorizationService.removeRightsOnEntity(any()) } returns Unit.right()
@@ -2166,7 +2158,7 @@ class EntityHandlerTests {
entityEventService.publishEntityDeleteEvent(
eq("60AAEBA3-C0C7-42B6-8CB0-0D30857F210E"),
eq(entity),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
@@ -2284,7 +2276,7 @@ class EntityHandlerTests {
eq(TEMPERATURE_PROPERTY),
isNull(),
eq(false),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
@@ -2319,7 +2311,7 @@ class EntityHandlerTests {
eq(TEMPERATURE_PROPERTY),
isNull(),
eq(true),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
@@ -2354,7 +2346,7 @@ class EntityHandlerTests {
eq(TEMPERATURE_PROPERTY),
eq(datasetId.toUri()),
eq(false),
- eq(listOf(APIC_COMPOUND_CONTEXT))
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityOperationHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityOperationHandlerTests.kt
index 4a19fc35f..a503bb35f 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityOperationHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityOperationHandlerTests.kt
@@ -14,7 +14,7 @@ import com.egm.stellio.search.service.EntityPayloadService
import com.egm.stellio.search.service.QueryService
import com.egm.stellio.shared.config.ApplicationProperties
import com.egm.stellio.shared.model.AccessDeniedException
-import com.egm.stellio.shared.model.JsonLdEntity
+import com.egm.stellio.shared.model.ExpandedEntity
import com.egm.stellio.shared.model.NgsiLdEntity
import com.egm.stellio.shared.util.*
import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DEFAULT_VOCAB
@@ -70,9 +70,9 @@ class EntityOperationHandlerTests {
private lateinit var mockedTemperatureSensorEntity: NgsiLdEntity
private lateinit var mockedDissolvedOxygenSensorEntity: NgsiLdEntity
private lateinit var mockedDeviceEntity: NgsiLdEntity
- private lateinit var mockedTemperatureSensorJsonLdEntity: JsonLdEntity
- private lateinit var mockedDissolvedOxygenSensorJsonLdEntity: JsonLdEntity
- private lateinit var mockedDeviceJsonLdEntity: JsonLdEntity
+ private lateinit var mockedTemperatureSensorExpandedEntity: ExpandedEntity
+ private lateinit var mockedDissolvedOxygenSensorExpandedEntity: ExpandedEntity
+ private lateinit var mockedDeviceExpandedEntity: ExpandedEntity
@BeforeAll
fun configureWebClientDefaults() {
@@ -93,7 +93,7 @@ class EntityOperationHandlerTests {
every { types } returns listOf(SENSOR_TYPE)
every { contexts } returns listOf(AQUAC_COMPOUND_CONTEXT)
}
- mockedTemperatureSensorJsonLdEntity = mockkClass(JsonLdEntity::class) {
+ mockedTemperatureSensorExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns temperatureSensorUri.toString()
every { members } returns emptyMap()
}
@@ -102,7 +102,7 @@ class EntityOperationHandlerTests {
every { types } returns listOf(SENSOR_TYPE)
every { contexts } returns listOf(AQUAC_COMPOUND_CONTEXT)
}
- mockedDissolvedOxygenSensorJsonLdEntity = mockkClass(JsonLdEntity::class) {
+ mockedDissolvedOxygenSensorExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns dissolvedOxygenSensorUri.toString()
every { members } returns emptyMap()
}
@@ -111,7 +111,7 @@ class EntityOperationHandlerTests {
every { types } returns listOf(DEVICE_TYPE)
every { contexts } returns listOf(AQUAC_COMPOUND_CONTEXT)
}
- mockedDeviceJsonLdEntity = mockkClass(JsonLdEntity::class) {
+ mockedDeviceExpandedEntity = mockkClass(ExpandedEntity::class) {
every { id } returns deviceUri.toString()
every { members } returns emptyMap()
}
@@ -137,9 +137,9 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity),
- Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity)
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity),
+ Pair(mockedDeviceExpandedEntity, mockedDeviceEntity)
),
emptyList()
)
@@ -170,8 +170,8 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity),
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity),
),
emptyList()
)
@@ -210,7 +210,7 @@ class EntityOperationHandlerTests {
val jsonLdFile = ClassPathResource("/ngsild/two_sensors_one_invalid.jsonld")
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity)),
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity)),
emptyList()
)
coEvery { authorizationService.userCanUpdateEntity(any(), sub) } returns Unit.right()
@@ -252,8 +252,8 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity),
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity),
),
emptyList()
)
@@ -279,8 +279,8 @@ class EntityOperationHandlerTests {
val jsonLdFile = ClassPathResource("/ngsild/hcmr/HCMR_test_file.json")
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity)),
- listOf(Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity))
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity)),
+ listOf(Pair(mockedDeviceExpandedEntity, mockedDeviceEntity))
)
coEvery { authorizationService.userCanUpdateEntity(any(), sub) } returns Unit.right()
coEvery { entityOperationService.update(any(), any(), any()) } returns BatchOperationResult(
@@ -363,10 +363,10 @@ class EntityOperationHandlerTests {
entityOperationService.splitEntitiesByExistence(any())
} answers {
Pair(
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity)),
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity)),
listOf(
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity),
- Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity)
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity),
+ Pair(mockedDeviceExpandedEntity, mockedDeviceEntity)
)
)
}
@@ -421,7 +421,7 @@ class EntityOperationHandlerTests {
coEvery {
entityOperationService.splitEntitiesByExistence(any())
- } returns Pair(emptyList(), listOf(Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity)))
+ } returns Pair(emptyList(), listOf(Pair(mockedDeviceExpandedEntity, mockedDeviceEntity)))
coEvery {
authorizationService.userCanCreateEntities(sub)
} returns AccessDeniedException(ENTITIY_CREATION_FORBIDDEN_MESSAGE).left()
@@ -488,10 +488,10 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity),
- Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity)
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity),
+ Pair(mockedDeviceExpandedEntity, mockedDeviceEntity)
),
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity))
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity))
)
coEvery { authorizationService.userCanCreateEntities(any()) } returns Unit.right()
coEvery { entityOperationService.create(any(), any()) } returns createdBatchResult
@@ -538,7 +538,7 @@ class EntityOperationHandlerTests {
val jsonLdFile = ClassPathResource("/ngsild/hcmr/HCMR_test_file.json")
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity)),
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity)),
emptyList()
)
coEvery { authorizationService.userCanUpdateEntity(any(), sub) } returns Unit.right()
@@ -567,10 +567,10 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity)
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity)
),
- listOf(Pair(mockedDeviceJsonLdEntity, mockedDeviceEntity))
+ listOf(Pair(mockedDeviceExpandedEntity, mockedDeviceEntity))
)
coEvery { authorizationService.userCanCreateEntities(sub) } returns Unit.right()
coEvery { entityOperationService.create(any(), any()) } returns BatchOperationResult(
@@ -619,8 +619,8 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity)
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity)
),
emptyList()
)
@@ -656,7 +656,7 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
emptyList(),
- listOf(Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity))
+ listOf(Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity))
)
coEvery {
authorizationService.userCanCreateEntities(sub)
@@ -691,8 +691,8 @@ class EntityOperationHandlerTests {
coEvery { entityOperationService.splitEntitiesByExistence(any()) } returns Pair(
listOf(
- Pair(mockedTemperatureSensorJsonLdEntity, mockedTemperatureSensorEntity),
- Pair(mockedDissolvedOxygenSensorJsonLdEntity, mockedDissolvedOxygenSensorEntity)
+ Pair(mockedTemperatureSensorExpandedEntity, mockedTemperatureSensorEntity),
+ Pair(mockedDissolvedOxygenSensorExpandedEntity, mockedDissolvedOxygenSensorEntity)
),
emptyList()
)
@@ -882,7 +882,7 @@ class EntityOperationHandlerTests {
@Test
fun `query entities should return a 200 if the query is correct`() = runTest {
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
- coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 0).right()
+ coEvery { queryService.queryEntities(any(), any()) } returns Pair(emptyList(), 0).right()
val query = """
{
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityTypeHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityTypeHandlerTests.kt
index 2847bae64..67e26edda 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityTypeHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/EntityTypeHandlerTests.kt
@@ -40,8 +40,6 @@ class EntityTypeHandlerTests {
@MockkBean
private lateinit var entityTypeService: EntityTypeService
- private val apicHeaderLink = buildContextLinkHeader(APIC_COMPOUND_CONTEXT)
-
private val deadFishesType = "https://ontology.eglobalmark.com/aquac#DeadFishes"
private val sensorType = "https://ontology.eglobalmark.com/egm#Sensor"
@@ -261,7 +259,7 @@ class EntityTypeHandlerTests {
webClient.get()
.uri("/ngsi-ld/v1/types/BeeHive")
- .header(HttpHeaders.LINK, apicHeaderLink)
+ .header(HttpHeaders.LINK, APIC_HEADER_LINK)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.exchange()
.expectStatus().isOk
@@ -270,7 +268,7 @@ class EntityTypeHandlerTests {
coVerify {
entityTypeService.getEntityTypeInfoByType(
"https://ontology.eglobalmark.com/apic#BeeHive",
- listOf(APIC_COMPOUND_CONTEXT)
+ APIC_COMPOUND_CONTEXTS
)
}
}
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityHandlerTests.kt
index 738a02b21..d0fcb3c62 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityHandlerTests.kt
@@ -16,19 +16,11 @@ import com.egm.stellio.search.service.QueryService
import com.egm.stellio.search.service.TemporalEntityAttributeService
import com.egm.stellio.search.support.EMPTY_JSON_PAYLOAD
import com.egm.stellio.shared.config.ApplicationProperties
-import com.egm.stellio.shared.model.AccessDeniedException
-import com.egm.stellio.shared.model.BadRequestDataException
-import com.egm.stellio.shared.model.NgsiLdEntity
-import com.egm.stellio.shared.model.ResourceNotFoundException
+import com.egm.stellio.shared.model.*
import com.egm.stellio.shared.util.*
-import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CORE_CONTEXT
import com.egm.stellio.shared.util.JsonUtils.deserializeAsMap
-import com.egm.stellio.shared.util.JsonUtils.deserializeObject
import com.ninjasquad.springmockk.MockkBean
-import io.mockk.Called
-import io.mockk.coEvery
-import io.mockk.coVerify
-import io.mockk.confirmVerified
+import io.mockk.*
import kotlinx.coroutines.test.runTest
import org.hamcrest.core.Is
import org.junit.jupiter.api.BeforeAll
@@ -57,8 +49,6 @@ import java.util.UUID
@Import(WebSecurityTestConfig::class)
class TemporalEntityHandlerTests {
- private lateinit var apicHeaderLink: String
-
@Autowired
private lateinit var webClient: WebTestClient
@@ -83,8 +73,6 @@ class TemporalEntityHandlerTests {
@BeforeAll
fun configureWebClientDefaults() {
- apicHeaderLink = buildContextLinkHeader(APIC_COMPOUND_CONTEXT)
-
webClient = webClient.mutate()
.apply(mockJwt().jwt { it.subject(MOCK_USER_SUB) })
.apply(csrf())
@@ -113,7 +101,7 @@ class TemporalEntityHandlerTests {
val data =
loadSampleData("/temporal/beehive_create_temporal_entity_first_instance.jsonld").deserializeAsMap()
- val jsonLdEntity = JsonLdUtils.expandJsonLdEntity(data, listOf(APIC_COMPOUND_CONTEXT))
+ val expandedEntity = JsonLdUtils.expandJsonLdEntity(data, APIC_COMPOUND_CONTEXTS)
val expectedInstancesFilePath =
"/temporal/beehive_create_temporal_entity_without_first_instance_expanded.jsonld"
val jsonInstances =
@@ -131,7 +119,7 @@ class TemporalEntityHandlerTests {
coVerify {
entityPayloadService.createEntity(
any(),
- eq(jsonLdEntity),
+ eq(expandedEntity),
eq(sub.value)
)
}
@@ -186,7 +174,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(entityTemporalFragment))
.exchange()
@@ -213,7 +201,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(entityTemporalFragment))
.exchange()
@@ -240,7 +228,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(entityTemporalFragment))
.exchange()
@@ -267,7 +255,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(entityTemporalFragment))
.exchange()
@@ -290,7 +278,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue("{ \"id\": \"bad\" }"))
.exchange()
@@ -319,7 +307,7 @@ class TemporalEntityHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(entityTemporalFragment))
.exchange()
@@ -377,9 +365,10 @@ class TemporalEntityHandlerTests {
fun `it should give a 200 if no timerel and no time query params are in the request`() {
buildDefaultMockResponsesForGetEntity()
+ val returnedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
coEvery {
queryService.queryTemporalEntity(any(), any(), any())
- } returns emptyMap().right()
+ } returns returnedExpandedEntity.right()
webClient.get()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri")
@@ -566,16 +555,17 @@ class TemporalEntityHandlerTests {
fun `it should return a 200 if minimal required parameters are valid`() {
buildDefaultMockResponsesForGetEntity()
+ val returnedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
coEvery {
queryService.queryTemporalEntity(any(), any(), any())
- } returns emptyMap().right()
+ } returns returnedExpandedEntity.right()
webClient.get()
.uri(
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
@@ -590,7 +580,7 @@ class TemporalEntityHandlerTests {
!temporalEntitiesQuery.withTemporalValues &&
!temporalEntitiesQuery.withAudit
},
- eq(APIC_COMPOUND_CONTEXT)
+ eq(APIC_COMPOUND_CONTEXTS)
)
}
confirmVerified(queryService)
@@ -600,16 +590,17 @@ class TemporalEntityHandlerTests {
fun `it should return a 200 if minimal required parameters are valid and entity is publicly readable`() {
buildDefaultMockResponsesForGetEntity()
+ val returnedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
coEvery {
queryService.queryTemporalEntity(any(), any(), any())
- } returns emptyMap().right()
+ } returns returnedExpandedEntity.right()
webClient.get()
.uri(
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
@@ -620,16 +611,17 @@ class TemporalEntityHandlerTests {
fun `it should return a 200 if minimal required parameters are valid and user can read the entity`() {
buildDefaultMockResponsesForGetEntity()
+ val returnedExpandedEntity = mockkClass(ExpandedEntity::class, relaxed = true)
coEvery {
queryService.queryTemporalEntity(any(), any(), any())
- } returns emptyMap().right()
+ } returns returnedExpandedEntity.right()
webClient.get()
.uri(
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
@@ -639,7 +631,7 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `it should return an entity with two temporal properties evolution`() {
+ fun `it should return an entity with two temporal properties evolution`() = runTest {
buildDefaultMockResponsesForGetEntity()
mockWithIncomingAndOutgoingTemporalProperties(false)
@@ -649,7 +641,7 @@ class TemporalEntityHandlerTests {
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectBody().jsonPath("$").isMap
@@ -661,7 +653,7 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `it should return a json entity with two temporal properties evolution`() {
+ fun `it should return a json entity with two temporal properties evolution`() = runTest {
buildDefaultMockResponsesForGetEntity()
mockWithIncomingAndOutgoingTemporalProperties(false)
@@ -671,7 +663,7 @@ class TemporalEntityHandlerTests {
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.header("Accept", MediaType.APPLICATION_JSON.toString())
.exchange()
.expectStatus().isOk
@@ -685,7 +677,7 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `it should return an entity with two temporal properties evolution with temporalValues option`() {
+ fun `it should return an entity with two temporal properties evolution with temporalValues option`() = runTest {
buildDefaultMockResponsesForGetEntity()
mockWithIncomingAndOutgoingTemporalProperties(true)
@@ -695,18 +687,18 @@ class TemporalEntityHandlerTests {
"/ngsi-ld/v1/temporal/entities/$entityUri?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z&options=temporalValues"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectBody().jsonPath("$").isMap
.jsonPath("$.id").exists()
.jsonPath("$.type").exists()
.jsonPath("$..observedAt").doesNotExist()
- .jsonPath("$.incoming[0].values.length()").isEqualTo(2)
- .jsonPath("$.outgoing[0].values.length()").isEqualTo(2)
+ .jsonPath("$.incoming.values.length()").isEqualTo(2)
+ .jsonPath("$.outgoing.values.length()").isEqualTo(2)
}
- private fun mockWithIncomingAndOutgoingTemporalProperties(withTemporalValues: Boolean) {
+ private suspend fun mockWithIncomingAndOutgoingTemporalProperties(withTemporalValues: Boolean) {
val entityTemporalProperties = listOf(INCOMING_PROPERTY, OUTGOING_PROPERTY)
.map {
TemporalEntityAttribute(
@@ -722,7 +714,7 @@ class TemporalEntityHandlerTests {
else
"beehive_with_two_temporal_attributes_evolution.jsonld"
- val entityWith2temporalEvolutions = deserializeObject(loadSampleData(entityFileName))
+ val entityWith2temporalEvolutions = loadAndExpandSampleData(entityFileName)
coEvery {
temporalEntityAttributeService.getForEntity(any(), any())
} returns listOf(entityTemporalProperties[0], entityTemporalProperties[1])
@@ -786,7 +778,7 @@ class TemporalEntityHandlerTests {
"/ngsi-ld/v1/temporal/entities?" +
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z&type=BeeHive"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectBody().json("[]")
@@ -808,11 +800,9 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `it should return 200 with jsonld response body for query temporal entities`() {
- val firstTemporalEntity = deserializeObject(
- loadSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
- ).minus("@context")
- val secondTemporalEntity = deserializeObject(loadSampleData("beehive.jsonld")).minus("@context")
+ fun `it should return 200 with jsonld response body for query temporal entities`() = runTest {
+ val firstTemporalEntity = loadAndExpandSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
+ val secondTemporalEntity = loadAndExpandSampleData("beehive.jsonld")
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
coEvery {
@@ -825,7 +815,7 @@ class TemporalEntityHandlerTests {
"timerel=between&timeAt=2019-10-17T07:31:39Z&endTimeAt=2019-10-18T07:31:39Z&" +
"type=BeeHive"
)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectBody()
@@ -836,11 +826,9 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `it should return 200 with json response body for query temporal entities`() {
- val firstTemporalEntity = deserializeObject(
- loadSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
- ).minus("@context")
- val secondTemporalEntity = deserializeObject(loadSampleData("beehive.jsonld")).minus("@context")
+ fun `it should return 200 with json response body for query temporal entities`() = runTest {
+ val firstTemporalEntity = loadAndExpandSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
+ val secondTemporalEntity = loadAndExpandSampleData("beehive.jsonld")
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
coEvery {
@@ -854,7 +842,7 @@ class TemporalEntityHandlerTests {
"type=BeeHive"
)
.header("Accept", MediaType.APPLICATION_JSON.toString())
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectHeader().exists("Link")
@@ -866,11 +854,9 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `query temporal entity should return 200 with prev link header if exists`() {
- val firstTemporalEntity = deserializeObject(
- loadSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
- ).minus("@context")
- val secondTemporalEntity = deserializeObject(loadSampleData("beehive.jsonld")).minus("@context")
+ fun `query temporal entity should return 200 with prev link header if exists`() = runTest {
+ val firstTemporalEntity = loadAndExpandSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
+ val secondTemporalEntity = loadAndExpandSampleData("beehive.jsonld")
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
coEvery {
@@ -928,11 +914,9 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `query temporal entity should return 200 with next link header if exists`() {
- val firstTemporalEntity = deserializeObject(
- loadSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
- ).minus("@context")
- val secondTemporalEntity = deserializeObject(loadSampleData("beehive.jsonld")).minus("@context")
+ fun `query temporal entity should return 200 with next link header if exists`() = runTest {
+ val firstTemporalEntity = loadAndExpandSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
+ val secondTemporalEntity = loadAndExpandSampleData("beehive.jsonld")
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
coEvery {
@@ -957,11 +941,9 @@ class TemporalEntityHandlerTests {
}
@Test
- fun `query temporal entity should return 200 with prev and next link header if exists`() {
- val firstTemporalEntity = deserializeObject(
- loadSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
- ).minus("@context")
- val secondTemporalEntity = deserializeObject(loadSampleData("beehive.jsonld")).minus("@context")
+ fun `query temporal entity should return 200 with prev and next link header if exists`() = runTest {
+ val firstTemporalEntity = loadAndExpandSampleData("beehive_with_two_temporal_attributes_evolution.jsonld")
+ val secondTemporalEntity = loadAndExpandSampleData("beehive.jsonld")
coEvery { authorizationService.computeAccessRightFilter(any()) } returns { null }
coEvery {
@@ -1083,7 +1065,7 @@ class TemporalEntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$TEMPERATURE_COMPACT_PROPERTY/$attributeInstanceId")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(instanceTemporalFragment))
.exchange()
@@ -1114,7 +1096,7 @@ class TemporalEntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$TEMPERATURE_COMPACT_PROPERTY/$attributeInstanceId")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(instanceTemporalFragment))
.exchange()
@@ -1144,7 +1126,7 @@ class TemporalEntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$TEMPERATURE_COMPACT_PROPERTY/$attributeInstanceId")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(instanceTemporalFragment))
.exchange()
@@ -1165,7 +1147,7 @@ class TemporalEntityHandlerTests {
fun `modify attribute instance should return a 404 if attributeInstanceId or attribute name is not found`() {
val instanceTemporalFragment =
loadSampleData("fragments/temporal_instance_fragment.jsonld")
- val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_CORE_CONTEXT)
+ val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_TEST_CORE_CONTEXT)
coEvery { entityPayloadService.checkEntityExistence(any()) } returns Unit.right()
coEvery { authorizationService.userCanUpdateEntity(any(), sub) } returns Unit.right()
@@ -1177,7 +1159,7 @@ class TemporalEntityHandlerTests {
webClient.patch()
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$TEMPERATURE_COMPACT_PROPERTY/$attributeInstanceId")
- .header("Link", buildContextLinkHeader(APIC_COMPOUND_CONTEXT))
+ .header("Link", APIC_HEADER_LINK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(instanceTemporalFragment))
.exchange()
@@ -1542,7 +1524,7 @@ class TemporalEntityHandlerTests {
@Test
fun `delete attribute instance temporal should return 204`() {
- val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_CORE_CONTEXT)
+ val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_TEST_CORE_CONTEXT)
coEvery {
entityPayloadService.checkEntityExistence(any())
} returns Unit.right()
@@ -1555,7 +1537,7 @@ class TemporalEntityHandlerTests {
webClient
.method(HttpMethod.DELETE)
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$temporalEntityAttributeName/$attributeInstanceId")
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isNoContent
.expectBody().isEmpty
@@ -1578,7 +1560,7 @@ class TemporalEntityHandlerTests {
webClient
.method(HttpMethod.DELETE)
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$temporalEntityAttributeName/$attributeInstanceId")
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isNotFound
.expectBody().json(
@@ -1599,7 +1581,7 @@ class TemporalEntityHandlerTests {
@Test
fun `delete attribute instance temporal should return 404 if attributeInstanceId or attribute name is not found`() {
- val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_CORE_CONTEXT)
+ val expandedAttr = JsonLdUtils.expandJsonLdTerm(temporalEntityAttributeName, NGSILD_TEST_CORE_CONTEXT)
coEvery {
entityPayloadService.checkEntityExistence(any())
@@ -1615,7 +1597,7 @@ class TemporalEntityHandlerTests {
webClient
.method(HttpMethod.DELETE)
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$temporalEntityAttributeName/$attributeInstanceId")
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isNotFound
.expectBody().json(
@@ -1653,7 +1635,7 @@ class TemporalEntityHandlerTests {
webClient
.method(HttpMethod.DELETE)
.uri("/ngsi-ld/v1/temporal/entities/$entityUri/attrs/$temporalEntityAttributeName/$attributeInstanceId")
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isForbidden
.expectBody().json(
diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandlerTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandlerTests.kt
index d853c43e3..9b297bd01 100644
--- a/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandlerTests.kt
+++ b/search-service/src/test/kotlin/com/egm/stellio/search/web/TemporalEntityOperationsHandlerTests.kt
@@ -30,8 +30,6 @@ import java.time.ZonedDateTime
@Import(WebSecurityTestConfig::class)
class TemporalEntityOperationsHandlerTests {
- private lateinit var apicHeaderLink: String
-
@Autowired
private lateinit var webClient: WebTestClient
@@ -43,8 +41,6 @@ class TemporalEntityOperationsHandlerTests {
@BeforeAll
fun configureWebClientDefaults() {
- apicHeaderLink = buildContextLinkHeader(APIC_COMPOUND_CONTEXT)
-
webClient = webClient.mutate()
.apply(mockJwt().jwt { it.subject(MOCK_USER_SUB) })
.apply(csrf())
@@ -84,7 +80,7 @@ class TemporalEntityOperationsHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entityOperations/query?options=temporalValues")
.bodyValue(query)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
@@ -133,7 +129,7 @@ class TemporalEntityOperationsHandlerTests {
webClient.post()
.uri("/ngsi-ld/v1/temporal/entityOperations/query?options=temporalValues&count=true")
.bodyValue(query)
- .header("Link", apicHeaderLink)
+ .header("Link", APIC_HEADER_LINK)
.exchange()
.expectStatus().isOk
.expectHeader().valueEquals(RESULTS_COUNT_HEADER, "2")
diff --git a/search-service/src/test/kotlin/db/migration/V0_29_JsonLd_migrationTests.kt b/search-service/src/test/kotlin/db/migration/V0_29_JsonLd_migrationTests.kt
index 645011f5e..8266a912e 100644
--- a/search-service/src/test/kotlin/db/migration/V0_29_JsonLd_migrationTests.kt
+++ b/search-service/src/test/kotlin/db/migration/V0_29_JsonLd_migrationTests.kt
@@ -1,6 +1,6 @@
package db.migration
-import com.egm.stellio.shared.util.APIC_COMPOUND_CONTEXT
+import com.egm.stellio.shared.util.APIC_COMPOUND_CONTEXTS
import com.egm.stellio.shared.util.JsonLdUtils
import com.egm.stellio.shared.util.JsonUtils.deserializeAsMap
import com.egm.stellio.shared.util.loadSampleData
@@ -12,7 +12,7 @@ import org.springframework.test.context.ActiveProfiles
@ActiveProfiles("test")
class V0_29_JsonLd_migrationTests {
- private val contexts = listOf(APIC_COMPOUND_CONTEXT)
+ private val contexts = APIC_COMPOUND_CONTEXTS
@Test
fun `it should remove instances when attribute has more than one instance with the same datasetId`() = runTest {
diff --git a/search-service/src/test/resources/junit-platform.properties b/search-service/src/test/resources/junit-platform.properties
index 2af5bf864..9911aeba0 100644
--- a/search-service/src/test/resources/junit-platform.properties
+++ b/search-service/src/test/resources/junit-platform.properties
@@ -1 +1,2 @@
junit.jupiter.testinstance.lifecycle.default=per_class
+junit.jupiter.extensions.autodetection.enabled=true
diff --git a/search-service/src/test/resources/logback-test.xml b/search-service/src/test/resources/logback-test.xml
index 6f4662426..81c32e60b 100644
--- a/search-service/src/test/resources/logback-test.xml
+++ b/search-service/src/test/resources/logback-test.xml
@@ -19,6 +19,7 @@
+
diff --git a/search-service/src/test/resources/ngsild/apiary.jsonld b/search-service/src/test/resources/ngsild/apiary.jsonld
index 1efc5e6bd..e9ed32250 100644
--- a/search-service/src/test/resources/ngsild/apiary.jsonld
+++ b/search-service/src/test/resources/ngsild/apiary.jsonld
@@ -2,6 +2,6 @@
"id":"urn:ngsi-ld:Apiary:05",
"type":"Apiary",
"@context":[
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/aquac/BreedingService.json b/search-service/src/test/resources/ngsild/aquac/BreedingService.json
deleted file mode 100644
index 9ef25f9ce..000000000
--- a/search-service/src/test/resources/ngsild/aquac/BreedingService.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "id":"urn:ngsi-ld:BreedingService:0214",
- "type":"BreedingService",
- "location":{
- "type":"GeoProperty",
- "value":{
- "type":"Point",
- "coordinates":[
- -8.5,
- 41.2
- ]
- }
- },
- "@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/shared-jsonld-contexts/egm.jsonld",
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac.jsonld",
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
- ]
-}
diff --git a/search-service/src/test/resources/ngsild/aquac/breedingService.jsonld b/search-service/src/test/resources/ngsild/aquac/breedingService.jsonld
new file mode 100644
index 000000000..7a0294978
--- /dev/null
+++ b/search-service/src/test/resources/ngsild/aquac/breedingService.jsonld
@@ -0,0 +1,17 @@
+{
+ "id":"urn:ngsi-ld:BreedingService:0214",
+ "type":"BreedingService",
+ "location":{
+ "type":"GeoProperty",
+ "value":{
+ "type":"Point",
+ "coordinates":[
+ -8.5,
+ 41.2
+ ]
+ }
+ },
+ "@context": [
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
+ ]
+}
diff --git a/search-service/src/test/resources/ngsild/beehive.jsonld b/search-service/src/test/resources/ngsild/beehive.jsonld
index d67e1ffa5..cc172a46a 100644
--- a/search-service/src/test/resources/ngsild/beehive.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive.jsonld
@@ -26,6 +26,6 @@
"object": "urn:ngsi-ld:Beekeeper:Pascal"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_minimal.jsonld b/search-service/src/test/resources/ngsild/beehive_minimal.jsonld
index 4b0f4cc89..649ef1afd 100644
--- a/search-service/src/test/resources/ngsild/beehive_minimal.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_minimal.jsonld
@@ -2,6 +2,6 @@
"id": "urn:ngsi-ld:BeeHive:TESTC",
"type": "BeeHive",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_multi_instance_property.jsonld b/search-service/src/test/resources/ngsild/beehive_multi_instance_property.jsonld
index e78dacf95..3f12aa000 100644
--- a/search-service/src/test/resources/ngsild/beehive_multi_instance_property.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_multi_instance_property.jsonld
@@ -27,6 +27,6 @@
}
],
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_two_temporal_properties.jsonld b/search-service/src/test/resources/ngsild/beehive_two_temporal_properties.jsonld
index defd6eaf8..4075c3119 100644
--- a/search-service/src/test/resources/ngsild/beehive_two_temporal_properties.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_two_temporal_properties.jsonld
@@ -33,6 +33,6 @@
"object": "urn:ngsi-ld:Beekeeper:Pascal"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_with_sap.jsonld b/search-service/src/test/resources/ngsild/beehive_with_sap.jsonld
index cc7f5dba9..bd297bcd7 100644
--- a/search-service/src/test/resources/ngsild/beehive_with_sap.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_with_sap.jsonld
@@ -10,7 +10,7 @@
"value": "AUTH_READ"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/authorization/jsonld-contexts/authorization.jsonld",
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/authorization.jsonld",
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_with_scope.jsonld b/search-service/src/test/resources/ngsild/beehive_with_scope.jsonld
index de6b2e03f..df43d3f6a 100644
--- a/search-service/src/test/resources/ngsild/beehive_with_scope.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_with_scope.jsonld
@@ -3,6 +3,6 @@
"type": "BeeHive",
"scope": "/A",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution.jsonld b/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution.jsonld
index 008c1d7ea..413ea392b 100644
--- a/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution.jsonld
@@ -40,5 +40,8 @@
"object": "urn:ngsi-ld:Sensor:IncomingSensor"
}
}
+ ],
+ "@context":[
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution_temporal_values.jsonld b/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution_temporal_values.jsonld
index 4551fa75b..64722ed5a 100644
--- a/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/beehive_with_two_temporal_attributes_evolution_temporal_values.jsonld
@@ -1,22 +1,21 @@
{
"id": "urn:ngsi-ld:BeeHive:TESTC",
"type": "BeeHive",
- "incoming": [
- {
+ "incoming": {
"type": "Property",
"values": [
[1543.0, "2020-01-24T13:01:22.066Z"],
[1600.0, "2020-01-24T14:01:22.066Z"]
]
- }
- ],
- "outgoing": [
- {
+ },
+ "outgoing": {
"type": "Property",
"values": [
[133.0, "2020-01-24T13:01:22.066Z"],
[100.0, "2020-01-24T14:01:22.066Z"]
]
- }
+ },
+ "@context":[
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/beekeeper.jsonld b/search-service/src/test/resources/ngsild/beekeeper.jsonld
index 84db148e7..abfe62f9c 100644
--- a/search-service/src/test/resources/ngsild/beekeeper.jsonld
+++ b/search-service/src/test/resources/ngsild/beekeeper.jsonld
@@ -2,6 +2,6 @@
"id":"urn:ngsi-ld:Beekeeper:04",
"type":"Beekeeper",
"@context":[
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/entity_with_all_attributes_1.jsonld b/search-service/src/test/resources/ngsild/entity_with_all_attributes_1.jsonld
index 3c55f875e..926d6d75b 100644
--- a/search-service/src/test/resources/ngsild/entity_with_all_attributes_1.jsonld
+++ b/search-service/src/test/resources/ngsild/entity_with_all_attributes_1.jsonld
@@ -103,6 +103,6 @@
}
},
"@context": [
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/entity_with_all_attributes_2.jsonld b/search-service/src/test/resources/ngsild/entity_with_all_attributes_2.jsonld
index 099292586..f0ceaf1dc 100644
--- a/search-service/src/test/resources/ngsild/entity_with_all_attributes_2.jsonld
+++ b/search-service/src/test/resources/ngsild/entity_with_all_attributes_2.jsonld
@@ -103,6 +103,6 @@
}
},
"@context": [
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/entity_with_multi_types.jsonld b/search-service/src/test/resources/ngsild/entity_with_multi_types.jsonld
index 2e0d84f4e..ddb937baf 100644
--- a/search-service/src/test/resources/ngsild/entity_with_multi_types.jsonld
+++ b/search-service/src/test/resources/ngsild/entity_with_multi_types.jsonld
@@ -2,6 +2,6 @@
"id": "urn:ngsi-ld:MultiTypes:03",
"type": ["Beekeeper", "Sensor"],
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_aggregated_outgoing.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_aggregated_outgoing.jsonld
index 645bd52dc..0c8f276ea 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_aggregated_outgoing.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_aggregated_outgoing.jsonld
@@ -1,31 +1,83 @@
{
- "id": "urn:ngsi-ld:Beehive:1234",
- "type": "BeeHive",
- "outgoing": {
- "type": "Property",
- "sum": [
- [
- 12,
- "2020-03-25T08:29:17.965206Z",
- "2020-03-25T10:29:17.965206Z"
+ "@id": "urn:ngsi-ld:Beehive:1234",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://uri.etsi.org/ngsi-ld/createdAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "$now"
+ }
+ ],
+ "https://ontology.eglobalmark.com/apic#outgoing": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
],
- [
- 14,
- "2020-03-25T10:29:17.965206Z",
- "2020-03-25T12:29:17.965206Z"
- ]
- ],
- "avg": [
- [
- 2,
- "2020-03-25T08:29:17.965206Z",
- "2020-03-25T10:29:17.965206Z"
+ "https://uri.etsi.org/ngsi-ld/sum": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 12
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T10:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 14
+ },
+ {
+ "@value": "2020-03-25T10:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T12:29:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
],
- [
- 2.5,
- "2020-03-25T10:29:17.965206Z",
- "2020-03-25T12:29:17.965206Z"
+ "https://uri.etsi.org/ngsi-ld/avg": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 2
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T10:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 2.5
+ },
+ {
+ "@value": "2020-03-25T10:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T12:29:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
]
- ]
- }
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_empty_outgoing.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_empty_outgoing.jsonld
index 6a376ea9d..bdd2e80c1 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_empty_outgoing.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_empty_outgoing.jsonld
@@ -1,5 +1,13 @@
{
- "id":"urn:ngsi-ld:Beehive:1234",
- "type":"BeeHive",
- "outgoing": []
+ "@id": "urn:ngsi-ld:Beehive:1234",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://uri.etsi.org/ngsi-ld/createdAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "$now"
+ }
+ ],
+ "https://ontology.eglobalmark.com/apic#outgoing": []
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances.jsonld
index e514cb9e9..0928207b7 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances.jsonld
@@ -1,29 +1,112 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:01234",
- "value" : 550.0,
- "instanceId" : "urn:ngsi-ld:Instance:01234",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:01234",
- "value" : 650.0,
- "instanceId" : "urn:ngsi-ld:Instance:01235",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : 487.0,
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : 698.0,
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:01234"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:01234"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 550.0
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:01235"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:01234"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 650.0
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 487.0
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 698.0
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_temporal_values.jsonld
index ce8b9fb6e..43d0a2df8 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_temporal_values.jsonld
@@ -1,9 +1,44 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "values" : [ ["Beehive_incoming_123","2020-03-25T08:29:17.965206Z"], ["Beehive_incoming_124","2020-03-25T08:33:17.965206Z"] ]
- }
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "Beehive_incoming_123"
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": "Beehive_incoming_124"
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values.jsonld
index d5fe27e52..4e2c7c542 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values.jsonld
@@ -1,17 +1,60 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : "Beehive_incoming_123",
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : "Beehive_incoming_124",
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_123"
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_124"
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values_with_audit.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values_with_audit.jsonld
index 93034293e..5271c0ba5 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values_with_audit.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_string_values_with_audit.jsonld
@@ -1,19 +1,84 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : "Beehive_incoming_123",
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z",
- "sub": "sub1"
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "value" : "Beehive_incoming_124",
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z",
- "sub": "sub2"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_123"
+ }
+ ],
+ "https://ontology.eglobalmark.com/authorization#sub": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "sub1"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_124"
+ }
+ ],
+ "https://ontology.eglobalmark.com/authorization#sub": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "sub2"
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_temporal_values.jsonld
index 21a2e1e7b..caad2fe99 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_temporal_values.jsonld
@@ -1,13 +1,80 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:01234",
- "values" : [ [550.0,"2020-03-25T08:29:17.965206Z"], [650.0,"2020-03-25T08:33:17.965206Z"] ]
- }, {
- "type" : "Property",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "values" : [ [487.0,"2020-03-25T08:29:17.965206Z"], [698.0,"2020-03-25T08:33:17.965206Z"] ]
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:01234"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 550.0
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 650.0
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 487.0
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 698.0
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId.jsonld
index 4c6c11ec3..052ac8d03 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId.jsonld
@@ -1,15 +1,50 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "value" : 550.0,
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Property",
- "value" : 650.0,
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 550.0
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 650.0
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_temporal_values.jsonld
index 598b60fd7..97a3674fb 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_temporal_values.jsonld
@@ -1,8 +1,39 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : {
- "type" : "Property",
- "values" : [ ["Beehive_incoming_123","2020-03-25T08:29:17.965206Z"], ["Beehive_incoming_124","2020-03-25T08:33:17.965206Z"] ]
- }
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "Beehive_incoming_123"
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": "Beehive_incoming_124"
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_values.jsonld
index 852fe621c..728087365 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_string_values.jsonld
@@ -1,15 +1,50 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Property",
- "value" : "Beehive_incoming_123",
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Property",
- "value" : "Beehive_incoming_124",
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_123"
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "Beehive_incoming_124"
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_temporal_values.jsonld
index 45dc973b2..3c1e0dbca 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_incoming_multi_instances_without_datasetId_temporal_values.jsonld
@@ -1,8 +1,39 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : {
- "type" : "Property",
- "values" : [ [550.0,"2020-03-25T08:29:17.965206Z"], [650.0,"2020-03-25T08:33:17.965206Z"] ]
- }
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 550.0
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 650.0
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_temporal_values.jsonld
index 126edbb3a..cb274be28 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_temporal_values.jsonld
@@ -1,9 +1,44 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : {
- "type" : "Relationship",
- "datasetId" : "urn:ngsi-ld:Dataset:45678",
- "objects" : [ ["urn:ngsi-ld:Entity:1234","2020-03-25T08:29:17.965206Z"], ["urn:ngsi-ld:Entity:5678","2020-03-25T08:33:17.965206Z"] ]
- }
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Relationship"
+ ],
+ "https://uri.etsi.org/ngsi-ld/datasetId": [
+ {
+ "@id": "urn:ngsi-ld:Dataset:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasObjects": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "urn:ngsi-ld:Entity:1234"
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": "urn:ngsi-ld:Entity:5678"
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_without_datasetId.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_without_datasetId.jsonld
index d45ace0bd..5f015132c 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_without_datasetId.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_relationship_multi_instances_without_datasetId.jsonld
@@ -1,15 +1,50 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "incoming" : [ {
- "type" : "Relationship",
- "object" : "urn:ngsi-ld:Entity:1234",
- "instanceId" : "urn:ngsi-ld:Instance:45678",
- "observedAt" : "2020-03-25T08:29:17.965206Z"
- }, {
- "type" : "Relationship",
- "object" : "urn:ngsi-ld:Entity:5678",
- "instanceId" : "urn:ngsi-ld:Instance:45679",
- "observedAt" : "2020-03-25T08:33:17.965206Z"
- } ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Relationship"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasObject": [
+ {
+ "@id": "urn:ngsi-ld:Entity:1234"
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Relationship"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasObject": [
+ {
+ "@id": "urn:ngsi-ld:Entity:5678"
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances.jsonld
index 94b5f66c7..fa9d04beb 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances.jsonld
@@ -1,13 +1,43 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "scope" : [{
- "type": "Property",
- "value": ["/A/B", "/C/D"],
- "modifiedAt": "2020-03-25T08:29:17.965206Z"
- }, {
- "type": "Property",
- "value": ["/C/D"],
- "modifiedAt": "2020-03-25T09:29:17.965206Z"
- }]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://uri.etsi.org/ngsi-ld/scope": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "/A/B"
+ },
+ {
+ "@value": "/C/D"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/modifiedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "/C/D"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/modifiedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T09:29:17.965206Z"
+ }
+ ]
+ }
+ ]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances_temporal_values.jsonld b/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances_temporal_values.jsonld
index 60cbfc466..c5e79b2be 100644
--- a/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances_temporal_values.jsonld
+++ b/search-service/src/test/resources/ngsild/expectations/beehive_scope_multi_instances_temporal_values.jsonld
@@ -1,8 +1,48 @@
{
- "id" : "urn:ngsi-ld:BeeHive:TESTC",
- "type" : "BeeHive",
- "scope" : {
- "type" : "Property",
- "values" : [ [["/A/B", "/C/D"],"2020-03-25T08:29:17.965206Z"], [["/C/D"],"2020-03-25T09:29:17.965206Z"] ]
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://uri.etsi.org/ngsi-ld/scope": {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "/A/B"
+ },
+ {
+ "@value": "/C/D"
+ }
+ ]
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "/C/D"
+ }
+ ]
+ },
+ {
+ "@value": "2020-03-25T09:29:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
}
diff --git a/search-service/src/test/resources/ngsild/expectations/query/two_beehives.json b/search-service/src/test/resources/ngsild/expectations/query/two_beehives.json
index 7fea5dc75..49ffe76c3 100644
--- a/search-service/src/test/resources/ngsild/expectations/query/two_beehives.json
+++ b/search-service/src/test/resources/ngsild/expectations/query/two_beehives.json
@@ -1,26 +1,71 @@
[
{
- "id":"urn:ngsi-ld:BeeHive:TESTC",
- "type":"BeeHive",
- "incoming":[
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
{
- "type":"Property",
- "value":20,
- "instanceId":"urn:ngsi-ld:Instance:45678",
- "observedAt":"2020-03-25T08:33:17.965206Z",
- "sub": "sub"
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45678"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 20
+ }
+ ],
+ "https://ontology.eglobalmark.com/authorization#sub": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "sub"
+ }
+ ]
+ }
+ ]
}
]
},
{
- "id":"urn:ngsi-ld:BeeHive:TESTD",
- "type":"BeeHive",
- "outgoing":[
+ "@id": "urn:ngsi-ld:BeeHive:TESTD",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#outgoing": [
{
- "type":"Property",
- "value":25,
- "instanceId":"urn:ngsi-ld:Instance:45679",
- "observedAt":"2020-03-25T08:33:17.965206Z"
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/instanceId": [
+ {
+ "@id": "urn:ngsi-ld:Instance:45679"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": 25
+ }
+ ]
}
]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/query/two_beehives_temporal_values.json b/search-service/src/test/resources/ngsild/expectations/query/two_beehives_temporal_values.json
index b1bd89f81..b0b4425e9 100644
--- a/search-service/src/test/resources/ngsild/expectations/query/two_beehives_temporal_values.json
+++ b/search-service/src/test/resources/ngsild/expectations/query/two_beehives_temporal_values.json
@@ -1,28 +1,60 @@
[
- {
- "id":"urn:ngsi-ld:BeeHive:TESTC",
- "type":"BeeHive",
- "incoming": {
- "type":"Property",
- "values":[
- [
- 20,
- "2020-03-25T08:33:17.965206Z"
+ {
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 20
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
+ }
+ ]
}
- },
- {
- "id":"urn:ngsi-ld:BeeHive:TESTD",
- "type":"BeeHive",
- "outgoing": {
- "type":"Property",
- "values":[
- [
- 25,
- "2020-03-25T08:33:17.965206Z"
+ ]
+ },
+ {
+ "@id": "urn:ngsi-ld:BeeHive:TESTD",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#outgoing": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 25
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
+ }
+ ]
}
- }
+ ]
+ }
]
diff --git a/search-service/src/test/resources/ngsild/expectations/query/two_entities_temporal_values_property_and_relationship.json b/search-service/src/test/resources/ngsild/expectations/query/two_entities_temporal_values_property_and_relationship.json
index 91143499e..1a907f952 100644
--- a/search-service/src/test/resources/ngsild/expectations/query/two_entities_temporal_values_property_and_relationship.json
+++ b/search-service/src/test/resources/ngsild/expectations/query/two_entities_temporal_values_property_and_relationship.json
@@ -1,46 +1,106 @@
[
- {
- "id":"urn:ngsi-ld:BeeHive:TESTC",
- "type":"BeeHive",
- "incoming": {
- "type":"Property",
- "values":[
- [
- 20,
- "2020-03-25T08:33:17.965206Z"
+ {
+ "@id": "urn:ngsi-ld:BeeHive:TESTC",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#incoming": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 20
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
- },
- "managedBy": {
- "type": "Relationship",
- "objects": [
- [
- "urn:ngsi-ld:Beekeeper:1234",
- "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ],
+ "https://ontology.eglobalmark.com/egm#managedBy": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Relationship"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasObjects": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "urn:ngsi-ld:Beekeeper:1234"
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
+ }
+ ]
}
- },
- {
- "id":"urn:ngsi-ld:BeeHive:TESTD",
- "type":"BeeHive",
- "outgoing": {
- "type":"Property",
- "values":[
- [
- 25,
- "2020-03-25T08:33:17.965206Z"
+ ]
+ },
+ {
+ "@id": "urn:ngsi-ld:BeeHive:TESTD",
+ "@type": [
+ "https://ontology.eglobalmark.com/apic#BeeHive"
+ ],
+ "https://ontology.eglobalmark.com/apic#outgoing": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 25
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
- },
- "managedBy": {
- "type": "Relationship",
- "objects": [
- [
- "urn:ngsi-ld:Beekeeper:5678",
- "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
+ ],
+ "https://ontology.eglobalmark.com/egm#managedBy": [
+ {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Relationship"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasObjects": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "urn:ngsi-ld:Beekeeper:5678"
+ },
+ {
+ "@value": "2020-03-25T08:33:17.965206Z"
+ }
+ ]
+ }
]
- ]
+ }
+ ]
}
- }
+ ]
+ }
]
diff --git a/search-service/src/test/resources/ngsild/expectations/scope_aggregated_instances.json b/search-service/src/test/resources/ngsild/expectations/scope_aggregated_instances.json
index 2f282f079..4001e0fc8 100644
--- a/search-service/src/test/resources/ngsild/expectations/scope_aggregated_instances.json
+++ b/search-service/src/test/resources/ngsild/expectations/scope_aggregated_instances.json
@@ -1,29 +1,71 @@
{
- "scope": {
- "type": "Property",
- "sum": [
- [
- 12,
- "2020-03-25T08:29:17.965206Z",
- "2020-03-25T10:29:18.965206Z"
- ],
- [
- 14,
- "2020-03-25T10:29:18.965206Z",
- "2020-03-25T12:29:19.965206Z"
- ]
+ "https://uri.etsi.org/ngsi-ld/scope": {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
],
- "avg": [
- [
- 2,
- "2020-03-25T08:29:17.965206Z",
- "2020-03-25T10:29:18.965206Z"
- ],
- [
- 2.5,
- "2020-03-25T10:29:18.965206Z",
- "2020-03-25T12:29:19.965206Z"
- ]
+ "https://uri.etsi.org/ngsi-ld/sum": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 12
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T10:29:18.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 14
+ },
+ {
+ "@value": "2020-03-25T10:29:18.965206Z"
+ },
+ {
+ "@value": "2020-03-25T12:29:19.965206Z"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/avg": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": 2
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ },
+ {
+ "@value": "2020-03-25T10:29:18.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@value": 2.5
+ },
+ {
+ "@value": "2020-03-25T10:29:18.965206Z"
+ },
+ {
+ "@value": "2020-03-25T12:29:19.965206Z"
+ }
+ ]
+ }
+ ]
+ }
]
}
}
diff --git a/search-service/src/test/resources/ngsild/expectations/scope_full_instances.json b/search-service/src/test/resources/ngsild/expectations/scope_full_instances.json
index 5fa547855..c25bcfc57 100644
--- a/search-service/src/test/resources/ngsild/expectations/scope_full_instances.json
+++ b/search-service/src/test/resources/ngsild/expectations/scope_full_instances.json
@@ -1,20 +1,42 @@
{
- "scope": [
+ "https://uri.etsi.org/ngsi-ld/scope": [
{
- "type": "Property",
- "value": [
- "/A/B",
- "/B/C"
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
],
- "observedAt": "2020-03-25T08:29:17.965206Z"
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "/A/B"
+ },
+ {
+ "@value": "/B/C"
+ }
+ ],
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
},
{
- "type": "Property",
- "value": [
- "/B/C",
- "/D/E"
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValue": [
+ {
+ "@value": "/B/C"
+ },
+ {
+ "@value": "/D/E"
+ }
],
- "observedAt": "2020-03-25T08:30:17.965206Z"
+ "https://uri.etsi.org/ngsi-ld/observedAt": [
+ {
+ "@type": "https://uri.etsi.org/ngsi-ld/DateTime",
+ "@value": "2020-03-25T08:30:17.965206Z"
+ }
+ ]
}
]
}
diff --git a/search-service/src/test/resources/ngsild/expectations/scope_temporal_values_instances.json b/search-service/src/test/resources/ngsild/expectations/scope_temporal_values_instances.json
index 11907f86a..08b333aec 100644
--- a/search-service/src/test/resources/ngsild/expectations/scope_temporal_values_instances.json
+++ b/search-service/src/test/resources/ngsild/expectations/scope_temporal_values_instances.json
@@ -1,21 +1,47 @@
{
- "scope": {
- "type": "Property",
- "values": [
- [
- [
- "/A/B",
- "/B/C"
- ],
- "2020-03-25T08:29:17.965206Z"
- ],
- [
- [
- "/B/C",
- "/D/E"
- ],
- "2020-03-25T08:30:17.965206Z"
- ]
+ "https://uri.etsi.org/ngsi-ld/scope": {
+ "@type": [
+ "https://uri.etsi.org/ngsi-ld/Property"
+ ],
+ "https://uri.etsi.org/ngsi-ld/hasValues": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "/A/B"
+ },
+ {
+ "@value": "/B/C"
+ }
+ ]
+ },
+ {
+ "@value": "2020-03-25T08:29:17.965206Z"
+ }
+ ]
+ },
+ {
+ "@list": [
+ {
+ "@list": [
+ {
+ "@value": "/B/C"
+ },
+ {
+ "@value": "/D/E"
+ }
+ ]
+ },
+ {
+ "@value": "2020-03-25T08:30:17.965206Z"
+ }
+ ]
+ }
+ ]
+ }
]
}
}
diff --git a/search-service/src/test/resources/ngsild/fragments/temporal_instance_fragment.jsonld b/search-service/src/test/resources/ngsild/fragments/temporal_instance_fragment.jsonld
index 3ab3fe316..d9628f0cb 100644
--- a/search-service/src/test/resources/ngsild/fragments/temporal_instance_fragment.jsonld
+++ b/search-service/src/test/resources/ngsild/fragments/temporal_instance_fragment.jsonld
@@ -1,7 +1,5 @@
-[
- {
- "type": "Property",
- "value": 10,
- "observedAt": "2023-03-13T12:33:06Z"
- }
-]
\ No newline at end of file
+{
+ "type": "Property",
+ "value": 10,
+ "observedAt": "2023-03-13T12:33:06Z"
+}
diff --git a/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file.json b/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file.json
index 5ccb0f6e3..694ae2682 100644
--- a/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file.json
+++ b/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file.json
@@ -11,7 +11,7 @@
"object": "urn:ngsi-ld:Device:HCMR-AQUABOX1"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
},
{
@@ -26,7 +26,7 @@
"object": "urn:ngsi-ld:Device:HCMR-AQUABOX1"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
},
{
@@ -37,7 +37,7 @@
"value": "BIOCEANOR"
},
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
}
]
diff --git a/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file_one_entity_missing_context.json b/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file_one_entity_missing_context.json
index 491624867..d601b8cf0 100644
--- a/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file_one_entity_missing_context.json
+++ b/search-service/src/test/resources/ngsild/hcmr/HCMR_test_file_one_entity_missing_context.json
@@ -3,9 +3,7 @@
"id": "urn:ngsi-ld:Sensor:HCMR-AQUABOX1temperature",
"type": "Sensor",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/shared-jsonld-contexts/egm.jsonld",
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac.jsonld",
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
},
{
@@ -16,9 +14,7 @@
"id": "urn:ngsi-ld:Device:HCMR-AQUABOX1",
"type": "Device",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/shared-jsonld-contexts/egm.jsonld",
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac.jsonld",
- "https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.7.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
}
]
diff --git a/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity.jsonld b/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity.jsonld
index 20475a7c4..431948fb6 100644
--- a/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity.jsonld
+++ b/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity.jsonld
@@ -52,6 +52,6 @@
}
],
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity_first_instance.jsonld b/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity_first_instance.jsonld
index 22eff0cf4..be48f58e5 100644
--- a/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity_first_instance.jsonld
+++ b/search-service/src/test/resources/ngsild/temporal/beehive_create_temporal_entity_first_instance.jsonld
@@ -24,6 +24,6 @@
}
],
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/temporal/beehive_update_temporal_entity.jsonld b/search-service/src/test/resources/ngsild/temporal/beehive_update_temporal_entity.jsonld
index acad55aab..1b235ef66 100644
--- a/search-service/src/test/resources/ngsild/temporal/beehive_update_temporal_entity.jsonld
+++ b/search-service/src/test/resources/ngsild/temporal/beehive_update_temporal_entity.jsonld
@@ -71,6 +71,6 @@
}
],
"@context":[
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
-}
\ No newline at end of file
+}
diff --git a/search-service/src/test/resources/ngsild/temporal/invalid_beehive_create_temporal_entity.jsonld b/search-service/src/test/resources/ngsild/temporal/invalid_beehive_create_temporal_entity.jsonld
index 977a2c8a3..3397aae90 100644
--- a/search-service/src/test/resources/ngsild/temporal/invalid_beehive_create_temporal_entity.jsonld
+++ b/search-service/src/test/resources/ngsild/temporal/invalid_beehive_create_temporal_entity.jsonld
@@ -51,6 +51,6 @@
}
],
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/apic/jsonld-contexts/apic-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/apic-compound.jsonld"
]
}
diff --git a/search-service/src/test/resources/ngsild/two_sensors_one_invalid.jsonld b/search-service/src/test/resources/ngsild/two_sensors_one_invalid.jsonld
index 43b7a6771..1f96193d6 100644
--- a/search-service/src/test/resources/ngsild/two_sensors_one_invalid.jsonld
+++ b/search-service/src/test/resources/ngsild/two_sensors_one_invalid.jsonld
@@ -3,13 +3,13 @@
"id": "urn:ngsi-ld:Sensor:HCMR-AQUABOX1temperature",
"type": "Sensor",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
},
{
"id": "urn:ngsi-ld:Sensor:HCMR-AQUABOX2temperature",
"@context": [
- "https://raw.githubusercontent.com/easy-global-market/ngsild-api-data-models/master/aquac/jsonld-contexts/aquac-compound.jsonld"
+ "http://localhost:8093/jsonld-contexts/aquac-compound.jsonld"
]
}
]
diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts
index 0b186007d..112b58960 100644
--- a/shared/build.gradle.kts
+++ b/shared/build.gradle.kts
@@ -31,6 +31,8 @@ dependencies {
// to ensure we are using mocks and spies from springmockk lib instead
exclude(module = "mockito-core")
}
+ testFixturesImplementation("org.mock-server:mockserver-netty-no-dependencies:5.15.0")
+ testFixturesImplementation("org.mock-server:mockserver-client-java-no-dependencies:5.15.0")
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.4")
diff --git a/shared/config/detekt/baseline.xml b/shared/config/detekt/baseline.xml
index aa4e5a0a6..4f8418074 100644
--- a/shared/config/detekt/baseline.xml
+++ b/shared/config/detekt/baseline.xml
@@ -3,15 +3,14 @@
CyclomaticComplexMethod:ExceptionHandler.kt$ExceptionHandler$@ExceptionHandler fun transformErrorResponse(throwable: Throwable): ResponseEntity<ProblemDetail>
- LongMethod:JsonLdEntityTests.kt$JsonLdEntityTests$@Test fun `it should return simplified GeoJSON entities`()
+ LongMethod:ExpandedEntityTests.kt$ExpandedEntityTests$@Test fun `it should return simplified GeoJSON entities`()
LongMethod:QueryUtils.kt$private fun transformQQueryToSqlJsonPath( mainAttributePath: List<ExpandedTerm>, trailingAttributePath: List<ExpandedTerm>, operator: String, value: String )
- LongParameterList:ApiResponses.kt$( body: String, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap<String, String>, mediaType: MediaType, contextLink: String )
- LongParameterList:ApiResponses.kt$( entities: Any, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap<String, String>, mediaType: MediaType, contextLink: String )
+ LongParameterList:ApiResponses.kt$( body: String, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap<String, String>, mediaType: MediaType, contexts: List<String> )
+ LongParameterList:ApiResponses.kt$( entities: Any, count: Int, resourceUrl: String, paginationQuery: PaginationQuery, requestParams: MultiValueMap<String, String>, mediaType: MediaType, contexts: List<String> )
LongParameterList:NgsiLdEntity.kt$NgsiLdEntity$( val id: URI, val types: List<ExpandedTerm>, val scopes: List<String>?, val relationships: List<NgsiLdRelationship>, val properties: List<NgsiLdProperty>, val geoProperties: List<NgsiLdGeoProperty>, val contexts: List<String> )
LongParameterList:NgsiLdEntity.kt$NgsiLdGeoPropertyInstance$( val coordinates: WKTCoordinates, createdAt: ZonedDateTime?, modifiedAt: ZonedDateTime?, observedAt: ZonedDateTime?, datasetId: URI?, properties: List<NgsiLdProperty>, relationships: List<NgsiLdRelationship> )
LongParameterList:NgsiLdEntity.kt$NgsiLdPropertyInstance$( val value: Any, val unitCode: String?, createdAt: ZonedDateTime?, modifiedAt: ZonedDateTime?, observedAt: ZonedDateTime?, datasetId: URI?, properties: List<NgsiLdProperty>, relationships: List<NgsiLdRelationship> )
LongParameterList:NgsiLdEntity.kt$NgsiLdRelationshipInstance$( val objectId: URI, createdAt: ZonedDateTime?, modifiedAt: ZonedDateTime?, observedAt: ZonedDateTime?, datasetId: URI?, properties: List<NgsiLdProperty>, relationships: List<NgsiLdRelationship> )
- NestedBlockDepth:JsonLdUtils.kt$JsonLdUtils$fun getPropertyValueFromMap(value: ExpandedAttributeInstance, propertyKey: String): Any?
SpreadOperator:EntityEvent.kt$EntityEvent$( *[ JsonSubTypes.Type(value = EntityCreateEvent::class), JsonSubTypes.Type(value = EntityReplaceEvent::class), JsonSubTypes.Type(value = EntityDeleteEvent::class), JsonSubTypes.Type(value = AttributeAppendEvent::class), JsonSubTypes.Type(value = AttributeReplaceEvent::class), JsonSubTypes.Type(value = AttributeUpdateEvent::class), JsonSubTypes.Type(value = AttributeDeleteEvent::class), JsonSubTypes.Type(value = AttributeDeleteAllInstancesEvent::class) ] )
SwallowedException:JsonLdUtils.kt$JsonLdUtils$e: JsonLdError
TooManyFunctions:JsonLdUtils.kt$JsonLdUtils
diff --git a/shared/src/main/kotlin/com/egm/stellio/shared/model/ApiExceptions.kt b/shared/src/main/kotlin/com/egm/stellio/shared/model/ApiExceptions.kt
index 96b9dc168..e96b51108 100644
--- a/shared/src/main/kotlin/com/egm/stellio/shared/model/ApiExceptions.kt
+++ b/shared/src/main/kotlin/com/egm/stellio/shared/model/ApiExceptions.kt
@@ -1,6 +1,7 @@
package com.egm.stellio.shared.model
-import com.github.jsonldjava.core.JsonLdError
+import com.apicatalog.jsonld.JsonLdError
+import com.apicatalog.jsonld.JsonLdErrorCode
sealed class APIException(
override val message: String
@@ -20,11 +21,12 @@ data class LdContextNotAvailableException(override val message: String) : APIExc
data class NonexistentTenantException(override val message: String) : APIException(message)
data class NotAcceptableException(override val message: String) : APIException(message)
-fun Throwable.toAPIException(fallbackMessage: String = ""): APIException =
+fun Throwable.toAPIException(specificMessage: String? = null): APIException =
when (this) {
+ is APIException -> this
is JsonLdError ->
- if (this.type == JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED)
- LdContextNotAvailableException("Unable to load remote context (cause was: $this)")
+ if (this.code == JsonLdErrorCode.LOADING_REMOTE_CONTEXT_FAILED)
+ LdContextNotAvailableException(specificMessage ?: "Unable to load remote context (cause was: $this)")
else BadRequestDataException("Unexpected error while parsing payload (cause was: $this)")
- else -> BadRequestDataException(this.message ?: fallbackMessage)
+ else -> BadRequestDataException(specificMessage ?: this.localizedMessage)
}
diff --git a/shared/src/main/kotlin/com/egm/stellio/shared/model/CompactedEntity.kt b/shared/src/main/kotlin/com/egm/stellio/shared/model/CompactedEntity.kt
new file mode 100644
index 000000000..cbbcc998f
--- /dev/null
+++ b/shared/src/main/kotlin/com/egm/stellio/shared/model/CompactedEntity.kt
@@ -0,0 +1,119 @@
+package com.egm.stellio.shared.model
+
+import com.egm.stellio.shared.util.*
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_CONTEXT
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_OBJECT
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_GEOPROPERTY_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_TERM
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SYSATTRS_TERMS
+
+typealias CompactedEntity = Map
+
+fun CompactedEntity.toKeyValues(): Map =
+ this.mapValues { (_, value) -> simplifyRepresentation(value) }
+
+private fun simplifyRepresentation(value: Any): Any =
+ when (value) {
+ // an attribute with a single instance
+ is Map<*, *> -> simplifyValue(value as Map)
+ // an attribute with multiple instances
+ is List<*> -> value.map {
+ when (it) {
+ is Map<*, *> -> simplifyValue(it as Map)
+ // we keep @context value as it is (List)
+ else -> it
+ }
+ }
+ // keep id, type and other non-reified properties as they are (typically string or list)
+ else -> value
+ }
+
+private fun simplifyValue(value: Map): Any =
+ when (value[JSONLD_TYPE_TERM]) {
+ NGSILD_PROPERTY_TERM, NGSILD_GEOPROPERTY_TERM -> value.getOrDefault(JSONLD_VALUE_TERM, value)
+ NGSILD_RELATIONSHIP_TERM -> value.getOrDefault(JSONLD_OBJECT, value)
+ else -> value
+ }
+
+fun CompactedEntity.toGeoJson(geometryProperty: String): Map {
+ val geometryAttributeContent = this[geometryProperty] as? Map
+ val geometryPropertyValue = geometryAttributeContent?.let {
+ if (it.containsKey(JSONLD_VALUE_TERM)) it[JSONLD_VALUE_TERM]
+ else it
+ }
+
+ return mapOf(
+ JSONLD_ID_TERM to this[JSONLD_ID_TERM]!!,
+ JSONLD_TYPE_TERM to FEATURE_TYPE,
+ GEOMETRY_PROPERTY_TERM to geometryPropertyValue,
+ PROPERTIES_PROPERTY_TERM to this.filter { it.key != JSONLD_ID_TERM }
+ )
+}
+
+fun CompactedEntity.withoutSysAttrs(sysAttrToKeep: String?): Map {
+ val sysAttrsToRemove = NGSILD_SYSATTRS_TERMS.minus(sysAttrToKeep)
+ return this.filter {
+ !sysAttrsToRemove.contains(it.key)
+ }.mapValues {
+ when (it.value) {
+ is Map<*, *> -> (it.value as Map<*, *>).minus(sysAttrsToRemove)
+ is List<*> -> (it.value as List<*>).map { valueInstance ->
+ when (valueInstance) {
+ is Map<*, *> -> valueInstance.minus(sysAttrsToRemove)
+ // we keep @context value as it is (List)
+ else -> valueInstance
+ }
+ }
+
+ else -> it.value
+ }
+ }
+}
+
+/**
+ * Create the final representation of the entity, taking into account the options parameter and the Accept header.
+ *
+ * As a GeoJSON representation may have a null value for a key, returns a Map instead of CompactedEntity.
+ */
+fun CompactedEntity.toFinalRepresentation(
+ ngsiLdDataRepresentation: NgsiLdDataRepresentation
+): Map =
+ this.let {
+ if (!ngsiLdDataRepresentation.includeSysAttrs) it.withoutSysAttrs(ngsiLdDataRepresentation.timeproperty)
+ else it
+ }.let {
+ if (ngsiLdDataRepresentation.attributeRepresentation == AttributeRepresentation.SIMPLIFIED) it.toKeyValues()
+ else it
+ }.let {
+ when (ngsiLdDataRepresentation.entityRepresentation) {
+ EntityRepresentation.GEO_JSON ->
+ // geometryProperty is not null when GeoJSON representation is asked (defaults to location)
+ it.toGeoJson(ngsiLdDataRepresentation.geometryProperty!!)
+ EntityRepresentation.JSON -> it.minus(JSONLD_CONTEXT)
+ EntityRepresentation.JSON_LD -> it
+ }
+ }
+
+/**
+ * Create the final representation of a list of entities, taking into account the options parameter
+ * and the Accept header.
+ *
+ * For a GeoJSON representation, the result is a map containing a list of GeoJson objects.
+ */
+fun List.toFinalRepresentation(
+ ngsiLdDataRepresentation: NgsiLdDataRepresentation
+): Any =
+ this.map {
+ it.toFinalRepresentation(ngsiLdDataRepresentation)
+ }.let {
+ if (ngsiLdDataRepresentation.entityRepresentation == EntityRepresentation.GEO_JSON) {
+ mapOf(
+ JSONLD_TYPE_TERM to FEATURE_COLLECTION_TYPE,
+ FEATURES_PROPERTY_TERM to it
+ )
+ } else it
+ }
diff --git a/shared/src/main/kotlin/com/egm/stellio/shared/model/EntityEvent.kt b/shared/src/main/kotlin/com/egm/stellio/shared/model/EntityEvent.kt
index a618fa22f..8ef6476b1 100644
--- a/shared/src/main/kotlin/com/egm/stellio/shared/model/EntityEvent.kt
+++ b/shared/src/main/kotlin/com/egm/stellio/shared/model/EntityEvent.kt
@@ -1,6 +1,5 @@
package com.egm.stellio.shared.model
-import com.egm.stellio.shared.util.ExpandedTerm
import com.egm.stellio.shared.web.DEFAULT_TENANT_URI
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonSubTypes
diff --git a/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedEntity.kt b/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedEntity.kt
new file mode 100644
index 000000000..9c699bf1b
--- /dev/null
+++ b/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedEntity.kt
@@ -0,0 +1,110 @@
+package com.egm.stellio.shared.model
+
+import arrow.core.Either
+import arrow.core.left
+import arrow.core.right
+import com.egm.stellio.shared.util.JsonLdUtils
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_EXPANDED_ENTITY_CORE_MEMBERS
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
+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.entityOrAttrsNotFoundMessage
+import java.time.ZonedDateTime
+
+data class ExpandedEntity(
+ val members: Map,
+ val contexts: List
+) {
+ fun containsAnyOf(expandedAttributes: Set): Boolean =
+ expandedAttributes.isEmpty() || members.keys.any { expandedAttributes.contains(it) }
+
+ fun checkContainsAnyOf(expandedAttributes: Set): Either =
+ if (containsAnyOf(expandedAttributes))
+ Unit.right()
+ else ResourceNotFoundException(entityOrAttrsNotFoundMessage(id, expandedAttributes)).left()
+
+ fun getAttributes(): ExpandedAttributes =
+ members.filter { !JSONLD_EXPANDED_ENTITY_CORE_MEMBERS.contains(it.key) }
+ .mapValues { castAttributeValue(it.value) }
+
+ fun getScopes(): List? =
+ (members as Map>).getScopes()
+
+ /**
+ * Called at entity creation time to populate entity and attributes with createdAt information
+ */
+ fun populateCreationTimeDate(createdAt: ZonedDateTime): ExpandedEntity =
+ ExpandedEntity(
+ members = members.mapValues {
+ if (JSONLD_EXPANDED_ENTITY_CORE_MEMBERS.contains(it.key))
+ it.value
+ else castAttributeValue(it.value).map { expandedAttributeInstance ->
+ expandedAttributeInstance.addDateTimeProperty(
+ NGSILD_CREATED_AT_PROPERTY,
+ createdAt
+ ) as ExpandedAttributeInstance
+ }
+ }.addDateTimeProperty(NGSILD_CREATED_AT_PROPERTY, createdAt),
+ contexts = contexts
+ )
+
+ /**
+ * Called when replacing entity to populate entity and attributes with createdAt and modifiedAt information
+ * for attributes, the modification date is added as the creation date
+ */
+ fun populateReplacementTimeDates(createdAt: ZonedDateTime, replacedAt: ZonedDateTime): ExpandedEntity =
+ ExpandedEntity(
+ members = members.mapValues {
+ if (JSONLD_EXPANDED_ENTITY_CORE_MEMBERS.contains(it.key))
+ it.value
+ else castAttributeValue(it.value).map { expandedAttributeInstance ->
+ expandedAttributeInstance.addDateTimeProperty(
+ NGSILD_CREATED_AT_PROPERTY,
+ replacedAt
+ ) as ExpandedAttributeInstance
+ }
+ }
+ .addDateTimeProperty(NGSILD_CREATED_AT_PROPERTY, createdAt)
+ .addDateTimeProperty(NGSILD_MODIFIED_AT_PROPERTY, replacedAt),
+ contexts = contexts
+ )
+
+ val id by lazy {
+ (members[JSONLD_ID] ?: throw BadRequestDataException("Could not extract id from JSON-LD entity")) as String
+ }
+
+ val types by lazy {
+ (members[JSONLD_TYPE] ?: throw BadRequestDataException("Could not extract type from JSON-LD entity"))
+ as List
+ }
+
+ private fun Map.addDateTimeProperty(propertyKey: String, dateTime: ZonedDateTime?): Map =
+ if (dateTime != null)
+ this.plus(propertyKey to JsonLdUtils.buildNonReifiedTemporalValue(dateTime))
+ else this
+
+ fun filterOnAttributes(includedAttributes: Set): Map {
+ val inputToMap = { i: ExpandedEntity -> i.members }
+ return filterEntityOnAttributes(this, inputToMap, includedAttributes)
+ }
+
+ private fun filterEntityOnAttributes(
+ input: T,
+ inputToMap: (T) -> Map,
+ includedAttributes: Set
+ ): Map {
+ return if (includedAttributes.isEmpty()) {
+ inputToMap(input)
+ } else {
+ val includedKeys = JSONLD_EXPANDED_ENTITY_CORE_MEMBERS.plus(includedAttributes)
+ inputToMap(input).filterKeys { includedKeys.contains(it) }
+ }
+ }
+}
+
+fun List.filterOnAttributes(includedAttributes: Set): List =
+ this.filter { it.containsAnyOf(includedAttributes) }
+ .map {
+ ExpandedEntity(it.filterOnAttributes(includedAttributes), it.contexts)
+ }
diff --git a/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedMembers.kt b/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedMembers.kt
new file mode 100644
index 000000000..b4ed57866
--- /dev/null
+++ b/shared/src/main/kotlin/com/egm/stellio/shared/model/ExpandedMembers.kt
@@ -0,0 +1,208 @@
+package com.egm.stellio.shared.model
+
+import arrow.core.Either
+import arrow.core.flatMap
+import arrow.core.left
+import arrow.core.right
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_ID
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.JSONLD_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_CREATED_AT_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATASET_ID_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATE_TIME_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_DATE_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_MODIFIED_AT_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_PROPERTY_VALUE
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_RELATIONSHIP_OBJECT
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_SCOPE_PROPERTY
+import com.egm.stellio.shared.util.JsonLdUtils.NGSILD_TIME_TYPE
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedPropertyValue
+import com.egm.stellio.shared.util.JsonLdUtils.buildNonReifiedTemporalValue
+import com.egm.stellio.shared.util.toUri
+import java.net.URI
+import java.time.LocalDate
+import java.time.LocalTime
+import java.time.ZonedDateTime
+import kotlin.reflect.full.safeCast
+
+// basic alias to help identify, mainly in method calls, if the expected value is a compact or expanded one
+typealias ExpandedTerm = String
+typealias ExpandedAttributes = Map
+typealias ExpandedAttribute = Pair
+typealias ExpandedAttributeInstances = List
+typealias ExpandedAttributeInstance = Map>
+typealias ExpandedNonReifiedPropertyValue = List