From e70c288aef73c43d50ed082408b95ce144f464e1 Mon Sep 17 00:00:00 2001 From: ShehriyarShariq-Fraunhofer Date: Tue, 12 Nov 2024 09:32:12 +0100 Subject: [PATCH] Add submodelReference eventing to MqttAasRepository PR (#515) * feat: Events + Tests * fix: remove extra line * style: bump header date --------- Co-authored-by: Mateus Molina --- .../Readme.md | 4 +- .../feature/mqtt/MqttAasRepository.java | 17 +++++++- .../mqtt/MqttAasRepositoryTopicFactory.java | 39 +++++++++++++++++- .../mqtt/TestMqttV2AASAggregatorObserver.java | 41 +++++++++++++++++-- 4 files changed, 94 insertions(+), 7 deletions(-) diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md index e632464eb..a3f13cc22 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md +++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md @@ -5,4 +5,6 @@ This feature provides hierarchical MQTT eventing for a multitude of events: | ----------- | ----------- | --- | | AAS Created | aas-repository/\$repoId/shells/created| Created AAS JSON | | AAS Updated | aas-repository/\$repoId/shells/updated| Updated AAS JSON| -| AAS Deleted | aas-repository/\$repoId/shells/deleted| Deleted AAS JSON| \ No newline at end of file +| AAS Deleted | aas-repository/\$repoId/shells/deleted| Deleted AAS JSON| +| Submodel Reference Created | aas-repository/\$repoId/shells/submodels/\$submodelId/created| Created AAS JSON | +| Submodel Reference Deleted | aas-repository/\$repoId/shells/submodels/\$submodelId/deleted| Deleted AAS JSON| \ No newline at end of file diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java index ce2ed9418..48732da4c 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2024 the Eclipse BaSyx Authors * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -107,12 +107,19 @@ public CursorResult> getSubmodelReferences(String aasId, Paginat @Override public void addSubmodelReference(String aasId, Reference submodelReference) { + AssetAdministrationShell shell = decorated.getAas(aasId); decorated.addSubmodelReference(aasId, submodelReference); + + String referenceId = submodelReference.getKeys().get(0).getValue(); + + submodelReferenceCreated(shell, getName(), referenceId); } @Override public void removeSubmodelReference(String aasId, String submodelId) { + AssetAdministrationShell shell = decorated.getAas(aasId); decorated.removeSubmodelReference(aasId, submodelId); + submodelReferenceDeleted(shell, getName(), submodelId); } @Override @@ -136,6 +143,14 @@ private void aasUpdated(AssetAdministrationShell shell, String repoId) { private void aasDeleted(AssetAdministrationShell shell, String repoId) { sendMqttMessage(topicFactory.createDeleteAASTopic(repoId), serializePayload(shell)); } + + private void submodelReferenceCreated(AssetAdministrationShell shell, String repoId, String referenceId) { + sendMqttMessage(topicFactory.createCreateAASSubmodelReferenceTopic(repoId, referenceId), serializePayload(shell)); + } + + private void submodelReferenceDeleted(AssetAdministrationShell shell, String repoId, String referenceId) { + sendMqttMessage(topicFactory.createDeleteAASSubmodelReferenceTopic(repoId, referenceId), serializePayload(shell)); + } private String serializePayload(AssetAdministrationShell shell) { try { diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java index f79ce8961..f714d69e6 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2024 the Eclipse BaSyx Authors * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -37,6 +37,7 @@ public class MqttAasRepositoryTopicFactory extends AbstractMqttTopicFactory { private static final String AASREPOSITORY = "aas-repository"; private static final String SHELLS = "shells"; + private static final String SUBMODELS = "submodels"; private static final String CREATED = "created"; private static final String UPDATED = "updated"; private static final String DELETED = "deleted"; @@ -93,4 +94,40 @@ public String createDeleteAASTopic(String repoId) { .add(DELETED) .toString(); } + + /** + * Creates the hierarchical topic for the submodel reference create event + * + * @param repoId + * @param referenceId + * @return + */ + public String createCreateAASSubmodelReferenceTopic(String repoId, String referenceId) { + return new StringJoiner("/", "", "") + .add(AASREPOSITORY) + .add(repoId) + .add(SHELLS) + .add(SUBMODELS) + .add(referenceId) + .add(CREATED) + .toString(); + } + + /** + * Creates the hierarchical topic for the submodel reference delete event + * + * @param repoId + * @param referenceId + * @return + */ + public String createDeleteAASSubmodelReferenceTopic(String repoId, String referenceId) { + return new StringJoiner("/", "", "") + .add(AASREPOSITORY) + .add(repoId) + .add(SHELLS) + .add(SUBMODELS) + .add(referenceId) + .add(DELETED) + .toString(); + } } diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java index 785bd0e33..fd61cf76b 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java @@ -1,7 +1,5 @@ -package org.eclipse.digitaltwin.basyx.aasrepository.feature.mqtt; - /******************************************************************************* - * Copyright (C) 2021 the Eclipse BaSyx Authors + * Copyright (C) 2024 the Eclipse BaSyx Authors * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -24,10 +22,12 @@ * * SPDX-License-Identifier: MIT ******************************************************************************/ +package org.eclipse.digitaltwin.basyx.aasrepository.feature.mqtt; import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -94,7 +94,7 @@ public static void tearDownClass() { public void createAasEvent() throws DeserializationException { AssetAdministrationShell shell = createAasDummy("createAasEventId"); aasRepository.createAas(shell); - + assertEquals(topicFactory.createCreateAASTopic(aasRepository.getName()), listener.lastTopic); assertEquals(shell, deserializePayload(listener.lastPayload)); } @@ -121,6 +121,29 @@ public void deleteAasEvent() throws DeserializationException { assertEquals(topicFactory.createDeleteAASTopic(aasRepository.getName()), listener.lastTopic); assertEquals(shell, deserializePayload(listener.lastPayload)); } + + @Test + public void addSubmodelReferenceEvent() throws DeserializationException { + AssetAdministrationShell shell = createAasDummy("createAasSubmodelRefEventId"); + aasRepository.createAas(shell); + + Reference submodelReference = DummyAasFactory.createDummyReference(DummyAasFactory.DUMMY_SUBMODEL_ID); + aasRepository.addSubmodelReference(shell.getId(), submodelReference); + + assertEquals(topicFactory.createCreateAASSubmodelReferenceTopic(aasRepository.getName(), DummyAasFactory.DUMMY_SUBMODEL_ID), listener.lastTopic); + assertEquals(shell, deserializePayload(listener.lastPayload)); + } + + @Test + public void removeSubmodelReferenceEvent() throws DeserializationException { + AssetAdministrationShell shell = createAasWithSubmodelReference("removeAasSubmodelRefEventId"); + aasRepository.createAas(shell); + + aasRepository.removeSubmodelReference(shell.getId(), DummyAasFactory.DUMMY_SUBMODEL_ID); + + assertEquals(topicFactory.createDeleteAASSubmodelReferenceTopic(aasRepository.getName(), DummyAasFactory.DUMMY_SUBMODEL_ID), listener.lastTopic); + assertEquals(shell, deserializePayload(listener.lastPayload)); + } private AssetAdministrationShell deserializePayload(String payload) throws DeserializationException { return new JsonDeserializer().read(payload, AssetAdministrationShell.class); @@ -135,6 +158,16 @@ private AssetAdministrationShell createAasDummy(String aasId) { return new DefaultAssetAdministrationShell.Builder().id(aasId) .build(); } + + private AssetAdministrationShell createAasWithSubmodelReference(String aasId) { + Reference submodelReference = DummyAasFactory.createDummyReference(DummyAasFactory.DUMMY_SUBMODEL_ID); + + List submodelReferences = new ArrayList(); + submodelReferences.add(submodelReference); + + return new DefaultAssetAdministrationShell.Builder().id(aasId).submodels(submodelReferences) + .build(); + } private static AasRepository createMqttAasRepository(MqttClient client) { AasRepositoryFactory repoFactory = new SimpleAasRepositoryFactory(new AasInMemoryBackendProvider(), new InMemoryAasServiceFactory(new InMemoryFileRepository()));