diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/AasDescriptorSimple_2.json b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/AasDescriptorSimple_2.json index 423a700a3..5d22b649c 100644 --- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/AasDescriptorSimple_2.json +++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/AasDescriptorSimple_2.json @@ -32,7 +32,7 @@ "idShort": "specificAasIdShort-2-SM", "id": "specificAasId-2-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor.json b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor.json index 80e3c4d15..9086b0793 100644 --- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor.json +++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-SM", "id": "dummyShellId_3-1-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json index 338719502..c2e40f757 100644 --- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json +++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-Update-SM", "id": "dummyShellId_3-1-Update-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/integration/BaseIntegrationTest.java b/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/integration/BaseIntegrationTest.java index f5503018c..6708a2ed8 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/integration/BaseIntegrationTest.java +++ b/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/integration/BaseIntegrationTest.java @@ -567,7 +567,7 @@ public void whenSendFullObjectStructure_ItemIsProcessedProperly() throws ApiExce EmbeddedDataSpecification edSpec = new EmbeddedDataSpecification().dataSpecification(reference).dataSpecificationContent(new DataSpecificationContent(dsContent)); AdministrativeInformation aInfo = new AdministrativeInformation().addEmbeddedDataSpecificationsItem(edSpec); - SubmodelDescriptor sm = new SubmodelDescriptor().id("sm").id("short").addDescriptionItem(dType).addDisplayNameItem(nType).addEndpointsItem(ep).addExtensionsItem(ext).addSupplementalSemanticIdItem(reference); + SubmodelDescriptor sm = new SubmodelDescriptor().id("sm").id("short").addDescriptionItem(dType).addDisplayNameItem(nType).addEndpointsItem(ep).addExtensionsItem(ext).addSupplementalSemanticIdsItem(reference); AssetAdministrationShellDescriptor descriptor = new AssetAdministrationShellDescriptor().id("id1").id("short").addDescriptionItem(dType).addDisplayNameItem(nType).addEndpointsItem(ep).addExtensionsItem(ext) .addSpecificAssetIdsItem(saId).administration(aInfo).assetKind(AssetKind.TYPE).assetType("tp1").globalAssetId("global1").addSubmodelDescriptorsItem(sm); diff --git a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/storage/mongodb/MongoDbAasRegistryStorage.java b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/storage/mongodb/MongoDbAasRegistryStorage.java index 389291be3..9010fddf3 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/storage/mongodb/MongoDbAasRegistryStorage.java +++ b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/storage/mongodb/MongoDbAasRegistryStorage.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import org.bson.Document; import org.eclipse.digitaltwin.basyx.aasregistry.model.AssetAdministrationShellDescriptor; import org.eclipse.digitaltwin.basyx.aasregistry.model.AssetKind; import org.eclipse.digitaltwin.basyx.aasregistry.model.ShellDescriptorQuery; @@ -80,6 +81,8 @@ public class MongoDbAasRegistryStorage implements AasRegistryStorage { private static final String SUBMODEL_DESCRIPTORS_ID = "submodelDescriptors._id"; private static final String ASSET_TYPE = "assetType"; private static final String ASSET_KIND = "assetKind"; + private static final String SUPPLEMENTAL_SEMANTIC_ID = "supplementalSemanticId"; + private static final String SUPPLEMENTAL_SEMANTIC_IDS = "supplementalSemanticIds"; private final MongoTemplate template; @@ -91,8 +94,8 @@ public CursorResult> getAllAasDescripto applyFilter(filter, allAggregations); applySorting(allAggregations); applyPagination(pRequest, allAggregations); - AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, AssetAdministrationShellDescriptor.class); - List foundDescriptors = results.getMappedResults(); + AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, Document.class); + List foundDescriptors = results.getMappedResults().stream().map(this::toAasDescriptor).collect(Collectors.toList()); String cursor = resolveCursor(pRequest, foundDescriptors, AssetAdministrationShellDescriptor::getId); return new CursorResult<>(cursor, foundDescriptors); } @@ -148,11 +151,11 @@ public Optional createFilterCriteria(DescriptorFilter filter) { @Override public AssetAdministrationShellDescriptor getAasDescriptor(@NonNull String aasDescriptorId) throws AasDescriptorNotFoundException { - AssetAdministrationShellDescriptor descriptor = template.findById(aasDescriptorId, AssetAdministrationShellDescriptor.class, collectionName); + Document descriptor = template.findById(aasDescriptorId, Document.class, collectionName); if (descriptor == null) { throw new AasDescriptorNotFoundException(aasDescriptorId); } - return descriptor; + return toAasDescriptor(descriptor); } @Override @@ -212,8 +215,8 @@ public CursorResult> getAllSubmodels(@NonNull String aa allAggregations.add(Aggregation.replaceRoot(SUBMODEL_DESCRIPTORS)); this.applySorting(allAggregations); this.applyPagination(pRequest, allAggregations); - AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, SubmodelDescriptor.class); - List submodels = results.getMappedResults(); + AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, Document.class); + List submodels = results.getMappedResults().stream().map(this::toSubmodelDescriptor).collect(Collectors.toList()); String cursor = resolveCursor(pRequest, submodels, SubmodelDescriptor::getId); return new CursorResult<>(cursor, submodels); } @@ -224,16 +227,21 @@ public SubmodelDescriptor getSubmodel(@NonNull String aasDescriptorId, @NonNull all.add(Aggregation.match(Criteria.where(ID).is(aasDescriptorId))); ArrayOperators.Filter filter = ArrayOperators.arrayOf(SUBMODEL_DESCRIPTORS).filter().as(SUBMODEL_DESCRIPTORS).by(ComparisonOperators.valueOf(SUBMODEL_DESCRIPTORS_ID).equalToValue(submodelId)); all.add(Aggregation.project().and(filter).as(SUBMODEL_DESCRIPTORS)); - AggregationResults results = template.aggregate(Aggregation.newAggregation(all), collectionName, AssetAdministrationShellDescriptor.class); - List aasDescriptors = results.getMappedResults(); + AggregationResults results = template.aggregate(Aggregation.newAggregation(all), collectionName, Document.class); + List aasDescriptors = results.getMappedResults(); if (aasDescriptors.isEmpty()) { throw new AasDescriptorNotFoundException(aasDescriptorId); } - List descriptors = aasDescriptors.get(0).getSubmodelDescriptors(); - if (descriptors == null || descriptors.isEmpty()) { + Document compatibleAasDescriptor = ensureLegacyAasDescriptorCompatibility(aasDescriptors.get(0)); + Object descriptorsObject = compatibleAasDescriptor.get(SUBMODEL_DESCRIPTORS); + if (!(descriptorsObject instanceof List descriptors) || descriptors.isEmpty()) { throw new SubmodelNotFoundException(aasDescriptorId, submodelId); } - return descriptors.get(0); + Object firstDescriptor = descriptors.get(0); + if (!(firstDescriptor instanceof Document descriptorDocument)) { + throw new SubmodelNotFoundException(aasDescriptorId, submodelId); + } + return toSubmodelDescriptor(descriptorDocument); } @Override @@ -321,9 +329,52 @@ public ShellDescriptorSearchResponse searchAasDescriptors(@NonNull ShellDescript qBuilder.withProjection(grouped.getQueriesInsideSubmodel(), aggregationOps); Aggregation aggregation = Aggregation.newAggregation(aggregationOps); - AggregationResults results = template.aggregate(aggregation, collectionName, AssetAdministrationShellDescriptor.class); + AggregationResults results = template.aggregate(aggregation, collectionName, Document.class); - List descriptors = results.getMappedResults(); + List descriptors = results.getMappedResults().stream().map(this::toAasDescriptor).collect(Collectors.toList()); return new ShellDescriptorSearchResponse(total, descriptors); } + + private AssetAdministrationShellDescriptor toAasDescriptor(Document descriptorDocument) { + Document compatibleDocument = ensureLegacyAasDescriptorCompatibility(descriptorDocument); + return template.getConverter().read(AssetAdministrationShellDescriptor.class, compatibleDocument); + } + + private SubmodelDescriptor toSubmodelDescriptor(Document descriptorDocument) { + Document compatibleDocument = ensureLegacySubmodelDescriptorCompatibility(descriptorDocument); + return template.getConverter().read(SubmodelDescriptor.class, compatibleDocument); + } + + private Document ensureLegacyAasDescriptorCompatibility(Document descriptorDocument) { + Object submodelDescriptorsObject = descriptorDocument.get(SUBMODEL_DESCRIPTORS); + if (!(submodelDescriptorsObject instanceof List submodelDescriptors)) { + return descriptorDocument; + } + boolean changed = false; + List compatibleSubmodels = new ArrayList<>(submodelDescriptors.size()); + for (Object eachSubmodel : submodelDescriptors) { + if (eachSubmodel instanceof Document submodelDocument) { + Document compatibleSubmodel = ensureLegacySubmodelDescriptorCompatibility(submodelDocument); + compatibleSubmodels.add(compatibleSubmodel); + changed |= compatibleSubmodel != submodelDocument; + } else { + compatibleSubmodels.add(eachSubmodel); + } + } + if (!changed) { + return descriptorDocument; + } + Document compatibleDescriptor = new Document(descriptorDocument); + compatibleDescriptor.put(SUBMODEL_DESCRIPTORS, compatibleSubmodels); + return compatibleDescriptor; + } + + private Document ensureLegacySubmodelDescriptorCompatibility(Document descriptorDocument) { + if (descriptorDocument.containsKey(SUPPLEMENTAL_SEMANTIC_IDS) || !descriptorDocument.containsKey(SUPPLEMENTAL_SEMANTIC_ID)) { + return descriptorDocument; + } + Document compatibleDocument = new Document(descriptorDocument); + compatibleDocument.put(SUPPLEMENTAL_SEMANTIC_IDS, descriptorDocument.get(SUPPLEMENTAL_SEMANTIC_ID)); + return compatibleDocument; + } } diff --git a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/MongoDbAasRegistryStorageTest.java b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/MongoDbAasRegistryStorageTest.java index e3a4bf5c3..b42cccfe7 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/MongoDbAasRegistryStorageTest.java +++ b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/MongoDbAasRegistryStorageTest.java @@ -26,18 +26,24 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; +import java.util.List; import java.util.Optional; import org.bson.Document; +import org.eclipse.digitaltwin.basyx.aasregistry.model.AssetAdministrationShellDescriptor; import org.eclipse.digitaltwin.basyx.aasregistry.model.AssetKind; import org.eclipse.digitaltwin.basyx.aasregistry.model.ShellDescriptorQuery; import org.eclipse.digitaltwin.basyx.aasregistry.model.ShellDescriptorQuery.QueryTypeEnum; +import org.eclipse.digitaltwin.basyx.aasregistry.model.SubmodelDescriptor; import org.eclipse.digitaltwin.basyx.aasregistry.paths.AasRegistryPaths; import org.eclipse.digitaltwin.basyx.aasregistry.service.configuration.MongoDbConfiguration; import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.DescriptorFilter; import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.ShellDescriptorSearchRequests; import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.mongodb.MongoDbAasRegistryStorage; import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.mongodb.SearchQueryBuilder; +import org.eclipse.digitaltwin.basyx.core.pagination.CursorResult; +import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -51,7 +57,7 @@ import com.mongodb.client.MongoCollection; @TestPropertySource(properties = { "registry.type=mongodb", "spring.data.mongodb.database=aasregistry" - , "spring.data.mongodb.uri=mongodb://mongoAdmin:mongoPassword@localhost:27017" }) + , "spring.data.mongodb.uri=mongodb://mongoAdmin:mongoPassword@localhost:27017", "basyx.aasregistry.mongodb.collectionName=aasdescriptors" }) @ContextConfiguration(classes = { MongoDbConfiguration.class }) @EnableAutoConfiguration public class MongoDbAasRegistryStorageTest extends AasRegistryStorageTest { @@ -111,6 +117,39 @@ public void whenGetByAasID_NotAllDocumentsScannedButIndexUsed() { assertThat(doc.toJson()).doesNotContain("\"COLLSCAN\""); } + @Test + public void givenLegacySupplementalSemanticIdInSubmodel_whenGetAasById_thenSubmodelContainsSupplementalSemanticField() { + template.remove(new Query(), "aasdescriptors"); + template.save(createLegacyAasDocument("legacy-aas-1", "legacy-submodel-1"), "aasdescriptors"); + + AssetAdministrationShellDescriptor descriptor = storage.getAasDescriptor("legacy-aas-1"); + SubmodelDescriptor submodelDescriptor = descriptor.getSubmodelDescriptors().get(0); + + Document writtenSubmodelDescriptor = new Document(); + template.getConverter().write(submodelDescriptor, writtenSubmodelDescriptor); + + assertThat(extractSupplementalSemanticField(writtenSubmodelDescriptor)).isNotNull(); + assertThat(extractSupplementalSemanticField(writtenSubmodelDescriptor)).isInstanceOf(List.class); + assertThat((List) extractSupplementalSemanticField(writtenSubmodelDescriptor)).hasSize(1); + } + + @Test + public void givenLegacySupplementalSemanticIdInSubmodel_whenGetAllSubmodels_thenSubmodelContainsSupplementalSemanticField() { + template.remove(new Query(), "aasdescriptors"); + template.save(createLegacyAasDocument("legacy-aas-2", "legacy-submodel-2"), "aasdescriptors"); + + CursorResult> result = storage.getAllSubmodels("legacy-aas-2", PaginationInfo.NO_LIMIT); + SubmodelDescriptor submodelDescriptor = result.getResult().stream().filter(x -> "legacy-submodel-2".equals(x.getId())).findFirst().orElse(null); + assertThat(submodelDescriptor).isNotNull(); + + Document writtenSubmodelDescriptor = new Document(); + template.getConverter().write(submodelDescriptor, writtenSubmodelDescriptor); + + assertThat(extractSupplementalSemanticField(writtenSubmodelDescriptor)).isNotNull(); + assertThat(extractSupplementalSemanticField(writtenSubmodelDescriptor)).isInstanceOf(List.class); + assertThat((List) extractSupplementalSemanticField(writtenSubmodelDescriptor)).hasSize(1); + } + private void testIndexFilter(AssetKind kind, String type) { MongoDbAasRegistryStorage storage = new MongoDbAasRegistryStorage(template, "aasdescriptors"); Optional criteriaOpt = storage.createFilterCriteria(new DescriptorFilter(kind, type)); @@ -124,4 +163,19 @@ private void testIndexFilter(Criteria criteria) { Document doc = collection.find(Query.query(criteria).getQueryObject()).explain(ExplainVerbosity.QUERY_PLANNER); assertThat(doc.toJson()).doesNotContain("\"COLLSCAN\""); } + + private Object extractSupplementalSemanticField(Document descriptorDocument) { + if (descriptorDocument.containsKey("supplementalSemanticIds")) { + return descriptorDocument.get("supplementalSemanticIds"); + } + return descriptorDocument.get("supplementalSemanticId"); + } + + private Document createLegacyAasDocument(String aasId, String submodelId) { + Document key = new Document("type", "FILE").append("value", "urn:test:" + submodelId); + Document reference = new Document("type", "EXTERNALREFERENCE").append("keys", Arrays.asList(key)); + Document submodelDescriptor = new Document("_id", submodelId).append("idShort", "short-" + submodelId).append("endpoints", Arrays.asList()) + .append("supplementalSemanticId", Arrays.asList(reference)); + return new Document("_id", aasId).append("idShort", "short-" + aasId).append("endpoints", Arrays.asList()).append("submodelDescriptors", Arrays.asList(submodelDescriptor)); + } } \ No newline at end of file diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/AasDescriptorSimple_2.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/AasDescriptorSimple_2.json index 423a700a3..5d22b649c 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/AasDescriptorSimple_2.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/AasDescriptorSimple_2.json @@ -32,7 +32,7 @@ "idShort": "specificAasIdShort-2-SM", "id": "specificAasId-2-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json index 80e3c4d15..9086b0793 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-SM", "id": "dummyShellId_3-1-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json index 338719502..c2e40f757 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-Update-SM", "id": "dummyShellId_3-1-Update-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json index 423a700a3..5d22b649c 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json @@ -32,7 +32,7 @@ "idShort": "specificAasIdShort-2-SM", "id": "specificAasId-2-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json index 80e3c4d15..9086b0793 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-SM", "id": "dummyShellId_3-1-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json index 338719502..c2e40f757 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-Update-SM", "id": "dummyShellId_3-1-Update-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/AasDescriptorSimple_2.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/AasDescriptorSimple_2.json index 423a700a3..5d22b649c 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/AasDescriptorSimple_2.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/AasDescriptorSimple_2.json @@ -32,7 +32,7 @@ "idShort": "specificAasIdShort-2-SM", "id": "specificAasId-2-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json index 80e3c4d15..9086b0793 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-SM", "id": "dummyShellId_3-1-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json index 338719502..c2e40f757 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-Update-SM", "id": "dummyShellId_3-1-Update-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json index 423a700a3..5d22b649c 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/AasDescriptorSimple_2.json @@ -32,7 +32,7 @@ "idShort": "specificAasIdShort-2-SM", "id": "specificAasId-2-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json index 80e3c4d15..9086b0793 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-SM", "id": "dummyShellId_3-1-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json index 338719502..c2e40f757 100644 --- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json +++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/test/resources/authorization/SingleSubmodelDescriptor_Update.json @@ -6,7 +6,7 @@ "idShort": "dummyShellIdShort_3-1-Update-SM", "id": "dummyShellId_3-1-Update-SM", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml index 1ab6c30e0..7f5e1b693 100644 --- a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml +++ b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml @@ -1192,7 +1192,7 @@ components: type: string semanticId: $ref: '#/components/schemas/Reference' - supplementalSemanticId: + supplementalSemanticIds: minItems: 1 type: array items: diff --git a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved-altered.yaml b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved-altered.yaml index 3f13a5de7..1021064f9 100644 --- a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved-altered.yaml +++ b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved-altered.yaml @@ -1194,7 +1194,7 @@ components: type: string semanticId: $ref: '#/components/schemas/Reference' - supplementalSemanticId: + supplementalSemanticIds: minItems: 1 type: array items: diff --git a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved.yaml b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved.yaml index f3347c120..bfc3fe7de 100644 --- a/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved.yaml +++ b/basyx.aasregistry/open-api/Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0_SSP-001-resolved.yaml @@ -1185,7 +1185,7 @@ components: type: string semanticId: $ref: '#/components/schemas/Reference' - supplementalSemanticId: + supplementalSemanticIds: minItems: 1 type: array items: diff --git a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/factory/SubmodelDescriptorFactory.java b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/factory/SubmodelDescriptorFactory.java index 3506e59fe..e17e36e98 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/factory/SubmodelDescriptorFactory.java +++ b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/factory/SubmodelDescriptorFactory.java @@ -86,7 +86,7 @@ public SubmodelDescriptor create(Submodel submodel) { setSemanticId(submodel.getSemanticId(), descriptor); - setSupplementalSemanticId(submodel.getSupplementalSemanticIds(), descriptor); + setSupplementalSemanticIds(submodel.getSupplementalSemanticIds(), descriptor); return descriptor; } @@ -131,12 +131,12 @@ private void setSemanticId(Reference reference, SubmodelDescriptor descriptor) { descriptor.setSemanticId(attributeMapper.mapSemanticId(reference)); } - private void setSupplementalSemanticId(List supplementalSemanticIds, SubmodelDescriptor descriptor) { + private void setSupplementalSemanticIds(List supplementalSemanticIds, SubmodelDescriptor descriptor) { if (supplementalSemanticIds == null || supplementalSemanticIds.isEmpty()) return; - descriptor.setSupplementalSemanticId(attributeMapper.mapSupplementalSemanticId(supplementalSemanticIds)); + descriptor.setSupplementalSemanticIds(attributeMapper.mapSupplementalSemanticIds(supplementalSemanticIds)); } private void setEndpointItem(String submodelId, SubmodelDescriptor descriptor, List submodelServerURLs) { diff --git a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/AttributeMapper.java b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/AttributeMapper.java index 75f3a4beb..3d2cd42ad 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/AttributeMapper.java +++ b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/AttributeMapper.java @@ -147,15 +147,15 @@ public Reference mapSemanticId(org.eclipse.digitaltwin.aas4j.v3.model.Reference * @param supplementalSemanticIds * @return the mapped supplementalSemanticIds */ - public List mapSupplementalSemanticId(List supplementalSemanticIds) { + public List mapSupplementalSemanticIds(List supplementalSemanticIds) { CustomTypeCloneFactory cloneFactory = new CustomTypeCloneFactory<>(Reference.class, mapper); - List mappedSupplementalSemanticId = cloneFactory.create(supplementalSemanticIds); + List mappedSupplementalSemanticIds = cloneFactory.create(supplementalSemanticIds); - if (mappedSupplementalSemanticId == null) + if (mappedSupplementalSemanticIds == null) logger.error("SupplementalSemanticId could not be mapped due to a failure."); - return mappedSupplementalSemanticId; + return mappedSupplementalSemanticIds; } } diff --git a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/TestAttributeMapper.java b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/TestAttributeMapper.java index e8f31bbed..cfae58851 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/TestAttributeMapper.java +++ b/basyx.submodelregistry/basyx.submodelregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/client/mapper/TestAttributeMapper.java @@ -100,10 +100,10 @@ public void mapSemanticId() { } @Test - public void mapSupplementalSemanticId() { + public void mapSupplementalSemanticIds() { List expectedSupplementalSemanticId = AttributeMapperFixture.getSubmodelRegSupplementalSemanticIds(); - List actualSupplementalSemanticId = attributeMapper.mapSupplementalSemanticId(AttributeMapperFixture.getAas4jSupplementalSemanticIds()); + List actualSupplementalSemanticId = attributeMapper.mapSupplementalSemanticIds(AttributeMapperFixture.getAas4jSupplementalSemanticIds()); assertEquals(expectedSupplementalSemanticId.size(), actualSupplementalSemanticId.size()); assertEquals(expectedSupplementalSemanticId, actualSupplementalSemanticId); diff --git a/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_1.json b/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_1.json index e9c5d704a..13ece5c9f 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_1.json +++ b/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_1.json @@ -6,7 +6,7 @@ "idShort": "dummySubmodelIdShort_3", "id": "dummySubmodelId_3", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_2.json b/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_2.json index 370b78932..aabfcf2f6 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_2.json +++ b/basyx.submodelregistry/basyx.submodelregistry-feature-authorization/src/test/resources/authorization/SubmodelDescriptorSimple_2.json @@ -6,7 +6,7 @@ "idShort": "specificSubmodelIdShort-2", "id": "specificSubmodelId-2", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/integration/BaseIntegrationTest.java b/basyx.submodelregistry/basyx.submodelregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/integration/BaseIntegrationTest.java index 1fc1daa0f..dbd7d0ba4 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/integration/BaseIntegrationTest.java +++ b/basyx.submodelregistry/basyx.submodelregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/integration/BaseIntegrationTest.java @@ -304,7 +304,7 @@ public void whenSendFullObjectStructure_ItemIsProcessedProperly() throws ApiExce .symbol("$$"); EmbeddedDataSpecification edSpec = new EmbeddedDataSpecification().dataSpecification(reference).dataSpecificationContent(new DataSpecificationContent(dsContent)); AdministrativeInformation aInfo = new AdministrativeInformation().addEmbeddedDataSpecificationsItem(edSpec); - SubmodelDescriptor sm = new SubmodelDescriptor().id("sm").id("short").addDescriptionItem(dType).addDisplayNameItem(nType).addEndpointsItem(ep).addExtensionsItem(ext).addSupplementalSemanticIdItem(reference); + SubmodelDescriptor sm = new SubmodelDescriptor().id("sm").id("short").addDescriptionItem(dType).addDisplayNameItem(nType).addEndpointsItem(ep).addExtensionsItem(ext).addSupplementalSemanticIdsItem(reference); sm.setAdministration(aInfo); SubmodelDescriptor descr = api.postSubmodelDescriptor(sm); diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/storage/mongodb/MongoDbSubmodelRegistryStorage.java b/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/storage/mongodb/MongoDbSubmodelRegistryStorage.java index b06b6c098..c6b65bdd0 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/storage/mongodb/MongoDbSubmodelRegistryStorage.java +++ b/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/storage/mongodb/MongoDbSubmodelRegistryStorage.java @@ -30,6 +30,7 @@ import java.util.Set; import java.util.stream.Collectors; +import org.bson.Document; import org.eclipse.digitaltwin.basyx.core.pagination.CursorResult; import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo; import org.eclipse.digitaltwin.basyx.submodelregistry.model.SubmodelDescriptor; @@ -58,6 +59,8 @@ public class MongoDbSubmodelRegistryStorage implements SubmodelRegistryStorage { // mongodb maps all id fields internally to _id private static final String ID = "_id"; + private static final String SUPPLEMENTAL_SEMANTIC_ID = "supplementalSemanticId"; + private static final String SUPPLEMENTAL_SEMANTIC_IDS = "supplementalSemanticIds"; private final MongoTemplate template; @@ -68,8 +71,8 @@ public CursorResult> getAllSubmodelDescriptors(@NonNull List allAggregations = new LinkedList<>(); applySorting(allAggregations); applyPagination(pRequest, allAggregations); - AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, SubmodelDescriptor.class); - List foundDescriptors = results.getMappedResults(); + AggregationResults results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, Document.class); + List foundDescriptors = results.getMappedResults().stream().map(this::toSubmodelDescriptor).collect(Collectors.toList()); String cursor = resolveCursor(pRequest, foundDescriptors); return new CursorResult>(cursor, foundDescriptors); } @@ -84,11 +87,11 @@ public Set clear() { @Override public SubmodelDescriptor getSubmodelDescriptor(@NonNull String submodelId) throws SubmodelNotFoundException { - SubmodelDescriptor descriptor = template.findById(submodelId, SubmodelDescriptor.class, collectionName); - if (descriptor == null) { + Document foundDescriptor = template.findById(submodelId, Document.class, collectionName); + if (foundDescriptor == null) { throw new SubmodelNotFoundException(submodelId); } - return descriptor; + return toSubmodelDescriptor(foundDescriptor); } @Override @@ -142,6 +145,20 @@ private void applySorting(List allAggregations) { allAggregations.add(sortOp); } + private SubmodelDescriptor toSubmodelDescriptor(Document descriptorDocument) { + Document compatibleDocument = ensureLegacyFieldCompatibility(descriptorDocument); + return template.getConverter().read(SubmodelDescriptor.class, compatibleDocument); + } + + private Document ensureLegacyFieldCompatibility(Document descriptorDocument) { + if (descriptorDocument.containsKey(SUPPLEMENTAL_SEMANTIC_IDS) || !descriptorDocument.containsKey(SUPPLEMENTAL_SEMANTIC_ID)) { + return descriptorDocument; + } + Document compatibleDocument = new Document(descriptorDocument); + compatibleDocument.put(SUPPLEMENTAL_SEMANTIC_IDS, descriptorDocument.get(SUPPLEMENTAL_SEMANTIC_ID)); + return compatibleDocument; + } + private String resolveCursor(PaginationInfo pRequest, List foundDescriptors) { if (foundDescriptors.isEmpty() || !pRequest.isPaged()) { return null; diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/MongoDbSubmodelRegistryStorageTest.java b/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/MongoDbSubmodelRegistryStorageTest.java index 168f6f833..393a388de 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/MongoDbSubmodelRegistryStorageTest.java +++ b/basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/MongoDbSubmodelRegistryStorageTest.java @@ -26,11 +26,20 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; +import java.util.List; + import org.bson.Document; +import org.eclipse.digitaltwin.basyx.core.pagination.CursorResult; +import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo; +import org.eclipse.digitaltwin.basyx.submodelregistry.model.SubmodelDescriptor; +import org.eclipse.digitaltwin.basyx.submodelregistry.service.configuration.MongoDbConfiguration; +import org.eclipse.digitaltwin.basyx.submodelregistry.service.storage.SubmodelRegistryStorage; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; @@ -47,10 +56,60 @@ public class MongoDbSubmodelRegistryStorageTest extends SubmodelRegistryStorageT @Autowired private MongoTemplate template; + @Autowired + private SubmodelRegistryStorage storage; + + @Autowired + private MongoDbConfiguration configuration; + @Test public void whenGetById_NotAllDocumentsScannedButIndexUsed() { MongoCollection collection = template.getCollection("submodeldescriptors"); Document doc = collection.find(new Document("_id", "11")).explain(ExplainVerbosity.QUERY_PLANNER); assertThat(doc.toJson()).doesNotContain("\"COLLSCAN\""); } + + @Test + public void givenLegacySupplementalSemanticId_whenGetById_thenDescriptorContainsSupplementalSemanticField() { + template.remove(new Query(), configuration.collectionName); + template.save(createLegacyDocument("legacy-get-1"), configuration.collectionName); + + SubmodelDescriptor descriptor = storage.getSubmodelDescriptor("legacy-get-1"); + Document writtenDescriptor = new Document(); + template.getConverter().write(descriptor, writtenDescriptor); + + assertThat(extractSupplementalSemanticField(writtenDescriptor)).isNotNull(); + assertThat(extractSupplementalSemanticField(writtenDescriptor)).isInstanceOf(List.class); + assertThat((List) extractSupplementalSemanticField(writtenDescriptor)).hasSize(1); + } + + @Test + public void givenLegacySupplementalSemanticId_whenGetAll_thenDescriptorContainsSupplementalSemanticField() { + template.remove(new Query(), configuration.collectionName); + template.save(createLegacyDocument("legacy-getall-1"), configuration.collectionName); + + CursorResult> result = storage.getAllSubmodelDescriptors(PaginationInfo.NO_LIMIT); + SubmodelDescriptor descriptor = result.getResult().stream().filter(x -> "legacy-getall-1".equals(x.getId())).findFirst().orElse(null); + assertThat(descriptor).isNotNull(); + + Document writtenDescriptor = new Document(); + template.getConverter().write(descriptor, writtenDescriptor); + + assertThat(extractSupplementalSemanticField(writtenDescriptor)).isNotNull(); + assertThat(extractSupplementalSemanticField(writtenDescriptor)).isInstanceOf(List.class); + assertThat((List) extractSupplementalSemanticField(writtenDescriptor)).hasSize(1); + } + + private Object extractSupplementalSemanticField(Document descriptorDocument) { + if (descriptorDocument.containsKey("supplementalSemanticIds")) { + return descriptorDocument.get("supplementalSemanticIds"); + } + return descriptorDocument.get("supplementalSemanticId"); + } + + private Document createLegacyDocument(String id) { + Document key = new Document("type", "FILE").append("value", "urn:test:" + id); + Document reference = new Document("type", "EXTERNALREFERENCE").append("keys", Arrays.asList(key)); + return new Document("_id", id).append("idShort", "short-" + id).append("endpoints", Arrays.asList()).append("supplementalSemanticId", Arrays.asList(reference)); + } } \ No newline at end of file diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json index e9c5d704a..13ece5c9f 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json @@ -6,7 +6,7 @@ "idShort": "dummySubmodelIdShort_3", "id": "dummySubmodelId_3", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json index 370b78932..aabfcf2f6 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json @@ -6,7 +6,7 @@ "idShort": "specificSubmodelIdShort-2", "id": "specificSubmodelId-2", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json index e9c5d704a..13ece5c9f 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json @@ -6,7 +6,7 @@ "idShort": "dummySubmodelIdShort_3", "id": "dummySubmodelId_3", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json index 370b78932..aabfcf2f6 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json @@ -6,7 +6,7 @@ "idShort": "specificSubmodelIdShort-2", "id": "specificSubmodelId-2", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json index e9c5d704a..13ece5c9f 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_1.json @@ -6,7 +6,7 @@ "idShort": "dummySubmodelIdShort_3", "id": "dummySubmodelId_3", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json index 370b78932..aabfcf2f6 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/test/resources/authorization/SubmodelDescriptorSimple_2.json @@ -6,7 +6,7 @@ "idShort": "specificSubmodelIdShort-2", "id": "specificSubmodelId-2", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json index e9c5d704a..13ece5c9f 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_1.json @@ -6,7 +6,7 @@ "idShort": "dummySubmodelIdShort_3", "id": "dummySubmodelId_3", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json index 370b78932..aabfcf2f6 100644 --- a/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json +++ b/basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/test/resources/authorization/SubmodelDescriptorSimple_2.json @@ -6,7 +6,7 @@ "idShort": "specificSubmodelIdShort-2", "id": "specificSubmodelId-2", "semanticId": null, - "supplementalSemanticId": null, + "supplementalSemanticIds": null, "endpoints": [ { "interface": "AAS-3.0", diff --git a/basyx.submodelregistry/open-api/Plattform_i40-SubmodelRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml b/basyx.submodelregistry/open-api/Plattform_i40-SubmodelRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml index 756a3d9cc..9bc3ae0e0 100644 --- a/basyx.submodelregistry/open-api/Plattform_i40-SubmodelRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml +++ b/basyx.submodelregistry/open-api/Plattform_i40-SubmodelRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml @@ -366,7 +366,7 @@ components: type: string semanticId: $ref: '#/components/schemas/Reference' - supplementalSemanticId: + supplementalSemanticIds: minItems: 1 type: array items: