Merge "Adds possibility to register submodels to an aas"
diff --git a/components/basys.components/src/test/java/org/eclipse/basyx/regression/directory/sql/TestSQLRegistryProvider.java b/components/basys.components/src/test/java/org/eclipse/basyx/regression/directory/sql/TestSQLRegistryProvider.java
index 851d291..035f879 100644
--- a/components/basys.components/src/test/java/org/eclipse/basyx/regression/directory/sql/TestSQLRegistryProvider.java
+++ b/components/basys.components/src/test/java/org/eclipse/basyx/regression/directory/sql/TestSQLRegistryProvider.java
@@ -58,4 +58,10 @@
IModelProvider apiProxy = new VABElementProxy("/api/v1/registry", provider);
return apiProxy;
}
+
+ @Override
+ public void testSubmodelCalls() {
+ // FIXME: This test case is currently overwritten since the SQLProvider does not
+ // support the submodel api.
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
index 7750b07..2adffa1 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/manager/ConnectedAssetAdministrationShellManager.java
@@ -51,7 +51,7 @@
AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);
// Get submodel descriptor from the aas descriptor
- SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptor(smId.getId());
+ SubmodelDescriptor smDescriptor = aasDescriptor.getSubModelDescriptorFromIdentifierId(smId.getId());
// get address of the submodel descriptor
String addr = smDescriptor.getFirstEndpoint();
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
index cf31e92..22d135c 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/AASDescriptor.java
@@ -3,6 +3,7 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -91,11 +92,26 @@
return this;
}
+ @SuppressWarnings("unchecked")
+ public void removeSubmodelDescriptor(String idShort) {
+ Optional<SubmodelDescriptor> toRemove = getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny();
+
+ // TODO: Exception in else case
+ if (toRemove.isPresent()) {
+ // Don't use getSubmodelDescriptors here since it returns a copy
+ ((Set<Object>) get(AssetAdministrationShell.SUBMODELS)).remove(toRemove.get());
+ }
+ }
+
/**
- * Get a specific sub model descriptor
+ * Retrieves a submodel descriptor based on the globally unique id of the
+ * submodel
+ *
+ * @param subModelId
+ * @return
*/
@SuppressWarnings("unchecked")
- public SubmodelDescriptor getSubModelDescriptor(String subModelId) {
+ public SubmodelDescriptor getSubModelDescriptorFromIdentifierId(String subModelId) {
// Sub model descriptors are stored in a list
Collection<Map<String, Object>> smDescriptorMaps = (Collection<Map<String, Object>>) get(
AssetAdministrationShell.SUBMODELS);
@@ -114,10 +130,20 @@
}
/**
+ * Retrieves a submodel descriptor based on the idShort of the submodel
+ *
+ * @param idShort
+ * @return
+ */
+ public SubmodelDescriptor getSubmodelDescriptorFromIdShort(String idShort) {
+ return getSubModelDescriptors().stream().filter(x -> x.getIdShort().equals(idShort)).findAny().orElse(null); // TODO: Exception
+ }
+
+ /**
* Get a specific sub model descriptor from a ModelUrn
*/
public SubmodelDescriptor getSubModelDescriptor(ModelUrn submodelUrn) {
- return getSubModelDescriptor(submodelUrn.getURN());
+ return getSubModelDescriptorFromIdentifierId(submodelUrn.getURN());
}
/**
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
index 2a18a4d..61fe599 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/metamodel/map/descriptor/ModelDescriptor.java
@@ -5,9 +5,11 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+
import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.facade.identifier.IdentifierFacade;
+import org.eclipse.basyx.submodel.metamodel.facade.qualifier.ReferableFacade;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Identifiable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
@@ -62,6 +64,10 @@
return new IdentifierFacade(identifierModel);
}
+ public String getIdShort() {
+ return new ReferableFacade(this).getIdShort();
+ }
+
/**
* Return first AAS endpoint
*/
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
index 17462e9..4b0b0e2 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/api/IAASRegistryService.java
@@ -3,6 +3,7 @@
import java.util.List;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
@@ -28,15 +29,24 @@
/**
+ * Register SM descriptor in registry, delete old registration
+ */
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor);
+
+ /**
* Delete AAS descriptor from registry
*/
- public void delete(IIdentifier aasID);
+ public void delete(IIdentifier aasId);
+ /**
+ * Delete SM descriptor from registry
+ */
+ public void delete(IIdentifier aasId, String smIdShort);
/**
* Lookup AAS
*/
- public AASDescriptor lookupAAS(IIdentifier aasID);
+ public AASDescriptor lookupAAS(IIdentifier aasId);
/**
* Retrieve all registered AAS
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
index e770bcb..70d0281 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/InMemoryRegistry.java
@@ -6,6 +6,7 @@
import java.util.Map;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
@@ -47,4 +48,16 @@
return new ArrayList<>(descriptorMap.values());
}
+ @Override
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
+ descriptorMap.get(aas.getId()).addSubmodelDescriptor(smDescriptor);
+ // TODO: Add data to remote AAS
+ }
+
+ @Override
+ public void delete(IIdentifier aasId, String smIdShort) {
+ AASDescriptor desc = descriptorMap.get(aasId.getId());
+ desc.removeSubmodelDescriptor(smIdShort);
+ }
+
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
index 7174ecb..b7bfc67 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/proxy/AASRegistryProxy.java
@@ -8,11 +8,14 @@
import java.util.stream.Collectors;
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
+import org.eclipse.basyx.aas.registration.restapi.DirectoryModelProvider;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.vab.coder.json.connector.JSONConnector;
import org.eclipse.basyx.vab.directory.proxy.VABDirectoryProxy;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
+import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnector;
import org.slf4j.Logger;
@@ -118,5 +121,28 @@
return null;
}
}
+
+ @Override
+ public void register(IIdentifier aas, SubmodelDescriptor smDescriptor) {
+ delete(aas, smDescriptor.getIdShort());
+ try {
+ provider.createValue(buildSubmodelPath(aas), smDescriptor);
+ } catch (Exception e) {
+ logger.error("Exception in registering a Submodel", e);
+ }
+ }
+
+ @Override
+ public void delete(IIdentifier aasId, String smIdShort) {
+ try {
+ provider.deleteValue(VABPathTools.concatenatePaths(buildSubmodelPath(aasId), smIdShort));
+ } catch (Exception e) {
+ logger.error("Exception in deleting a Submodel", e);
+ }
+ }
+
+ private String buildSubmodelPath(IIdentifier aas) {
+ return VABPathTools.concatenatePaths(aas.getId(), DirectoryModelProvider.SUBMODELS);
+ }
}
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
index 92fba3f..a40c408 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/restapi/DirectoryModelProvider.java
@@ -4,6 +4,7 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
+import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
@@ -18,8 +19,9 @@
public class DirectoryModelProvider implements IModelProvider {
IAASRegistryService registry;
-
+
private static final String PREFIX = "api/v1/registry";
+ public static final String SUBMODELS = "submodels";
public DirectoryModelProvider(IAASRegistryService registry) {
this.registry = registry;
@@ -83,8 +85,10 @@
if (path.isEmpty()) { // Creating new entry
registry.register((AASDescriptor) newEntity);
+ } else if (path.endsWith(SUBMODELS)) {
+ registry.register(new ModelUrn(path.replace("/" + SUBMODELS, "")), (SubmodelDescriptor) newEntity);
} else {
- throw new RuntimeException("Create with non-empty path is not supported by registry");
+ throw new RuntimeException("Create was called with an unsupported path: " + path);
}
}
@@ -93,9 +97,17 @@
path = stripPrefix(path);
if (!path.isEmpty()) { // Deleting an entry
- // Decode encoded path
- path = URLDecoder.decode(path, "UTF-8");
- registry.delete(new ModelUrn(path));
+ if (path.contains(SUBMODELS)) {
+ // Delete submodel from AAS
+ String[] splitted = path.split("/" + SUBMODELS + "/");
+ String aasId = URLDecoder.decode(splitted[0], "UTF-8");
+ String smIdShort = splitted[1];
+ registry.delete(new ModelUrn(aasId), smIdShort);
+ } else {
+ // Decode encoded path
+ path = URLDecoder.decode(path, "UTF-8");
+ registry.delete(new ModelUrn(path));
+ }
} else {
throw new RuntimeException("Delete with empty path is not supported by registry");
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/proxy/TestRegistryProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/proxy/TestRegistryProvider.java
index 718bbe7..53cdec5 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/proxy/TestRegistryProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/proxy/TestRegistryProvider.java
@@ -9,6 +9,7 @@
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
+import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
import org.eclipse.basyx.aas.registration.proxy.AASRegistryProxy;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
@@ -25,19 +26,22 @@
*/
public abstract class TestRegistryProvider {
// The registry proxy that is used to access the sql servlet
- protected final AASRegistryProxy proxy = new AASRegistryProxy(getProxyProvider());
+ protected final IAASRegistryService proxy = new AASRegistryProxy(getProxyProvider());
// Ids, shortIds and endpoints for registered AAS and submodel
protected IIdentifier aasId1 = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:1:registryAAS#001");
protected IIdentifier aasId2 = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:1:registryAAS#002");
- protected IIdentifier smId = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:1:statusSM#001");
+ protected IIdentifier smId1 = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:1:statusSM#001");
+ protected IIdentifier smId2 = new ModelUrn("urn:de.FHG:devices.es.iese:aas:1.0:1:testSM#001");
protected String aasIdShort1 = "aasIdShort1";
protected String aasIdShort2 = "aasIdShort2";
- protected String smIdShort = "smIdShort";
+ protected String smIdShort1 = "smIdShort1";
+ protected String smIdShort2 = "smIdShort2";
protected String aasEndpoint1 = "http://www.registrytest.de/aas01/aas";
protected String aasEndpoint2 = "http://www.registrytest.de/aas02/aas";
- protected String smEndpoint = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort;
-
+ protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1;
+ protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2;
+
/**
* Getter for the tested registry provider. Tests for actual registry provider
* have to realize this method.
@@ -51,7 +55,7 @@
public void setUp() {
// Create descriptors for AAS and submodels
AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, aasEndpoint1);
- aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort, smId, smEndpoint));
+ aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, aasEndpoint2);
// Register Asset Administration Shells
@@ -83,11 +87,11 @@
assertEquals(aasEndpoint1, descriptor.getFirstEndpoint());
// Check, if the SM descriptor in the AASDescriptor is correct
- SubmodelDescriptor smDescriptor = descriptor.getSubModelDescriptor(smId.getId());
- assertEquals(smId.getId(), smDescriptor.getIdentifier().getId());
- assertEquals(smId.getIdType(), smDescriptor.getIdentifier().getIdType());
- assertEquals(smIdShort, smDescriptor.get(Referable.IDSHORT));
- assertEquals(smEndpoint, smDescriptor.getFirstEndpoint());
+ SubmodelDescriptor smDescriptor = descriptor.getSubModelDescriptorFromIdentifierId(smId1.getId());
+ assertEquals(smId1.getId(), smDescriptor.getIdentifier().getId());
+ assertEquals(smId1.getIdType(), smDescriptor.getIdentifier().getIdType());
+ assertEquals(smIdShort1, smDescriptor.get(Referable.IDSHORT));
+ assertEquals(smEndpoint1, smDescriptor.getFirstEndpoint());
// Retrieve and check the second AAS
result = proxy.lookupAAS(aasId2);
@@ -119,4 +123,27 @@
assertNull(proxy.lookupAAS(aasId1));
assertNull(proxy.lookupAAS(aasId2));
}
+
+ /**
+ * Tests additiona, retrieval and removal of submodels
+ */
+ @Test
+ public void testSubmodelCalls() {
+ // Add descriptor
+ SubmodelDescriptor smDesc = new SubmodelDescriptor(smIdShort2, smId2, smEndpoint2);
+ proxy.register(aasId1, smDesc);
+
+ // Ensure that the submodel is correctly stored in the aas descriptor
+ AASDescriptor aasDesc = proxy.lookupAAS(aasId1);
+ assertEquals(smDesc.getEndpoints(), aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2).getEndpoints());
+ assertNotNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort1));
+
+ // Remove Submodel
+ proxy.delete(aasId1, smIdShort2);
+
+ // Ensure that the submodel was correctly removed
+ aasDesc = proxy.lookupAAS(aasId1);
+ assertNotNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort1));
+ assertNull(aasDesc.getSubmodelDescriptorFromIdShort(smIdShort2));
+ }
}
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
index 8d8f553..4acc2ac 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/restapi/TestDirectoryModelProvider.java
@@ -5,6 +5,13 @@
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
+/**
+ * Tests correct behaviour of the DirectoryModelProvider using an InMemory
+ * database
+ *
+ * @author schnicke
+ *
+ */
public class TestDirectoryModelProvider extends TestRegistryProvider {
@Override