Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple descriptor endpoints #356

Merged
merged 3 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
package org.eclipse.digitaltwin.basyx.aasenvironment.client;


import java.util.List;

import org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration.AasDescriptorFactory;
import org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration.mapper.AttributeMapper;
import org.eclipse.digitaltwin.basyx.http.Aas4JHTTPSerializationExtension;
Expand Down Expand Up @@ -55,16 +57,16 @@ static ObjectMapper buildObjectMapper() {
return builder.build();
}

static AasDescriptorFactory buildAasDescriptorFactory(String aasRepositoryBaseUrl) {
static AasDescriptorFactory buildAasDescriptorFactory(String... aasRepositoryBaseUrls) {
AttributeMapper attributeMapper = new AttributeMapper(objectMapper);

return new AasDescriptorFactory(null, aasRepositoryBaseUrl, attributeMapper);
return new AasDescriptorFactory(null, List.of(aasRepositoryBaseUrls), attributeMapper);
}

static SubmodelDescriptorFactory buildSmDescriptorFactory(String aasRepositoryBaseUrl) {
static SubmodelDescriptorFactory buildSmDescriptorFactory(String... aasRepositoryBaseUrls) {
org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration.mapper.AttributeMapper attributeMapperSm = new org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration.mapper.AttributeMapper(
objectMapper);
return new SubmodelDescriptorFactory(null, aasRepositoryBaseUrl, attributeMapperSm);
return new SubmodelDescriptorFactory(null, List.of(aasRepositoryBaseUrls), attributeMapperSm);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.digitaltwin.aas4j.v3.model.AdministrativeInformation;
Expand All @@ -50,16 +51,16 @@ public class AasDescriptorFactory {

private static final String AAS_INTERFACE = "AAS-3.0";
private static final String AAS_REPOSITORY_PATH = "shells";

private AssetAdministrationShell shell;
private String aasRepositoryURL;
private List<String> aasRepositoryURLs;

private AttributeMapper attributeMapper;

public AasDescriptorFactory(AssetAdministrationShell shell, String aasRepositoryBaseURL, AttributeMapper attributeMapper) {
super();
public AasDescriptorFactory(AssetAdministrationShell shell, List<String> aasRepositoryBaseURLs,
AttributeMapper attributeMapper) {
this.shell = shell;
this.aasRepositoryURL = createAasRepositoryUrl(aasRepositoryBaseURL);
this.aasRepositoryURLs = createAasRepositoryUrls(aasRepositoryBaseURLs);
this.attributeMapper = attributeMapper;
}

Expand Down Expand Up @@ -124,7 +125,8 @@ private void setExtensions(List<Extension> extensions, AssetAdministrationShellD
descriptor.setExtensions(attributeMapper.mapExtensions(extensions));
}

private void setAdministration(AdministrativeInformation administration, AssetAdministrationShellDescriptor descriptor) {
private void setAdministration(AdministrativeInformation administration,
AssetAdministrationShellDescriptor descriptor) {

if (administration == null)
return;
Expand Down Expand Up @@ -157,17 +159,18 @@ private void setGlobalAssetId(AssetInformation assetInformation, AssetAdministra
}

private void setEndpointItem(String shellId, AssetAdministrationShellDescriptor descriptor) {
for (String eachUrl : aasRepositoryURLs) {
Endpoint endpoint = new Endpoint();
endpoint.setInterface(AAS_INTERFACE);
ProtocolInformation protocolInformation = createProtocolInformation(shellId, eachUrl);
endpoint.setProtocolInformation(protocolInformation);

Endpoint endpoint = new Endpoint();
endpoint.setInterface(AAS_INTERFACE);
ProtocolInformation protocolInformation = createProtocolInformation(shellId);
endpoint.setProtocolInformation(protocolInformation);

descriptor.addEndpointsItem(endpoint);
descriptor.addEndpointsItem(endpoint);
}
}

private ProtocolInformation createProtocolInformation(String shellId) {
String href = String.format("%s/%s", aasRepositoryURL, Base64UrlEncodedIdentifier.encodeIdentifier(shellId));
private ProtocolInformation createProtocolInformation(String shellId, String url) {
String href = String.format("%s/%s", url, Base64UrlEncodedIdentifier.encodeIdentifier(shellId));

ProtocolInformation protocolInformation = new ProtocolInformation();
protocolInformation.endpointProtocol(getProtocol(href));
Expand All @@ -192,6 +195,14 @@ private String getProtocol(String endpoint) {
}
}

private List<String> createAasRepositoryUrls(List<String> aasRepositoryBaseURLs) {
List<String> toReturn = new ArrayList<>(aasRepositoryBaseURLs.size());
for (String eachUrl : aasRepositoryBaseURLs) {
toReturn.add(createAasRepositoryUrl(eachUrl));
}
return toReturn;
}

private String createAasRepositoryUrl(String aasRepositoryBaseURL) {

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

package org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration;

import java.util.List;

import org.eclipse.digitaltwin.basyx.aasregistry.client.api.RegistryAndDiscoveryInterfaceApi;
import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;

Expand All @@ -36,20 +38,20 @@
public class AasRepositoryRegistryLink {

private RegistryAndDiscoveryInterfaceApi registryApi;
private String aasRepositoryBaseURL;
private List<String> aasRepositoryBaseURLs;

public AasRepositoryRegistryLink(RegistryAndDiscoveryInterfaceApi registryApi, String aasRepositoryBaseURL) {
public AasRepositoryRegistryLink(RegistryAndDiscoveryInterfaceApi registryApi, List<String> aasRepositoryBaseURLs) {
super();
this.registryApi = registryApi;
this.aasRepositoryBaseURL = aasRepositoryBaseURL;
this.aasRepositoryBaseURLs = aasRepositoryBaseURLs;
}

public RegistryAndDiscoveryInterfaceApi getRegistryApi() {
return registryApi;
}

public String getAasRepositoryBaseURL() {
return aasRepositoryBaseURL;
public List<String> getAasRepositoryBaseURLs() {
return aasRepositoryBaseURLs;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public AssetAdministrationShell getAas(String shellId) throws ElementDoesNotExis
public void createAas(AssetAdministrationShell shell) throws CollidingIdentifierException {
decorated.createAas(shell);

integrateAasWithRegistry(shell, aasRepositoryRegistryLink.getAasRepositoryBaseURL());
integrateAasWithRegistry(shell, aasRepositoryRegistryLink.getAasRepositoryBaseURLs());
}

@Override
Expand Down Expand Up @@ -124,8 +124,8 @@ public AssetInformation getAssetInformation(String shellId) throws ElementDoesNo
return decorated.getAssetInformation(shellId);
}

private void integrateAasWithRegistry(AssetAdministrationShell shell, String aasRepositoryURL) {
AssetAdministrationShellDescriptor descriptor = new AasDescriptorFactory(shell, aasRepositoryURL, attributeMapper).create();
private void integrateAasWithRegistry(AssetAdministrationShell shell, List<String> aasRepositoryURLs) {
AssetAdministrationShellDescriptor descriptor = new AasDescriptorFactory(shell, aasRepositoryURLs, attributeMapper).create();

RegistryAndDiscoveryInterfaceApi registryApi = aasRepositoryRegistryLink.getRegistryApi();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
package org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration;

import java.util.Collection;
import java.util.List;

import org.eclipse.digitaltwin.basyx.aasregistry.client.api.RegistryAndDiscoveryInterfaceApi;
import org.eclipse.digitaltwin.basyx.aasregistry.main.client.AuthorizedConnectedAasRegistry;
Expand Down Expand Up @@ -55,8 +56,8 @@ public class RegistryIntegrationAasRepositoryConfiguration {
@Value("${basyx.aasrepository.feature.registryintegration:#{null}}")
private String registryBasePath;

@Value("${basyx.externalurl:#{null}}")
private String aasRepositoryBaseURL;
@Value("#{'${basyx.externalurl}'.split(',')}")
private List<String> aasRepositoryBaseURLs;

@Value("${basyx.aasrepository.feature.registryintegration.authorization.enabled:false}")
private boolean isAuthorizationEnabledOnRegistry;
Expand Down Expand Up @@ -87,11 +88,11 @@ public class RegistryIntegrationAasRepositoryConfiguration {
public AasRepositoryRegistryLink getAasRepositoryRegistryLink() {

if (!isAuthorizationEnabledOnRegistry)
return new AasRepositoryRegistryLink(new RegistryAndDiscoveryInterfaceApi(registryBasePath), aasRepositoryBaseURL);
return new AasRepositoryRegistryLink(new RegistryAndDiscoveryInterfaceApi(registryBasePath), aasRepositoryBaseURLs);

TokenManager tokenManager = new TokenManager(authenticationServerTokenEndpoint, createAccessTokenProvider());

return new AasRepositoryRegistryLink(new AuthorizedConnectedAasRegistry(registryBasePath, tokenManager), aasRepositoryBaseURL);
return new AasRepositoryRegistryLink(new AuthorizedConnectedAasRegistry(registryBasePath, tokenManager), aasRepositoryBaseURLs);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ public static void tearDown() {
}

@Override
protected String getAasRepoBaseUrl() {
return AAS_REPO_URL;
protected String[] getAasRepoBaseUrls() {
return new String[] { AAS_REPO_URL};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.GetAssetAdministrationShellDescriptorsResult;
import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier;
import org.eclipse.digitaltwin.basyx.http.serialization.BaSyxHttpTestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpStatus;

Expand All @@ -56,36 +58,41 @@ public abstract class AasRepositoryRegistryLinkTestSuite {
private static final String DUMMY_IDSHORT = "ExampleMotor";
private static final String DUMMY_AAS_ID = "customIdentifier";

protected abstract String getAasRepoBaseUrl();
protected abstract String getAasRegistryUrl();
protected abstract RegistryAndDiscoveryInterfaceApi getAasRegistryApi();
protected abstract String[] getAasRepoBaseUrls();

private final AssetAdministrationShellDescriptor DUMMY_DESCRIPTOR = DummyAasDescriptorFactory.createDummyDescriptor(DUMMY_AAS_ID, DUMMY_IDSHORT, DUMMY_GLOBAL_ASSETID, getAasRepoBaseUrl());
protected abstract String getAasRegistryUrl();

protected abstract RegistryAndDiscoveryInterfaceApi getAasRegistryApi();

private final AssetAdministrationShellDescriptor DUMMY_DESCRIPTOR = DummyAasDescriptorFactory
.createDummyDescriptor(DUMMY_AAS_ID, DUMMY_IDSHORT, DUMMY_GLOBAL_ASSETID, getAasRepoBaseUrls());

@Test
public void createAas() throws FileNotFoundException, IOException, ApiException {
String aasJsonContent = getAas1JSONString();

CloseableHttpResponse creationResponse = createAasOnRepo(aasJsonContent);
assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode());
try (CloseableHttpResponse creationResponse = createAasOnRepo(aasJsonContent)) {
assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode());

AssetAdministrationShellDescriptor actualDescriptor = retrieveDescriptorFromRegistry();
AssetAdministrationShellDescriptor actualDescriptor = retrieveDescriptorFromRegistry();

assertEquals(DUMMY_DESCRIPTOR, actualDescriptor);
assertEquals(DUMMY_DESCRIPTOR, actualDescriptor);

resetRepository();
resetRepository();
}
}

@Test
public void deleteAas() throws FileNotFoundException, IOException, ApiException {
String aasJsonContent = getAas1JSONString();

CloseableHttpResponse creationResponse = createAasOnRepo(aasJsonContent);
assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode());

CloseableHttpResponse deleteResponse = deleteAasFromRepo(DUMMY_AAS_ID);
assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode());
try (CloseableHttpResponse creationResponse = createAasOnRepo(aasJsonContent)) {
assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode());
}

try (CloseableHttpResponse deleteResponse = deleteAasFromRepo(DUMMY_AAS_ID)) {
assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode());
}
assertDescriptionDeletionAtRegistry();
}

Expand All @@ -96,9 +103,9 @@ private AssetAdministrationShellDescriptor retrieveDescriptorFromRegistry() thro
}

private void resetRepository() throws IOException {
CloseableHttpResponse deleteResponse = deleteAasFromRepo(DUMMY_AAS_ID);

assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode());
try (CloseableHttpResponse deleteResponse = deleteAasFromRepo(DUMMY_AAS_ID)) {
assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode());
}
}

private CloseableHttpResponse deleteAasFromRepo(String shellId) throws IOException {
Expand All @@ -108,7 +115,8 @@ private CloseableHttpResponse deleteAasFromRepo(String shellId) throws IOExcepti
private void assertDescriptionDeletionAtRegistry() throws ApiException {
RegistryAndDiscoveryInterfaceApi api = getAasRegistryApi();

GetAssetAdministrationShellDescriptorsResult result = api.getAllAssetAdministrationShellDescriptors(null, null, null, null);
GetAssetAdministrationShellDescriptorsResult result = api.getAllAssetAdministrationShellDescriptors(null, null,
null, null);

List<AssetAdministrationShellDescriptor> actualDescriptors = result.getResult();

Expand All @@ -120,11 +128,16 @@ private String getAas1JSONString() throws FileNotFoundException, IOException {
}

private CloseableHttpResponse createAasOnRepo(String aasJsonContent) throws IOException {
return BaSyxHttpTestUtils.executePostOnURL(createAasRepositoryUrl(getAasRepoBaseUrl()), aasJsonContent);
return BaSyxHttpTestUtils.executePostOnURL(createAasRepositoryUrl(getFirstAasRepoBaseUrl()), aasJsonContent);
}

private String getSpecificAasAccessURL(String aasId) {
return createAasRepositoryUrl(getAasRepoBaseUrl()) + "/" + Base64UrlEncodedIdentifier.encodeIdentifier(aasId);
return createAasRepositoryUrl(getFirstAasRepoBaseUrl()) + "/"
+ Base64UrlEncodedIdentifier.encodeIdentifier(aasId);
}

private String getFirstAasRepoBaseUrl() {
return getAasRepoBaseUrls()[0];
}

private static String createAasRepositoryUrl(String aasRepositoryBaseURL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public static void tearDown() {
}

@Override
protected String getAasRepoBaseUrl() {
return AAS_REPO_URL;
protected String[] getAasRepoBaseUrls() {
return new String[] {AAS_REPO_URL};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,17 @@
public class DummyAasDescriptorFactory {
private static final String AAS_REPOSITORY_PATH = "/shells";

public static AssetAdministrationShellDescriptor createDummyDescriptor(String aasId, String idShort, String globalAssetId, String aasRepoBaseUrl) {
public static AssetAdministrationShellDescriptor createDummyDescriptor(String aasId, String idShort, String globalAssetId, String... aasRepoBaseUrls) {

AssetAdministrationShellDescriptor descriptor = new AssetAdministrationShellDescriptor();

descriptor.setId(aasId);
descriptor.setIdShort(idShort);
descriptor.setAssetKind(AssetKind.INSTANCE);
descriptor.setGlobalAssetId(globalAssetId);
descriptor.addEndpointsItem(createEndpointItem(aasId, aasRepoBaseUrl));

for (String eachUrl : aasRepoBaseUrls) {
descriptor.addEndpointsItem(createEndpointItem(aasId, eachUrl));
}
return descriptor;
}

Expand Down
Loading