From 4d970ce57231ac75e21000b0b8ba79d48d32026f Mon Sep 17 00:00:00 2001 From: fried Date: Thu, 12 Jun 2025 09:15:13 +0200 Subject: [PATCH 1/4] Fixes /shells Endpoint Query Param --- .../http/AasRepositoryHTTPSuite.java | 18 ++++++++++++++++++ .../src/test/resources/EmptyResponse.json | 5 +++++ .../aasservice/backend/InMemoryAasBackend.java | 3 +++ .../backend/MongoDBAasOperations.java | 14 ++++++-------- 4 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 basyx.aasrepository/basyx.aasrepository-http/src/test/resources/EmptyResponse.json diff --git a/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java b/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java index 9b589f488..bd0f063f0 100644 --- a/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java +++ b/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java @@ -192,6 +192,16 @@ public void getAllAasWithIdShort() throws IOException, ParseException { BaSyxHttpTestUtils.assertSameJSONContent(getPaginatedAas1JSONString(), getJSONWithoutCursorInfo(actualJsonFromServer)); } + @Test + public void getAllAasWithMultipleAssetIds() throws IOException, ParseException { + createMultipleAasOnServer(); + CloseableHttpResponse retrievalResponse = getAllAasMultipleGlobalAssetIdsParam(); + assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode()); + + String actualJsonFromServer = BaSyxHttpTestUtils.getResponseAsString(retrievalResponse); + BaSyxHttpTestUtils.assertSameJSONContent(getEmptyResultJSONString(), getJSONWithoutCursorInfo(actualJsonFromServer)); + } + @Test public void deleteAas() throws IOException { createDummyAasOnServer(getAas1JSONString()); @@ -423,6 +433,10 @@ public void deleteNonExistingThumbnail() throws FileNotFoundException, Unsupport private String getPaginatedAas1JSONString() throws FileNotFoundException, IOException { return BaSyxHttpTestUtils.readJSONStringFromClasspath("PaginatedAasSimple_1.json"); } + + private String getEmptyResultJSONString() throws FileNotFoundException, IOException { + return BaSyxHttpTestUtils.readJSONStringFromClasspath("EmptyResponse.json"); + } private String getJSONWithoutCursorInfo(String response) throws JsonMappingException, JsonProcessingException { return BaSyxHttpTestUtils.removeCursorFromJSON(response); @@ -489,6 +503,10 @@ protected CloseableHttpResponse getAllAasGlobalAssetIdsParam() throws IOExceptio return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9"); } + protected CloseableHttpResponse getAllAasMultipleGlobalAssetIdsParam() throws IOException { + return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9&assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6ImR1bW15QWFzQXNzZXRJZCINCn0"); + } + protected CloseableHttpResponse getAllAasIdShortParam() throws IOException { return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?idShort=ExampleMotor"); } diff --git a/basyx.aasrepository/basyx.aasrepository-http/src/test/resources/EmptyResponse.json b/basyx.aasrepository/basyx.aasrepository-http/src/test/resources/EmptyResponse.json new file mode 100644 index 000000000..309ebab7e --- /dev/null +++ b/basyx.aasrepository/basyx.aasrepository-http/src/test/resources/EmptyResponse.json @@ -0,0 +1,5 @@ +{ + "paging_metadata": {}, + "result": [ + ] +} \ No newline at end of file diff --git a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java index 69d17998f..f3eac586d 100644 --- a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java +++ b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java @@ -104,6 +104,9 @@ public Iterable getAllAas(List assetI List filteredAas = new java.util.ArrayList<>(); String globalAssetId = null; try { + if(assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).count() > 1){ + return filteredAas; + } globalAssetId = assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).findFirst().get().getValue(); assetIds = assetIds.stream().filter(assetId -> !assetId.getName().equals("globalAssetId")).collect(Collectors.toList()); } catch (Exception e) {} diff --git a/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java b/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java index 8b8286458..a92a1ec91 100644 --- a/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java +++ b/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java @@ -176,12 +176,10 @@ public Iterable getAllAas(List assetI Query query = new Query(); Criteria criteria = new Criteria(); - String globalAssetId = null; - try { - globalAssetId = assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).findFirst().get().getValue(); - assetIds = assetIds.stream().filter(assetId -> !assetId.getName().equals("globalAssetId")).collect(Collectors.toList()); - } catch (Exception ignored) {} - + List globalAssetId = assetIds.stream() + .filter(assetId -> "globalAssetId".equals(assetId.getName())) + .map(SpecificAssetId::getValue) + .collect(Collectors.toList()); if (assetIds != null && !assetIds.isEmpty()) { List assetIdCriteria = new ArrayList<>(); for (SpecificAssetId assetId : assetIds) { @@ -195,8 +193,8 @@ public Iterable getAllAas(List assetI } query.addCriteria(criteria); - if (globalAssetId != null && !globalAssetId.isEmpty()) { - query.addCriteria(Criteria.where("assetInformation.globalAssetId").is(globalAssetId)); + for (String id : globalAssetId) { + query.addCriteria(Criteria.where("assetInformation.globalAssetId").is(id)); } return mongoOperations.find(query, AssetAdministrationShell.class, collectionName); From 8d64fd8f9153c8294c9962a57e53ad58bb66611d Mon Sep 17 00:00:00 2001 From: FriedJannik Date: Thu, 11 Dec 2025 11:06:17 +0100 Subject: [PATCH 2/4] Intermediate commit --- .gitignore | 2 ++ .../aasservice/backend/MongoDBAasOperations.java | 12 +++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index ecadeccfa..b2ea72595 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,5 @@ local.properties /.env **.iml + +.DS_Store diff --git a/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java b/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java index 3fd254845..47b6ef440 100644 --- a/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java +++ b/basyx.aasservice/basyx.aasservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/MongoDBAasOperations.java @@ -240,13 +240,11 @@ private List buildAasFilterCriteria(List assetIds, St List criteriaList = new ArrayList<>(); // Extract globalAssetId from assetIds - String globalAssetId = null; + List globalAssetIds = new ArrayList<>(); try { - globalAssetId = assetIds.stream() + globalAssetIds = assetIds.stream() .filter(assetId -> "globalAssetId".equals(assetId.getName())) - .findFirst() - .map(SpecificAssetId::getValue) - .orElse(null); + .toList(); assetIds = assetIds.stream() .filter(assetId -> !"globalAssetId".equals(assetId.getName())) @@ -267,8 +265,8 @@ private List buildAasFilterCriteria(List assetIds, St } // Match globalAssetId if present - if (globalAssetId != null && !globalAssetId.isEmpty()) { - criteriaList.add(Criteria.where("assetInformation.globalAssetId").is(globalAssetId)); + for (SpecificAssetId globalAssetId : globalAssetIds) { + criteriaList.add(Criteria.where("assetInformation.globalAssetId").is(globalAssetId.getValue())); } return criteriaList; From 8395bc0ffcc3eab6c9f60f69199e45979aaf5a44 Mon Sep 17 00:00:00 2001 From: FriedJannik Date: Thu, 11 Dec 2025 11:48:59 +0100 Subject: [PATCH 3/4] Fixes InMemory Implementation of filtering --- .../http/AasRepositoryHTTPSuite.java | 21 +++++++++++++++---- .../backend/InMemoryAasBackend.java | 19 +++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java b/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java index bd0f063f0..1114eb0e0 100644 --- a/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java +++ b/basyx.aasrepository/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPSuite.java @@ -43,7 +43,6 @@ import org.apache.hc.core5.http.ProtocolException; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException; -import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetAdministrationShell; import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier; import org.eclipse.digitaltwin.basyx.http.HttpBaSyxHeader; import org.eclipse.digitaltwin.basyx.http.pagination.Base64UrlEncodedCursor; @@ -193,15 +192,25 @@ public void getAllAasWithIdShort() throws IOException, ParseException { } @Test - public void getAllAasWithMultipleAssetIds() throws IOException, ParseException { + public void getAllAasWithMultipleDifferentGlobalAssetIds() throws IOException, ParseException { createMultipleAasOnServer(); - CloseableHttpResponse retrievalResponse = getAllAasMultipleGlobalAssetIdsParam(); + CloseableHttpResponse retrievalResponse = getAllAasMultipleDifferentGlobalAssetIdsParam(); assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode()); String actualJsonFromServer = BaSyxHttpTestUtils.getResponseAsString(retrievalResponse); BaSyxHttpTestUtils.assertSameJSONContent(getEmptyResultJSONString(), getJSONWithoutCursorInfo(actualJsonFromServer)); } + @Test + public void getAllAasWithMultipleIdenticalGlobalAssetIds() throws IOException, ParseException { + createMultipleAasOnServer(); + CloseableHttpResponse retrievalResponse = getAllAasMultipleIdenticalGlobalAssetIdsParam(); + assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode()); + + String actualJsonFromServer = BaSyxHttpTestUtils.getResponseAsString(retrievalResponse); + BaSyxHttpTestUtils.assertSameJSONContent(getPaginatedAas1JSONString(), getJSONWithoutCursorInfo(actualJsonFromServer)); + } + @Test public void deleteAas() throws IOException { createDummyAasOnServer(getAas1JSONString()); @@ -503,10 +512,14 @@ protected CloseableHttpResponse getAllAasGlobalAssetIdsParam() throws IOExceptio return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9"); } - protected CloseableHttpResponse getAllAasMultipleGlobalAssetIdsParam() throws IOException { + protected CloseableHttpResponse getAllAasMultipleDifferentGlobalAssetIdsParam() throws IOException { return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9&assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6ImR1bW15QWFzQXNzZXRJZCINCn0"); } + protected CloseableHttpResponse getAllAasMultipleIdenticalGlobalAssetIdsParam() throws IOException { + return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9&assetIds=ew0KIm5hbWUiOiJnbG9iYWxBc3NldElkIiwNCiJ2YWx1ZSI6Imdsb2JhbEFzc2V0SWQiDQp9"); + } + protected CloseableHttpResponse getAllAasIdShortParam() throws IOException { return BaSyxHttpTestUtils.executeGetOnURL(getURL()+"?idShort=ExampleMotor"); } diff --git a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java index 3aafc2dd1..34da1bd29 100644 --- a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java +++ b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java @@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.TreeMap; @@ -115,12 +116,9 @@ public AssetInformation getAssetInformation(String aasId) { public Iterable getAllAas(List assetIds, String idShort) { Iterable allAas = findAll(); List filteredAas = new java.util.ArrayList<>(); - String globalAssetId = null; + List globalAssetIds = new ArrayList<>(); try { - if(assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).count() > 1){ - return filteredAas; - } - globalAssetId = assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).findFirst().get().getValue(); + globalAssetIds = assetIds.stream().filter(assetId -> assetId.getName().equals("globalAssetId")).toList(); assetIds = assetIds.stream().filter(assetId -> !assetId.getName().equals("globalAssetId")).collect(Collectors.toList()); } catch (Exception e) {} for (AssetAdministrationShell aas : allAas){ @@ -132,7 +130,16 @@ public Iterable getAllAas(List assetI matchesAssetIds = false; } boolean matchesIdShort = (idShort == null || aas.getIdShort().equals(idShort)); - boolean matchesGlobalAssetId = (globalAssetId == null || (aas.getAssetInformation() != null && aas.getAssetInformation().getGlobalAssetId() != null && aas.getAssetInformation().getGlobalAssetId().equals(globalAssetId))); + boolean matchesGlobalAssetId = globalAssetIds.isEmpty(); + for (SpecificAssetId globalAssetId : globalAssetIds){ + String id = globalAssetId.getValue(); + if (aas.getAssetInformation().getGlobalAssetId().equals(id)){ + matchesGlobalAssetId = true; + } else { + matchesGlobalAssetId = false; + break; + } + } if (matchesAssetIds && matchesIdShort && matchesGlobalAssetId) { filteredAas.add(aas); } From 8d85804837b348743f276ce8258b4c2a881d0f04 Mon Sep 17 00:00:00 2001 From: FriedJannik Date: Thu, 11 Dec 2025 12:58:30 +0100 Subject: [PATCH 4/4] Fixes InMemory Implementation of filtering --- .../basyx/aasservice/backend/InMemoryAasBackend.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java index 34da1bd29..3f88f07f3 100644 --- a/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java +++ b/basyx.aasservice/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasBackend.java @@ -133,12 +133,11 @@ public Iterable getAllAas(List assetI boolean matchesGlobalAssetId = globalAssetIds.isEmpty(); for (SpecificAssetId globalAssetId : globalAssetIds){ String id = globalAssetId.getValue(); - if (aas.getAssetInformation().getGlobalAssetId().equals(id)){ - matchesGlobalAssetId = true; - } else { + if (aas.getAssetInformation() == null || aas.getAssetInformation().getGlobalAssetId() == null || !aas.getAssetInformation().getGlobalAssetId().equals(id)) { matchesGlobalAssetId = false; break; } + matchesGlobalAssetId = true; } if (matchesAssetIds && matchesIdShort && matchesGlobalAssetId) { filteredAas.add(aas);