diff --git a/.github/workflows/docker-snapshot-release.yml b/.github/workflows/docker-snapshot-release.yml
new file mode 100644
index 000000000..f6d5f0798
--- /dev/null
+++ b/.github/workflows/docker-snapshot-release.yml
@@ -0,0 +1,141 @@
+name: Build and Push Docker Images on PR Merge
+
+on:
+ push:
+ branches:
+ - main
+ paths-ignore:
+ - '.github/ISSUE_TEMPLATE/**'
+ - '.github/CODE_OF_CONDUCT.md'
+ - '.github/CODING_CONVENTIONS.md'
+ - '.github/CONTRIBUTING.md'
+ - '.github/dependabot.yml'
+ - '.github/pull_request_template.md'
+ - '.github/SECURITY.md'
+ - 'docs/**'
+ - 'examples/**'
+ - 'README.md'
+ - '.gitattributes'
+ - '.gitignore'
+ - 'LICENSE'
+ - 'NOTICE'
+
+env:
+ DOCKER_NAMESPACE: eclipsebasyx
+
+jobs:
+ build-and-push-prerelease:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ include:
+ - name: aas-environment
+ path: basyx.aasenvironment/basyx.aasenvironment.component
+ - name: aas-repository
+ path: basyx.aasrepository/basyx.aasrepository.component
+ - name: submodel-repository
+ path: basyx.submodelrepository/basyx.submodelrepository.component
+ - name: conceptdescription-repository
+ path: basyx.conceptdescriptionrepository/basyx.conceptdescriptionrepository.component
+ - name: aas-discovery
+ path: basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component
+ - name: aasxfileserver
+ path: basyx.aasxfileserver/basyx.aasxfileserver.component
+ - name: aas-registry-kafka-mem
+ path: basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/main/docker
+ - name: aas-registry-kafka-mongodb
+ path: basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/main/docker
+ - name: aas-registry-log-mem
+ path: basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/main/docker
+ - name: aas-registry-log-mongodb
+ path: basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/main/docker
+ - name: submodel-registry-kafka-mem
+ path: basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mem/src/main/docker
+ - name: submodel-registry-kafka-mongodb
+ path: basyx.submodelregistry/basyx.submodelregistry-service-release-kafka-mongodb/src/main/docker
+ - name: submodel-registry-log-mem
+ path: basyx.submodelregistry/basyx.submodelregistry-service-release-log-mem/src/main/docker
+ - name: submodel-registry-log-mongodb
+ path: basyx.submodelregistry/basyx.submodelregistry-service-release-log-mongodb/src/main/docker
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ with:
+ platforms: linux/amd64,linux/arm64,linux/arm/v7
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKER_HUB_USER }}
+ password: ${{ secrets.DOCKER_HUB_TOKEN }}
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build all modules first
+ run: mvn clean install -DskipTests
+
+ # Build the project
+ # For registry modules, we activate the dockerbuild profile and specify the module with --pl
+ - name: Build BaSyx
+ run: |
+ if [[ "${{ matrix.name }}" == *"registry"* ]]; then
+ # Derive the module's artifactId from the path
+ module_root=$(dirname "$(dirname "$(dirname "${{ matrix.path }}")")")
+ artifact_id=$(basename "$module_root")
+ # Run with dockerbuild profile and namespace
+ mvn clean install -DskipTests -Pdockerbuild "-Ddocker.namespace=${{ env.DOCKER_NAMESPACE }}" --pl "org.eclipse.digitaltwin.basyx:${artifact_id}"
+ else
+ echo "Non-registry module - already built in the previous step."
+ fi
+
+ - name: Prepare Registry JAR for Docker
+ if: contains(matrix.name, 'registry')
+ run: |
+ # Go three levels up from src/main/docker to get the module root
+ module_root=$(dirname "$(dirname "$(dirname "${{ matrix.path }}")")")
+
+ # Adjust the path to where the dockerbuild profile places the JAR
+ JAR_FILE=$(ls "$module_root/target/docker/${{ env.DOCKER_NAMESPACE }}/${{ matrix.name }}/2.0.0-SNAPSHOT/build/maven/"*.jar | head -n 1)
+ if [ -z "$JAR_FILE" ]; then
+ echo "No repackaged JAR found in $module_root/target/docker/${{ env.DOCKER_NAMESPACE }}/${{ matrix.name }}/2.0.0-SNAPSHOT/build/maven. Check your build."
+ exit 1
+ fi
+
+ # Create the maven directory inside the Docker context and copy the JAR there
+ mkdir -p "${{ matrix.path }}/maven"
+ cp "$JAR_FILE" "${{ matrix.path }}/maven/"
+
+ # Extract the final name without .jar extension
+ FINAL_NAME=$(basename "$JAR_FILE" .jar)
+ echo "FINAL_ARGS=FINAL_NAME=${FINAL_NAME}" >> $GITHUB_ENV
+
+ - name: No-Op for Non-Registry Modules
+ if: "!contains(matrix.name, 'registry')"
+ run: echo "FINAL_ARGS=" >> $GITHUB_ENV
+
+ - name: Build and Push Docker Image
+ uses: docker/build-push-action@v6
+ with:
+ context: ${{ matrix.path }}
+ file: ${{ matrix.path }}/Dockerfile
+ push: true
+ platforms: linux/amd64,linux/arm64,linux/arm/v7
+ tags: |
+ ${{ env.DOCKER_NAMESPACE }}/${{ matrix.name }}:2.0.0-SNAPSHOT
+ build-args: ${{ env.FINAL_ARGS }}
+
+ - name: Verify Docker Image
+ run: |
+ docker pull ${{ env.DOCKER_NAMESPACE }}/${{ matrix.name }}:2.0.0-SNAPSHOT
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/pom.xml b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/pom.xml
index 7d7849257..62201b56d 100644
--- a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/pom.xml
+++ b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/pom.xml
@@ -19,8 +19,11 @@
org.eclipse.digitaltwin.basyx
basyx.aasdiscoveryservice-backend
-
-
+
+
+ org.eclipse.digitaltwin.basyx
+ basyx.backend.inmemory.core
+
org.eclipse.digitaltwin.basyx
basyx.aasdiscoveryservice-core
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryBackendProvider.java b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryBackendProvider.java
index 46971ba9c..21720e822 100644
--- a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryBackendProvider.java
+++ b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryBackendProvider.java
@@ -27,6 +27,7 @@
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.AasDiscoveryBackendProvider;
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.AasDiscoveryDocument;
+import org.eclipse.digitaltwin.basyx.common.backend.inmemory.core.InMemoryCrudRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
@@ -41,7 +42,7 @@
@Component
public class AasDiscoveryInMemoryBackendProvider implements AasDiscoveryBackendProvider {
- private AasDiscoveryInMemoryCrudRepository repository = new AasDiscoveryInMemoryCrudRepository();
+ private CrudRepository repository = new InMemoryCrudRepository(AasDiscoveryDocument::getShellIdentifier);
@Override
public CrudRepository getCrudRepository() {
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryCrudRepository.java b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryCrudRepository.java
deleted file mode 100644
index 7fdf732c7..000000000
--- a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/backend/inmemory/AasDiscoveryInMemoryCrudRepository.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2024 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.aasdiscoveryservice.backend.inmemory;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.StreamSupport;
-
-import org.eclipse.digitaltwin.aas4j.v3.model.SpecificAssetId;
-import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.AasDiscoveryDocument;
-import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.model.AssetLink;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.lang.NonNull;
-
-/**
- * In-memory implementation of the {@link CrudRepository} for the AAS Discovery
- *
- * @author zielstor, fried, mateusmolina
- */
-public class AasDiscoveryInMemoryCrudRepository implements CrudRepository {
-
- private final ConcurrentMap> assetLinks = new ConcurrentHashMap<>();
- private final ConcurrentMap> assetIds = new ConcurrentHashMap<>();
-
- @Override
- public synchronized @NonNull S save(@NonNull S entity) {
- String shellId = entity.getShellIdentifier();
-
- this.assetLinks.put(shellId, entity.getAssetLinks());
- this.assetIds.put(shellId, entity.getSpecificAssetIds());
-
- return entity;
- }
-
- @Override
- public @NonNull Iterable saveAll(@NonNull Iterable entities) {
- entities.forEach(this::save);
- return entities;
- }
-
- @Override
- public @NonNull Optional findById(@NonNull String id) {
- return Optional.ofNullable(buildAasDiscoveryDocument(id));
- }
-
- @Override
- public boolean existsById(@NonNull String id) {
- return this.assetLinks.containsKey(id);
- }
-
- @Override
- public @NonNull Iterable findAll() {
- return assetLinks.keySet().stream().map(this::buildAasDiscoveryDocument).toList();
- }
-
- @Override
- public @NonNull Iterable findAllById(@NonNull Iterable ids) {
- return StreamSupport.stream(ids.spliterator(), false).map(this::buildAasDiscoveryDocument).toList();
- }
-
- @Override
- public long count() {
- return this.assetLinks.size();
- }
-
- @Override
- public synchronized void deleteById(@NonNull String id) {
- this.assetLinks.remove(id);
- this.assetIds.remove(id);
- }
-
- @Override
- public void delete(@NonNull AasDiscoveryDocument entity) {
- this.deleteById(entity.getShellIdentifier());
- }
-
- @Override
- public void deleteAllById(@NonNull Iterable extends String> ids) {
- for (String id : ids) {
- this.deleteById(id);
- }
- }
-
- @Override
- public void deleteAll(@NonNull Iterable extends AasDiscoveryDocument> entities) {
- for (AasDiscoveryDocument entity : entities) {
- this.deleteById(entity.getShellIdentifier());
- }
- }
-
- @Override
- public synchronized void deleteAll() {
- this.assetLinks.clear();
- this.assetIds.clear();
- }
-
- private synchronized AasDiscoveryDocument buildAasDiscoveryDocument(String shellId) {
- Set assetLinksSet = assetLinks.get(shellId);
- List assetIdsList = assetIds.get(shellId);
-
- if (assetIdsList == null)
- assetIdsList = new ArrayList<>();
-
- if (assetLinksSet == null)
- assetLinksSet = new HashSet<>();
-
- return new AasDiscoveryDocument(shellId, assetLinksSet, assetIdsList);
- }
-
-}
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/core/AasDiscoveryServiceSuite.java b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/core/AasDiscoveryServiceSuite.java
index 536f21d7d..7e552bdea 100644
--- a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/core/AasDiscoveryServiceSuite.java
+++ b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-core/src/test/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/core/AasDiscoveryServiceSuite.java
@@ -55,8 +55,6 @@ public abstract class AasDiscoveryServiceSuite {
protected abstract AasDiscoveryService getAasDiscoveryService();
- private final PaginationInfo noLimitPaginationInfo = new PaginationInfo(0, "");
-
@Test
public void getAllAssetAdministrationShellIdsByAssetLink() {
AasDiscoveryService discoveryService = getAasDiscoveryService();
@@ -74,7 +72,7 @@ public void getAllAssetAdministrationShellIdsByAssetLink() {
new AssetLink("DummyAssetName2", "DummyAsset_2_Value")
));
- List actualResult = discoveryService.getAllAssetAdministrationShellIdsByAssetLink(noLimitPaginationInfo, assetIds)
+ List actualResult = discoveryService.getAllAssetAdministrationShellIdsByAssetLink(PaginationInfo.NO_LIMIT, assetIds)
.getResult();
assertEquals(expectedResult.size(), actualResult.size());
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-http/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/http/AasDiscoveryServiceDescriptionConfiguration.java b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-http/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/http/AasDiscoveryServiceDescriptionConfiguration.java
new file mode 100644
index 000000000..6a33d8b2d
--- /dev/null
+++ b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice-http/src/main/java/org/eclipse/digitaltwin/basyx/aasdiscoveryservice/http/AasDiscoveryServiceDescriptionConfiguration.java
@@ -0,0 +1,17 @@
+package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.http;
+
+import java.util.List;
+import java.util.TreeSet;
+
+import org.eclipse.digitaltwin.basyx.http.description.Profile;
+import org.eclipse.digitaltwin.basyx.http.description.ProfileDeclaration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AasDiscoveryServiceDescriptionConfiguration {
+ @Bean
+ public ProfileDeclaration aasDiscoveryProfiles() {
+ return () -> new TreeSet<>(List.of(Profile.DISCOVERYSERVICESPECIFICATION_SSP_001));
+ }
+}
\ No newline at end of file
diff --git a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component/Dockerfile b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component/Dockerfile
index 1c3e9648d..99b045565 100644
--- a/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component/Dockerfile
+++ b/basyx.aasdiscoveryservice/basyx.aasdiscoveryservice.component/Dockerfile
@@ -1,4 +1,6 @@
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
USER nobody
WORKDIR /application
ARG JAR_FILE=target/*-exec.jar
diff --git a/basyx.aasenvironment/Readme.md b/basyx.aasenvironment/Readme.md
index 4bfb39070..5e7c4a108 100644
--- a/basyx.aasenvironment/Readme.md
+++ b/basyx.aasenvironment/Readme.md
@@ -10,7 +10,7 @@ Eclipse BaSyx provides the AAS Environment as off-the-shelf component:
It aggregates the AAS Repository, Submodel Repository and ConceptDescription Repository into a single component. For its features and configuration, see the documentation of the respective components.
In addition, it supports the following endpoint defined in DotAAS Part 2 V3 - Serialization Interface:
-- GenerateSerializationByIds
+- GenerateSerializationByIds. For more information about this endpoint please refer to [Swagger API](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection/V3.0.1#/Serialization%20API/GenerateSerializationByIds)
The Aggregated API endpoint documentation is available at:
@@ -40,10 +40,19 @@ For examples, see [application.properties](./basyx.aasenvironment.component/src/
## AAS Environment Upload Endpoint
-AAS environments (e.g. XML, JSON, AASX) can be uploaded by a multipart/form-data POST on the `/upload` endpoint. Please note that the following MIME types are expected for the respective file uploads:
+AAS environments (e.g. XML, JSON, AASX) can be uploaded by a multipart/form-data POST on the `/upload` endpoint. Please note that the following MIME types as **Accept Header** are expected for the respective file uploads:
* AASX: application/asset-administration-shell-package
* JSON: application/json
* XML: application/xml
+
+Below is an example curl request:
+
+```
+curl --location 'http://localhost:8081/upload' \
+--header 'Accept: application/asset-administration-shell-package' \
+--form 'file=@"Sample.aasx"'
+
+```
The upload follows the same rules as the preconfiguration in terms of handling existing AAS, submodels and concept descriptions. In order for the file to be recognized correctly, please make sure that its MIME type is properly configured.
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManager.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManager.java
index f28480ed7..73ae1cbe1 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManager.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/ConnectedAasManager.java
@@ -223,10 +223,7 @@ public void createSubmodelInAas(String aasIdentifier, Submodel submodel) {
throw new RegistryHttpRequestException(aasIdentifier, e);
}
- Reference smRef = AasUtils.toReference(AasUtils.toReference(shell), submodel);
-
- // TODO See https://github.com/eclipse-aas4j/aas4j/issues/308
- smRef.setReferredSemanticId(submodel.getSemanticId());
+ Reference smRef = AasUtils.toReference(AasUtils.toReference(shell), submodel, true);
aasRepository.addSubmodelReference(aasIdentifier, smRef);
}
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 d6e0ab8c6..3d8a90ec7 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
@@ -60,13 +60,13 @@ static ObjectMapper buildObjectMapper() {
static AasDescriptorFactory buildAasDescriptorFactory(String... aasRepositoryBaseUrls) {
AttributeMapper attributeMapper = new AttributeMapper(objectMapper);
- return new AasDescriptorFactory(null, List.of(aasRepositoryBaseUrls), attributeMapper);
+ return new AasDescriptorFactory(List.of(aasRepositoryBaseUrls), attributeMapper);
}
static SubmodelDescriptorFactory buildSmDescriptorFactory(String... aasRepositoryBaseUrls) {
org.eclipse.digitaltwin.basyx.submodelregistry.client.mapper.AttributeMapper attributeMapperSm = new org.eclipse.digitaltwin.basyx.submodelregistry.client.mapper.AttributeMapper(
objectMapper);
- return new SubmodelDescriptorFactory(null, List.of(aasRepositoryBaseUrls), attributeMapperSm);
+ return new SubmodelDescriptorFactory(List.of(aasRepositoryBaseUrls), attributeMapperSm);
}
}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/AasDescriptorResolver.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/AasDescriptorResolver.java
index 6e743a8e1..a010f3df7 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/AasDescriptorResolver.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/AasDescriptorResolver.java
@@ -30,17 +30,20 @@
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetAdministrationShellDescriptor;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.Endpoint;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.model.ProtocolInformation;
import org.eclipse.digitaltwin.basyx.aasservice.client.ConnectedAasService;
import org.eclipse.digitaltwin.basyx.client.internal.resolver.DescriptorResolver;
/**
* Resolves an AasDescriptor into a {@link ConnectedAasService}
- *
+ *
* @author mateusmolina, danish
*
*/
public class AasDescriptorResolver implements DescriptorResolver {
+ static final String SPEC_INTERFACE = "AAS-3.0";
+
private final EndpointResolver endpointResolver;
/**
@@ -66,16 +69,7 @@ public ConnectedAasService resolveDescriptor(AssetAdministrationShellDescriptor
public static Optional parseEndpoint(Endpoint endpoint) {
try {
- if (endpoint == null || endpoint.getProtocolInformation() == null || endpoint.getProtocolInformation()
- .getHref() == null)
- return Optional.empty();
-
- String baseHref = endpoint.getProtocolInformation()
- .getHref();
- // TODO not working: String queryString = "?" + endpoint.toUrlQueryString();
- String queryString = "";
- URI uri = new URI(baseHref + queryString);
- return Optional.of(uri);
+ return Optional.ofNullable(endpoint).filter(ep -> ep.getInterface().equals(SPEC_INTERFACE)).map(Endpoint::getProtocolInformation).map(ProtocolInformation::getHref).map(URI::create);
} catch (Exception e) {
return Optional.empty();
}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/SubmodelDescriptorResolver.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/SubmodelDescriptorResolver.java
index 5ddc10d72..4d7014577 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/SubmodelDescriptorResolver.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/main/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/SubmodelDescriptorResolver.java
@@ -25,6 +25,7 @@
package org.eclipse.digitaltwin.basyx.aasenvironment.client.resolvers;
+import org.eclipse.digitaltwin.basyx.submodelregistry.client.model.ProtocolInformation;
import org.eclipse.digitaltwin.basyx.client.internal.resolver.DescriptorResolver;
import java.net.URI;
import java.util.Optional;
@@ -41,6 +42,8 @@
*/
public class SubmodelDescriptorResolver implements DescriptorResolver {
+ static final String SPEC_INTERFACE = "SUBMODEL-3.0";
+
private final EndpointResolver endpointResolver;
/**
@@ -67,16 +70,7 @@ public ConnectedSubmodelService resolveDescriptor(SubmodelDescriptor smDescripto
public static Optional parseEndpoint(Endpoint endpoint) {
try {
- if (endpoint == null || endpoint.getProtocolInformation() == null || endpoint.getProtocolInformation()
- .getHref() == null)
- return Optional.empty();
-
- String baseHref = endpoint.getProtocolInformation()
- .getHref();
- // TODO not working: String queryString = "?" + endpoint.toUrlQueryString();
- String queryString = "";
- URI uri = new URI(baseHref + queryString);
- return Optional.of(uri);
+ return Optional.ofNullable(endpoint).filter(ep -> ep.getInterface().equals(SPEC_INTERFACE)).map(Endpoint::getProtocolInformation).map(ProtocolInformation::getHref).map(URI::create);
} catch (Exception e) {
return Optional.empty();
}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestConnectedAasManagerMultithreading.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestConnectedAasManagerMultithreading.java
new file mode 100644
index 000000000..8ff0ea860
--- /dev/null
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestConnectedAasManagerMultithreading.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (C) 2024 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.aasenvironment.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.IntStream;
+
+import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
+import org.eclipse.digitaltwin.aas4j.v3.model.Key;
+import org.eclipse.digitaltwin.aas4j.v3.model.Reference;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetAdministrationShell;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodel;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.api.RegistryAndDiscoveryInterfaceApi;
+import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;
+import org.eclipse.digitaltwin.basyx.aasrepository.client.ConnectedAasRepository;
+import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
+import org.eclipse.digitaltwin.basyx.submodelregistry.client.api.SubmodelRegistryApi;
+import org.eclipse.digitaltwin.basyx.submodelrepository.SubmodelRepository;
+import org.eclipse.digitaltwin.basyx.submodelrepository.client.ConnectedSubmodelRepository;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class TestConnectedAasManagerMultithreading {
+ static final String AAS_REPOSITORY_BASE_PATH = "http://localhost:8081";
+ static final String SM_REPOSITORY_BASE_PATH = "http://localhost:8081";
+ static final String AAS_REGISTRY_BASE_PATH = "http://localhost:8050";
+ static final String SM_REGISTRY_BASE_PATH = "http://localhost:8060";
+ static final int N_THREADS = 20;
+
+ static ConfigurableApplicationContext appContext;
+ static AasRepository aasRepository;
+ static SubmodelRepository smRepository;
+
+ static ConnectedAasRepository connectedAasRepository;
+ static ConnectedSubmodelRepository connectedSmRepository;
+ static RegistryAndDiscoveryInterfaceApi aasRegistryApi;
+ static SubmodelRegistryApi smRegistryApi;
+
+ static ConnectedAasManager aasManager;
+
+ @BeforeClass
+ public static void setupRepositories() {
+ appContext = new SpringApplication(DummyAasEnvironmentComponent.class).run(new String[] {});
+
+ connectedAasRepository = new ConnectedAasRepository(AAS_REPOSITORY_BASE_PATH);
+ connectedSmRepository = new ConnectedSubmodelRepository(SM_REPOSITORY_BASE_PATH);
+ aasRegistryApi = new RegistryAndDiscoveryInterfaceApi(AAS_REGISTRY_BASE_PATH);
+ smRegistryApi = new SubmodelRegistryApi(SM_REGISTRY_BASE_PATH);
+ aasManager = new ConnectedAasManager(AAS_REGISTRY_BASE_PATH, AAS_REPOSITORY_BASE_PATH, SM_REGISTRY_BASE_PATH, SM_REPOSITORY_BASE_PATH);
+
+ cleanUpRegistries();
+ }
+
+ @After
+ public void cleanUpComponents() {
+ cleanUpRegistries();
+ }
+
+ @AfterClass
+ public static void stopContext() {
+ appContext.close();
+ }
+
+ @Test
+ public void testParallelSubmodelCreation() throws ExecutionException, InterruptedException {
+ AssetAdministrationShell shell = createShell();
+
+ ExecutorService executorService = Executors.newFixedThreadPool(N_THREADS);
+ ConcurrentLinkedDeque createdSubmodelIds = new ConcurrentLinkedDeque<>();
+
+ List> futures = IntStream.range(0, N_THREADS).mapToObj(i -> executorService.submit(() -> createdSubmodelIds.add(createSubmodel(shell.getId(), i)))).toList();
+
+ try {
+ for (int i = 0; i < N_THREADS; i++) {
+ futures.get(i).get();
+ }
+ } finally {
+ executorService.shutdown();
+ }
+
+ createdSubmodelIds.forEach(submodelId -> assertSubmodelWasCreatedAndRegistered(shell.getId(), submodelId));
+ }
+
+ static void assertSubmodelWasCreatedAndRegistered(String shellId, String submodelId) {
+ assertEquals(submodelId, aasManager.getSubmodelService(submodelId).getSubmodel().getId());
+ assertTrue(connectedAasRepository.getSubmodelReferences(shellId, PaginationInfo.NO_LIMIT).getResult().stream().map(Reference::getKeys).flatMap(Collection::stream).map(Key::getValue).anyMatch(submodelId::equals));
+ }
+
+
+ private static void cleanUpRegistries() {
+ try {
+ aasRegistryApi.deleteAllShellDescriptors();
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ try {
+ smRegistryApi.deleteAllSubmodelDescriptors();
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ private static AssetAdministrationShell createShell() {
+ String id = UUID.randomUUID().toString();
+ DefaultAssetAdministrationShell shell = new DefaultAssetAdministrationShell.Builder().id(id).build();
+ aasManager.createAas(shell);
+ return aasManager.getAasService(id).getAAS();
+ }
+
+ private static String createSubmodel(String aasId, int threadId) {
+ try {
+ String id = aasId + "-thread" + threadId;
+ DefaultSubmodel submodel = new DefaultSubmodel.Builder().id(id).build();
+ aasManager.createSubmodelInAas(aasId, submodel);
+ return id;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed at thread " + threadId, e);
+ }
+ }
+
+}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestFixture.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestFixture.java
index 275f54eb2..2d552fdae 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestFixture.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/TestFixture.java
@@ -25,6 +25,8 @@
package org.eclipse.digitaltwin.basyx.aasenvironment.client;
+import java.util.LinkedList;
+
import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
import org.eclipse.digitaltwin.aas4j.v3.model.AssetInformation;
import org.eclipse.digitaltwin.aas4j.v3.model.AssetKind;
@@ -38,6 +40,7 @@
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultReference;
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodel;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetAdministrationShellDescriptor;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.model.Endpoint;
import org.eclipse.digitaltwin.basyx.aasregistry.main.client.mapper.DummyAasDescriptorFactory;
import org.eclipse.digitaltwin.basyx.http.Base64UrlEncoder;
import org.eclipse.digitaltwin.basyx.submodelregistry.client.mapper.AttributeMapper;
@@ -88,7 +91,16 @@ public AssetInformation buildAasPre1AssetInformation() {
}
public AssetAdministrationShellDescriptor buildAasPre1Descriptor() {
- return DummyAasDescriptorFactory.createDummyDescriptor(AAS_PRE1_ID, AAS_PRE1_IDSHORT, AAS_PRE1_GLOBALASSETID, aasRepositoryBasePath);
+ return DummyAasDescriptorFactory.createDummyDescriptor(AAS_PRE1_ID, AAS_PRE1_IDSHORT, AAS_PRE1_GLOBALASSETID, null, aasRepositoryBasePath);
+ }
+
+ public AssetAdministrationShellDescriptor buildAasPre1Descriptor_withMultipleInterfaces() {
+ LinkedList endpoints = new LinkedList<>();
+
+ endpoints.add(DummyAasDescriptorFactory.createEndpoint(aasRepositoryBasePath, "AAS-REPOSITORY-3.0"));
+ endpoints.add(DummyAasDescriptorFactory.createEndpoint(AAS_PRE1_ID, aasRepositoryBasePath, "AAS-3.0"));
+
+ return DummyAasDescriptorFactory.createDummyDescriptor(AAS_PRE1_ID, AAS_PRE1_IDSHORT, AAS_PRE1_GLOBALASSETID, null, endpoints);
}
public Reference buildSmPre1Ref() {
@@ -100,7 +112,16 @@ public Submodel buildSmPre1() {
}
public SubmodelDescriptor buildSmPre1Descriptor() {
- return DummySubmodelDescriptorFactory.createDummyDescriptor(SM_PRE1_ID, SM_PRE1_IDSHORT, smRepositoryBasePath, null);
+ return DummySubmodelDescriptorFactory.createDummyDescriptor(SM_PRE1_ID, SM_PRE1_IDSHORT, null, null, smRepositoryBasePath);
+ }
+
+ public SubmodelDescriptor buildSmPre1Descriptor_withMultipleInterfaces() {
+ LinkedList endpoints = new LinkedList<>();
+
+ endpoints.add(DummySubmodelDescriptorFactory.createEndpoint(smRepositoryBasePath, "SUBMODEL-REPOSITORY-3.0"));
+ endpoints.add(DummySubmodelDescriptorFactory.createEndpoint(SM_PRE1_ID, smRepositoryBasePath, "SUBMODEL-3.0"));
+
+ return DummySubmodelDescriptorFactory.createDummyDescriptor(SM_PRE1_ID, SM_PRE1_IDSHORT, null, null, endpoints);
}
public AssetAdministrationShell buildAasPos1() {
@@ -112,11 +133,11 @@ public AssetInformation buildAasPos1AssetInformation() {
}
public AssetAdministrationShellDescriptor buildAasPos1Descriptor() {
- return DummyAasDescriptorFactory.createDummyDescriptor(AAS_POS1_ID, AAS_POS1_IDSHORT, AAS_POS1_GLOBALASSETID, aasRepositoryBasePath);
+ return DummyAasDescriptorFactory.createDummyDescriptor(AAS_POS1_ID, AAS_POS1_IDSHORT, AAS_POS1_GLOBALASSETID, null, aasRepositoryBasePath);
}
public SubmodelDescriptor buildSmPos1Descriptor() {
- return DummySubmodelDescriptorFactory.createDummyDescriptor(SM_POS1_ID, SM_POS1_IDSHORT, smRepositoryBasePath, new AttributeMapper(ConnectedAasManagerHelper.buildObjectMapper()).mapSemanticId(buildSmPos1SemanticId()));
+ return DummySubmodelDescriptorFactory.createDummyDescriptor(SM_POS1_ID, SM_POS1_IDSHORT, new AttributeMapper(ConnectedAasManagerHelper.buildObjectMapper()).mapSemanticId(buildSmPos1SemanticId()), null, smRepositoryBasePath);
}
public Reference buildSmPos1SemanticId() {
diff --git a/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/RegistryDescriptorResolverTest.java b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/RegistryDescriptorResolverTest.java
index e0666db0d..a6ced6534 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/RegistryDescriptorResolverTest.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-client/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/client/resolvers/RegistryDescriptorResolverTest.java
@@ -31,7 +31,6 @@
import org.eclipse.digitaltwin.aas4j.v3.model.Submodel;
import org.eclipse.digitaltwin.basyx.aasenvironment.client.DummyAasEnvironmentComponent;
import org.eclipse.digitaltwin.basyx.aasenvironment.client.TestFixture;
-import org.eclipse.digitaltwin.basyx.aasregistry.client.ApiException;
import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;
import org.eclipse.digitaltwin.basyx.submodelrepository.SubmodelRepository;
import org.junit.AfterClass;
@@ -52,10 +51,10 @@ public class RegistryDescriptorResolverTest {
private static AasRepository aasRepository;
private static SubmodelRepository smRepository;
- private final static String AAS_REPOSITORY_BASE_PATH = "http://localhost:8081";
- private final static String SM_REPOSITORY_BASE_PATH = "http://localhost:8081";
+ private static final String AAS_REPOSITORY_BASE_PATH = "http://localhost:8081";
+ private static final String SM_REPOSITORY_BASE_PATH = "http://localhost:8081";
- private final static TestFixture FIXTURE = new TestFixture(AAS_REPOSITORY_BASE_PATH, SM_REPOSITORY_BASE_PATH);
+ private static final TestFixture FIXTURE = new TestFixture(AAS_REPOSITORY_BASE_PATH, SM_REPOSITORY_BASE_PATH);
@BeforeClass
public static void initApplication() {
@@ -73,7 +72,7 @@ public static void cleanUp() {
}
@Test
- public void resolveAasDescriptor() throws ApiException {
+ public void resolveAasDescriptor() {
AasDescriptorResolver resolver = new AasDescriptorResolver(new EndpointResolver());
AssetAdministrationShell expectedAas = FIXTURE.buildAasPre1();
@@ -84,7 +83,18 @@ public void resolveAasDescriptor() throws ApiException {
}
@Test
- public void resolveSmDescriptor() throws ApiException {
+ public void resolveAasDescriptor_withMultipleInterfaces() {
+ AasDescriptorResolver resolver = new AasDescriptorResolver(new EndpointResolver());
+
+ AssetAdministrationShell expectedAas = FIXTURE.buildAasPre1();
+
+ AssetAdministrationShell actualAas = resolver.resolveDescriptor(FIXTURE.buildAasPre1Descriptor_withMultipleInterfaces()).getAAS();
+
+ assertEquals(expectedAas, actualAas);
+ }
+
+ @Test
+ public void resolveSmDescriptor() {
SubmodelDescriptorResolver resolver = new SubmodelDescriptorResolver(new EndpointResolver());
Submodel expectedSm = FIXTURE.buildSmPre1();
@@ -94,4 +104,14 @@ public void resolveSmDescriptor() throws ApiException {
assertEquals(expectedSm, actualSm);
}
+ @Test
+ public void resolveSmDescriptor_withMultipleInterfaces() {
+ SubmodelDescriptorResolver resolver = new SubmodelDescriptorResolver(new EndpointResolver());
+
+ Submodel expectedSm = FIXTURE.buildSmPre1();
+
+ Submodel actualSm = resolver.resolveDescriptor(FIXTURE.buildSmPre1Descriptor_withMultipleInterfaces()).getSubmodel();
+
+ assertEquals(expectedSm, actualSm);
+ }
}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-core/pom.xml b/basyx.aasenvironment/basyx.aasenvironment-core/pom.xml
index 3d8a5b48b..b64d501ce 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-core/pom.xml
+++ b/basyx.aasenvironment/basyx.aasenvironment-core/pom.xml
@@ -102,7 +102,7 @@
com.google.guava
guava
- 33.2.1-jre
+ 33.4.0-jre
diff --git a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironmentLoaderTest.java b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironmentLoaderTest.java
index 391bf22cd..c3fd3001b 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironmentLoaderTest.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/AasEnvironmentLoaderTest.java
@@ -69,8 +69,6 @@ public class AasEnvironmentLoaderTest {
protected static final String TEST_ENVIRONMENT_SHELLS_ONLY_JSON = "/org/eclipse/digitaltwin/basyx/aasenvironment/environment_with_shells_only.json";
protected static final String TEST_ENVIRONMENT_SUBMODELS_ONLY_JSON = "/org/eclipse/digitaltwin/basyx/aasenvironment/environment_with_submodels_only.json";
- protected static final PaginationInfo ALL = new PaginationInfo(0, null);
-
protected AasRepository aasRepository;
protected SubmodelRepository submodelRepository;
protected ConceptDescriptionRepository conceptDescriptionRepository;
@@ -96,9 +94,9 @@ protected void loadRepositories(List pathsToLoad) throws IOException, De
public void testWithResourceFile_AllElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException {
loadRepositories(List.of(TEST_ENVIRONMENT_JSON));
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
@Test
@@ -112,9 +110,9 @@ public void testDeployedTwiceNoVersion_AllDeployedButNotOverriden() throws Inval
Mockito.verify(submodelRepository, Mockito.times(2)).createSubmodel(Mockito.any());
Mockito.verify(submodelRepository, Mockito.times(0)).updateSubmodel(Mockito.anyString(), Mockito.any());
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
@Test
@@ -128,9 +126,9 @@ public void testDeployedTwiceWithSameVersion_AllDeployedButNotOverriden() throws
Mockito.verify(submodelRepository, Mockito.times(2)).createSubmodel(Mockito.any());
Mockito.verify(submodelRepository, Mockito.times(0)).updateSubmodel(Mockito.anyString(), Mockito.any());
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
@Test
@@ -144,9 +142,9 @@ public void testDeployedTwiceNewRevision_ElementsAreOverriden() throws InvalidFo
Mockito.verify(submodelRepository, Mockito.times(2)).createSubmodel(Mockito.any());
Mockito.verify(submodelRepository, Mockito.times(1)).updateSubmodel(Mockito.anyString(), Mockito.any());
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
@Test
@@ -168,17 +166,17 @@ public void testWithResourceFile_NoExceptionsWhenReuploadAfterElementsAreRemoved
loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader);
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
deleteElementsFromRepos();
loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader);
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
@Test
@@ -187,9 +185,9 @@ public void testWithResourceFile_ExceptionIsThrownWhenReuploadWithExistingElemen
loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader);
- Assert.assertEquals(2, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(2, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(2, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(2, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
String expectedMsg = new CollidingIdentifierException("aas1").getMessage();
Assert.assertThrows(expectedMsg, CollidingIdentifierException.class, () -> loadRepositoriesWithEnvironment(List.of(TEST_ENVIRONMENT_JSON), envLoader));
@@ -204,13 +202,13 @@ private void loadRepositoriesWithEnvironment(List pathsToLoad, AasEnviro
}
private void deleteElementsFromRepos() {
- aasRepository.getAllAas(ALL).getResult().stream().forEach(aas -> aasRepository.deleteAas(aas.getId()));
- submodelRepository.getAllSubmodels(ALL).getResult().stream().forEach(sm -> submodelRepository.deleteSubmodel(sm.getId()));
- conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().stream().forEach(cd -> conceptDescriptionRepository.deleteConceptDescription(cd.getId()));
+ aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().stream().forEach(aas -> aasRepository.deleteAas(aas.getId()));
+ submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().stream().forEach(sm -> submodelRepository.deleteSubmodel(sm.getId()));
+ conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().stream().forEach(cd -> conceptDescriptionRepository.deleteConceptDescription(cd.getId()));
- Assert.assertEquals(0, aasRepository.getAllAas(ALL).getResult().size());
- Assert.assertEquals(0, submodelRepository.getAllSubmodels(ALL).getResult().size());
- Assert.assertEquals(0, conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().size());
+ Assert.assertEquals(0, aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(0, submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().size());
+ Assert.assertEquals(0, conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().size());
}
}
\ No newline at end of file
diff --git a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/PreconfigurationLoaderTextualResourceTest.java b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/PreconfigurationLoaderTextualResourceTest.java
index 29a8774c4..7cd689cc3 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/PreconfigurationLoaderTextualResourceTest.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/PreconfigurationLoaderTextualResourceTest.java
@@ -31,6 +31,7 @@
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
import org.eclipse.digitaltwin.basyx.aasenvironment.base.DefaultAASEnvironment;
import org.eclipse.digitaltwin.basyx.aasenvironment.preconfiguration.AasEnvironmentPreconfigurationLoader;
+import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
@@ -52,9 +53,9 @@ protected void loadRepositories(List pathsToLoad) throws IOException, In
@Test
public void testWithEmptyResource_NoElementsAreDeployed() throws InvalidFormatException, IOException, DeserializationException {
loadRepositories(List.of());
- Assert.assertTrue(aasRepository.getAllAas(ALL).getResult().isEmpty());
- Assert.assertTrue(submodelRepository.getAllSubmodels(ALL).getResult().isEmpty());
- Assert.assertTrue(conceptDescriptionRepository.getAllConceptDescriptions(ALL).getResult().isEmpty());
+ Assert.assertTrue(aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().isEmpty());
+ Assert.assertTrue(submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().isEmpty());
+ Assert.assertTrue(conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().isEmpty());
Mockito.verify(aasRepository, Mockito.never()).createAas(Mockito.any());
Mockito.verify(aasRepository, Mockito.never()).updateAas(Mockito.anyString(), Mockito.any());
diff --git a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/TestAASEnvironmentSerialization.java b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/TestAASEnvironmentSerialization.java
index 3734e36ea..0564b0d4a 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/TestAASEnvironmentSerialization.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-core/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/TestAASEnvironmentSerialization.java
@@ -74,7 +74,6 @@
public class TestAASEnvironmentSerialization {
- private static final PaginationInfo NO_LIMIT_PAGINATION_INFO = new PaginationInfo(0, "");
public static final String AAS_TECHNICAL_DATA_ID = "shell001";
public static final String AAS_OPERATIONAL_DATA_ID = "shell002";
public static final String SUBMODEL_TECHNICAL_DATA_ID = "7A7104BDAB57E184";
@@ -266,9 +265,9 @@ private static List retrieveConceptDescriptionIds(Environment aasEnviron
}
private void validateRepositoriesState() {
- assertTrue(aasRepository.getAllAas(NO_LIMIT_PAGINATION_INFO).getResult().containsAll(createDummyShells()));
- assertTrue(submodelRepository.getAllSubmodels(NO_LIMIT_PAGINATION_INFO).getResult().containsAll(createDummySubmodels()));
- assertTrue(conceptDescriptionRepository.getAllConceptDescriptions(NO_LIMIT_PAGINATION_INFO).getResult().containsAll(createDummyConceptDescriptions()));
+ assertTrue(aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().containsAll(createDummyShells()));
+ assertTrue(submodelRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().containsAll(createDummySubmodels()));
+ assertTrue(conceptDescriptionRepository.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult().containsAll(createDummyConceptDescriptions()));
}
}
diff --git a/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentSerialization.java b/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentSerialization.java
index 8f056bd58..7676800a3 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentSerialization.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentSerialization.java
@@ -70,7 +70,6 @@
*/
public class TestAuthorizedAasEnvironmentSerialization {
- private static final PaginationInfo NO_LIMIT_PAGINATION_INFO = new PaginationInfo(0, null);
private static String authenticaltionServerTokenEndpoint = "http://localhost:9096/realms/BaSyx/protocol/openid-connect/token";
private static String clientId = "basyx-client-api";
private static AccessTokenProvider tokenProvider;
@@ -101,9 +100,9 @@ public static void tearDown() {
public void reset() throws FileNotFoundException, IOException {
configureSecurityContext();
- Collection assetAdministrationShells = aasRepo.getAllAas(NO_LIMIT_PAGINATION_INFO).getResult();
- Collection submodels = submodelRepo.getAllSubmodels(NO_LIMIT_PAGINATION_INFO).getResult();
- Collection conceptDescriptions = conceptDescriptionRepo.getAllConceptDescriptions(NO_LIMIT_PAGINATION_INFO).getResult();
+ Collection assetAdministrationShells = aasRepo.getAllAas(PaginationInfo.NO_LIMIT).getResult();
+ Collection submodels = submodelRepo.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult();
+ Collection conceptDescriptions = conceptDescriptionRepo.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult();
assetAdministrationShells.stream().forEach(aas -> aasRepo.deleteAas(aas.getId()));
submodels.stream().forEach(sm -> submodelRepo.deleteSubmodel(sm.getId()));
diff --git a/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentUpload.java b/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentUpload.java
index 785ae35ad..3b39566dd 100644
--- a/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentUpload.java
+++ b/basyx.aasenvironment/basyx.aasenvironment-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/feature/authorization/TestAuthorizedAasEnvironmentUpload.java
@@ -67,7 +67,6 @@
*/
public class TestAuthorizedAasEnvironmentUpload {
- private static final PaginationInfo NO_LIMIT_PAGINATION_INFO = new PaginationInfo(0, null);
private static String authenticaltionServerTokenEndpoint = "http://localhost:9096/realms/BaSyx/protocol/openid-connect/token";
private static String clientId = "basyx-client-api";
private static AccessTokenProvider tokenProvider;
@@ -94,9 +93,9 @@ public void reset() throws FileNotFoundException, IOException {
configureSecurityContext();
- Collection assetAdministrationShells = aasRepo.getAllAas(NO_LIMIT_PAGINATION_INFO).getResult();
- Collection submodels = submodelRepo.getAllSubmodels(NO_LIMIT_PAGINATION_INFO).getResult();
- Collection conceptDescriptions = conceptDescriptionRepo.getAllConceptDescriptions(NO_LIMIT_PAGINATION_INFO).getResult();
+ Collection assetAdministrationShells = aasRepo.getAllAas(PaginationInfo.NO_LIMIT).getResult();
+ Collection submodels = submodelRepo.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult();
+ Collection conceptDescriptions = conceptDescriptionRepo.getAllConceptDescriptions(PaginationInfo.NO_LIMIT).getResult();
assetAdministrationShells.stream().forEach(aas -> aasRepo.deleteAas(aas.getId()));
submodels.stream().forEach(sm -> submodelRepo.deleteSubmodel(sm.getId()));
diff --git a/basyx.aasenvironment/basyx.aasenvironment.component/Dockerfile b/basyx.aasenvironment/basyx.aasenvironment.component/Dockerfile
index 1c3e9648d..99b045565 100644
--- a/basyx.aasenvironment/basyx.aasenvironment.component/Dockerfile
+++ b/basyx.aasenvironment/basyx.aasenvironment.component/Dockerfile
@@ -1,4 +1,6 @@
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
USER nobody
WORKDIR /application
ARG JAR_FILE=target/*-exec.jar
diff --git a/basyx.aasenvironment/basyx.aasenvironment.component/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/component/TestEnvironmentWithRegistryIntegration.java b/basyx.aasenvironment/basyx.aasenvironment.component/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/component/TestEnvironmentWithRegistryIntegration.java
new file mode 100644
index 000000000..ca223dbeb
--- /dev/null
+++ b/basyx.aasenvironment/basyx.aasenvironment.component/src/test/java/org/eclipse/digitaltwin/basyx/aasenvironment/component/TestEnvironmentWithRegistryIntegration.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (C) 2024 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.aasenvironment.component;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
+import org.eclipse.digitaltwin.basyx.aasenvironment.AasEnvironment;
+import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment;
+import org.eclipse.digitaltwin.basyx.aasenvironment.environmentloader.CompleteEnvironment.EnvironmentType;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.ApiException;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetAdministrationShellDescriptor;
+import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;
+import org.eclipse.digitaltwin.basyx.aasrepository.feature.registry.integration.AasRepositoryRegistryLink;
+import org.eclipse.digitaltwin.basyx.core.exceptions.RepositoryRegistryLinkException;
+import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
+import org.eclipse.digitaltwin.basyx.submodelrepository.SubmodelRepository;
+import org.eclipse.digitaltwin.basyx.submodelrepository.feature.registry.integration.SubmodelRepositoryRegistryLink;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+
+/**
+ *
+ * Test the {@link AasEnvironment} with aas and submodel registry integration
+ * features enabled
+ *
+ * @author mateusmolina
+ */
+public class TestEnvironmentWithRegistryIntegration {
+
+ static final String ENV_PATH = "testEnvironment.json";
+
+ static ConfigurableApplicationContext appContext;
+
+ static AasEnvironment aasEnvironment;
+ static AasRepositoryRegistryLink aasRepositoryRegistryLink;
+ static SubmodelRepositoryRegistryLink smRepositoryRegistryLink;
+ static AasRepository aasRepository;
+ static SubmodelRepository smRepository;
+
+ @BeforeClass
+ public static void startAASEnvironment() {
+ appContext = new SpringApplicationBuilder(AasEnvironmentComponent.class).profiles("reginteg").run(new String[] {});
+
+ aasEnvironment = appContext.getBean(AasEnvironment.class);
+ aasRepositoryRegistryLink = appContext.getBean(AasRepositoryRegistryLink.class);
+ smRepositoryRegistryLink = appContext.getBean(SubmodelRepositoryRegistryLink.class);
+ aasRepository = appContext.getBean(AasRepository.class);
+ smRepository = appContext.getBean(SubmodelRepository.class);
+
+ assertRepositoriesAreEmpty();
+ }
+
+ @AfterClass
+ public static void stopAASEnvironment() {
+ appContext.close();
+ }
+
+ @AfterClass
+ public static void clearRegistries() throws Exception {
+ smRepositoryRegistryLink.getRegistryApi().deleteAllSubmodelDescriptors();
+ aasRepositoryRegistryLink.getRegistryApi().deleteAllShellDescriptors();
+ }
+
+ @Test
+ public void whenUploadDescriptorToRegistryFails_thenNoAasOrSmAreAddedToRepository() throws InvalidFormatException, DeserializationException, IOException, ApiException {
+ // simulate descriptor already being in registry
+ aasRepositoryRegistryLink.getRegistryApi().postAssetAdministrationShellDescriptor(buildTestAasDescriptor());
+
+ CompleteEnvironment completeEnvironment = CompleteEnvironment.fromInputStream(getIsFromClasspath(ENV_PATH), EnvironmentType.JSON);
+
+ assertThrows(RepositoryRegistryLinkException.class, () -> aasEnvironment.loadEnvironment(completeEnvironment));
+
+ assertRepositoriesAreEmpty();
+ }
+
+ private static AssetAdministrationShellDescriptor buildTestAasDescriptor() {
+ AssetAdministrationShellDescriptor descriptor = new AssetAdministrationShellDescriptor();
+ descriptor.setId("https://acplt.test/Test_AssetAdministrationShell");
+ return descriptor;
+ }
+
+ private static InputStream getIsFromClasspath(String fileName) throws IOException {
+ return new ClassPathResource(fileName).getInputStream();
+ }
+
+ private static void assertRepositoriesAreEmpty() {
+ assertTrue(aasRepository.getAllAas(PaginationInfo.NO_LIMIT).getResult().isEmpty());
+ assertTrue(smRepository.getAllSubmodels(PaginationInfo.NO_LIMIT).getResult().isEmpty());
+ }
+
+}
diff --git a/basyx.aasenvironment/basyx.aasenvironment.component/src/test/resources/application-reginteg.properties b/basyx.aasenvironment/basyx.aasenvironment.component/src/test/resources/application-reginteg.properties
new file mode 100644
index 000000000..ce166b3ec
--- /dev/null
+++ b/basyx.aasenvironment/basyx.aasenvironment.component/src/test/resources/application-reginteg.properties
@@ -0,0 +1,7 @@
+basyx.aasrepository.feature.registryintegration=http://localhost:8050
+basyx.submodelrepository.feature.registryintegration=http://localhost:8060
+
+basyx.externalurl=http://localhost:8080
+
+# Override for empty environment
+basyx.environment=
\ No newline at end of file
diff --git a/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/factory/AasDescriptorFactory.java b/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/factory/AasDescriptorFactory.java
index c1091086e..1fe0709bb 100644
--- a/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/factory/AasDescriptorFactory.java
+++ b/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/factory/AasDescriptorFactory.java
@@ -40,6 +40,7 @@
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.Endpoint;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.ProtocolInformation;
import org.eclipse.digitaltwin.basyx.aasregistry.main.client.mapper.AttributeMapper;
+import org.eclipse.digitaltwin.basyx.core.RepositoryUrlHelper;
import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier;
/**
@@ -52,15 +53,12 @@ public class AasDescriptorFactory {
private static final String AAS_INTERFACE = "AAS-3.0";
private static final String AAS_REPOSITORY_PATH = "shells";
- private AssetAdministrationShell shell;
- private List aasRepositoryURLs;
+ private final List aasRepositoryURLs;
+ private static AttributeMapper attributeMapper;
- private AttributeMapper attributeMapper;
-
- public AasDescriptorFactory(AssetAdministrationShell shell, List aasRepositoryBaseURLs, AttributeMapper attributeMapper) {
- this.shell = shell;
+ public AasDescriptorFactory(List aasRepositoryBaseURLs, AttributeMapper attributeMapper) {
this.aasRepositoryURLs = createAasRepositoryUrls(aasRepositoryBaseURLs);
- this.attributeMapper = attributeMapper;
+ AasDescriptorFactory.attributeMapper = attributeMapper;
}
/**
@@ -68,7 +66,7 @@ public AasDescriptorFactory(AssetAdministrationShell shell, List aasRepo
*
* @return the created AssetAdministrationShellDescriptor
*/
- public AssetAdministrationShellDescriptor create() {
+ public AssetAdministrationShellDescriptor create(AssetAdministrationShell shell) {
AssetAdministrationShellDescriptor descriptor = new AssetAdministrationShellDescriptor();
@@ -76,7 +74,7 @@ public AssetAdministrationShellDescriptor create() {
setIdShort(shell.getIdShort(), descriptor);
- setEndpointItem(shell.getId(), descriptor);
+ setEndpointItem(shell.getId(), descriptor, aasRepositoryURLs);
setDescription(shell.getDescription(), descriptor);
@@ -95,12 +93,7 @@ public AssetAdministrationShellDescriptor create() {
return descriptor;
}
- public AssetAdministrationShellDescriptor create(AssetAdministrationShell shell) {
- this.shell = shell;
- return create();
- }
-
- private void setDescription(List descriptions, AssetAdministrationShellDescriptor descriptor) {
+ private static void setDescription(List descriptions, AssetAdministrationShellDescriptor descriptor) {
if (descriptions == null || descriptions.isEmpty())
return;
@@ -108,7 +101,7 @@ private void setDescription(List descriptions, AssetAdminist
descriptor.setDescription(attributeMapper.mapDescription(descriptions));
}
- private void setDisplayName(List displayNames, AssetAdministrationShellDescriptor descriptor) {
+ private static void setDisplayName(List displayNames, AssetAdministrationShellDescriptor descriptor) {
if (displayNames == null || displayNames.isEmpty())
return;
@@ -116,7 +109,7 @@ private void setDisplayName(List displayNames, AssetAdminist
descriptor.setDisplayName(attributeMapper.mapDisplayName(displayNames));
}
- private void setExtensions(List extensions, AssetAdministrationShellDescriptor descriptor) {
+ private static void setExtensions(List extensions, AssetAdministrationShellDescriptor descriptor) {
if (extensions == null || extensions.isEmpty())
return;
@@ -124,7 +117,7 @@ private void setExtensions(List extensions, AssetAdministrationShellD
descriptor.setExtensions(attributeMapper.mapExtensions(extensions));
}
- private void setAdministration(AdministrativeInformation administration, AssetAdministrationShellDescriptor descriptor) {
+ private static void setAdministration(AdministrativeInformation administration, AssetAdministrationShellDescriptor descriptor) {
if (administration == null)
return;
@@ -132,7 +125,7 @@ private void setAdministration(AdministrativeInformation administration, AssetAd
descriptor.setAdministration(attributeMapper.mapAdministration(administration));
}
- private void setAssetKind(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
+ private static void setAssetKind(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
if (assetInformation == null || assetInformation.getAssetKind() == null)
return;
@@ -140,7 +133,7 @@ private void setAssetKind(AssetInformation assetInformation, AssetAdministration
descriptor.setAssetKind(attributeMapper.mapAssetKind(assetInformation.getAssetKind()));
}
- private void setAssetType(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
+ private static void setAssetType(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
if (assetInformation == null || assetInformation.getAssetType() == null)
return;
@@ -148,7 +141,7 @@ private void setAssetType(AssetInformation assetInformation, AssetAdministration
descriptor.setAssetType(assetInformation.getAssetType());
}
- private void setGlobalAssetId(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
+ private static void setGlobalAssetId(AssetInformation assetInformation, AssetAdministrationShellDescriptor descriptor) {
if (assetInformation == null || assetInformation.getGlobalAssetId() == null)
return;
@@ -156,7 +149,7 @@ private void setGlobalAssetId(AssetInformation assetInformation, AssetAdministra
descriptor.setGlobalAssetId(assetInformation.getGlobalAssetId());
}
- private void setEndpointItem(String shellId, AssetAdministrationShellDescriptor descriptor) {
+ private static void setEndpointItem(String shellId, AssetAdministrationShellDescriptor descriptor, List aasRepositoryURLs) {
for (String eachUrl : aasRepositoryURLs) {
Endpoint endpoint = new Endpoint();
endpoint.setInterface(AAS_INTERFACE);
@@ -167,7 +160,7 @@ private void setEndpointItem(String shellId, AssetAdministrationShellDescriptor
}
}
- private ProtocolInformation createProtocolInformation(String shellId, String url) {
+ private static ProtocolInformation createProtocolInformation(String shellId, String url) {
String href = String.format("%s/%s", url, Base64UrlEncodedIdentifier.encodeIdentifier(shellId));
ProtocolInformation protocolInformation = new ProtocolInformation();
@@ -177,15 +170,15 @@ private ProtocolInformation createProtocolInformation(String shellId, String url
return protocolInformation;
}
- private void setIdShort(String idShort, AssetAdministrationShellDescriptor descriptor) {
+ private static void setIdShort(String idShort, AssetAdministrationShellDescriptor descriptor) {
descriptor.setIdShort(idShort);
}
- private void setId(String shellId, AssetAdministrationShellDescriptor descriptor) {
+ private static void setId(String shellId, AssetAdministrationShellDescriptor descriptor) {
descriptor.setId(shellId);
}
- private String getProtocol(String endpoint) {
+ private static String getProtocol(String endpoint) {
try {
return new URL(endpoint).getProtocol();
} catch (MalformedURLException e) {
@@ -193,21 +186,11 @@ private String getProtocol(String endpoint) {
}
}
- private List createAasRepositoryUrls(List aasRepositoryBaseURLs) {
+ private static List createAasRepositoryUrls(List aasRepositoryBaseURLs) {
List toReturn = new ArrayList<>(aasRepositoryBaseURLs.size());
for (String eachUrl : aasRepositoryBaseURLs) {
- toReturn.add(createAasRepositoryUrl(eachUrl));
+ toReturn.add(RepositoryUrlHelper.createRepositoryUrl(eachUrl, AAS_REPOSITORY_PATH));
}
return toReturn;
}
-
- private String createAasRepositoryUrl(String aasRepositoryBaseURL) {
-
- try {
- return new URL(new URL(aasRepositoryBaseURL), AAS_REPOSITORY_PATH).toString();
- } catch (MalformedURLException e) {
- throw new RuntimeException("The AAS Repository Base url is malformed.\n" + e.getMessage());
- }
- }
-
}
diff --git a/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/AttributeMapper.java b/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/AttributeMapper.java
index 2a9a46b7d..eb0a28140 100644
--- a/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/AttributeMapper.java
+++ b/basyx.aasregistry/basyx.aasregistry-client-native/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/AttributeMapper.java
@@ -134,8 +134,16 @@ public AdministrativeInformation mapAdministration(org.eclipse.digitaltwin.aas4j
* @return the mapped assetKind
*/
public AssetKind mapAssetKind(org.eclipse.digitaltwin.aas4j.v3.model.AssetKind assetKind) {
-
- return AssetKind.valueOf(AssetKind.class, assetKind.name());
+ switch (assetKind) {
+ case INSTANCE:
+ return AssetKind.INSTANCE;
+ case NOT_APPLICABLE:
+ return AssetKind.NOTAPPLICABLE;
+ case TYPE:
+ return AssetKind.TYPE;
+ default:
+ throw new IllegalArgumentException("Unknown AssetKind: " + assetKind);
+ }
}
}
diff --git a/basyx.aasregistry/basyx.aasregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/DummyAasDescriptorFactory.java b/basyx.aasregistry/basyx.aasregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/DummyAasDescriptorFactory.java
index 7441ce29c..ef1f44e2e 100644
--- a/basyx.aasregistry/basyx.aasregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/DummyAasDescriptorFactory.java
+++ b/basyx.aasregistry/basyx.aasregistry-client-native/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/main/client/mapper/DummyAasDescriptorFactory.java
@@ -27,11 +27,15 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AdministrativeInformation;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetAdministrationShellDescriptor;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetKind;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.Endpoint;
import org.eclipse.digitaltwin.basyx.aasregistry.client.model.ProtocolInformation;
+import org.eclipse.digitaltwin.basyx.core.RepositoryUrlHelper;
import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier;
/**
@@ -43,7 +47,7 @@
public class DummyAasDescriptorFactory {
private static final String AAS_REPOSITORY_PATH = "/shells";
- public static AssetAdministrationShellDescriptor createDummyDescriptor(String aasId, String idShort, String globalAssetId, String... aasRepoBaseUrls) {
+ public static AssetAdministrationShellDescriptor createDummyDescriptor(String aasId, String idShort, String globalAssetId, AdministrativeInformation administrativeInformation, List endpoints) {
AssetAdministrationShellDescriptor descriptor = new AssetAdministrationShellDescriptor();
@@ -51,23 +55,46 @@ public static AssetAdministrationShellDescriptor createDummyDescriptor(String aa
descriptor.setIdShort(idShort);
descriptor.setAssetKind(AssetKind.INSTANCE);
descriptor.setGlobalAssetId(globalAssetId);
+ descriptor.setEndpoints(endpoints);
+ descriptor.setAdministration(administrativeInformation);
+
+ return descriptor;
+ }
+
+ public static AssetAdministrationShellDescriptor createDummyDescriptor(String aasId, String idShort, String globalAssetId, AdministrativeInformation administrativeInformation, String... aasRepoBaseUrls) {
+ LinkedList endpoints = new LinkedList<>();
+
for (String eachUrl : aasRepoBaseUrls) {
- descriptor.addEndpointsItem(createEndpointItem(aasId, eachUrl));
+ endpoints.add(createEndpoint(aasId, eachUrl, "AAS-3.0"));
}
- return descriptor;
+
+ return createDummyDescriptor(aasId, idShort, globalAssetId, administrativeInformation, endpoints);
+ }
+
+ public static AdministrativeInformation buildAdministrationInformation(String version, String revision, String templateId) {
+ AdministrativeInformation administrativeInformation = new AdministrativeInformation();
+ administrativeInformation.setVersion(version);
+ administrativeInformation.setRevision(revision);
+ administrativeInformation.setTemplateId(templateId);
+ return administrativeInformation;
}
- private static Endpoint createEndpointItem(String aasId, String aasRepoBaseUrl) {
+ public static Endpoint createEndpoint(String endpointUrl, String endpointInterface) {
Endpoint endpoint = new Endpoint();
- endpoint.setInterface("AAS-3.0");
- endpoint.setProtocolInformation(createProtocolInformation(aasId, aasRepoBaseUrl));
+ endpoint.setInterface(endpointInterface);
+ endpoint.setProtocolInformation(createProtocolInformation(endpointUrl));
return endpoint;
}
- private static ProtocolInformation createProtocolInformation(String aasId, String aasRepoBaseUrl) {
+ public static Endpoint createEndpoint(String aasId, String aasRepoBaseUrl, String endpointInterface) {
String href = createHref(aasId, aasRepoBaseUrl);
+ return createEndpoint(href, endpointInterface);
+ }
+
+
+ private static ProtocolInformation createProtocolInformation(String href) {
ProtocolInformation protocolInformation = new ProtocolInformation();
protocolInformation.setHref(href);
protocolInformation.endpointProtocol(getProtocol(href));
@@ -76,7 +103,7 @@ private static ProtocolInformation createProtocolInformation(String aasId, Strin
}
private static String createHref(String aasId, String aasRepoBaseUrl) {
- return String.format("%s/%s", createAasRepositoryUrl(aasRepoBaseUrl), Base64UrlEncodedIdentifier.encodeIdentifier(aasId));
+ return String.format("%s/%s", RepositoryUrlHelper.createRepositoryUrl(aasRepoBaseUrl, AAS_REPOSITORY_PATH), Base64UrlEncodedIdentifier.encodeIdentifier(aasId));
}
private static String getProtocol(String endpoint) {
@@ -87,13 +114,5 @@ private static String getProtocol(String endpoint) {
}
}
- private static String createAasRepositoryUrl(String aasRepositoryBaseURL) {
-
- try {
- return new URL(new URL(aasRepositoryBaseURL), AAS_REPOSITORY_PATH).toString();
- } catch (MalformedURLException e) {
- throw new RuntimeException("The AAS Repository Base url is malformed. " + e.getMessage());
- }
- }
}
diff --git a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/TestAuthorizedAasRegistry.java b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/TestAuthorizedAasRegistry.java
index 4d8eabf33..31d3f5b02 100644
--- a/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/TestAuthorizedAasRegistry.java
+++ b/basyx.aasregistry/basyx.aasregistry-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/regression/feature/authorization/TestAuthorizedAasRegistry.java
@@ -66,7 +66,6 @@
public class TestAuthorizedAasRegistry {
private static final String AAS_REGISTRY_PATH = "shell-descriptors";
- private static final PaginationInfo NO_LIMIT_PAGINATION_INFO = new PaginationInfo(0, null);
private static final String AAS_DESCRIPTOR_SIMPLE_2_JSON = "authorization/AasDescriptorSimple_2.json";
private static final String AAS_DESCRIPTOR_SIMPLE_1_JSON = "authorization/AasDescriptorSimple_1.json";
private static final String SPECIFIC_SHELL_ID_2 = "specificAasId-2";
@@ -108,7 +107,7 @@ public void initializeRepositories() throws FileNotFoundException, IOException {
public void reset() throws FileNotFoundException, IOException {
configureSecurityContext();
- Collection descriptors = storage.getAllAasDescriptors(NO_LIMIT_PAGINATION_INFO, new DescriptorFilter(AssetKind.TYPE, "TestAsset")).getResult();
+ Collection descriptors = storage.getAllAasDescriptors(PaginationInfo.NO_LIMIT, new DescriptorFilter(AssetKind.TYPE, "TestAsset")).getResult();
descriptors.forEach(descriptor -> storage.removeAasDescriptor(descriptor.getId()));
diff --git a/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/BaseInterfaceTest.java b/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/BaseInterfaceTest.java
index 0ade65fce..8e85e1d00 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/BaseInterfaceTest.java
+++ b/basyx.aasregistry/basyx.aasregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/BaseInterfaceTest.java
@@ -134,12 +134,12 @@ protected void verifyNoEventSent() {
}
protected List getAllAasDescriptors() {
- return storage.getAllAasDescriptors(new PaginationInfo(null, null), new DescriptorFilter(null, null)).getResult();
+ return storage.getAllAasDescriptors(PaginationInfo.NO_LIMIT, new DescriptorFilter(null, null)).getResult();
}
protected List getAllAasDescriptorsFiltered(AssetKind kind, String type) {
- return storage.getAllAasDescriptors(new PaginationInfo(null, null), new DescriptorFilter(kind, type)).getResult();
+ return storage.getAllAasDescriptors(PaginationInfo.NO_LIMIT, new DescriptorFilter(kind, type)).getResult();
}
protected CursorResult> getAllAasDescriptorsWithPagination(int limit, String cursor) {
@@ -147,7 +147,7 @@ protected CursorResult> getAllAasDescri
}
protected List getAllSubmodels(String id) {
- return storage.getAllSubmodels(id, new PaginationInfo(null, null)).getResult();
+ return storage.getAllSubmodels(id, PaginationInfo.NO_LIMIT).getResult();
}
protected CursorResult> getAllSubmodelsWithPagination(String aasId, int limit, String cursor) {
diff --git a/basyx.aasregistry/basyx.aasregistry-service-kafka-events/pom.xml b/basyx.aasregistry/basyx.aasregistry-service-kafka-events/pom.xml
index f475fccbd..6637743f0 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-kafka-events/pom.xml
+++ b/basyx.aasregistry/basyx.aasregistry-service-kafka-events/pom.xml
@@ -17,7 +17,7 @@
jar
- 2023.0.3
+ 2024.0.0
diff --git a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/pom.xml b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/pom.xml
index 0e56f534e..5bc78acca 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/pom.xml
+++ b/basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/pom.xml
@@ -16,7 +16,7 @@
jar
- 2023.0.3
+ 2024.0.0
${project.basedir}/${openapi.folder.name}
${openapi.folder}/${openapi.mongodb.file.name}
${openapi.folder}/temporary-extensions-result-file.yaml
diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/main/docker/Dockerfile b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/main/docker/Dockerfile
index 324d4fc49..5fd979847 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/main/docker/Dockerfile
+++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mem/src/main/docker/Dockerfile
@@ -1,8 +1,11 @@
-FROM amazoncorretto:17 as builder
-COPY maven/${project.build.finalName}.jar ./
-RUN java -Djarmode=layertools -jar ${project.build.finalName}.jar extract
+FROM eclipse-temurin:17 as builder
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
+ARG FINAL_NAME=${project.build.finalName}
+COPY maven/${FINAL_NAME}.jar ./
+RUN java -Djarmode=layertools -jar ${FINAL_NAME}.jar extract
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
RUN mkdir /workspace
WORKDIR /workspace
COPY --from=builder dependencies/ ./
diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/main/docker/Dockerfile b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/main/docker/Dockerfile
index b064339b7..1a5c74674 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/main/docker/Dockerfile
+++ b/basyx.aasregistry/basyx.aasregistry-service-release-kafka-mongodb/src/main/docker/Dockerfile
@@ -1,8 +1,13 @@
-FROM amazoncorretto:17 as builder
-COPY maven/${project.build.finalName}.jar ./
-RUN java -Djarmode=layertools -jar ${project.build.finalName}.jar extract
+FROM eclipse-temurin:17 as builder
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
+ARG FINAL_NAME=${project.build.finalName}
+COPY maven/${FINAL_NAME}.jar ./
+RUN java -Djarmode=layertools -jar ${FINAL_NAME}.jar extract
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
RUN mkdir /workspace
WORKDIR /workspace
COPY --from=builder dependencies/ ./
diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/main/docker/Dockerfile b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/main/docker/Dockerfile
index cba9fc132..ae897c5af 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/main/docker/Dockerfile
+++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mem/src/main/docker/Dockerfile
@@ -1,8 +1,13 @@
-FROM amazoncorretto:17 as builder
-COPY maven/${project.build.finalName}.jar ./
-RUN java -Djarmode=layertools -jar ${project.build.finalName}.jar extract
+FROM eclipse-temurin:17 as builder
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
+ARG FINAL_NAME=${project.build.finalName}
+COPY maven/${FINAL_NAME}.jar ./
+RUN java -Djarmode=layertools -jar ${FINAL_NAME}.jar extract
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
RUN mkdir /workspace
WORKDIR /workspace
COPY --from=builder dependencies/ ./
diff --git a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/main/docker/Dockerfile b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/main/docker/Dockerfile
index 807bbd7ca..2924f4e1f 100644
--- a/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/main/docker/Dockerfile
+++ b/basyx.aasregistry/basyx.aasregistry-service-release-log-mongodb/src/main/docker/Dockerfile
@@ -1,8 +1,13 @@
-FROM amazoncorretto:17 as builder
-COPY maven/${project.build.finalName}.jar ./
-RUN java -Djarmode=layertools -jar ${project.build.finalName}.jar extract
+FROM eclipse-temurin:17 as builder
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
+ARG FINAL_NAME=${project.build.finalName}
+COPY maven/${FINAL_NAME}.jar ./
+RUN java -Djarmode=layertools -jar ${FINAL_NAME}.jar extract
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
RUN mkdir /workspace
WORKDIR /workspace
COPY --from=builder dependencies/ ./
diff --git a/basyx.aasregistry/basyx.aasregistry-service/pom.xml b/basyx.aasregistry/basyx.aasregistry-service/pom.xml
index 5cc6e735b..f3f08e22f 100644
--- a/basyx.aasregistry/basyx.aasregistry-service/pom.xml
+++ b/basyx.aasregistry/basyx.aasregistry-service/pom.xml
@@ -16,7 +16,7 @@
jar
- 2023.0.3
+ 2024.0.0
${project.basedir}/${openapi.folder.name}
${openapi.folder}/${openapi.name}
diff --git a/basyx.aasregistry/open-api/patch-base-extensions.yaml b/basyx.aasregistry/open-api/patch-base-extensions.yaml
index 37082ee38..a6ca0bb6f 100644
--- a/basyx.aasregistry/open-api/patch-base-extensions.yaml
+++ b/basyx.aasregistry/open-api/patch-base-extensions.yaml
@@ -92,7 +92,7 @@
value: "^(0|[1-9][0-9]{0,3})$"
- op: replace
path: /components/schemas/AdministrativeInformation/allOf/1/properties/templateId/pattern
- value: "^([\\t\\n\\r \\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$"
+ value: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$"
## EmbeddedDataSpecification
- op: replace
path: /components/schemas/EmbeddedDataSpecification/properties/dataSpecificationContent/$ref
diff --git a/basyx.aasregistry/pom.xml b/basyx.aasregistry/pom.xml
index ce4c59025..0aca16197 100644
--- a/basyx.aasregistry/pom.xml
+++ b/basyx.aasregistry/pom.xml
@@ -16,18 +16,19 @@
1.18.20.0
+ 1.18.30
${java.version}
${java.version}
UTF-8
src/generated
- 3.0.42
+ 3.0.64
3.0.0
open-api
Plattform_i40-AssetAdministrationShellRegistryServiceSpecification-V3.0.1_SSP-001-resolved.yaml
Plattform_i40-Registry-and-Discovery.yaml
- 33.2.1-jre
+ 33.4.0-jre
3.9.0
3.0-alpha-2
0.9.14
@@ -75,6 +76,13 @@
org.projectlombok
lombok-maven-plugin
${lombok.maven-plugin.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.maven-plugin.lombok.version}
+
+
org.apache.maven.plugins
@@ -241,6 +249,13 @@
org.projectlombok
lombok-maven-plugin
+
+
+ org.projectlombok
+ lombok
+ ${lombok.maven-plugin.lombok.version}
+
+
generate-sources
diff --git a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/pom.xml b/basyx.aasrepository/basyx.aasrepository-backend-inmemory/pom.xml
index 3f6b3a9b8..45c8dc476 100644
--- a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/pom.xml
+++ b/basyx.aasrepository/basyx.aasrepository-backend-inmemory/pom.xml
@@ -22,6 +22,10 @@
org.eclipse.digitaltwin.basyx
basyx.aasrepository-backend
+
+ org.eclipse.digitaltwin.basyx
+ basyx.backend.inmemory.core
+
org.eclipse.digitaltwin.basyx
basyx.aasrepository-core
diff --git a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackend.java b/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackend.java
deleted file mode 100644
index aeb02fd99..000000000
--- a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackend.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * 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.backend.inmemory;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.lang.NonNull;
-
-/**
- * InMemory implementation for the AAS backend
- *
- * @author mateusmolina
- *
- */
-public class AasInMemoryBackend implements CrudRepository {
-
- private final ConcurrentMap inMemoryStore = new ConcurrentHashMap<>();
-
- @Override
- public @NonNull S save(@NonNull S entity) {
- inMemoryStore.put(entity.getId(), entity);
-
- return entity;
- }
-
- @Override
- public @NonNull Iterable saveAll(@NonNull Iterable entities) {
- entities.forEach(this::save);
-
- return entities;
- }
-
- @Override
- public @NonNull Optional findById(@NonNull String id) {
- return Optional.ofNullable(inMemoryStore.get(id));
- }
-
- @Override
- public boolean existsById(@NonNull String id) {
- return inMemoryStore.containsKey(id);
- }
-
- @Override
- public @NonNull Iterable findAll() {
- return inMemoryStore.values();
- }
-
- @Override
- public @NonNull Iterable findAllById(@NonNull Iterable ids) {
- return StreamSupport.stream(ids.spliterator(), false).map(inMemoryStore::get).filter(Objects::nonNull).collect(Collectors.toList());
- }
-
- @Override
- public long count() {
- return inMemoryStore.size();
- }
-
- @Override
- public void deleteById(@NonNull String id) {
- inMemoryStore.remove(id);
- }
-
- @Override
- public void delete(@NonNull AssetAdministrationShell entity) {
- inMemoryStore.remove(entity.getId());
- }
-
- @Override
- public void deleteAllById(@NonNull Iterable extends String> ids) {
- for (String id : ids)
- inMemoryStore.remove(id);
- }
-
- @Override
- public void deleteAll(@NonNull Iterable extends AssetAdministrationShell> entities) {
- for (AssetAdministrationShell entity : entities)
- inMemoryStore.remove(entity.getId());
- }
-
- @Override
- public void deleteAll() {
- inMemoryStore.clear();
- }
-
-
-}
-
diff --git a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackendProvider.java b/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackendProvider.java
index 0a8a4e788..44860711d 100644
--- a/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackendProvider.java
+++ b/basyx.aasrepository/basyx.aasrepository-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/backend/inmemory/AasInMemoryBackendProvider.java
@@ -27,6 +27,7 @@
import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
import org.eclipse.digitaltwin.basyx.aasrepository.backend.AasBackendProvider;
+import org.eclipse.digitaltwin.basyx.common.backend.inmemory.core.InMemoryCrudRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
@@ -35,7 +36,7 @@
*
* InMemory backend provider for the AAS
*
- * @author mateusmolina
+ * @author mateusmolina, danish
*/
@ConditionalOnExpression("'${basyx.backend}'.equals('InMemory')")
@Component
@@ -43,7 +44,7 @@ public class AasInMemoryBackendProvider implements AasBackendProvider {
@Override
public CrudRepository getCrudRepository() {
- return new AasInMemoryBackend();
+ return new InMemoryCrudRepository(AssetAdministrationShell::getId);
}
}
diff --git a/basyx.aasrepository/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java b/basyx.aasrepository/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java
index 0020d6ba3..6e50cf903 100644
--- a/basyx.aasrepository/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java
+++ b/basyx.aasrepository/basyx.aasrepository-core/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/AasRepositorySuite.java
@@ -51,7 +51,6 @@
*
*/
public abstract class AasRepositorySuite extends AasServiceSuite {
- private final PaginationInfo noLimitPaginationInfo = new PaginationInfo(0, "");
private static final String AAS_EMPTY_ID = " ";
private static final String AAS_NULL_ID = null;
@@ -132,7 +131,7 @@ public void deleteNonExistingAas() {
@Test(expected = ElementDoesNotExistException.class)
public void getSubmodelReferencesOfNonExistingAas() {
AasRepository aasRepo = getAasRepository();
- aasRepo.getSubmodelReferences("doesNotMatter", noLimitPaginationInfo).getResult();
+ aasRepo.getSubmodelReferences("doesNotMatter", PaginationInfo.NO_LIMIT).getResult();
}
@Test(expected = ElementDoesNotExistException.class)
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/authorization/TestAuthorizedAasRepository.java b/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/authorization/TestAuthorizedAasRepository.java
index a38bbe50c..9d08021b4 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/authorization/TestAuthorizedAasRepository.java
+++ b/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/authorization/TestAuthorizedAasRepository.java
@@ -150,6 +150,26 @@ public void getAasWithCorrectRoleAndPermission() throws IOException {
assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode());
}
+ @Test
+ public void getAasWithOnlyResourceRole() throws IOException {
+ DummyCredential dummyCredential = DummyCredentialStore.USER_CREDENTIAL;
+
+ String accessToken = tokenProvider.getAccessToken(dummyCredential.getUsername(), dummyCredential.getPassword());
+
+ CloseableHttpResponse retrievalResponse = getElementWithAuthorization(getSpecificAasAccessURL(SPECIFIC_SHELL_ID), accessToken);
+ assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode());
+ }
+
+ @Test
+ public void getAasWithBothRealmAndResourceRole() throws IOException {
+ DummyCredential dummyCredential = DummyCredentialStore.VISITOR_CREDENTIAL;
+
+ String accessToken = tokenProvider.getAccessToken(dummyCredential.getUsername(), dummyCredential.getPassword());
+
+ CloseableHttpResponse retrievalResponse = getElementWithAuthorization(getSpecificAasAccessURL(SPECIFIC_SHELL_ID), accessToken);
+ assertEquals(HttpStatus.OK.value(), retrievalResponse.getCode());
+ }
+
@Test
public void getAasWithCorrectRoleAndSpecificAasPermission() throws IOException {
DummyCredential dummyCredential = DummyCredentialStore.BASYX_READER_TWO_CREDENTIAL;
@@ -196,6 +216,16 @@ public void createAasWithCorrectRoleAndPermission() throws IOException {
deleteElementWithAuthorization(getSpecificAasAccessURL(SPECIFIC_SHELL_ID_2), getAccessToken(DummyCredentialStore.ADMIN_CREDENTIAL));
}
+ @Test
+ public void createAasWithBothRealmAndResourceRole() throws IOException {
+ String accessToken = getAccessToken(DummyCredentialStore.VISITOR_CREDENTIAL);
+
+ CloseableHttpResponse retrievalResponse = createAasOnRepositoryWithAuthorization(getAasJSONString(AAS_SIMPLE_2_JSON), accessToken);
+ assertEquals(HttpStatus.CREATED.value(), retrievalResponse.getCode());
+
+ deleteElementWithAuthorization(getSpecificAasAccessURL(SPECIFIC_SHELL_ID_2), getAccessToken(DummyCredentialStore.ADMIN_CREDENTIAL));
+ }
+
@Test
public void createAasWithInsufficientPermissionRole() throws IOException {
String accessToken = getAccessToken(DummyCredentialStore.BASYX_READER_CREDENTIAL);
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/resources/rbac_rules.json b/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/resources/rbac_rules.json
index 6bf880c8d..4dc81114d 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/resources/rbac_rules.json
+++ b/basyx.aasrepository/basyx.aasrepository-feature-authorization/src/test/resources/rbac_rules.json
@@ -15,6 +15,30 @@
"aasIds": "*"
}
},
+ {
+ "role": "basyx-user",
+ "action": "READ",
+ "targetInformation": {
+ "@type": "aas",
+ "aasIds": "specificAasId"
+ }
+ },
+ {
+ "role": "basyx-user",
+ "action": "CREATE",
+ "targetInformation": {
+ "@type": "aas",
+ "aasIds": "specificAasId-2"
+ }
+ },
+ {
+ "role": "visitor",
+ "action": "READ",
+ "targetInformation": {
+ "@type": "aas",
+ "aasIds": "specificAasId"
+ }
+ },
{
"role": "basyx-reader-two",
"action": "READ",
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md
index e632464eb..a3f13cc22 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md
+++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/Readme.md
@@ -5,4 +5,6 @@ This feature provides hierarchical MQTT eventing for a multitude of events:
| ----------- | ----------- | --- |
| AAS Created | aas-repository/\$repoId/shells/created| Created AAS JSON |
| AAS Updated | aas-repository/\$repoId/shells/updated| Updated AAS JSON|
-| AAS Deleted | aas-repository/\$repoId/shells/deleted| Deleted AAS JSON|
\ No newline at end of file
+| AAS Deleted | aas-repository/\$repoId/shells/deleted| Deleted AAS JSON|
+| Submodel Reference Created | aas-repository/\$repoId/shells/submodels/\$submodelId/created| Created AAS JSON |
+| Submodel Reference Deleted | aas-repository/\$repoId/shells/submodels/\$submodelId/deleted| Deleted AAS JSON|
\ No newline at end of file
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java
index ce2ed9418..48732da4c 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java
+++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepository.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * Copyright (C) 2024 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
@@ -107,12 +107,19 @@ public CursorResult> getSubmodelReferences(String aasId, Paginat
@Override
public void addSubmodelReference(String aasId, Reference submodelReference) {
+ AssetAdministrationShell shell = decorated.getAas(aasId);
decorated.addSubmodelReference(aasId, submodelReference);
+
+ String referenceId = submodelReference.getKeys().get(0).getValue();
+
+ submodelReferenceCreated(shell, getName(), referenceId);
}
@Override
public void removeSubmodelReference(String aasId, String submodelId) {
+ AssetAdministrationShell shell = decorated.getAas(aasId);
decorated.removeSubmodelReference(aasId, submodelId);
+ submodelReferenceDeleted(shell, getName(), submodelId);
}
@Override
@@ -136,6 +143,14 @@ private void aasUpdated(AssetAdministrationShell shell, String repoId) {
private void aasDeleted(AssetAdministrationShell shell, String repoId) {
sendMqttMessage(topicFactory.createDeleteAASTopic(repoId), serializePayload(shell));
}
+
+ private void submodelReferenceCreated(AssetAdministrationShell shell, String repoId, String referenceId) {
+ sendMqttMessage(topicFactory.createCreateAASSubmodelReferenceTopic(repoId, referenceId), serializePayload(shell));
+ }
+
+ private void submodelReferenceDeleted(AssetAdministrationShell shell, String repoId, String referenceId) {
+ sendMqttMessage(topicFactory.createDeleteAASSubmodelReferenceTopic(repoId, referenceId), serializePayload(shell));
+ }
private String serializePayload(AssetAdministrationShell shell) {
try {
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java
index f79ce8961..f714d69e6 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java
+++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/main/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/MqttAasRepositoryTopicFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * Copyright (C) 2024 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
@@ -37,6 +37,7 @@
public class MqttAasRepositoryTopicFactory extends AbstractMqttTopicFactory {
private static final String AASREPOSITORY = "aas-repository";
private static final String SHELLS = "shells";
+ private static final String SUBMODELS = "submodels";
private static final String CREATED = "created";
private static final String UPDATED = "updated";
private static final String DELETED = "deleted";
@@ -93,4 +94,40 @@ public String createDeleteAASTopic(String repoId) {
.add(DELETED)
.toString();
}
+
+ /**
+ * Creates the hierarchical topic for the submodel reference create event
+ *
+ * @param repoId
+ * @param referenceId
+ * @return
+ */
+ public String createCreateAASSubmodelReferenceTopic(String repoId, String referenceId) {
+ return new StringJoiner("/", "", "")
+ .add(AASREPOSITORY)
+ .add(repoId)
+ .add(SHELLS)
+ .add(SUBMODELS)
+ .add(referenceId)
+ .add(CREATED)
+ .toString();
+ }
+
+ /**
+ * Creates the hierarchical topic for the submodel reference delete event
+ *
+ * @param repoId
+ * @param referenceId
+ * @return
+ */
+ public String createDeleteAASSubmodelReferenceTopic(String repoId, String referenceId) {
+ return new StringJoiner("/", "", "")
+ .add(AASREPOSITORY)
+ .add(repoId)
+ .add(SHELLS)
+ .add(SUBMODELS)
+ .add(referenceId)
+ .add(DELETED)
+ .toString();
+ }
}
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java
index 785bd0e33..fd61cf76b 100644
--- a/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java
+++ b/basyx.aasrepository/basyx.aasrepository-feature-mqtt/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/mqtt/TestMqttV2AASAggregatorObserver.java
@@ -1,7 +1,5 @@
-package org.eclipse.digitaltwin.basyx.aasrepository.feature.mqtt;
-
/*******************************************************************************
- * Copyright (C) 2021 the Eclipse BaSyx Authors
+ * Copyright (C) 2024 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
@@ -24,10 +22,12 @@
*
* SPDX-License-Identifier: MIT
******************************************************************************/
+package org.eclipse.digitaltwin.basyx.aasrepository.feature.mqtt;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -94,7 +94,7 @@ public static void tearDownClass() {
public void createAasEvent() throws DeserializationException {
AssetAdministrationShell shell = createAasDummy("createAasEventId");
aasRepository.createAas(shell);
-
+
assertEquals(topicFactory.createCreateAASTopic(aasRepository.getName()), listener.lastTopic);
assertEquals(shell, deserializePayload(listener.lastPayload));
}
@@ -121,6 +121,29 @@ public void deleteAasEvent() throws DeserializationException {
assertEquals(topicFactory.createDeleteAASTopic(aasRepository.getName()), listener.lastTopic);
assertEquals(shell, deserializePayload(listener.lastPayload));
}
+
+ @Test
+ public void addSubmodelReferenceEvent() throws DeserializationException {
+ AssetAdministrationShell shell = createAasDummy("createAasSubmodelRefEventId");
+ aasRepository.createAas(shell);
+
+ Reference submodelReference = DummyAasFactory.createDummyReference(DummyAasFactory.DUMMY_SUBMODEL_ID);
+ aasRepository.addSubmodelReference(shell.getId(), submodelReference);
+
+ assertEquals(topicFactory.createCreateAASSubmodelReferenceTopic(aasRepository.getName(), DummyAasFactory.DUMMY_SUBMODEL_ID), listener.lastTopic);
+ assertEquals(shell, deserializePayload(listener.lastPayload));
+ }
+
+ @Test
+ public void removeSubmodelReferenceEvent() throws DeserializationException {
+ AssetAdministrationShell shell = createAasWithSubmodelReference("removeAasSubmodelRefEventId");
+ aasRepository.createAas(shell);
+
+ aasRepository.removeSubmodelReference(shell.getId(), DummyAasFactory.DUMMY_SUBMODEL_ID);
+
+ assertEquals(topicFactory.createDeleteAASSubmodelReferenceTopic(aasRepository.getName(), DummyAasFactory.DUMMY_SUBMODEL_ID), listener.lastTopic);
+ assertEquals(shell, deserializePayload(listener.lastPayload));
+ }
private AssetAdministrationShell deserializePayload(String payload) throws DeserializationException {
return new JsonDeserializer().read(payload, AssetAdministrationShell.class);
@@ -135,6 +158,16 @@ private AssetAdministrationShell createAasDummy(String aasId) {
return new DefaultAssetAdministrationShell.Builder().id(aasId)
.build();
}
+
+ private AssetAdministrationShell createAasWithSubmodelReference(String aasId) {
+ Reference submodelReference = DummyAasFactory.createDummyReference(DummyAasFactory.DUMMY_SUBMODEL_ID);
+
+ List submodelReferences = new ArrayList();
+ submodelReferences.add(submodelReference);
+
+ return new DefaultAssetAdministrationShell.Builder().id(aasId).submodels(submodelReferences)
+ .build();
+ }
private static AasRepository createMqttAasRepository(MqttClient client) {
AasRepositoryFactory repoFactory = new SimpleAasRepositoryFactory(new AasInMemoryBackendProvider(), new InMemoryAasServiceFactory(new InMemoryFileRepository()));
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 17d93879d..f5a8a238c 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
@@ -78,9 +78,19 @@ public AssetAdministrationShell getAas(String shellId) throws ElementDoesNotExis
@Override
public void createAas(AssetAdministrationShell shell) throws CollidingIdentifierException {
+ AssetAdministrationShellDescriptor descriptor = new AasDescriptorFactory(aasRepositoryRegistryLink.getAasRepositoryBaseURLs(), attributeMapper).create(shell);
+
decorated.createAas(shell);
- integrateAasWithRegistry(shell, aasRepositoryRegistryLink.getAasRepositoryBaseURLs());
+ boolean registrationSuccessful = false;
+
+ try {
+ registerAas(descriptor);
+ registrationSuccessful = true;
+ } finally {
+ if (!registrationSuccessful)
+ decorated.deleteAas(shell.getId());
+ }
}
@Override
@@ -125,17 +135,15 @@ public AssetInformation getAssetInformation(String shellId) throws ElementDoesNo
return decorated.getAssetInformation(shellId);
}
- private void integrateAasWithRegistry(AssetAdministrationShell shell, List aasRepositoryURLs) {
- AssetAdministrationShellDescriptor descriptor = new AasDescriptorFactory(shell, aasRepositoryURLs, attributeMapper).create();
-
+ private void registerAas(AssetAdministrationShellDescriptor descriptor) {
RegistryAndDiscoveryInterfaceApi registryApi = aasRepositoryRegistryLink.getRegistryApi();
try {
registryApi.postAssetAdministrationShellDescriptor(descriptor);
- logger.info("Shell '{}' has been automatically linked with the Registry", shell.getId());
+ logger.info("Shell '{}' has been automatically linked with the Registry", descriptor.getId());
} catch (ApiException e) {
- throw new RepositoryRegistryLinkException(shell.getId(), e);
+ throw new RepositoryRegistryLinkException(descriptor.getId(), e);
}
}
diff --git a/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkDescriptorGenerationTest.java b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkDescriptorGenerationTest.java
new file mode 100644
index 000000000..8b3739033
--- /dev/null
+++ b/basyx.aasrepository/basyx.aasrepository-feature-registry-integration/src/test/java/org/eclipse/digitaltwin/basyx/aasrepository/feature/registry/integration/AasRepositoryRegistryLinkDescriptorGenerationTest.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2024 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 static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShell;
+import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultAssetAdministrationShell;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.api.RegistryAndDiscoveryInterfaceApi;
+import org.eclipse.digitaltwin.basyx.aasregistry.client.model.AssetAdministrationShellDescriptor;
+import org.eclipse.digitaltwin.basyx.aasregistry.main.client.factory.AasDescriptorFactory;
+import org.eclipse.digitaltwin.basyx.aasregistry.main.client.mapper.AttributeMapper;
+import org.eclipse.digitaltwin.basyx.aasrepository.AasRepository;
+import org.eclipse.digitaltwin.basyx.aasrepository.backend.SimpleAasRepositoryFactory;
+import org.eclipse.digitaltwin.basyx.aasrepository.backend.inmemory.AasInMemoryBackendProvider;
+import org.eclipse.digitaltwin.basyx.aasservice.backend.InMemoryAasServiceFactory;
+import org.eclipse.digitaltwin.basyx.core.filerepository.InMemoryFileRepository;
+import org.eclipse.digitaltwin.basyx.http.Base64UrlEncodedIdentifier;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+/**
+ * Test suite for {@link RegistryIntegrationAasRepository} feature
+ */
+@RunWith(Parameterized.class)
+public class AasRepositoryRegistryLinkDescriptorGenerationTest {
+ private static final String DUMMY_IDSHORT = "ExampleMotor";
+ private static final String DUMMY_AAS_ID = "customIdentifier";
+
+ private static final String BASE_URL = "http://localhost:8081";
+
+ private RegistryIntegrationAasRepository registryIntegrationAasRepository;
+ private AasRepository mockedAasRepository;
+ private AasRepositoryRegistryLink mockedRegistryLink;
+ private AttributeMapper mockedAttributeMapper;
+ private RegistryAndDiscoveryInterfaceApi mockedRegistryApi;
+
+ @Before
+ public void setUp() {
+ mockedAasRepository = getAasRepository();
+ mockedRegistryLink = Mockito.mock(AasRepositoryRegistryLink.class);
+ mockedAttributeMapper = Mockito.mock(AttributeMapper.class);
+ mockedRegistryApi = Mockito.mock(RegistryAndDiscoveryInterfaceApi.class);
+
+ Mockito.when(mockedRegistryLink.getRegistryApi()).thenReturn(mockedRegistryApi);
+
+ registryIntegrationAasRepository = new RegistryIntegrationAasRepository(mockedAasRepository, mockedRegistryLink, mockedAttributeMapper);
+ }
+
+ @Parameterized.Parameter(0)
+ public String externalUrl;
+
+ @Parameterized.Parameter(1)
+ public String expectedUrl;
+
+ @Parameterized.Parameters
+ public static Collection
+
+ org.eclipse.digitaltwin.basyx
+ basyx.backend.inmemory.core
+
org.eclipse.digitaltwin.basyx
basyx.aasxfileserver-core
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryBackendProvider.java b/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryBackendProvider.java
index 68a050e98..b80b64198 100644
--- a/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryBackendProvider.java
+++ b/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryBackendProvider.java
@@ -27,6 +27,7 @@
import org.eclipse.digitaltwin.basyx.aasxfileserver.backend.AASXFileServerBackendProvider;
import org.eclipse.digitaltwin.basyx.aasxfileserver.model.Package;
+import org.eclipse.digitaltwin.basyx.common.backend.inmemory.core.InMemoryCrudRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
@@ -36,7 +37,7 @@
@Component
public class AASXFileServerInMemoryBackendProvider implements AASXFileServerBackendProvider {
- private AASXFileServerInMemoryCrudRepository repository = new AASXFileServerInMemoryCrudRepository();
+ private CrudRepository repository = new InMemoryCrudRepository(Package::getPackageId);
@Override
public CrudRepository getCrudRepository() {
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryCrudRepository.java b/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryCrudRepository.java
deleted file mode 100644
index f1c61802a..000000000
--- a/basyx.aasxfileserver/basyx.aasxfileserver-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/AASXFileServerInMemoryCrudRepository.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*******************************************************************************
-* Copyright (C) 2024 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.aasxfileserver;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-import org.eclipse.digitaltwin.basyx.aasxfileserver.model.Package;
-import org.springframework.data.repository.CrudRepository;
-import org.springframework.lang.NonNull;
-
-public class AASXFileServerInMemoryCrudRepository implements CrudRepository {
-
- private final ConcurrentMap packageMap = new ConcurrentHashMap<>();
-
- @Override
- public @NonNull S save(@NonNull S entity) {
- packageMap.put(entity.getPackageId(), entity);
-
- return entity;
- }
-
- @Override
- public @NonNull Iterable saveAll(@NonNull Iterable entities) {
- entities.forEach(this::save);
-
- return entities;
- }
-
- @Override
- public @NonNull Optional findById(@NonNull String id) {
- return Optional.ofNullable(packageMap.get(id));
- }
-
- @Override
- public boolean existsById(@NonNull String id) {
- return packageMap.containsKey(id);
- }
-
- @Override
- public @NonNull Iterable findAll() {
- return packageMap.values();
- }
-
- @Override
- public @NonNull Iterable findAllById(@NonNull Iterable ids) {
- List idList = StreamSupport.stream(ids.spliterator(), false).collect(Collectors.toList());
- return packageMap.entrySet().stream().filter(entry -> idList.contains(entry.getKey())).map(Entry::getValue).collect(Collectors.toList());
- }
-
- @Override
- public long count() {
- return packageMap.size();
- }
-
- @Override
- public void deleteById(@NonNull String id) {
- packageMap.remove(id);
- }
-
- @Override
- public void delete(@NonNull Package entity) {
- packageMap.remove(entity.getPackageId());
- }
-
- @Override
- public void deleteAllById(@NonNull Iterable extends String> ids) {
- List idList = StreamSupport.stream(ids.spliterator(), false).collect(Collectors.toList());
- packageMap.keySet().removeAll(idList);
- }
-
- @Override
- public void deleteAll(@NonNull Iterable extends Package> entities) {
- List idList = StreamSupport.stream(entities.spliterator(), false).map(Package::getPackageId).collect(Collectors.toList());
- packageMap.keySet().removeAll(idList);
- }
-
- @Override
- public void deleteAll() {
- packageMap.clear();
- }
-}
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-backend/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/backend/CrudAASXFileServer.java b/basyx.aasxfileserver/basyx.aasxfileserver-backend/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/backend/CrudAASXFileServer.java
index 599a28c7b..ce5211c52 100644
--- a/basyx.aasxfileserver/basyx.aasxfileserver-backend/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/backend/CrudAASXFileServer.java
+++ b/basyx.aasxfileserver/basyx.aasxfileserver-backend/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/backend/CrudAASXFileServer.java
@@ -25,7 +25,6 @@
package org.eclipse.digitaltwin.basyx.aasxfileserver.backend;
import java.io.InputStream;
-import java.util.Collection;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -33,7 +32,6 @@
import java.util.stream.StreamSupport;
import org.eclipse.digitaltwin.aas4j.v3.model.PackageDescription;
-import org.eclipse.digitaltwin.aas4j.v3.model.Submodel;
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultPackageDescription;
import org.eclipse.digitaltwin.basyx.aasxfileserver.AASXFileServer;
import org.eclipse.digitaltwin.basyx.aasxfileserver.model.Package;
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-core/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/core/AASXFileServerSuite.java b/basyx.aasxfileserver/basyx.aasxfileserver-core/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/core/AASXFileServerSuite.java
index e93d552a4..2d0fc77b0 100644
--- a/basyx.aasxfileserver/basyx.aasxfileserver-core/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/core/AASXFileServerSuite.java
+++ b/basyx.aasxfileserver/basyx.aasxfileserver-core/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/core/AASXFileServerSuite.java
@@ -53,7 +53,6 @@
public abstract class AASXFileServerSuite {
protected abstract AASXFileServer getAASXFileServer();
- private static final PaginationInfo NO_LIMIT_PAGINATION_INFO = new PaginationInfo(0,"");
@Test
public void getAllAASXPackageIds() {
@@ -65,7 +64,7 @@ public void getAllAASXPackageIds() {
List expectedPackageDescriptions = Arrays.asList(expectedDescription1, expectedDescription2);
- CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("",NO_LIMIT_PAGINATION_INFO);
+ CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("", PaginationInfo.NO_LIMIT);
List actualPackageDescriptions = pagedPackageDescriptions.getResult();
@@ -82,7 +81,7 @@ public void getAllAASXPackageIdsByShellId() {
List expectedPackageDescriptions = Arrays.asList(expectedDescription);
- CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("AAS_ID_3",NO_LIMIT_PAGINATION_INFO);
+ CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("AAS_ID_3", PaginationInfo.NO_LIMIT);
List actualPackageDescriptions = pagedPackageDescriptions.getResult();
assertGetAllAASXPackageIds(expectedPackageDescriptions, actualPackageDescriptions);
}
@@ -103,7 +102,7 @@ public void getAllAASXPackageIdsEmpty() {
String shellId = "testShellId";
AASXFileServer server = getAASXFileServer();
- CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds(shellId,NO_LIMIT_PAGINATION_INFO);
+ CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds(shellId, PaginationInfo.NO_LIMIT);
List packageDescriptions = pagedPackageDescriptions.getResult();
assertTrue(packageDescriptions.isEmpty());
}
@@ -128,7 +127,7 @@ public void updateExistingAASXByPackageId() throws IOException {
expectedPackageDescription.setPackageId("1");
expectedPackageDescription.setItems(DummyAASXFileServerFactory.SECOND_SHELL_IDS);
- CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("",NO_LIMIT_PAGINATION_INFO);
+ CursorResult> pagedPackageDescriptions = server.getAllAASXPackageIds("", PaginationInfo.NO_LIMIT);
List actualPackageDescription = pagedPackageDescriptions.getResult();
assertUpdatedAASXPackageId(expectedPackageDescription, actualPackageDescription, server);
}
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-http/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/AASXFileServerDescriptionConfiguration.java b/basyx.aasxfileserver/basyx.aasxfileserver-http/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/AASXFileServerDescriptionConfiguration.java
new file mode 100644
index 000000000..1d4c88c95
--- /dev/null
+++ b/basyx.aasxfileserver/basyx.aasxfileserver-http/src/main/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/AASXFileServerDescriptionConfiguration.java
@@ -0,0 +1,17 @@
+package org.eclipse.digitaltwin.basyx.aasxfileserver.http;
+
+import java.util.List;
+import java.util.TreeSet;
+
+import org.eclipse.digitaltwin.basyx.http.description.Profile;
+import org.eclipse.digitaltwin.basyx.http.description.ProfileDeclaration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AASXFileServerDescriptionConfiguration {
+ @Bean
+ public ProfileDeclaration aasxFileServerProfiles() {
+ return () -> new TreeSet<>(List.of(Profile.AASXFILESERVERSERVICESPECIFICATION_SSP_001));
+ }
+}
\ No newline at end of file
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver-http/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/TestAASXFileServerHTTP.java b/basyx.aasxfileserver/basyx.aasxfileserver-http/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/TestAASXFileServerHTTP.java
index 8fb388f8c..33de1702d 100644
--- a/basyx.aasxfileserver/basyx.aasxfileserver-http/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/TestAASXFileServerHTTP.java
+++ b/basyx.aasxfileserver/basyx.aasxfileserver-http/src/test/java/org/eclipse/digitaltwin/basyx/aasxfileserver/http/TestAASXFileServerHTTP.java
@@ -74,7 +74,7 @@ public void setup() {
@AfterMethod
public void cleanUp() {
try {
- this.aasxFileServer.getAllAASXPackageIds("", new PaginationInfo(0, "")).getResult().stream().forEach(p -> this.aasxFileServer.deleteAASXByPackageId(p.getPackageId()));
+ this.aasxFileServer.getAllAASXPackageIds("", PaginationInfo.NO_LIMIT).getResult().stream().forEach(p -> this.aasxFileServer.deleteAASXByPackageId(p.getPackageId()));
}
catch (Exception ignored) {
}
@@ -193,11 +193,11 @@ public void testGetAllPackages() throws Exception {
}
private boolean isPackageNotPresent(String aasId) {
- return this.aasxFileServer.getAllAASXPackageIds(aasId, new PaginationInfo(0, "")).getResult().size() == 0;
+ return this.aasxFileServer.getAllAASXPackageIds(aasId, PaginationInfo.NO_LIMIT).getResult().size() == 0;
}
private boolean isPackagePresentOneTime(String aasId) {
- return this.aasxFileServer.getAllAASXPackageIds(aasId, new PaginationInfo(0, "")).getResult().size() == 1;
+ return this.aasxFileServer.getAllAASXPackageIds(aasId, PaginationInfo.NO_LIMIT).getResult().size() == 1;
}
private PackageDescription createAASXPackageOnServer() throws Exception {
diff --git a/basyx.aasxfileserver/basyx.aasxfileserver.component/Dockerfile b/basyx.aasxfileserver/basyx.aasxfileserver.component/Dockerfile
index 1c3e9648d..99b045565 100644
--- a/basyx.aasxfileserver/basyx.aasxfileserver.component/Dockerfile
+++ b/basyx.aasxfileserver/basyx.aasxfileserver.component/Dockerfile
@@ -1,4 +1,6 @@
-FROM amazoncorretto:17
+FROM eclipse-temurin:17
+ARG HTTP_PROXY
+ARG HTTPS_PROXY
USER nobody
WORKDIR /application
ARG JAR_FILE=target/*-exec.jar
diff --git a/basyx.common/basyx.authorization.rules.rbac.backend.submodel/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rules/rbac/backend/submodel/SubmodelAuthorizationRbacStorage.java b/basyx.common/basyx.authorization.rules.rbac.backend.submodel/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rules/rbac/backend/submodel/SubmodelAuthorizationRbacStorage.java
index fed4005aa..2c8ea1652 100644
--- a/basyx.common/basyx.authorization.rules.rbac.backend.submodel/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rules/rbac/backend/submodel/SubmodelAuthorizationRbacStorage.java
+++ b/basyx.common/basyx.authorization.rules.rbac.backend.submodel/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rules/rbac/backend/submodel/SubmodelAuthorizationRbacStorage.java
@@ -91,7 +91,7 @@ public boolean exist(String key) {
@Override
public Map getRbacRules() {
- return smService.getSubmodelElements(new PaginationInfo(0, "")).getResult().stream().map(SubmodelElementCollection.class::cast).map(ruleAdapter::adapt).collect(Collectors.toMap(rbacRule -> createKey(rbacRule), rbacRule -> rbacRule));
+ return smService.getSubmodelElements(PaginationInfo.NO_LIMIT).getResult().stream().map(SubmodelElementCollection.class::cast).map(ruleAdapter::adapt).collect(Collectors.toMap(rbacRule -> createKey(rbacRule), rbacRule -> rbacRule));
}
private String createKey(RbacRule rbacRule) {
diff --git a/basyx.common/basyx.authorization/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rbac/KeycloakRoleProvider.java b/basyx.common/basyx.authorization/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rbac/KeycloakRoleProvider.java
index 5394a509f..6a0a8088c 100644
--- a/basyx.common/basyx.authorization/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rbac/KeycloakRoleProvider.java
+++ b/basyx.common/basyx.authorization/src/main/java/org/eclipse/digitaltwin/basyx/authorization/rbac/KeycloakRoleProvider.java
@@ -27,8 +27,10 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import org.eclipse.digitaltwin.basyx.authorization.CommonAuthorizationProperties;
import org.eclipse.digitaltwin.basyx.authorization.SubjectInformation;
@@ -48,6 +50,7 @@
public class KeycloakRoleProvider implements RoleProvider {
private static final String CLAIM_REALM_ACCESS = "realm_access";
+ private static final String CLAIM_RESOURCE_ACCESS = "resource_access";
private static final String CLAIM_ROLES = "roles";
@@ -65,21 +68,38 @@ public List getRoles() {
validateJwt(jwt);
- Map> realmAccess = jwt.getClaim(CLAIM_REALM_ACCESS);
+ Map> realmAccess = new HashMap<>();
+ Map>> resourceAccess = new HashMap<>();
+
+ if (jwt.hasClaim(CLAIM_REALM_ACCESS))
+ realmAccess = jwt.getClaim(CLAIM_REALM_ACCESS);
+
+ if (jwt.hasClaim(CLAIM_RESOURCE_ACCESS))
+ resourceAccess = jwt.getClaim(CLAIM_RESOURCE_ACCESS);
- return getRolesFromRealmAccess(realmAccess);
+ return extractRolesFromClaims(realmAccess, resourceAccess);
}
- private List getRolesFromRealmAccess(Map> realmAccess) {
- if (realmAccess == null || realmAccess.isEmpty())
+ private List extractRolesFromClaims(Map> realmAccess, Map>> resourceAccess) {
+ if (realmAccess.isEmpty() && resourceAccess.isEmpty())
return new ArrayList<>();
- Collection roles = realmAccess.get(CLAIM_ROLES);
-
- if (roles == null || roles.isEmpty())
- return new ArrayList<>();
-
- return new ArrayList<>(roles);
+ List roles = new ArrayList<>();
+
+ Collection realmRoles = realmAccess.get(CLAIM_ROLES);
+
+ if (realmRoles != null && !realmRoles.isEmpty())
+ roles.addAll(realmRoles);
+
+ for (Map.Entry>> entry : resourceAccess.entrySet()) {
+ Map> clientRolesMap = entry.getValue();
+ Collection clientRoles = clientRolesMap.get(CLAIM_ROLES);
+
+ if (clientRoles != null)
+ roles.addAll(clientRoles);
+ }
+
+ return roles.stream().distinct().collect(Collectors.toList());
}
private void validateJwt(Jwt jwt) {
@@ -96,4 +116,4 @@ private SubjectInformation