Skip to content

Commit 9ca510f

Browse files
FriedJannikaaronzi
andauthored
Finalizes AASX File Server (#334)
* Adds AASX File Server API Signed-off-by: FriedJannik <[email protected]> Co-authored-by: Aaron Zielstorff <[email protected]> * Adds MongoDB Backend for AASXFileServer Adapts HTTP Test Co-authored-by: Aaron Zielstorff <[email protected]> * Applies Refactoring Co-authored-by: Aaron Zielstorff <[email protected]> * Fixes test and adds dependency to pom * Adds missing dependency * Makes use of AAS4J Package Description * Adds missing dependency * Adapts Parsing in test * Code Review * Adds missing Test cases --------- Signed-off-by: FriedJannik <[email protected]> Co-authored-by: Aaron Zielstorff <[email protected]>
1 parent 1ac413e commit 9ca510f

File tree

29 files changed

+1372
-179
lines changed

29 files changed

+1372
-179
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>org.eclipse.digitaltwin.basyx</groupId>
8+
<artifactId>basyx.aasxfileserver</artifactId>
9+
<version>${revision}</version>
10+
</parent>
11+
12+
<artifactId>basyx.aasxfileserver-backend-mongodb</artifactId>
13+
<dependencies>
14+
<dependency>
15+
<groupId>org.eclipse.digitaltwin.basyx</groupId>
16+
<artifactId>basyx.aasxfileserver-core</artifactId>
17+
</dependency>
18+
<dependency>
19+
<groupId>org.eclipse.digitaltwin.basyx</groupId>
20+
<artifactId>basyx.aasxfileserver-core</artifactId>
21+
<classifier>tests</classifier>
22+
<scope>test</scope>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.springframework</groupId>
26+
<artifactId>spring-context</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-data-mongodb</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>commons-io</groupId>
38+
<artifactId>commons-io</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.eclipse.digitaltwin.basyx</groupId>
43+
<artifactId>basyx.aasxfileserver-backend</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.eclipse.digitaltwin.basyx</groupId>
47+
<artifactId>basyx.mongodbcore</artifactId>
48+
</dependency>
49+
</dependencies>
50+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*******************************************************************************
2+
* Copyright (C) 2024 the Eclipse BaSyx Authors
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining
5+
* a copy of this software and associated documentation files (the
6+
* "Software"), to deal in the Software without restriction, including
7+
* without limitation the rights to use, copy, modify, merge, publish,
8+
* distribute, sublicense, and/or sell copies of the Software, and to
9+
* permit persons to whom the Software is furnished to do so, subject to
10+
* the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
*
23+
* SPDX-License-Identifier: MIT
24+
******************************************************************************/
25+
26+
package org.eclipse.digitaltwin.basyx.aasxfileserver;
27+
28+
import org.eclipse.digitaltwin.basyx.aasxfileserver.backend.AASXFileServerBackendProvider;
29+
import org.eclipse.digitaltwin.basyx.aasxfileserver.model.Package;
30+
import org.springframework.beans.factory.annotation.Autowired;
31+
import org.springframework.beans.factory.annotation.Value;
32+
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
33+
import org.springframework.data.mongodb.core.MongoTemplate;
34+
import org.springframework.data.repository.CrudRepository;
35+
import org.springframework.stereotype.Component;
36+
37+
/**
38+
* Implementation of {@link AASXFileServerBackendProvider} for MongoDB Backend
39+
*
40+
* @author zielstor, fried
41+
*
42+
*/
43+
@ConditionalOnExpression("'${basyx.backend}'.equals('MongoDB')")
44+
@Component
45+
public class AASXFileServerMongoDBBackendProvider implements AASXFileServerBackendProvider {
46+
47+
private AASXFileServerMongoDBCrudRepository repository;
48+
49+
@Autowired
50+
public AASXFileServerMongoDBBackendProvider(MongoTemplate template, @Value("${basyx.aasx-fileserver.mongodb.collectionName:aasx-fileserver}") String collectionName, @Value("${basyx.aasx-fileserver.mongodb.collectionName:aasx-fileserver}") String gridFsBucketName) {
51+
this.repository = new AASXFileServerMongoDBCrudRepository(template,collectionName,gridFsBucketName);
52+
}
53+
54+
@Override
55+
public CrudRepository<Package, String> getCrudRepository() {
56+
return repository;
57+
}
58+
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*******************************************************************************
2+
* Copyright (C) 2024 the Eclipse BaSyx Authors
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining
5+
* a copy of this software and associated documentation files (the
6+
* "Software"), to deal in the Software without restriction, including
7+
* without limitation the rights to use, copy, modify, merge, publish,
8+
* distribute, sublicense, and/or sell copies of the Software, and to
9+
* permit persons to whom the Software is furnished to do so, subject to
10+
* the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
*
23+
* SPDX-License-Identifier: MIT
24+
******************************************************************************/
25+
26+
package org.eclipse.digitaltwin.basyx.aasxfileserver;
27+
import com.mongodb.client.*;
28+
import com.mongodb.client.gridfs.*;
29+
import com.mongodb.client.gridfs.model.*;
30+
import com.mongodb.client.model.Filters;
31+
import org.bson.Document;
32+
import org.bson.types.ObjectId;
33+
import org.eclipse.digitaltwin.aas4j.v3.model.PackageDescription;
34+
import org.eclipse.digitaltwin.basyx.aasxfileserver.model.Package;
35+
import org.eclipse.digitaltwin.basyx.aasxfileserver.model.PackagesBody;
36+
import org.springframework.beans.factory.annotation.Autowired;
37+
import org.springframework.data.mongodb.core.MongoTemplate;
38+
import org.springframework.data.mongodb.core.query.Criteria;
39+
import org.springframework.data.mongodb.core.query.Query;
40+
import org.springframework.data.repository.CrudRepository;
41+
42+
import java.io.ByteArrayInputStream;
43+
import java.io.InputStream;
44+
import java.util.ArrayList;
45+
import java.util.List;
46+
import java.util.Optional;
47+
import java.util.stream.Collectors;
48+
import java.util.stream.StreamSupport;
49+
50+
/**
51+
* Implementation of {@link CrudRepository} for MongoDB Backend
52+
*
53+
* @author zielstor, fried
54+
*/
55+
public class AASXFileServerMongoDBCrudRepository implements CrudRepository<Package, String> {
56+
57+
private final MongoTemplate mongoTemplate;
58+
private final String collectionName;
59+
private final GridFSBucket gridFSBucket;
60+
61+
public AASXFileServerMongoDBCrudRepository(MongoTemplate mongoTemplate, String collectionName, String gridfsBucketName) {
62+
this.mongoTemplate = mongoTemplate;
63+
this.collectionName = collectionName;
64+
this.gridFSBucket = GridFSBuckets.create(mongoTemplate.getDb(), gridfsBucketName);
65+
}
66+
67+
@Override
68+
public <S extends Package> S save(S entity) {
69+
if (entity.getPackagesBody().getFile() != null) {
70+
GridFSUploadOptions options = new GridFSUploadOptions();
71+
ObjectId fileId = gridFSBucket.uploadFromStream(entity.getPackagesBody().getFileName(), entity.getPackagesBody().getFile(), options);
72+
entity.getPackagesBody().setFile(null);
73+
entity.getPackagesBody().setPackageId(fileId.toString());
74+
}
75+
mongoTemplate.save(entity, collectionName);
76+
return entity;
77+
}
78+
79+
@Override
80+
public <S extends Package> Iterable<S> saveAll(Iterable<S> entities) {
81+
List<S> result = new ArrayList<>();
82+
for (S entity : entities) {
83+
result.add(save(entity));
84+
}
85+
return result;
86+
}
87+
88+
@Override
89+
public Optional<Package> findById(String id) {
90+
Package pkg = mongoTemplate.findById(id, Package.class, collectionName);
91+
if (pkg != null && pkg.getPackagesBody().getPackageId() != null) {
92+
InputStream file = gridFSBucket.openDownloadStream(new ObjectId(pkg.getPackagesBody().getPackageId()));
93+
pkg.getPackagesBody().setFile(file);
94+
}
95+
return Optional.ofNullable(pkg);
96+
}
97+
98+
@Override
99+
public boolean existsById(String id) {
100+
Query query = new Query(Criteria.where("packageId").is(id));
101+
return mongoTemplate.exists(query, Package.class, collectionName);
102+
}
103+
104+
@Override
105+
public Iterable<Package> findAll() {
106+
return mongoTemplate.findAll(Package.class, collectionName);
107+
}
108+
109+
@Override
110+
public Iterable<Package> findAllById(Iterable<String> ids) {
111+
Query query = new Query(Criteria.where("packageId").in(ids));
112+
return mongoTemplate.find(query, Package.class, collectionName);
113+
}
114+
115+
@Override
116+
public long count() {
117+
return mongoTemplate.count(new Query(), Package.class, collectionName);
118+
}
119+
120+
@Override
121+
public void deleteById(String id) {
122+
Package pkg = mongoTemplate.findAndRemove(new Query(Criteria.where("packageId").is(id)), Package.class, collectionName);
123+
if (pkg != null && pkg.getPackagesBody().getPackageId() != null) {
124+
gridFSBucket.delete(new ObjectId(pkg.getPackagesBody().getPackageId()));
125+
}
126+
}
127+
128+
@Override
129+
public void delete(Package entity) {
130+
deleteById(entity.getPackageId());
131+
}
132+
133+
@Override
134+
public void deleteAllById(Iterable<? extends String> ids) {
135+
for (String id : ids) {
136+
deleteById(id);
137+
}
138+
}
139+
140+
@Override
141+
public void deleteAll(Iterable<? extends Package> entities) {
142+
for (Package entity : entities) {
143+
deleteById(entity.getPackageId());
144+
}
145+
}
146+
147+
@Override
148+
public void deleteAll() {
149+
mongoTemplate.dropCollection(collectionName);
150+
gridFSBucket.drop();
151+
}
152+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*******************************************************************************
2+
* Copyright (C) 2024 the Eclipse BaSyx Authors
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining
5+
* a copy of this software and associated documentation files (the
6+
* "Software"), to deal in the Software without restriction, including
7+
* without limitation the rights to use, copy, modify, merge, publish,
8+
* distribute, sublicense, and/or sell copies of the Software, and to
9+
* permit persons to whom the Software is furnished to do so, subject to
10+
* the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
*
23+
* SPDX-License-Identifier: MIT
24+
******************************************************************************/
25+
26+
package org.eclipse.digitaltwin.basyx.aasxfileserver;
27+
28+
import com.mongodb.client.MongoClient;
29+
import com.mongodb.client.MongoClients;
30+
import org.eclipse.digitaltwin.basyx.aasxfileserver.backend.SimpleAASXFileServerFactory;
31+
import org.eclipse.digitaltwin.basyx.aasxfileserver.core.AASXFileServerSuite;
32+
import org.eclipse.digitaltwin.basyx.common.mongocore.MongoDBUtilities;
33+
import org.junit.Test;
34+
import org.springframework.data.mongodb.core.MongoTemplate;
35+
36+
import static org.junit.Assert.assertEquals;
37+
38+
/**
39+
* Tests the {@link AASXFileServerMongoDBBackendProvider}
40+
*
41+
* @author zielstor,fried
42+
*
43+
*/
44+
public class TestMongoDBAASXFileServer extends AASXFileServerSuite {
45+
46+
private static final String CONFIGURED_AASX_SERVER_NAME = "configured-aasx-server-name";
47+
private final String CONNECTION_URL = "mongodb://mongoAdmin:mongoPassword@localhost:27017";
48+
private final MongoClient CLIENT = MongoClients.create(CONNECTION_URL);
49+
private final MongoTemplate TEMPLATE = new MongoTemplate(CLIENT, "BaSyxTestDb");
50+
51+
@Override
52+
protected AASXFileServer getAASXFileServer() {
53+
MongoDBUtilities.clearCollection(TEMPLATE, "BaSyxAASXFileServerTest");
54+
MongoDBUtilities.clearCollection(TEMPLATE, "BaSyxAASXFileServerTestFileBucket.chunks");
55+
MongoDBUtilities.clearCollection(TEMPLATE, "BaSyxAASXFileServerTestFileBucket.files");
56+
return new SimpleAASXFileServerFactory(new AASXFileServerMongoDBBackendProvider(TEMPLATE,"BaSyxAASXFileServerTest","BaSyxAASXFileServerTestFileBucket")).create();
57+
}
58+
59+
@Test
60+
public void getConfiguredInMemoryAASXFileServer() {
61+
AASXFileServer server = new SimpleAASXFileServerFactory(new AASXFileServerMongoDBBackendProvider(TEMPLATE,"BaSyxAASXFileServerTest","BaSyxAASXFileServerTestFileBucket"),CONFIGURED_AASX_SERVER_NAME).create();
62+
63+
assertEquals(CONFIGURED_AASX_SERVER_NAME, server.getName());
64+
}
65+
66+
}

0 commit comments

Comments
 (0)