Add asset-id reference to the registry

Signed-off-by: zhangzai <zai.mueller-zhang@iese.fraunhofer.de>
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 d03600d..cdd617e 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
@@ -7,7 +7,9 @@
 import java.util.stream.Collectors;
 
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 import org.eclipse.basyx.aas.metamodel.map.AssetAdministrationShell;
+import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.map.modeltype.ModelType;
@@ -21,6 +23,7 @@
  */
 public class AASDescriptor extends ModelDescriptor {
 	public static final String MODELTYPE = "AASDescriptor";
+	public static final String ASSET = "asset";
 	
 	/**
 	 * Create descriptor from existing hash map
@@ -35,20 +38,25 @@
 
 	/**
 	 * Create a new aas descriptor that retrieves the necessary information from a
-	 * passend AssetAdministrationShell
+	 * passed AssetAdministrationShell
 	 * 
 	 * @param iAssetAdministrationShell
+	 * @param IAsset                    - The asset which is associated to the AAS
 	 * @param endpoint
 	 */
 	public AASDescriptor(IAssetAdministrationShell assetAdministrationShell, String endpoint) {
-		this(assetAdministrationShell.getIdShort(), assetAdministrationShell.getIdentification(), endpoint);
+		this(assetAdministrationShell.getIdShort(), assetAdministrationShell.getIdentification(), assetAdministrationShell.getAsset(), endpoint);
 	}
 
+
 	/**
-	 * Create a new descriptor with minimal information
+	 * Create a new descriptor with aasid, idshort , assetid, and endpoint
 	 */
-	public AASDescriptor(String idShort, IIdentifier id, String httpEndpoint) {
-		super(idShort, id, httpEndpoint);
+	public AASDescriptor(String idShort, IIdentifier aasid, IAsset asset, String httpEndpoint) {
+		super(idShort, aasid, httpEndpoint);
+
+		// Set Asset
+		put(ASSET, asset);
 
 		// Set Submodels
 		put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
@@ -58,10 +66,24 @@
 	}
 	
 	/**
-	 * Create a new descriptor with minimal information (idShort is assumed to be set to "")
+	 * Create a new descriptor with minimal information
 	 */
-	public AASDescriptor(IIdentifier id, String httpEndpoint) {
-		this("", id, httpEndpoint);
+	public AASDescriptor(String idShort, IIdentifier aasid, String httpEndpoint) {
+		super(idShort, aasid, httpEndpoint);
+
+		// Set Submodels
+		put(AssetAdministrationShell.SUBMODELS, new HashSet<SubmodelDescriptor>());
+
+		// Add model type
+		putAll(new ModelType(MODELTYPE));
+	}
+
+	/**
+	 * Create a new descriptor with minimal information (idShort is assumed to be
+	 * set to "")
+	 */
+	public AASDescriptor(IIdentifier aasid, String httpEndpoint) {
+		this("", aasid, httpEndpoint);
 	}
 	
 	/**
@@ -148,5 +170,14 @@
 	protected String getModelType() {
 		return MODELTYPE;
 	}
+	
+	/**
+	 * Get asset
+	 */
+	@SuppressWarnings("unchecked")
+	public IAsset getAsset() {
+		Map<String, Object> assetModel = (Map<String, Object>) get(ASSET);
+		return Asset.createAsFacade(assetModel);
+	}
 }
 
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
index 6e9deb6..f21a55d 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/registration/memory/MapRegistry.java
@@ -1,9 +1,11 @@
 package org.eclipse.basyx.aas.registration.memory;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 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;
@@ -32,10 +34,25 @@
 	@Override
 	public void register(AASDescriptor aasDescriptor) {
 		String aasId = aasDescriptor.getIdentifier().getId();
+
+		// Get the Asset identifier from the descriptor
+		IAsset asset = aasDescriptor.getAsset();
+
 		if (descriptorMap.containsKey(aasId)) {
 			descriptorMap.remove(aasId);
 		}
 
+		// If asset identifier exists, delete the existing mapping,
+		// and add the new mapping
+		if (asset != null) {
+			IIdentifier assetIdentifier = asset.getIdentification();
+			if (descriptorMap.containsKey(assetIdentifier.getId())) {
+				descriptorMap.remove(assetIdentifier.getId());
+			}
+			descriptorMap.put(assetIdentifier.getId(), aasDescriptor);
+		}
+
+
 		descriptorMap.put(aasId, aasDescriptor);
 		logger.debug("Registered " + aasId);
 	}
@@ -43,6 +60,18 @@
 	@Override
 	public void registerOnly(AASDescriptor aasDescriptor) {
 		String aasId = aasDescriptor.getIdentifier().getId();
+		IAsset asset = aasDescriptor.getAsset();
+
+		// Check if the asset id exists in the mapping
+		if (asset != null) {
+			String assetId = aasDescriptor.getAsset().getIdentification().getId();
+			if (descriptorMap.containsKey(assetId)) {
+				throw new ResourceAlreadyExistsException("Could not create new key for AAS with Asset Id" + assetId + " since it already exists");
+			} else {
+				descriptorMap.put(assetId, aasDescriptor);
+			}
+		}
+
 		if (descriptorMap.containsKey(aasId)) {
 			throw new ResourceAlreadyExistsException("Could not create new key for AAS " + aasId + " since it already exists");
 		} else {
@@ -57,7 +86,16 @@
 		if (!descriptorMap.containsKey(aasId)) {
 			throw new ResourceNotFoundException("Could not delete key for AAS " + aasId + " since it does not exist");
 		} else {
+			AASDescriptor aasDescriptor = lookupAAS(aasIdentifier);
 			descriptorMap.remove(aasId);
+
+			// Get the identifier of the asset
+			IAsset asset = aasDescriptor.getAsset();
+			// Delete the Mapping of asset-id to the AAS if exists
+			if (asset != null) {
+				descriptorMap.remove(asset.getIdentification().getId());
+			}
+
 			logger.debug("Removed " + aasId);
 		}
 	}
@@ -71,10 +109,12 @@
 		return descriptorMap.get(aasIdentifier.getId());
 	}
 
+
 	@Override
 	public List<AASDescriptor> lookupAll() {
 		logger.debug("Looking up all AAS");
-		return new ArrayList<>(descriptorMap.values());
+		// duplicate entries should be filtered
+		return new ArrayList<>(new HashSet<>(descriptorMap.values()));
 	}
 
 	@Override
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
index c100de5..6f86dd6 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/registration/TestRegistryProviderSuite.java
@@ -7,14 +7,18 @@
 
 import java.util.List;
 
+import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
 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.metamodel.map.parts.Asset;
 import org.eclipse.basyx.aas.registration.api.IAASRegistryService;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
+import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
 import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
 import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
+import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
 import org.eclipse.basyx.vab.exception.provider.ResourceAlreadyExistsException;
 import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
 import org.junit.After;
@@ -44,7 +48,8 @@
 	protected String aasEndpoint2 = "http://www.registrytest.de/aas02/aas";
 	protected String smEndpoint1 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort1;
 	protected String smEndpoint2 = "http://www.registrytest.de/aas01/aas/submodels/" + smIdShort2;
-	
+	protected Asset asset1;
+	protected Asset asset2;
 	/**
 	 * Getter for the tested registry provider. Tests for actual registry provider
 	 * have to realize this method.
@@ -56,10 +61,15 @@
 	 */
 	@Before
 	public void setUp() {
+		// Create assets
+		asset1 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset001"), KeyElements.ASSET, false));
+		asset1.setIdentification(IdentifierType.CUSTOM, "asset001");
+		asset2 = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "asset002"), KeyElements.ASSET, false));
+		asset2.setIdentification(IdentifierType.CUSTOM, "asset002");
 		// Create descriptors for AAS and submodels
