Skip to content

Commit

Permalink
Updates ConAasManager's implementation to try all endpoints (#248)
Browse files Browse the repository at this point in the history

Signed-off-by: Mohammad Ghazanfar Ali Danish <ghazanfar.danish@iese.fraunhofer.de>
  • Loading branch information
mdanish98 committed Mar 21, 2023
1 parent d36db87 commit ee9469a
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.eclipse.basyx.aas.aggregator.AASAggregatorAPIHelper;
Expand All @@ -41,9 +42,12 @@
import org.eclipse.basyx.aas.registration.api.IAASRegistry;
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
import org.eclipse.basyx.submodel.metamodel.connected.ConnectedElement;
import org.eclipse.basyx.submodel.metamodel.connected.ConnectedSubmodel;
import org.eclipse.basyx.submodel.metamodel.map.Submodel;
import org.eclipse.basyx.submodel.restapi.SubmodelProvider;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.factory.java.ModelProxyFactory;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
Expand All @@ -55,7 +59,7 @@
* Implement a AAS manager backend that communicates via HTTP/REST<br>
* <br>
*
* @author kuhn, schnicke
* @author kuhn, schnicke, danish
*
*/
public class ConnectedAssetAdministrationShellManager implements IAssetAdministrationShellManager {
Expand Down Expand Up @@ -85,14 +89,8 @@ public ConnectedAssetAdministrationShellManager(IAASRegistry directory, IConnect

@Override
public ISubmodel retrieveSubmodel(IIdentifier aasId, IIdentifier smId) {
// look up SM descriptor in the registry
SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);

// get address of the submodel descriptor
String addr = smDescriptor.getFirstEndpoint();

// Return a new VABElementProxy
return new ConnectedSubmodel(proxyFactory.createProxy(addr));
VABElementProxy proxy = getSubmodelProxyFromId(aasId, smId);
return new ConnectedSubmodel(proxy);
}

@Override
Expand All @@ -107,26 +105,14 @@ public Map<String, ISubmodel> retrieveSubmodels(IIdentifier aasId) {
Collection<SubmodelDescriptor> smDescriptors = aasDesc.getSubmodelDescriptors();
Map<String, ISubmodel> submodels = new LinkedHashMap<>();
for (SubmodelDescriptor smDesc : smDescriptors) {
String smEndpoint = smDesc.getFirstEndpoint();
String smIdShort = smDesc.getIdShort();
VABElementProxy smProxy = proxyFactory.createProxy(smEndpoint);
ConnectedSubmodel connectedSM = new ConnectedSubmodel(smProxy);
ISubmodel connectedSM = retrieveSubmodel(aasDesc.getIdentifier(), smDesc.getIdentifier());
submodels.put(smIdShort, connectedSM);
}

return submodels;
}

private VABElementProxy getAASProxyFromId(IIdentifier aasId) {
// Lookup AAS descriptor
AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);

// Get AAS address from AAS descriptor
String addr = aasDescriptor.getFirstEndpoint();

// Return a new VABElementProxy
return proxyFactory.createProxy(addr);
}

