From 03ec45b20f8f7478b2dead992479b78d6bb217af Mon Sep 17 00:00:00 2001 From: Markus Damm <125889012+M-Damm@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:20:59 +0100 Subject: [PATCH 1/4] Implements AssetInformation Endpoint Signed-off-by: Markus Damm <125889012+M-Damm@users.noreply.github.com> --- basyx.aasrepository-backend-inmemory/pom.xml | 8 ++++ .../aasrepository/InMemoryAasRepository.java | 13 ++++++ .../aasrepository/MongoDBAasRepository.java | 15 +++++++ basyx.aasrepository-core/pom.xml | 8 ++++ .../basyx/aasrepository/AasRepository.java | 21 +++++++++ .../aasrepository/AasRepositorySuite.java | 40 +++++++++++++++-- .../feature/mqtt/MqttAasRepository.java | 12 +++++ .../http/AasRepositoryApiHTTPController.java | 16 +++++++ .../http/AasRepositoryHTTPApi.java | 18 +++++++- .../http/TestAasRepositoryHTTP.java | 45 +++++++++++++++++++ .../src/test/resources/assetInfoSimple.json | 40 +++++++++++++++++ .../src/test/resources/exampleAssetInfo.json | 27 +++++++++++ .../backend/InMemoryAasService.java | 12 +++++ .../basyx/aasservice/AasService.java | 13 ++++++ .../basyx/aasservice/AasServiceSuite.java | 29 ++++++++++-- .../DummyAssetAdministrationShell.java | 7 ++- 16 files changed, 315 insertions(+), 9 deletions(-) create mode 100644 basyx.aasrepository-http/src/test/resources/assetInfoSimple.json create mode 100644 basyx.aasrepository-http/src/test/resources/exampleAssetInfo.json diff --git a/basyx.aasrepository-backend-inmemory/pom.xml b/basyx.aasrepository-backend-inmemory/pom.xml index c8e80dec..5945ab50 100644 --- a/basyx.aasrepository-backend-inmemory/pom.xml +++ b/basyx.aasrepository-backend-inmemory/pom.xml @@ -37,6 +37,14 @@ tests test + + + org.eclipse.digitaltwin.basyx + basyx.aasservice-core + 2.0.0-SNAPSHOT + tests + test + org.eclipse.digitaltwin.basyx diff --git a/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/InMemoryAasRepository.java b/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/InMemoryAasRepository.java index 45a30f07..f85b8745 100644 --- a/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/InMemoryAasRepository.java +++ b/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/InMemoryAasRepository.java @@ -30,6 +30,7 @@ import java.util.stream.Collectors; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.aasservice.AasService; import org.eclipse.digitaltwin.basyx.aasservice.AasServiceFactory; @@ -119,4 +120,16 @@ public void removeSubmodelReference(String aasId, String submodelId) { aasServices.get(aasId).removeSubmodelReference(submodelId); } + @Override + public void setAssetInformation(String aasId, AssetInformation aasInfo) throws ElementDoesNotExistException { + throwIfAasDoesNotExist(aasId); + aasServices.get(aasId).getAAS().setAssetInformation(aasInfo); + } + + @Override + public AssetInformation getAssetInformation(String aasId) throws ElementDoesNotExistException{ + throwIfAasDoesNotExist(aasId); + return aasServices.get(aasId).getAAS().getAssetInformation(); + } + } diff --git a/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java b/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java index 0d57abc6..63a01340 100644 --- a/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java +++ b/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java @@ -27,6 +27,7 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.aasservice.backend.InMemoryAasService; import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingIdentifierException; @@ -125,4 +126,18 @@ public void removeSubmodelReference(String aasId, String submodelId) { updateAas(service.getAAS()); } + + @Override + public void setAssetInformation(String aasId, AssetInformation aasInfo) throws ElementDoesNotExistException { + InMemoryAasService service = new InMemoryAasService(getAas(aasId)); + service.setAssetInformation(aasInfo); + + updateAas(service.getAAS()); + } + + @Override + public AssetInformation getAssetInformation(String aasId) throws ElementDoesNotExistException{ + return this.getAas(aasId).getAssetInformation(); + } + } diff --git a/basyx.aasrepository-core/pom.xml b/basyx.aasrepository-core/pom.xml index 5a96fba0..699f1dab 100644 --- a/basyx.aasrepository-core/pom.xml +++ b/basyx.aasrepository-core/pom.xml @@ -23,6 +23,14 @@ basyx.aasservice-core 2.0.0-SNAPSHOT + + + org.eclipse.digitaltwin.basyx + basyx.aasservice-core + 2.0.0-SNAPSHOT + tests + test + diff --git a/basyx.aasrepository-core/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepository.java b/basyx.aasrepository-core/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepository.java index 153b2a55..1ca2a63b 100644 --- a/basyx.aasrepository-core/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepository.java +++ b/basyx.aasrepository-core/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepository.java @@ -28,6 +28,7 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingIdentifierException; import org.eclipse.digitaltwin.basyx.core.exceptions.ElementDoesNotExistException; @@ -100,6 +101,26 @@ public interface AasRepository { */ public void removeSubmodelReference(String aasId, String submodelId); + /** + * Sets the asset-information of a specific AAS + * + * @param aasId + * the id of the AAS + * + * @return the requested Asset-Information of the specified AAS + */ + public void setAssetInformation(String aasId, AssetInformation aasInfo) throws ElementDoesNotExistException; + + /** + * Retrieves the asset-information of a specific AAS + * + * @param aasId + * the id of the AAS + * + * @return the requested AAS + */ + public AssetInformation getAssetInformation(String aasId) throws ElementDoesNotExistException; + public default String getName() { return "aasRepository-default-name"; } diff --git a/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java b/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java index dd1f8471..96c089df 100644 --- a/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java +++ b/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java @@ -34,9 +34,12 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetKind; import org.eclipse.digitaltwin.aas4j.v3.model.KeyTypes; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultKey; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultReference; import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingIdentifierException; @@ -54,6 +57,7 @@ public abstract class AasRepositorySuite { private AssetAdministrationShell aas1; private AssetAdministrationShell aas2; + private AssetAdministrationShell aas3; private List preconfiguredShells = new ArrayList<>(); private static final String DUMMY_SUBMODEL_ID = "dummySubmodelId"; @@ -66,11 +70,11 @@ public abstract class AasRepositorySuite { public void createAasRepoWithDummyAas() { aasRepo = getAasRepositoryFactory().create(); - aas1 = new DefaultAssetAdministrationShell.Builder().id("aas1/s").submodels(createDummyReference()) - .build(); + aas1 = new DefaultAssetAdministrationShell.Builder().id("aas1/s").submodels(createDummyReference()).build(); - aas2 = new DefaultAssetAdministrationShell.Builder().id("aas2") - .build(); + aas2 = new DefaultAssetAdministrationShell.Builder().id("aas2").build(); + AssetInformation assetInfo = createDummyAssetInformation(); + aas2.setAssetInformation(assetInfo); preconfiguredShells.add(aas1); preconfiguredShells.add(aas2); @@ -170,4 +174,32 @@ private Reference createDummyReference() { .keys(new DefaultKey.Builder().type(KeyTypes.SUBMODEL).value(DUMMY_SUBMODEL_ID).build()).build(); } + @Test + public void getAssetInformation() { + assertEquals(aas2.getAssetInformation(), aasRepo.getAssetInformation(aas2.getId())); + } + + @Test(expected = ElementDoesNotExistException.class) + public void getAssetInformationOfNonExistingAas() { + aasRepo.getAssetInformation("nonExisting"); + } + + @Test + public void setAssetInformation() { + AssetInformation assetInfo = createDummyAssetInformation(); + aasRepo.setAssetInformation(aas2.getId(), assetInfo); + assertEquals(assetInfo, aasRepo.getAssetInformation(aas2.getId())); + } + + private AssetInformation createDummyAssetInformation() { + AssetInformation assetInfo = new DefaultAssetInformation.Builder().assetKind(AssetKind.INSTANCE).globalAssetId( + new DefaultReference.Builder().keys(new DefaultKey.Builder().value("assetIDTestKey").build()).build()) + .build(); + return assetInfo; + } + + @Test(expected = ElementDoesNotExistException.class) + public void setAssetInformationOfNonExistingAas() { + aasRepo.setAssetInformation("nonExisting", createDummyAssetInformation()); + } } diff --git a/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java b/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java index a9affdd4..4efd7bcd 100644 --- a/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java +++ b/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java @@ -30,6 +30,7 @@ import org.eclipse.digitaltwin.aas4j.v3.dataformat.SerializationException; import org.eclipse.digitaltwin.aas4j.v3.dataformat.json.JsonSerializer; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository; import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingIdentifierException; @@ -111,6 +112,16 @@ public void removeSubmodelReference(String aasId, String submodelId) { decorated.removeSubmodelReference(aasId, submodelId); } + @Override + public void setAssetInformation(String aasId, AssetInformation aasInfo) throws ElementDoesNotExistException { + decorated.getAas(aasId).setAssetInformation(aasInfo); + } + + @Override + public AssetInformation getAssetInformation(String aasId) throws ElementDoesNotExistException{ + return decorated.getAas(aasId).getAssetInformation(); + } + private void aasCreated(AssetAdministrationShell shell, String repoId) { sendMqttMessage(topicFactory.createCreateAASTopic(repoId), serializePayload(shell)); } @@ -159,4 +170,5 @@ private MqttMessage createMqttMessage(String payload) { return new MqttMessage(payload.getBytes()); } } + } diff --git a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java index 5c8be544..fd90b550 100644 --- a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java +++ b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java @@ -33,6 +33,7 @@ import javax.validation.Valid; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository; import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier; @@ -168,4 +169,19 @@ public ResponseEntity> getAllAssetAdministrationS @Parameter(in = ParameterIn.QUERY, description = "The Asset Administration Shell’s IdShort", schema = @Schema()) @Valid @RequestParam(value = "idShort", required = false) String idShort) { return new ResponseEntity>(new ArrayList<>(aasRepository.getAllAas()), HttpStatus.OK); } + + @Override + public ResponseEntity postAssetInformationByAasId( + @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier, + @Parameter(in = ParameterIn.DEFAULT, description = "Asset Information object", required = true, schema = @Schema()) @Valid @RequestBody AssetInformation body) { + aasRepository.setAssetInformation(aasIdentifier.getIdentifier(), body); + return new ResponseEntity(HttpStatus.OK); + } + + @Override + public ResponseEntity getAssetInformationByAasId( + @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier) { + return new ResponseEntity(aasRepository.getAssetInformation(aasIdentifier.getIdentifier()), HttpStatus.OK); + } + } diff --git a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java index 9d3b0c6a..fe0cdf86 100644 --- a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java +++ b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java @@ -36,6 +36,7 @@ import javax.validation.Valid; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier; import org.springframework.http.ResponseEntity; @@ -125,11 +126,26 @@ ResponseEntity putAssetAdministrationShell( @Parameter(in = ParameterIn.QUERY, description = "Determines the request or response kind of the resource", schema = @Schema(allowableValues = { "normal", "trimmed", "value", "reference", "path" }, defaultValue = "normal")) @Valid @RequestParam(value = "content", required = false, defaultValue = "normal") String content); - @Operation(summary = "Updates an existing Asset Administration Shell", description = "", tags = { "Asset Administration Shell Repository" }) @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Asset Administration Shell updated successfully") }) @RequestMapping(value = "/shells/{aasIdentifier}", consumes = { "application/json" }, method = RequestMethod.PUT) ResponseEntity putAssetAdministrationShellById( @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier, @Parameter(in = ParameterIn.DEFAULT, description = "Asset Administration Shell object", required = true, schema = @Schema()) @Valid @RequestBody AssetAdministrationShell body); + + @Operation(summary = "Updates the Asset Information of an existing Asset Administration Shell", description = "", tags = { "Asset Administration Shell Repository" }) + @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Asset Information updated successfully") }) + @RequestMapping(value = "/shells/{aasIdentifier}/asset-information", consumes = { "application/json" }, method = RequestMethod.POST) + ResponseEntity postAssetInformationByAasId( + @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier, + @Parameter(in = ParameterIn.DEFAULT, description = "Asset Information object", required = true, schema = @Schema()) @Valid @RequestBody AssetInformation body); + + @Operation(summary = "Returns the Asset Information of a specific Asset Administration Shell", description = "", tags = { "Asset Administration Shell Repository" }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Requested Asset Information of Asset Administration Shell", content = @Content(mediaType = "application/json", schema = @Schema(implementation = AssetInformation.class))) }) + @RequestMapping(value = "/shells/{aasIdentifier}/asset-information", produces = { + "application/json" }, method = RequestMethod.GET) + ResponseEntity getAssetInformationByAasId( + @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier); + + } diff --git a/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java b/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java index 94761206..7104b240 100644 --- a/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java +++ b/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java @@ -187,6 +187,51 @@ public void removeNonExistingSubmodelReference() throws FileNotFoundException, I assertEquals(404, deleteResponse.getCode()); } + @Test + public void getAssetInformationByIdentifier() throws FileNotFoundException, IOException, ParseException { + createDummyAasOnServer(); + String url = getSpecificAasAccessURL(dummyAasId) + "/asset-information"; + CloseableHttpResponse response = BaSyxHttpTestUtils.executeGetOnURL(url); + + String expected = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:assetInfoSimple.json"); + + BaSyxHttpTestUtils.assertSameJSONContent(expected, BaSyxHttpTestUtils.getResponseAsString(response)); + } + + @Test + public void getNonExistingAssetInformationByIdentifier() throws FileNotFoundException, IOException, ParseException { + String url = getSpecificAasAccessURL("someAasThatSureWontExist") + "/asset-information"; + CloseableHttpResponse response = BaSyxHttpTestUtils.executeGetOnURL(url); + + assertEquals(404, response.getCode()); + } + + @Test + public void postAssetInformationByIdentifier() throws FileNotFoundException, IOException, ParseException { + createDummyAasOnServer(); + + String json = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:exampleAssetInfo.json"); + + BaSyxHttpTestUtils.executePostOnServer(getSpecificAasAccessURL(dummyAasId) + "/asset-information", json); + + CloseableHttpResponse response = BaSyxHttpTestUtils + .executeGetOnURL(getSpecificAasAccessURL(dummyAasId) + "/asset-information"); + + BaSyxHttpTestUtils.assertSameJSONContent(json, BaSyxHttpTestUtils.getResponseAsString(response)); + } + + @Test + public void postAssetInformationToNonExistingAasByIdentifier() + throws FileNotFoundException, IOException, ParseException { + + String json = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:exampleAssetInfo.json"); + + CloseableHttpResponse response = BaSyxHttpTestUtils + .executeGetOnURL(getSpecificAasAccessURL("someAasThatSureWontExist") + "/asset-information"); + + assertEquals(404, response.getCode()); + } + private String createDummyAasOnServer() throws FileNotFoundException, IOException { String aasJsonContent = getAasJSONString(); createAasOnServer(aasJsonContent); diff --git a/basyx.aasrepository-http/src/test/resources/assetInfoSimple.json b/basyx.aasrepository-http/src/test/resources/assetInfoSimple.json new file mode 100644 index 00000000..4c87dc28 --- /dev/null +++ b/basyx.aasrepository-http/src/test/resources/assetInfoSimple.json @@ -0,0 +1,40 @@ +{ + "assetKind":"Instance", + "globalAssetId":{ + "keys":[ + { + "type":"AssetAdministrationShell", + "value":"http://customer.com/assets/KHBVZJSQKIY" + } + ], + "type":"GlobalReference" + }, + "specificAssetIds":[ + { + "name":"EquipmentID", + "value":"538fd1b3-f99f-4a52-9c75-72e9fa921270", + "externalSubjectId":{ + "keys":[ + { + "type":"GlobalReference", + "value":"http://customer.com/Systems/ERP/012" + } + ], + "type":"GlobalReference" + } + }, + { + "name":"DeviceID", + "value":"QjYgPggjwkiHk4RrQiYSLg==", + "externalSubjectId":{ + "keys":[ + { + "type":"GlobalReference", + "value":"http://customer.com/Systems/IoT/1" + } + ], + "type":"GlobalReference" + } + } + ] +} \ No newline at end of file diff --git a/basyx.aasrepository-http/src/test/resources/exampleAssetInfo.json b/basyx.aasrepository-http/src/test/resources/exampleAssetInfo.json new file mode 100644 index 00000000..958d6c60 --- /dev/null +++ b/basyx.aasrepository-http/src/test/resources/exampleAssetInfo.json @@ -0,0 +1,27 @@ +{ + "assetKind":"Instance", + "globalAssetId":{ + "keys":[ + { + "type":"AssetAdministrationShell", + "value":"http://customer.com/assets/KHBVZJSQKIY" + } + ], + "type":"GlobalReference" + }, + "specificAssetIds":[ + { + "name":"EquipmentID", + "value":"007", + "externalSubjectId":{ + "keys":[ + { + "type":"GlobalReference", + "value":"http://customer.com/Systems/ERP/007" + } + ], + "type":"GlobalReference" + } + } + ] +} \ No newline at end of file diff --git a/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasService.java b/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasService.java index b1a1003b..370bf6de 100644 --- a/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasService.java +++ b/basyx.aasservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/backend/InMemoryAasService.java @@ -27,6 +27,7 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Key; import org.eclipse.digitaltwin.aas4j.v3.model.KeyTypes; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; @@ -73,6 +74,16 @@ public void removeSubmodelReference(String submodelId) { aas.getSubmodels().remove(specificSubmodelReference); } + @Override + public void setAssetInformation(AssetInformation aasInfo) { + aas.setAssetInformation(aasInfo); + } + + @Override + public AssetInformation getAssetInformation() { + return aas.getAssetInformation(); + } + private Reference getSubmodelReferenceById(String submodelId) { List submodelReferences = aas.getSubmodels(); @@ -84,4 +95,5 @@ private Reference getSubmodelReferenceById(String submodelId) { return specificSubmodelReference; } + } diff --git a/basyx.aasservice-core/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/AasService.java b/basyx.aasservice-core/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/AasService.java index 7c344b44..4857b7d5 100644 --- a/basyx.aasservice-core/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/AasService.java +++ b/basyx.aasservice-core/src/main/java/org/eclipse/digitaltwin/basyx/aasservice/AasService.java @@ -27,6 +27,7 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; /** @@ -60,4 +61,16 @@ public interface AasService { * Removes a Submodel Reference */ public void removeSubmodelReference(String submodelId); + + /** + * Sets the asset-information of the AAS contained in the server + */ + public void setAssetInformation(AssetInformation aasInfo); + + /** + * Retrieves the asset-information of the AAS contained in the server + * + * @return the Asset-Information of the AAS + */ + public AssetInformation getAssetInformation(); } diff --git a/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/AasServiceSuite.java b/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/AasServiceSuite.java index 4810dd7a..2e3d6624 100644 --- a/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/AasServiceSuite.java +++ b/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/AasServiceSuite.java @@ -32,8 +32,11 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetKind; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.aas4j.v3.model.Submodel; +import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultKey; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultReference; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodel; @@ -62,7 +65,7 @@ public void initSuite() { } @Test - public void aasRetrieval() { + public void getAas() { assertEquals(aas, aasService.getAAS()); } @@ -76,7 +79,7 @@ public void getSubmodelReference() { @Test public void addSubmodelReference() { - Submodel submodel = createNewSubmodel(); + Submodel submodel = createDummySubmodel(); aasService.addSubmodelReference(submodel.getSemanticId()); @@ -101,11 +104,31 @@ public void removeNonExistingSubmodelReference() { aasService.removeSubmodelReference("doesNotMatter"); } + @Test + public void getAssetInformation() { + assertEquals(aas.getAssetInformation(), aasService.getAssetInformation()); + } + + @Test + public void setAssetInformation() { + AssetInformation assetInfo = createDummyAssetInformation(); + aasService.setAssetInformation(assetInfo); + assertEquals(assetInfo, aasService.getAssetInformation()); + } + + private AssetInformation createDummyAssetInformation() { + AssetInformation assetInfo = new DefaultAssetInformation.Builder().assetKind(AssetKind.INSTANCE) + .globalAssetId( + new DefaultReference.Builder().keys(new DefaultKey.Builder().value("assetIDTestKey").build()).build()) + .build(); + return assetInfo; + } + private Reference getFirstSubmodelReference(List submodelReferences) { return submodelReferences.get(0); } - private DefaultSubmodel createNewSubmodel() { + private DefaultSubmodel createDummySubmodel() { return new DefaultSubmodel.Builder() .semanticId( new DefaultReference.Builder().keys(new DefaultKey.Builder().value("testKey").build()).build()) diff --git a/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/DummyAssetAdministrationShell.java b/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/DummyAssetAdministrationShell.java index 7760cbb5..25791163 100644 --- a/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/DummyAssetAdministrationShell.java +++ b/basyx.aasservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasservice/DummyAssetAdministrationShell.java @@ -4,9 +4,11 @@ import java.util.List; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetKind; import org.eclipse.digitaltwin.aas4j.v3.model.KeyTypes; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetAdministrationShell; +import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetInformation; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultKey; import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultReference; @@ -22,7 +24,10 @@ public class DummyAssetAdministrationShell { public static Reference submodelReference = buildDummyReference(); public static AssetAdministrationShell getDummyShell() { - return new DefaultAssetAdministrationShell.Builder().id("arbitrary").build(); + return new DefaultAssetAdministrationShell.Builder().id("arbitrary") + .assetInformation(new DefaultAssetInformation.Builder().assetKind(AssetKind.INSTANCE) + .globalAssetId(buildDummyReference()).build()) + .build(); } /** From 0d74d768924325b208899c50a4b107913990d835 Mon Sep 17 00:00:00 2001 From: Frank Schnicke <77283144+FrankSchnicke@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:38:16 +0100 Subject: [PATCH 2/4] CI trigger --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 9a501fae..849071ac 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ # Eclipse BaSyx Java Components [![Docker Pulls](https://img.shields.io/docker/pulls/eclipsebasyx/aas-server?style=plastic)](https://hub.docker.com/search?q=eclipsebasyx) [![BaSyx Logo](https://www.eclipse.org/basyx/img/basyxlogo.png)](https://www.eclipse.org/basyx/) - + [![AAS Server javadoc](https://javadoc.io/badge2/org.eclipse.basyx/basyx.components.AASServer/javadoc.svg)](https://javadoc.io/doc/org.eclipse.basyx/basyx.components.AASServer) AAS Server [![AAS Registry javadoc](https://javadoc.io/badge2/org.eclipse.basyx/basyx.components.registry/javadoc.svg)](https://javadoc.io/doc/org.eclipse.basyx/basyx.components.registry) AAS Registry From b32575e8e186d54420f5ea3a3a41f939dfa1251a Mon Sep 17 00:00:00 2001 From: Markus Damm Date: Wed, 15 Mar 2023 15:56:53 +0100 Subject: [PATCH 3/4] addressed comments wrt pull request Development v2 asset info #295 --- .../aasrepository/AasRepositorySuite.java | 23 +++++++++---------- .../feature/mqtt/MqttAasRepository.java | 4 ++-- .../http/TestAasRepositoryHTTP.java | 22 +++++++++++------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java b/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java index 96c089df..8d014077 100644 --- a/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java +++ b/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java @@ -169,11 +169,6 @@ public void removeSubmodelReferenceOfNonExistingAas() { aasRepo.removeSubmodelReference("nonExisting", "doesNotMatter"); } - private Reference createDummyReference() { - return new DefaultReference.Builder() - .keys(new DefaultKey.Builder().type(KeyTypes.SUBMODEL).value(DUMMY_SUBMODEL_ID).build()).build(); - } - @Test public void getAssetInformation() { assertEquals(aas2.getAssetInformation(), aasRepo.getAssetInformation(aas2.getId())); @@ -191,15 +186,19 @@ public void setAssetInformation() { assertEquals(assetInfo, aasRepo.getAssetInformation(aas2.getId())); } - private AssetInformation createDummyAssetInformation() { - AssetInformation assetInfo = new DefaultAssetInformation.Builder().assetKind(AssetKind.INSTANCE).globalAssetId( - new DefaultReference.Builder().keys(new DefaultKey.Builder().value("assetIDTestKey").build()).build()) - .build(); - return assetInfo; - } - @Test(expected = ElementDoesNotExistException.class) public void setAssetInformationOfNonExistingAas() { aasRepo.setAssetInformation("nonExisting", createDummyAssetInformation()); + } + + private Reference createDummyReference() { + return new DefaultReference.Builder() + .keys(new DefaultKey.Builder().type(KeyTypes.SUBMODEL).value(DUMMY_SUBMODEL_ID).build()).build(); + } + + private AssetInformation createDummyAssetInformation() { + return new DefaultAssetInformation.Builder().assetKind(AssetKind.INSTANCE).globalAssetId( + new DefaultReference.Builder().keys(new DefaultKey.Builder().value("assetIDTestKey").build()).build()) + .build(); } } diff --git a/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java b/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java index 4efd7bcd..9dc6feff 100644 --- a/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java +++ b/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java @@ -114,12 +114,12 @@ public void removeSubmodelReference(String aasId, String submodelId) { @Override public void setAssetInformation(String aasId, AssetInformation aasInfo) throws ElementDoesNotExistException { - decorated.getAas(aasId).setAssetInformation(aasInfo); + decorated.setAssetInformation(aasId, aasInfo); } @Override public AssetInformation getAssetInformation(String aasId) throws ElementDoesNotExistException{ - return decorated.getAas(aasId).getAssetInformation(); + return decorated.getAssetInformation(aasId); } private void aasCreated(AssetAdministrationShell shell, String repoId) { diff --git a/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java b/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java index 7104b240..dc60a05b 100644 --- a/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java +++ b/basyx.aasrepository-http/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/http/TestAasRepositoryHTTP.java @@ -184,13 +184,13 @@ public void removeNonExistingSubmodelReference() throws FileNotFoundException, I createDummyAasOnServer(); String url = getSpecificSubmodelReferenceUrl(); CloseableHttpResponse deleteResponse = BaSyxHttpTestUtils.executeDeleteOnURL(url); - assertEquals(404, deleteResponse.getCode()); + assertEquals(HttpStatus.NOT_FOUND.value(), deleteResponse.getCode()); } @Test public void getAssetInformationByIdentifier() throws FileNotFoundException, IOException, ParseException { createDummyAasOnServer(); - String url = getSpecificAasAccessURL(dummyAasId) + "/asset-information"; + String url = getSpecificAssetInformationAccessURL(dummyAasId); CloseableHttpResponse response = BaSyxHttpTestUtils.executeGetOnURL(url); String expected = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:assetInfoSimple.json"); @@ -198,12 +198,13 @@ public void getAssetInformationByIdentifier() throws FileNotFoundException, IOEx BaSyxHttpTestUtils.assertSameJSONContent(expected, BaSyxHttpTestUtils.getResponseAsString(response)); } + @Test public void getNonExistingAssetInformationByIdentifier() throws FileNotFoundException, IOException, ParseException { - String url = getSpecificAasAccessURL("someAasThatSureWontExist") + "/asset-information"; + String url = getSpecificAasAccessURL("nonExisting") + "/asset-information"; CloseableHttpResponse response = BaSyxHttpTestUtils.executeGetOnURL(url); - assertEquals(404, response.getCode()); + assertEquals(HttpStatus.NOT_FOUND.value(), response.getCode()); } @Test @@ -212,10 +213,10 @@ public void postAssetInformationByIdentifier() throws FileNotFoundException, IOE String json = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:exampleAssetInfo.json"); - BaSyxHttpTestUtils.executePostOnServer(getSpecificAasAccessURL(dummyAasId) + "/asset-information", json); + BaSyxHttpTestUtils.executePostOnServer(getSpecificAssetInformationAccessURL(dummyAasId), json); CloseableHttpResponse response = BaSyxHttpTestUtils - .executeGetOnURL(getSpecificAasAccessURL(dummyAasId) + "/asset-information"); + .executeGetOnURL(getSpecificAssetInformationAccessURL(dummyAasId)); BaSyxHttpTestUtils.assertSameJSONContent(json, BaSyxHttpTestUtils.getResponseAsString(response)); } @@ -227,9 +228,14 @@ public void postAssetInformationToNonExistingAasByIdentifier() String json = BaSyxHttpTestUtils.readJSONStringFromFile("classpath:exampleAssetInfo.json"); CloseableHttpResponse response = BaSyxHttpTestUtils - .executeGetOnURL(getSpecificAasAccessURL("someAasThatSureWontExist") + "/asset-information"); + .executeGetOnURL(getSpecificAssetInformationAccessURL("nonExisting")); + + assertEquals(HttpStatus.NOT_FOUND.value(), response.getCode()); + } + - assertEquals(404, response.getCode()); + private String getSpecificAssetInformationAccessURL(String aasID) { + return getSpecificAasAccessURL(aasID) + "/asset-information"; } private String createDummyAasOnServer() throws FileNotFoundException, IOException { From e0dab52032ca17291c0233e40cfc8e48450ddc0a Mon Sep 17 00:00:00 2001 From: Frank Schnicke Date: Thu, 16 Mar 2023 11:51:08 +0100 Subject: [PATCH 4/4] Fixes merge --- .../basyx/aasrepository/MongoDBAasRepository.java | 2 +- .../http/AasRepositoryApiHTTPController.java | 6 +----- .../basyx/aasrepository/http/AasRepositoryHTTPApi.java | 9 --------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java b/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java index 35035c5e..3d65ecdf 100644 --- a/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java +++ b/basyx.aasrepository-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/MongoDBAasRepository.java @@ -132,7 +132,7 @@ public void setAssetInformation(String aasId, AssetInformation aasInfo) throws E InMemoryAasService service = new InMemoryAasService(getAas(aasId)); service.setAssetInformation(aasInfo); - updateAas(service.getAAS()); + updateAas(aasId, service.getAAS()); } @Override diff --git a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java index a4ab58c3..9aadcc95 100644 --- a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java +++ b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryApiHTTPController.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell; @@ -60,15 +59,12 @@ public class AasRepositoryApiHTTPController implements AasRepositoryHTTPApi { private static final Logger log = LoggerFactory.getLogger(AasRepositoryApiHTTPController.class); private final ObjectMapper objectMapper; - - private final HttpServletRequest request; private final AasRepository aasRepository; @Autowired - public AasRepositoryApiHTTPController(ObjectMapper objectMapper, HttpServletRequest request, AasRepository aasRepository) { + public AasRepositoryApiHTTPController(ObjectMapper objectMapper, AasRepository aasRepository) { this.objectMapper = objectMapper; - this.request = request; this.aasRepository = aasRepository; } diff --git a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java index 6f43238f..76f1b6cb 100644 --- a/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java +++ b/basyx.aasrepository-http/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/http/AasRepositoryHTTPApi.java @@ -116,15 +116,6 @@ ResponseEntity postSubmodelReference( @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier, @Parameter(in = ParameterIn.DEFAULT, description = "Reference to the Submodel", required = true, schema = @Schema()) @Valid @RequestBody Reference body); - @Operation(summary = "Updates the Asset Administration Shell", description = "", tags = { "Asset Administration Shell Repository" }) - @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Asset Administration Shell updated successfully") }) - @RequestMapping(value = "/shells/{aasIdentifier}/aas", consumes = { "application/json" }, method = RequestMethod.PUT) - ResponseEntity putAssetAdministrationShell( - @Parameter(in = ParameterIn.PATH, description = "The Asset Administration Shell’s unique id (BASE64-URL-encoded)", required = true, schema = @Schema()) @PathVariable("aasIdentifier") Base64UrlEncodedIdentifier aasIdentifier, - @Parameter(in = ParameterIn.DEFAULT, description = "Asset Administration Shell object", required = true, schema = @Schema()) @Valid @RequestBody AssetAdministrationShell body, - @Parameter(in = ParameterIn.QUERY, description = "Determines the request or response kind of the resource", schema = @Schema(allowableValues = { "normal", "trimmed", "value", "reference", - "path" }, defaultValue = "normal")) @Valid @RequestParam(value = "content", required = false, defaultValue = "normal") String content); - @Operation(summary = "Updates an existing Asset Administration Shell", description = "", tags = { "Asset Administration Shell Repository" }) @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Asset Administration Shell updated successfully") }) @RequestMapping(value = "/shells/{aasIdentifier}", consumes = { "application/json" }, method = RequestMethod.PUT)