diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManagerHelper.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManagerHelper.java index ab6044d7f..8290ba0f9 100644 --- a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManagerHelper.java +++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManagerHelper.java @@ -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; @@ -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); } } diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasDescriptorFactory.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasDescriptorFactory.java index fa26f48a2..a28948c34 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasDescriptorFactory.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasDescriptorFactory.java @@ -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; @@ -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 aasRepositoryURLs; private AttributeMapper attributeMapper; - - public AasDescriptorFactory(AssetAdministrationShell shell, String aasRepositoryBaseURL, AttributeMapper attributeMapper) { - super(); + + public AasDescriptorFactory(AssetAdministrationShell shell, List aasRepositoryBaseURLs, + AttributeMapper attributeMapper) { this.shell = shell; - this.aasRepositoryURL = createAasRepositoryUrl(aasRepositoryBaseURL); + this.aasRepositoryURLs = createAasRepositoryUrls(aasRepositoryBaseURLs); this.attributeMapper = attributeMapper; } @@ -124,7 +125,8 @@ private void setExtensions(List 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; @@ -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)); @@ -192,6 +195,14 @@ private String getProtocol(String endpoint) { } } + private List createAasRepositoryUrls(List aasRepositoryBaseURLs) { + List toReturn = new ArrayList<>(aasRepositoryBaseURLs.size()); + for (String eachUrl : aasRepositoryBaseURLs) { + toReturn.add(createAasRepositoryUrl(eachUrl)); + } + return toReturn; + } + private String createAasRepositoryUrl(String aasRepositoryBaseURL) { try { diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLink.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLink.java index 9210e24cd..d22a91eb6 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLink.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLink.java @@ -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; @@ -36,20 +38,20 @@ public class AasRepositoryRegistryLink { private RegistryAndDiscoveryInterfaceApi registryApi; - private String aasRepositoryBaseURL; + private List aasRepositoryBaseURLs; - public AasRepositoryRegistryLink(RegistryAndDiscoveryInterfaceApi registryApi, String aasRepositoryBaseURL) { + public AasRepositoryRegistryLink(RegistryAndDiscoveryInterfaceApi registryApi, List aasRepositoryBaseURLs) { super(); this.registryApi = registryApi; - this.aasRepositoryBaseURL = aasRepositoryBaseURL; + this.aasRepositoryBaseURLs = aasRepositoryBaseURLs; } public RegistryAndDiscoveryInterfaceApi getRegistryApi() { return registryApi; } - public String getAasRepositoryBaseURL() { - return aasRepositoryBaseURL; + public List getAasRepositoryBaseURLs() { + return aasRepositoryBaseURLs; } } diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepository.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepository.java index ba9457e3e..a2233b0d9 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepository.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepository.java @@ -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 @@ -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 aasRepositoryURLs) { + AssetAdministrationShellDescriptor descriptor = new AasDescriptorFactory(shell, aasRepositoryURLs, attributeMapper).create(); RegistryAndDiscoveryInterfaceApi registryApi = aasRepositoryRegistryLink.getRegistryApi(); diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepositoryConfiguration.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepositoryConfiguration.java index a3e78e837..a468b5dd1 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepositoryConfiguration.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/RegistryIntegrationAasRepositoryConfiguration.java @@ -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; @@ -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 aasRepositoryBaseURLs; @Value("${basyx.aasrepository.feature.registryintegration.authorization.enabled:false}") private boolean isAuthorizationEnabledOnRegistry; @@ -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 diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTest.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTest.java index 4c563eb38..e35a8130a 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTest.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTest.java @@ -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 diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTestSuite.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTestSuite.java index a289abfa0..3c169f084 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTestSuite.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkTestSuite.java @@ -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; @@ -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(); } @@ -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 { @@ -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 actualDescriptors = result.getResult(); @@ -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) { diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AuthorizedAasRepositoryRegistryLinkTest.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AuthorizedAasRepositoryRegistryLinkTest.java index 5829e7ee1..c56d5db09 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AuthorizedAasRepositoryRegistryLinkTest.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AuthorizedAasRepositoryRegistryLinkTest.java @@ -89,8 +89,8 @@ public void sendUnauthorizedRequest() throws IOException { } @Override - protected String getAasRepoBaseUrl() { - return AAS_REPO_URL; + protected String[] getAasRepoBaseUrls() { + return new String[] {AAS_REPO_URL}; } @Override diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/DummyAasDescriptorFactory.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/DummyAasDescriptorFactory.java index 9a832d3c6..d134100b1 100644 --- a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/DummyAasDescriptorFactory.java +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/DummyAasDescriptorFactory.java @@ -43,7 +43,7 @@ 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(); @@ -51,8 +51,9 @@ public static AssetAdministrationShellDescriptor createDummyDescriptor(String aa 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; } diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/MultiUrlAasRepositoryRegistryLinkTest.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/MultiUrlAasRepositoryRegistryLinkTest.java new file mode 100644 index 000000000..ef9ac377d --- /dev/null +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/MultiUrlAasRepositoryRegistryLinkTest.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2023 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 + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.eclipse.digitaltwin.basyx.aasregistry.client.api.RegistryAndDiscoveryInterfaceApi; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.springframework.boot.SpringApplication; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * Integration test for {@link RegistryIntegrationAasRepository} feature + * + * @author danish + */ +public class MultiUrlAasRepositoryRegistryLinkTest extends AasRepositoryRegistryLinkTestSuite { + + private static final String[] AAS_REPO_URLS = new String []{"http://localhost:8081","https://aas-repo.example.org","http://aas-repo:8081"}; + private static final String AAS_REGISTRY_BASE_URL = "http://localhost:8050"; + private static ConfigurableApplicationContext appContext; + private static AasRepositoryRegistryLink aasRepositoryRegistryLink; + + @BeforeClass + public static void setUp() throws FileNotFoundException, IOException { + SpringApplication application = new SpringApplication(DummyAasRepositoryIntegrationComponent.class); + application.setAdditionalProfiles("multiurl"); + + appContext = application.run(new String[] {}); + + aasRepositoryRegistryLink = appContext.getBean(AasRepositoryRegistryLink.class); + } + + @AfterClass + public static void tearDown() { + appContext.close(); + } + + @Override + protected String[] getAasRepoBaseUrls() { + return AAS_REPO_URLS; + } + + @Override + protected String getAasRegistryUrl() { + return AAS_REGISTRY_BASE_URL; + } + + @Override + protected RegistryAndDiscoveryInterfaceApi getAasRegistryApi() { + + return aasRepositoryRegistryLink.getRegistryApi(); + } + +} diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/resources/application-multiurl.properties b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/resources/application-multiurl.properties new file mode 100644 index 000000000..323b793be --- /dev/null +++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/resources/application-multiurl.properties @@ -0,0 +1,35 @@ +server.port=8081 +server.error.path=/error + +spring.application.name=AAS Repository +basyx.aasrepo.name=aas-repo + +basyx.backend = InMemory + +basyx.aasrepository.feature.registryintegration=http://localhost:8050 +basyx.externalurl=http://localhost:8081,https://aas-repo.example.org,http://aas-repo:8081 + +#basyx.backend = MongoDB +#spring.data.mongodb.host=127.0.0.1 +#spring.data.mongodb.port=27017 +#spring.data.mongodb.database=aas +#spring.data.mongodb.authentication-database=admin +#spring.data.mongodb.username=mongoAdmin +#spring.data.mongodb.password=mongoPassword + + +# basyx.aasrepository.feature.mqtt.enabled = true +# mqtt.clientId=TestClient +# mqtt.hostname = localhost +# mqtt.port = 1883 + +# basyx.cors.allowed-origins=http://localhost:3000, http://localhost:4000 + +#################################################################################### +# Authorization +#################################################################################### +#basyx.feature.authorization.enabled = true +#basyx.feature.authorization.type = rbac +#basyx.feature.authorization.jwtBearerTokenProvider = keycloak +#basyx.feature.authorization.rbac.file = classpath:rbac_rules.json +#spring.security.oauth2.resourceserver.jwt.issuer-uri= http://localhost:9096/realms/BaSyx diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepository.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepository.java index ef09a1ec4..4f51226db 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepository.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepository.java @@ -87,7 +87,7 @@ public void updateSubmodel(String submodelId, Submodel submodel) throws ElementD public void createSubmodel(Submodel submodel) throws CollidingIdentifierException { decorated.createSubmodel(submodel); - integrateSubmodelWithRegistry(submodel, submodelRepositoryRegistryLink.getSubmodelRepositoryBaseURL()); + integrateSubmodelWithRegistry(submodel, submodelRepositoryRegistryLink.getSubmodelRepositoryBaseURLs()); } @Override @@ -167,8 +167,8 @@ public void deleteFileValue(String submodelId, String idShortPath) throws Elemen decorated.deleteFileValue(submodelId, idShortPath); } - private void integrateSubmodelWithRegistry(Submodel submodel, String submodelRepositoryURL) { - SubmodelDescriptor descriptor = new SubmodelDescriptorFactory(submodel, submodelRepositoryURL, attributeMapper).create(); + private void integrateSubmodelWithRegistry(Submodel submodel, List submodelRepositoryURLs) { + SubmodelDescriptor descriptor = new SubmodelDescriptorFactory(submodel, submodelRepositoryURLs, attributeMapper).create(); SubmodelRegistryApi registryApi = submodelRepositoryRegistryLink.getRegistryApi(); diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepositoryConfiguration.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepositoryConfiguration.java index b0ff9e81d..1c8390618 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepositoryConfiguration.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/RegistryIntegrationSubmodelRepositoryConfiguration.java @@ -26,6 +26,7 @@ package org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration; import java.util.Collection; +import java.util.List; import org.eclipse.digitaltwin.basyx.client.internal.authorization.AccessTokenProviderFactory; import org.eclipse.digitaltwin.basyx.client.internal.authorization.TokenManager; @@ -55,8 +56,8 @@ public class RegistryIntegrationSubmodelRepositoryConfiguration { @Value("${basyx.submodelrepository.feature.registryintegration:#{null}}") private String registryBasePath; - @Value("${basyx.externalurl:#{null}}") - private String submodelRepositoryBaseURL; + @Value("#{'${basyx.externalurl}'.split(',')}") + private List submodelRepositoryBaseURLs; @Value("${basyx.submodelrepository.feature.registryintegration.authorization.enabled:false}") private boolean isAuthorizationEnabledOnRegistry; @@ -84,14 +85,14 @@ public class RegistryIntegrationSubmodelRepositoryConfiguration { @Bean @ConditionalOnMissingBean - public SubmodelRepositoryRegistryLink getSubmodelRepositoryRegistryLink(@Value("${basyx.submodelrepository.feature.registryintegration}") String registryBasePath, @Value("${basyx.externalurl}") String submodelRepositoryBaseURL) { + public SubmodelRepositoryRegistryLink getSubmodelRepositoryRegistryLink() { if (!isAuthorizationEnabledOnRegistry) - return new SubmodelRepositoryRegistryLink(new SubmodelRegistryApi(registryBasePath), submodelRepositoryBaseURL); + return new SubmodelRepositoryRegistryLink(new SubmodelRegistryApi(registryBasePath), submodelRepositoryBaseURLs); TokenManager tokenManager = new TokenManager(authenticationServerTokenEndpoint, createAccessTokenProvider()); - return new SubmodelRepositoryRegistryLink(new AuthorizedConnectedSubmodelRegistry(registryBasePath, tokenManager), submodelRepositoryBaseURL); + return new SubmodelRepositoryRegistryLink(new AuthorizedConnectedSubmodelRegistry(registryBasePath, tokenManager), submodelRepositoryBaseURLs); } @Bean diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelDescriptorFactory.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelDescriptorFactory.java index fc96f639e..ec2dbff4a 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelDescriptorFactory.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelDescriptorFactory.java @@ -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; @@ -52,14 +53,14 @@ public class SubmodelDescriptorFactory { private static final String SUBMODEL_REPOSITORY_PATH = "submodels"; private Submodel submodel; - private String submodelRepositoryURL; + private List submodelRepositoryURLs; private AttributeMapper attributeMapper; - public SubmodelDescriptorFactory(Submodel submodel, String submodelRepositoryBaseURL, AttributeMapper attributeMapper) { - super(); + public SubmodelDescriptorFactory(Submodel submodel, List submodelRepositoryBaseURLs, + AttributeMapper attributeMapper) { this.submodel = submodel; - this.submodelRepositoryURL = createSubmodelRepositoryUrl(submodelRepositoryBaseURL); + this.submodelRepositoryURLs = createSubmodelRepositoryUrls(submodelRepositoryBaseURLs); this.attributeMapper = attributeMapper; } @@ -148,16 +149,19 @@ private void setSupplementalSemanticId(List supplementalSemanticIds, private void setEndpointItem(String shellId, SubmodelDescriptor descriptor) { - Endpoint endpoint = new Endpoint(); - endpoint.setInterface(SUBMODEL_INTERFACE); - ProtocolInformation protocolInformation = createProtocolInformation(shellId); - endpoint.setProtocolInformation(protocolInformation); + for (String eachUrl : submodelRepositoryURLs) { + Endpoint endpoint = new Endpoint(); + endpoint.setInterface(SUBMODEL_INTERFACE); + ProtocolInformation protocolInformation = createProtocolInformation(shellId, eachUrl); + endpoint.setProtocolInformation(protocolInformation); - descriptor.addEndpointsItem(endpoint); + descriptor.addEndpointsItem(endpoint); + } } - private ProtocolInformation createProtocolInformation(String shellId) { - String href = String.format("%s/%s", submodelRepositoryURL, 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)); @@ -182,6 +186,14 @@ private String getProtocol(String endpoint) { } } + private List createSubmodelRepositoryUrls(List submodelRepositoryBaseURLs) { + List toReturn = new ArrayList<>(submodelRepositoryBaseURLs.size()); + for (String eachUrl : submodelRepositoryBaseURLs) { + toReturn.add(createSubmodelRepositoryUrl(eachUrl)); + } + return toReturn; + } + private String createSubmodelRepositoryUrl(String submodelRepositoryBaseURL) { try { diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLink.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLink.java index 56b1198ca..5ba4fc175 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLink.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLink.java @@ -25,6 +25,8 @@ package org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration; +import java.util.List; + import org.eclipse.digitaltwin.basyx.submodelregistry.client.api.SubmodelRegistryApi; import org.eclipse.digitaltwin.basyx.submodelrepository.SubmodelRepository; @@ -36,20 +38,20 @@ public class SubmodelRepositoryRegistryLink { private SubmodelRegistryApi registryApi; - private String submodelRepositoryBaseURL; + private List submodelRepositoryBaseURLs; - public SubmodelRepositoryRegistryLink(SubmodelRegistryApi registryApi, String submodelRepositoryBaseURL) { + public SubmodelRepositoryRegistryLink(SubmodelRegistryApi registryApi, List submodelRepositoryBaseURLs) { super(); this.registryApi = registryApi; - this.submodelRepositoryBaseURL = submodelRepositoryBaseURL; + this.submodelRepositoryBaseURLs = submodelRepositoryBaseURLs; } public SubmodelRegistryApi getRegistryApi() { return registryApi; } - public String getSubmodelRepositoryBaseURL() { - return submodelRepositoryBaseURL; + public List getSubmodelRepositoryBaseURLs() { + return submodelRepositoryBaseURLs; } } diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/AuthorizedSubmodelRepositoryRegistryLinkTest.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/AuthorizedSubmodelRepositoryRegistryLinkTest.java index 8e2bbe8b8..87f3836b2 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/AuthorizedSubmodelRepositoryRegistryLinkTest.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/AuthorizedSubmodelRepositoryRegistryLinkTest.java @@ -90,8 +90,8 @@ public void sendUnauthorizedRequest() throws IOException { } @Override - protected String getSubmodelRepoBaseUrl() { - return SUBMODEL_REPO_URL; + protected String[] getSubmodelRepoBaseUrls() { + return new String[] { SUBMODEL_REPO_URL }; } @Override diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/DummySubmodelDescriptorFactory.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/DummySubmodelDescriptorFactory.java index 4e821bc9b..5d00fb86e 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/DummySubmodelDescriptorFactory.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/DummySubmodelDescriptorFactory.java @@ -48,14 +48,18 @@ public class DummySubmodelDescriptorFactory { private static final String SUBMODEL_REPOSITORY_PATH = "/submodels"; public static SubmodelDescriptor createDummyDescriptor(String smId, String idShort, String smRepoBaseUrl, Reference semanticId) { - + return createDummyDescriptor(smId, idShort, new String[] {smRepoBaseUrl}, semanticId); + } + + public static SubmodelDescriptor createDummyDescriptor(String smId, String idShort, String[] smRepoBaseUrls, Reference semanticId) { SubmodelDescriptor descriptor = new SubmodelDescriptor(); descriptor.setId(smId); descriptor.setIdShort(idShort); descriptor.setSemanticId(semanticId); - descriptor.addEndpointsItem(createEndpointItem(smId, smRepoBaseUrl)); - + for (String eachUrl : smRepoBaseUrls) { + descriptor.addEndpointsItem(createEndpointItem(smId, eachUrl)); + } return descriptor; } diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/MultiUrlSubmodelRepositoryRegistryLinkTest.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/MultiUrlSubmodelRepositoryRegistryLinkTest.java new file mode 100644 index 000000000..e34ae3d07 --- /dev/null +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/MultiUrlSubmodelRepositoryRegistryLinkTest.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (C) 2023 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 + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + ******************************************************************************/ + +package org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration; + +import java.io.FileNotFoundException; +import java.io.IOException; +import org.eclipse.digitaltwin.basyx.submodelregistry.client.api.SubmodelRegistryApi; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.springframework.boot.SpringApplication; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * Integration test for {@link RegistryIntegrationSubmodelRepository} feature + * + * @author danish + */ +public class MultiUrlSubmodelRepositoryRegistryLinkTest extends SubmodelRepositoryRegistryLinkTestSuite { + + private static final String[] SUBMODEL_REPO_URLS = new String[] {"http://localhost:8081", "https://sm-repo.example.org", "http://sm-repo:8081"}; + private static final String SUBMODEL_REGISTRY_BASE_URL = "http://localhost:8060"; + private static ConfigurableApplicationContext appContext; + private static SubmodelRepositoryRegistryLink submodelRepositoryRegistryLink; + + @BeforeClass + public static void setUp() throws FileNotFoundException, IOException { + SpringApplication application = new SpringApplication(DummySubmodelRepositoryIntegrationComponent.class); + application.setAdditionalProfiles("multiurl"); + appContext = application.run(new String[] {}); + submodelRepositoryRegistryLink = appContext.getBean(SubmodelRepositoryRegistryLink.class); + } + + @AfterClass + public static void tearDown() { + appContext.close(); + } + + @Override + protected String[] getSubmodelRepoBaseUrls() { + return SUBMODEL_REPO_URLS; + } + @Override + protected String getSubmodelRegistryUrl() { + return SUBMODEL_REGISTRY_BASE_URL; + } + @Override + protected SubmodelRegistryApi getSubmodelRegistryApi() { + + return submodelRepositoryRegistryLink.getRegistryApi(); + } + + +} diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTest.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTest.java index 8b08db14d..35f7b1831 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTest.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTest.java @@ -58,8 +58,8 @@ public static void tearDown() { } @Override - protected String getSubmodelRepoBaseUrl() { - return SUBMODEL_REPO_URL; + protected String[] getSubmodelRepoBaseUrls() { + return new String[] { SUBMODEL_REPO_URL }; } @Override protected String getSubmodelRegistryUrl() { diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTestSuite.java b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTestSuite.java index 54b704301..d64e98328 100644 --- a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTestSuite.java +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/submodelrepository/feature/registry/integration/SubmodelRepositoryRegistryLinkTestSuite.java @@ -42,6 +42,8 @@ import org.eclipse.digitaltwin.basyx.submodelregistry.client.api.SubmodelRegistryApi; import org.eclipse.digitaltwin.basyx.submodelregistry.client.model.GetSubmodelDescriptorsResult; import org.eclipse.digitaltwin.basyx.submodelregistry.client.model.SubmodelDescriptor; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.springframework.http.HttpStatus; @@ -57,19 +59,19 @@ public abstract class SubmodelRepositoryRegistryLinkTestSuite { private static final String DUMMY_SUBMODEL_IDSHORT = "TechnicalData"; private static final String DUMMY_SUBMODEL_ID = "7A7104BDAB57E184"; - protected abstract String getSubmodelRepoBaseUrl(); + protected abstract String[] getSubmodelRepoBaseUrls(); protected abstract String getSubmodelRegistryUrl(); protected abstract SubmodelRegistryApi getSubmodelRegistryApi(); - private final SubmodelDescriptor DUMMY_DESCRIPTOR = DummySubmodelDescriptorFactory.createDummyDescriptor(DUMMY_SUBMODEL_ID, DUMMY_SUBMODEL_IDSHORT, getSubmodelRepoBaseUrl(), DummySubmodelDescriptorFactory.createSemanticId()); - + private final SubmodelDescriptor DUMMY_DESCRIPTOR = DummySubmodelDescriptorFactory.createDummyDescriptor(DUMMY_SUBMODEL_ID, DUMMY_SUBMODEL_IDSHORT, getSubmodelRepoBaseUrls(), DummySubmodelDescriptorFactory.createSemanticId()); + @Test public void createSubmodel() throws FileNotFoundException, IOException, ApiException { String submodelJsonContent = getSubmodelJSONString(); - CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent); - assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); - + try (CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent)) { + assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); + } SubmodelDescriptor actualDescriptor = retrieveDescriptorFromRegistry(); assertEquals(DUMMY_DESCRIPTOR, actualDescriptor); @@ -82,14 +84,14 @@ public void createSubmodelElementInSubmodelElementCollection() throws FileNotFou String submodelJsonContent = getSubmodelJSONString(); String submodelElementJsonContent = getSinglePropertyJSONString(); - CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent); - assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); + try (CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent)) { + assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); + } createSubmodelElementOnRepo(submodelElementJsonContent); - CloseableHttpResponse getResponse = BaSyxHttpTestUtils.executeGetOnURL(getSpecificSubmodelAccessURL(DUMMY_SUBMODEL_ID)); - - BaSyxHttpTestUtils.assertSameJSONContent(getExpectedSubmodel(), BaSyxHttpTestUtils.getResponseAsString(getResponse)); - + try (CloseableHttpResponse getResponse = BaSyxHttpTestUtils.executeGetOnURL(getSpecificSubmodelAccessURL(DUMMY_SUBMODEL_ID))) { + BaSyxHttpTestUtils.assertSameJSONContent(getExpectedSubmodel(), BaSyxHttpTestUtils.getResponseAsString(getResponse)); + } resetRepository(); } @@ -97,11 +99,13 @@ public void createSubmodelElementInSubmodelElementCollection() throws FileNotFou public void deleteSubmodel() throws FileNotFoundException, IOException, ApiException { String submodelJsonContent = getSubmodelJSONString(); - CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent); - assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); + try (CloseableHttpResponse creationResponse = createSubmodelOnRepo(submodelJsonContent)) { + assertEquals(HttpStatus.CREATED.value(), creationResponse.getCode()); + } - CloseableHttpResponse deleteResponse = deleteSubmodelFromRepo(DUMMY_SUBMODEL_ID); - assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode()); + try (CloseableHttpResponse deleteResponse = deleteSubmodelFromRepo(DUMMY_SUBMODEL_ID)) { + assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode()); + } assertDescriptionDeletionAtRegistry(); } @@ -113,9 +117,9 @@ private SubmodelDescriptor retrieveDescriptorFromRegistry() throws ApiException } private void resetRepository() throws IOException { - CloseableHttpResponse deleteResponse = deleteSubmodelFromRepo(DUMMY_SUBMODEL_ID); - - assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode()); + try (CloseableHttpResponse deleteResponse = deleteSubmodelFromRepo(DUMMY_SUBMODEL_ID)) { + assertEquals(HttpStatus.NO_CONTENT.value(), deleteResponse.getCode()); + } } private CloseableHttpResponse deleteSubmodelFromRepo(String shellId) throws IOException { @@ -145,7 +149,11 @@ private String getExpectedSubmodel() throws FileNotFoundException, IOException { } private CloseableHttpResponse createSubmodelOnRepo(String submodelJsonContent) throws IOException { - return BaSyxHttpTestUtils.executePostOnURL(createSubmodelRepositoryUrl(getSubmodelRepoBaseUrl()), submodelJsonContent); + return BaSyxHttpTestUtils.executePostOnURL(createSubmodelRepositoryUrl(getFirstSubmodeRepoBaseUrl()), submodelJsonContent); + } + + private String getFirstSubmodeRepoBaseUrl() { + return getSubmodelRepoBaseUrls()[0]; } private CloseableHttpResponse createSubmodelElementOnRepo(String submodelElementJsonContent) throws IOException { @@ -155,7 +163,7 @@ private CloseableHttpResponse createSubmodelElementOnRepo(String submodelElement } private String getSpecificSubmodelAccessURL(String submodelId) { - return createSubmodelRepositoryUrl(getSubmodelRepoBaseUrl()) + "/" + Base64UrlEncodedIdentifier.encodeIdentifier(submodelId); + return createSubmodelRepositoryUrl(getFirstSubmodeRepoBaseUrl()) + "/" + Base64UrlEncodedIdentifier.encodeIdentifier(submodelId); } private static String createSubmodelRepositoryUrl(String smRepositoryBaseURL) { diff --git a/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/resources/application-multiurl.properties b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/resources/application-multiurl.properties new file mode 100644 index 000000000..dd734fda8 --- /dev/null +++ b/basyx.submodelrepository/basyx.submodelrepository-feature-registry-integration/src/test/resources/application-multiurl.properties @@ -0,0 +1,34 @@ +server.port=8081 +server.error.path=/error + +spring.application.name=AAS Repository +basyx.smrepo.name = sm-repo + +basyx.backend = InMemory + +basyx.submodelrepository.feature.registryintegration=http://localhost:8060 +basyx.externalurl=http://localhost:8081,https://sm-repo.example.org,http://sm-repo:8081 + +#basyx.backend = MongoDB +#spring.data.mongodb.host=mongo +# or spring.data.mongodb.host=127.0.0.1 +#spring.data.mongodb.port=27017 +#spring.data.mongodb.database=submodels +#spring.data.mongodb.authentication-database=admin +#spring.data.mongodb.username=mongoAdmin +#spring.data.mongodb.password=mongoPassword + +# basyx.submodelrepository.feature.mqtt.enabled = true +# mqtt.clientId=TestClient +# mqtt.hostname = localhost +# mqtt.port = 1883 + +# basyx.cors.allowed-origins=http://localhost:3000, http://localhost:4000 + +#################################################################################### +# Authorization +#################################################################################### +#basyx.feature.authorization.enabled = true +#basyx.feature.authorization.type = rbac +#basyx.feature.authorization.jwtBearerTokenProvider = keycloak +#basyx.feature.authorization.rbac.file = classpath:rbac_rules.json diff --git a/examples/BaSyxMinimal/aas-env.properties b/examples/BaSyxMinimal/aas-env.properties index 9e1f52f44..7cbcf180e 100644 --- a/examples/BaSyxMinimal/aas-env.properties +++ b/examples/BaSyxMinimal/aas-env.properties @@ -20,4 +20,4 @@ basyx.cors.allowed-methods=GET,POST,PATCH,DELETE,PUT,OPTIONS,HEAD basyx.aasrepository.feature.registryintegration = http://aas-registry:8080 basyx.submodelrepository.feature.registryintegration = http://sm-registry:8080 -basyx.externalurl = http://localhost:8081 +basyx.externalurl = http://localhost:8081,http://aas-env:8081