Skip to content

Commit fcbb80a

Browse files
Merge pull request #425 from eclipse-basyx/development
1.5.1 Release
2 parents b1bd2b6 + a8ae3d7 commit fcbb80a

File tree

21 files changed

+385
-93
lines changed

21 files changed

+385
-93
lines changed

.github/workflows/maven-publish-snapshot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
steps:
4040
- uses: actions/checkout@v4
4141
- name: Set up JDK 11
42-
uses: actions/setup-java@v3
42+
uses: actions/setup-java@v4
4343
with:
4444
java-version: '11'
4545
distribution: 'adopt'

.github/workflows/maven-run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
steps:
5252
- uses: actions/checkout@v4
5353
- name: Set up JDK 11
54-
uses: actions/setup-java@v3
54+
uses: actions/setup-java@v4
5555
with:
5656
java-version: '11'
5757
distribution: 'adopt'

basyx.components/basyx.components.docker/basyx.components.AASServer/Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM openjdk:11-slim-bullseye
1+
FROM amazoncorretto:17
22

33
# Install dependency for wait-for-it-env.sh & wget for health check
4-
RUN apt update && apt install -y jq && apt clean
5-
RUN apt install -y wget
4+
RUN yum -y update && yum -y install jq && yum -y clean all
5+
RUN yum -y install wget
66

77
# Copy built jar to image using the jar name specified in the pom.xml (JAR_FILE)
88
ARG JAR_FILE

basyx.components/basyx.components.docker/basyx.components.AASServer/pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>org.eclipse.basyx</groupId>
99
<artifactId>basyx.components.docker</artifactId>
10-
<version>1.5.0</version>
10+
<version>1.5.1</version>
1111
</parent>
1212

1313
<artifactId>basyx.components.AASServer</artifactId>
@@ -80,14 +80,14 @@
8080
<dependency>
8181
<groupId>org.mongodb</groupId>
8282
<artifactId>mongodb-driver-sync</artifactId>
83-
<version>4.10.2</version>
83+
<version>4.11.1</version>
8484
</dependency>
8585

8686
<!-- Use Spring Data MongoDB for db data management -->
8787
<dependency>
8888
<groupId>org.springframework.data</groupId>
8989
<artifactId>spring-data-mongodb</artifactId>
90-
<version>3.4.15</version>
90+
<version>3.4.18</version>
9191
</dependency>
9292

9393
<!-- Adds additional classes of the BaSys SDK for tests -->
@@ -121,14 +121,14 @@
121121
<dependency>
122122
<groupId>org.eclipse.basyx</groupId>
123123
<artifactId>basyx.components.registry</artifactId>
124-
<version>1.5.0</version>
124+
<version>1.5.1</version>
125125
<scope>test</scope>
126126
</dependency>
127127
<dependency>
128128
<groupId>com.tngtech.keycloakmock</groupId>
129129
<artifactId>mock</artifactId>
130130
<scope>test</scope>
131-
<version>0.15.2</version>
131+
<version>0.16.0</version>
132132
</dependency>
133133

134134
<dependency>

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/AASServerComponent.java

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -251,22 +251,12 @@ public void startComponent() {
251251

252252
loadAASServerFeaturesFromConfig();
253253
initializeAASServerFeatures();
254-
255254
BaSyxContext context = contextConfig.createBaSyxContext();
256-
context.addServletMapping("/*", createAggregatorServlet());
257-
addAASServerFeaturesToContext(context);
258-
259-
// An initial AAS has been loaded from the drive?
260-
if (aasBundles != null) {
261-
createBasyxResourceDirectoryIfNotExists();
262-
263-
addAasxFilesResourceServlet(context);
264255

265-
// 2. Fix the file paths according to the servlet configuration
266-
modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), getRootFilePathWithContext(contextConfig.getContextPath()));
256+
initializeAasBundles(context);
267257

268-
registerWhitelistedSubmodels();
269-
}
258+
context.addServletMapping("/*", createAggregatorServlet());
259+
addAASServerFeaturesToContext(context);
270260

271261
logger.info("Start the server");
272262
server = new BaSyxHTTPServer(context);
@@ -523,6 +513,24 @@ private void initializeAASServerFeatures() {
523513
}
524514
}
525515