-		AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, aasEndpoint1);
+		AASDescriptor aasDesc1 = new AASDescriptor(aasIdShort1, aasId1, asset1, aasEndpoint1);
 		aasDesc1.addSubmodelDescriptor(new SubmodelDescriptor(smIdShort1, smId1, smEndpoint1));
-		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, aasEndpoint2);
+		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, aasEndpoint2);
 		
 		// Register Asset Administration Shells
 		proxy.register(aasDesc1);
@@ -93,6 +103,7 @@
 		validateDescriptor1(descriptor);
 	}
 
+
 	/**
 	 * Tests getting all entries from the registry and validates the result.
 	 */
@@ -118,7 +129,8 @@
 	private void validateDescriptor1(AASDescriptor descriptor) {
 		assertEquals(aasId1.getId(), descriptor.getIdentifier().getId());
 		assertEquals(aasId1.getIdType(), descriptor.getIdentifier().getIdType());
-		assertEquals(aasId1.getIdType(), descriptor.getIdentifier().getIdType());
+		IAsset asset = descriptor.getAsset();
+		assertEquals(asset1.getIdentification(), asset.getIdentification());
 		assertEquals(aasEndpoint1, descriptor.getFirstEndpoint());
 
 		// Check, if the SM descriptor in the AASDescriptor is correct
@@ -136,7 +148,8 @@
 	private void validateDescriptor2(AASDescriptor descriptor) {
 		assertEquals(aasId2.getId(), descriptor.getIdentifier().getId());
 		assertEquals(aasId2.getIdType(), descriptor.getIdentifier().getIdType());
-		assertEquals(aasId2.getIdType(), descriptor.getIdentifier().getIdType());
+		IAsset asset = descriptor.getAsset();
+		assertEquals(asset2.getIdentification(), asset.getIdentification());
 		assertEquals(aasEndpoint2, descriptor.getFirstEndpoint());
 	}
 
@@ -153,6 +166,7 @@
 		
 		// After aas2 has been deleted, only aas1 should be registered
 		assertNotNull(proxy.lookupAAS(aasId1));
+		assertNotNull(proxy.lookupAAS(asset1.getIdentification()));
 		try {
 			proxy.lookupAAS(aasId2);
 			fail();
@@ -160,8 +174,16 @@
 			// expected
 		}
 
+		// Reference of asset-id to the AAS descriptor should also to deleted
+		try {
+			proxy.lookupAAS(asset2.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
+
 		proxy.delete(aasId1);
-		
+
 		// After aas1 has been deleted, both should not be registered any more
 		try {
 			proxy.lookupAAS(aasId1);
@@ -175,6 +197,20 @@
 		} catch (ResourceNotFoundException e) {
 			// expected
 		}
+
+		// Reference of both asset-ids to the AAS descriptors should also to deleted
+		try {
+			proxy.lookupAAS(asset1.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
+		try {
+			proxy.lookupAAS(asset2.getIdentification());
+			fail();
+		} catch (ResourceNotFoundException e) {
+			// expected
+		}
 	}
 
 	@Test(expected = ResourceNotFoundException.class)
@@ -197,7 +233,7 @@
 	 */
 	@Test
 	public void testOverwritingAASDescriptor() {
-		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, "TestEndpoint");
+		AASDescriptor aasDesc2 = new AASDescriptor(aasIdShort2, aasId2, asset2, "TestEndpoint");
 		proxy.register(aasDesc2);
 		AASDescriptor retrieved = proxy.lookupAAS(aasId2);
 		assertEquals(aasDesc2.getFirstEndpoint(), retrieved.getFirstEndpoint());
@@ -234,10 +270,14 @@
 	@Test
 	public void testRegisterOnly() {
 		IIdentifier id = new ModelUrn("testURN");
-		AASDescriptor descriptorToRegister = new AASDescriptor(id, "testEndpoint");
+		String shortid = "testShortId";
+		Asset asset = new Asset(new Reference(new Identifier(IdentifierType.CUSTOM, "testAsset"), KeyElements.ASSET, false));
+		asset.setIdentification(IdentifierType.CUSTOM, "testAsset");
+		AASDescriptor descriptorToRegister = new AASDescriptor(shortid, id, asset, "testEndpoint");
 		proxy.registerOnly(descriptorToRegister);
 		AASDescriptor descriptor = proxy.lookupAAS(id);
 		assertEquals(descriptorToRegister.getFirstEndpoint(), descriptor.getFirstEndpoint());
+		assertEquals(asset.getIdentification().getId(), descriptor.getAsset().getIdentification().getId());
 		// clean up after this test
 		proxy.delete(id);
 	}