/**
* Retrieves all AASs registered. This can take a long time if many AASs are
* present! Use with caution!
Expand Down Expand Up @@ -196,4 +182,59 @@ public void createAAS(AssetAdministrationShell aas, String endpoint) {
String combinedEndpoint = VABPathTools.concatenatePaths(harmonizedEndpoint, AASAggregatorAPIHelper.getAASAccessPath(aas.getIdentification()));
aasDirectory.register(new AASDescriptor(aas, combinedEndpoint));
}

private VABElementProxy getAASProxyFromId(IIdentifier aasId) {
AASDescriptor aasDescriptor = aasDirectory.lookupAAS(aasId);

Optional<Map<String, Object>> optionalAasDescriptor = getWorkingAasEndpoint(aasDescriptor.getEndpoints());

if (!optionalAasDescriptor.isPresent())
throw new ResourceNotFoundException("The resource with id : " + aasId + " could not be found!");

return proxyFactory.createProxy((String) optionalAasDescriptor.get().get(AssetAdministrationShell.ADDRESS));
}

private VABElementProxy getSubmodelProxyFromId(IIdentifier aasId, IIdentifier smId) {
SubmodelDescriptor smDescriptor = aasDirectory.lookupSubmodel(aasId, smId);

Optional<Map<String, Object>> optionalSubmodelDescriptor = getWorkingSubmodelEndpoint(smDescriptor.getEndpoints());

if (!optionalSubmodelDescriptor.isPresent())
throw new ResourceNotFoundException("The resource with id : " + aasId + " could not be found!");

return proxyFactory.createProxy((String) optionalSubmodelDescriptor.get().get(AssetAdministrationShell.ADDRESS));
}

private Optional<Map<String, Object>> getWorkingAasEndpoint(Collection<Map<String, Object>> endpoints) {
return endpoints.stream().filter(endpoint -> isWorking(new ConnectedAssetAdministrationShell(createProxy(endpoint)))).findFirst();
}

private Optional<Map<String, Object>> getWorkingSubmodelEndpoint(Collection<Map<String, Object>> endpoints) {
return endpoints.stream().filter(endpoint -> isWorking(new ConnectedSubmodel(createProxy(endpoint)))).findFirst();
}

private VABElementProxy createProxy(Map<String, Object> endpoint) {
return proxyFactory.createProxy((String) endpoint.get(AssetAdministrationShell.ADDRESS));
}

private boolean isWorking(ConnectedElement connectedElement) {

try {
attemptIdentificationRetrieval(connectedElement);

return true;
} catch (ProviderException e) {
return false;
}

}

private void attemptIdentificationRetrieval(ConnectedElement connectedElement) {
if (connectedElement instanceof ConnectedAssetAdministrationShell) {
((ConnectedAssetAdministrationShell) connectedElement).getIdentification();
} else {
((ConnectedSubmodel) connectedElement).getIdentification();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,30 @@
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
import org.eclipse.basyx.vab.protocol.http.server.BaSyxContext;
import org.eclipse.basyx.vab.registry.memory.VABInMemoryRegistry;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;

/**
* Tests access to an AAS provided by a servlet. This is an integration test
*
* @author schnicke
* @author schnicke, danish
*
*/
public class TestAASHTTP {

private static final String WORKING_SM_ENDPOINT = "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel";
private static final String WORKING_AAS_ENDPOINT = "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas";
private static final String NOT_WORKING_404_ENDPOINT_1 = "http://localhost:8080/basys.sdk/Testsuite/StubAAS1/aas";
private static final String NOT_WORKING_404_ENDPOINT_2 = "http://localhost:8080/basys.sdk/Testsuite/StubAAS2/aas";

// Manager used to connect to the AAS
ConnectedAssetAdministrationShellManager manager;

private static BaSyxContext context = new BaSyxContext("/basys.sdk", System.getProperty("java.io.tmpdir")).addServletMapping("/Testsuite/StubAAS/*", new StubAASServlet());

private AASDescriptor aasDescriptor;
private SubmodelDescriptor submodelDescriptor;

/**
* Makes sure Tomcat Server is started
Expand All @@ -76,26 +83,12 @@ public class TestAASHTTP {
*/
@Before
public void build() {
// Fill directory stub
VABInMemoryRegistry directory = new VABInMemoryRegistry();
directory.addMapping(StubAASServlet.AASURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas");
directory.addMapping(StubAASServlet.SMURN.getId(), "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");

InMemoryRegistry registry = new InMemoryRegistry();

aasDescriptor = createAasDescriptor(WORKING_AAS_ENDPOINT);

// Create aas descriptor for the aas registry
AASDescriptor aasDescriptor = new AASDescriptor(StubAASServlet.AASURN, "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas");

// Create the submodel descriptor
SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN, "http://localhost:8080/basys.sdk/Testsuite/StubAAS/aas/submodels/" + StubAASServlet.SMIDSHORT + "/submodel");

// add submodel descriptor to the aas descriptor
aasDescriptor.addSubmodelDescriptor(submodelDescriptor);

// register the aas in the registry
registry.register(aasDescriptor);
registerAasDescriptorWithSubmodelDescriptor(registry, aasDescriptor);

// Create manager using the directory stub an the HTTPConnectorProvider
manager = new ConnectedAssetAdministrationShellManager(registry, new HTTPConnectorFactory());
}

Expand All @@ -119,6 +112,15 @@ public void testAAS() throws Exception {
assertEquals(1, submodels.size());
assertTrue(submodels.containsKey(StubAASServlet.SMIDSHORT));
}

@Test
public void retrieveSingleAas() throws Exception {
prepareAasDescriptorForMultipleEndpoints();

IAssetAdministrationShell assetAdministrationShell = manager.retrieveAAS(StubAASServlet.AASURN);

assertEquals(StubAASServlet.AASIDSHORT, assetAdministrationShell.getIdShort());
}

/**
* Tests accessing a submodel
Expand Down Expand Up @@ -172,6 +174,44 @@ public void testSubmodel() throws Exception {
Map<String, ISubmodelElement> elements = sm.getSubmodelElements();
// 2 properties, 4 operations, 1 collection
assertEquals(9, elements.size());
}

@Test
public void retrieveSingleSubmodel() {
prepareSubmodelDescriptorForMultipleEndpoints();

ISubmodel submodel = manager.retrieveSubmodel(StubAASServlet.AASURN, StubAASServlet.SMURN);

assertEquals(StubAASServlet.SMIDSHORT, submodel.getIdShort());
}

private void prepareAasDescriptorForMultipleEndpoints() {
aasDescriptor.removeEndpoint(WORKING_AAS_ENDPOINT);
aasDescriptor.addEndpoint(NOT_WORKING_404_ENDPOINT_1);
aasDescriptor.addEndpoint(WORKING_AAS_ENDPOINT);
aasDescriptor.addEndpoint(NOT_WORKING_404_ENDPOINT_2);
}

private void prepareSubmodelDescriptorForMultipleEndpoints() {
submodelDescriptor.removeEndpoint(WORKING_SM_ENDPOINT);
submodelDescriptor.addEndpoint(NOT_WORKING_404_ENDPOINT_1);
submodelDescriptor.addEndpoint(WORKING_SM_ENDPOINT);
submodelDescriptor.addEndpoint(NOT_WORKING_404_ENDPOINT_2);
}

private void registerAasDescriptorWithSubmodelDescriptor(InMemoryRegistry registry, AASDescriptor aasDescriptor) {
submodelDescriptor = createSubmodelDescriptor();

aasDescriptor.addSubmodelDescriptor(submodelDescriptor);

registry.register(aasDescriptor);
}

private SubmodelDescriptor createSubmodelDescriptor() {
return new SubmodelDescriptor(StubAASServlet.SMIDSHORT, StubAASServlet.SMURN, WORKING_SM_ENDPOINT);
}

private AASDescriptor createAasDescriptor(String url) {
return new AASDescriptor(StubAASServlet.AASURN, url);
}
}
Loading

0 comments on commit ee9469a

Please sign in to comment.