516+
private void initializeAasBundles(BaSyxContext context) {
517+
loadAASBundles();
518+
519+
if (aasBundles == null)
520+
return;
521+
522+
logger.info("Initializing AAS Bundles");
523+
524+
createBasyxResourceDirectoryIfNotExists();
525+
526+
addAasxFilesResourceServlet(context);
527+
528+
// 2. Fix the file paths according to the servlet configuration
529+
modifyFilePaths(contextConfig.getHostname(), contextConfig.getPort(), getRootFilePathWithContext(contextConfig.getContextPath()));
530+
531+
registerWhitelistedSubmodels();
532+
}
533+
526534
private void cleanUpAASServerFeatures() {
527535
for (IAASServerFeature aasServerFeature : aasServerFeatureList) {
528536
aasServerFeature.cleanUp();
@@ -585,7 +593,6 @@ private Collection<AASBundle> getFlatAASBundles() {
585593

586594
private VABHTTPInterface<?> createAggregatorServlet() {
587595
aggregator = createAASAggregator();
588-
loadAASBundles();
589596

590597
if (aasBundles != null) {
591598
try (final var ignored = ElevatedCodeAuthentication.enterElevatedCodeAuthenticationArea()) {
@@ -844,5 +851,6 @@ private void createBasyxResourceDirectoryIfNotExists() {
844851

845852
directory.mkdir();
846853
}
854+
847855

848856
}

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/internal/StorageSubmodelAPI.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ public java.io.File getSubmodelElementFile(String idShortPath) {
205205
public void uploadSubmodelElementFile(String idShortPath, InputStream fileStream) {
206206
VABSubmodelAPI api = new VABSubmodelAPI(new VABLambdaProvider(getSubmodel()));
207207
ISubmodelElement element = api.getSubmodelElement(idShortPath);
208-
String fileName = storageApi.writeFile(idShortPath, getSubmodel().getIdentification().getId(), fileStream, element);
209-
updateSubmodelElement(idShortPath, fileName);
208+
storageApi.writeFile(idShortPath, getSubmodel().getIdentification().getId(), fileStream, element);
210209
}
211210

212211
}

basyx.components/basyx.components.docker/basyx.components.AASServer/src/main/java/org/eclipse/basyx/components/aas/mongodb/MongoDBSubmodelAggregator.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import org.eclipse.basyx.submodel.metamodel.map.Submodel;
4343
import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPI;
4444
import org.eclipse.basyx.submodel.restapi.api.ISubmodelAPIFactory;
45-
import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPIFactory;
4645
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
4746

4847
import com.mongodb.client.MongoClient;
@@ -159,12 +158,12 @@ public ISubmodel getSubmodelbyIdShort(String idShort) throws ResourceNotFoundExc
159158
@Override
160159
public ISubmodelAPI getSubmodelAPIById(IIdentifier identifier) throws ResourceNotFoundException {
161160
Submodel submodel = (Submodel) getSubmodel(identifier);
162-
return new VABSubmodelAPIFactory().create(submodel);
161+
return submodelApiFactory.create(submodel);
163162
}
164163

165164
@Override
166165
public ISubmodelAPI getSubmodelAPIByIdShort(String idShort) throws ResourceNotFoundException {
167166
Submodel submodel = (Submodel) getSubmodelbyIdShort(idShort);
168-
return new VABSubmodelAPIFactory().create(submodel);
167+
return submodelApiFactory.create(submodel);
169168
}
170169
}

basyx.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/AASXSuite.java

Lines changed: 103 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,13 @@
2525
package org.eclipse.basyx.regression.AASServer;
2626

2727
import static org.junit.Assert.assertEquals;
28+
import static org.junit.Assert.assertNotEquals;
2829
import static org.junit.Assert.assertTrue;
2930

31+
import java.io.File;
32+
import java.io.IOException;
33+
import java.net.URISyntaxException;
34+
import java.net.URL;
3035
import java.util.Collection;
3136
import java.util.Iterator;
3237
import java.util.Map;
@@ -36,6 +41,14 @@
3641
import javax.ws.rs.client.WebTarget;
3742
import javax.ws.rs.core.Response;
3843

44+
import org.apache.http.HttpEntity;
45+
import org.apache.http.client.methods.CloseableHttpResponse;
46+
import org.apache.http.client.methods.HttpPost;
47+
import org.apache.http.entity.ContentType;
48+
import org.apache.http.entity.mime.MultipartEntityBuilder;
49+
import org.apache.http.impl.client.CloseableHttpClient;
50+
import org.apache.http.impl.client.HttpClients;
51+
import org.eclipse.basyx.aas.aggregator.restapi.AASAggregatorProvider;
3952
import org.eclipse.basyx.aas.manager.ConnectedAssetAdministrationShellManager;
4053
import org.eclipse.basyx.aas.metamodel.connected.ConnectedAssetAdministrationShell;
4154
import org.eclipse.basyx.aas.metamodel.map.descriptor.AASDescriptor;
@@ -44,25 +57,28 @@
4457
import org.eclipse.basyx.aas.metamodel.map.descriptor.SubmodelDescriptor;
4558
import org.eclipse.basyx.aas.registration.api.IAASRegistry;
4659
import org.eclipse.basyx.aas.registration.memory.InMemoryRegistry;
60+
import org.eclipse.basyx.components.configuration.BaSyxContextConfiguration;
4761
import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
4862
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
4963
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
5064
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
5165
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.ConnectedSubmodelElementCollection;
5266
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
67+
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
5368
import org.eclipse.basyx.vab.protocol.api.IConnectorFactory;
5469
import org.eclipse.basyx.vab.protocol.http.connector.HTTPConnectorFactory;
5570
import org.glassfish.jersey.client.JerseyClientBuilder;
5671
import org.junit.Before;
5772
import org.junit.Test;
5873
import org.slf4j.Logger;
5974
import org.slf4j.LoggerFactory;
75+
import org.springframework.http.HttpStatus;
6076

6177
/**
6278
* Suite for testing that the XMLAAS servlet is set up correctly. The tests here
6379
* can be used by the servlet test itself and the integration test
6480
*
65-
* @author schnicke, espen
81+
* @author schnicke, espen, mateusmolina
6682
*
6783
*/
6884
public abstract class AASXSuite {
@@ -86,6 +102,7 @@ public abstract class AASXSuite {
86102
protected static final String fileShortIdPath = "file";
87103

88104
// Has to be individualized by each test inheriting from this suite
105+
// Default configuration is provided by buildEnpoints method
89106
protected static String aasEndpoint;
90107
protected static String smEndpoint;
91108
protected static String aasAEndpoint;
@@ -137,37 +154,26 @@ public void testGetSingleSubmodel() throws Exception {
137154

138155
@Test
139156
public void testGetSingleModule() throws Exception {
140-
final String FILE_ENDING = "basyx-temp/aasx0/files/aasx/Nameplate/marking_rcm.jpg";
141-
final String FILE_PATH = rootEndpoint + "basyx-temp/aasx0/files/aasx/Nameplate/marking_rcm.jpg";
142-
checkFile(FILE_PATH);
157+
final String FILE_ENDING = VABPathTools.buildPath(new String[] { "basyx-temp", "aasx0", "files", "aasx", "Nameplate", "marking_rcm.jpg" }, 0);
158+
checkFile(VABPathTools.concatenatePaths(rootEndpoint, FILE_ENDING));
143159

144160
// Get the submdoel nameplate
145161
ISubmodel nameplate = manager.retrieveSubmodel(aasId, smId);
146162
// Get the submodel element collection marking_rcm
147163
ConnectedSubmodelElementCollection marking_rcm = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_RCM");
148-
Collection<ISubmodelElement> values = marking_rcm.getValue();
149164

150-
// navigate to the File element
151-
Iterator<ISubmodelElement> iter = values.iterator();
152-
while (iter.hasNext()) {
153-
ISubmodelElement element = iter.next();
154-
if (element instanceof ConnectedFile) {
155-
ConnectedFile connectedFile = (ConnectedFile) element;
156-
// get value of the file element
165+
ConnectedFile fileSE = retrieveFileSEFromCollection(marking_rcm);
157166

158-
String fileurl = connectedFile.getValue();
159-
assertTrue(fileurl.endsWith(FILE_ENDING));
160-
}
161-
}
167+
assertTrue(fileSE.getValue().endsWith(FILE_ENDING));
162168
}
163-
169+
164170
@Test
165171
public void testCollidingFiles() throws Exception {
166-
final String FILE_ENDING_A = "basyx-temp/aasx1/files/aasx/files/text.txt";
167-
final String FILE_ENDING_B = "basyx-temp/aasx2/files/aasx/files/text.txt";
172+
final String FILE_ENDING_A = VABPathTools.buildPath(new String[] { "basyx-temp", "aasx1", "files", "aasx", "files", "text.txt" }, 0);
173+
final String FILE_ENDING_B = VABPathTools.buildPath(new String[] { "basyx-temp", "aasx2", "files", "aasx", "files", "text.txt" }, 0);
168174

169-
checkFile(rootEndpoint + FILE_ENDING_A);
170-
checkFile(rootEndpoint + FILE_ENDING_B);
175+
checkFile(VABPathTools.concatenatePaths(rootEndpoint, FILE_ENDING_A));
176+
checkFile(VABPathTools.concatenatePaths(rootEndpoint, FILE_ENDING_B));
171177

172178
ISubmodel smA = manager.retrieveSubmodel(aasAId, smAId);
173179
ISubmodel smB = manager.retrieveSubmodel(aasBId, smBId);
@@ -194,6 +200,63 @@ public void testAllFiles() throws Exception {
194200

195201
}
196202

203+
@Test
204+
public void fileValueIsCorrectlyUpdated_whenFileIsUpdated() throws Exception {
205+
final String UPLOAD_ENDPOINT = VABPathTools.concatenatePaths(smEndpoint, "submodelElements", "Marking_CRUUS", "File", "upload");
206+
207+
ISubmodel nameplate = manager.retrieveSubmodel(aasId, smId);
208+
ConnectedSubmodelElementCollection marking_cruus = (ConnectedSubmodelElementCollection) nameplate.getSubmodelElements().get("Marking_CRUUS");
209+
ConnectedFile fileSE = retrieveFileSEFromCollection(marking_cruus);
210+
211+
String fileEndpointBefore = fileSE.getValue();
212+
checkFile(fileEndpointBefore);
213+
214+
CloseableHttpResponse response = uploadDummyFileToSubmodelElement(UPLOAD_ENDPOINT, getFileFromResources("BaSyx.png"), ContentType.IMAGE_PNG);
215+
try {
216+
int statusCode = response.getStatusLine().getStatusCode();
217+
218+
assertEquals(HttpStatus.CREATED.value(), statusCode);
219+
220+
String fileEndpointAfter = fileSE.getValue();
221+
222+
assertNotEquals(fileEndpointBefore, fileEndpointAfter);
223+
checkFile(fileEndpointAfter);
224+
225+
} finally {
226+
response.close();
227+
}
228+
}
229+
230+
private ConnectedFile retrieveFileSEFromCollection(ConnectedSubmodelElementCollection marking_rcm) throws Exception {
231+
Collection<ISubmodelElement> values = marking_rcm.getValue();
232+
233+
Iterator<ISubmodelElement> iter = values.iterator();
234+
while (iter.hasNext()) {
235+
ISubmodelElement element = iter.next();
236+
if (element instanceof ConnectedFile) {
237+
return (ConnectedFile) element;
238+
}
239+
}
240+
throw new RuntimeException("No File SubmodelElement found in " + marking_rcm.getIdShort());
241+
}
242+
243+
protected static void buildEndpoints(BaSyxContextConfiguration contextConfig) {
244+
rootEndpoint = VABPathTools.stripSlashes(contextConfig.getUrl());
245+
246+
aasEndpoint = VABPathTools.concatenatePaths(rootEndpoint, AASAggregatorProvider.PREFIX, aasId.getEncodedURN(), "aas");
247+
smEndpoint = VABPathTools.concatenatePaths(aasEndpoint, "submodels", smIdShort, "submodel");
248+
249+
String encodedAasAId = VABPathTools.encodePathElement(aasAId.getId());
250+
aasAEndpoint = VABPathTools.concatenatePaths(rootEndpoint, AASAggregatorProvider.PREFIX, encodedAasAId, "aas");
251+
smAEndpoint = VABPathTools.concatenatePaths(aasAEndpoint, "submodels", smAIdShort, "submodel");
252+
253+
String encodedAasBId = VABPathTools.encodePathElement(aasBId.getId());
254+
aasBEndpoint = VABPathTools.concatenatePaths(rootEndpoint, AASAggregatorProvider.PREFIX, encodedAasBId, "aas");
255+
smBEndpoint = VABPathTools.concatenatePaths(aasBEndpoint, "submodels", smBIdShort, "submodel");
256+
257+
logger.info("AAS URL for servlet test: " + aasEndpoint);
258+
}
259+
197260
private void checkElementCollectionFiles(Collection<ISubmodelElement> elements) {
198261
for (ISubmodelElement element : elements) {
199262
if (element instanceof IFile) {
@@ -226,4 +289,23 @@ private void checkFile(String absolutePath) {
226289
private ConnectedAssetAdministrationShell getConnectedAssetAdministrationShell() throws Exception {
227290
return manager.retrieveAAS(aasId);
228291
}
292+
293+
private File getFileFromResources(String filename) throws IOException, URISyntaxException {
294+
URL resource = getClass().getClassLoader().getResource(filename);
295+
if (resource == null)
296+
throw new IllegalArgumentException("File not found!");
297+
298+
return new File(resource.toURI());
299+
300+
}
301+
302+
private CloseableHttpResponse uploadDummyFileToSubmodelElement(String endpoint, File file, ContentType contentType) throws IOException {
303+
CloseableHttpClient client = HttpClients.createDefault();
304+
305+
HttpEntity fileEntity = MultipartEntityBuilder.create().addBinaryBody("file", file, contentType, file.getName()).build();
306+
HttpPost postRequest = new HttpPost(endpoint);
307+
postRequest.setEntity(fileEntity);
308+
309+
return client.execute(postRequest);
310+
}
229311
}

basyx.components/basyx.components.docker/basyx.components.AASServer/src/test/java/org/eclipse/basyx/regression/AASServer/MqttV2AASServerSuite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public abstract class MqttV2AASServerSuite extends AASServerSuite {
6060
protected static AASServerComponent component;
6161
protected static Server mqttBroker;
6262
protected MqttTestListener listener;
63-
private static final String AAS_SERVER_ID = "aas-server";
63+
protected static final String AAS_SERVER_ID = "aas-server";
6464

6565
@Override
6666
protected String getURL() {

0 commit comments

Comments
 (0)