Skip to content

Commit 87d97dd

Browse files
authored
Make MongoDB collection name configurable for AAS and Submodel registries (#875)
- Introduced properties: - basyx.aasregistry.mongodb.collectionName (default: aasdescriptors) - basyx.submodelregistry.mongodb.collectionName (default: submodeldescriptors) - Removed @document annotations to avoid static collection binding - Preserved @id usage for MongoDB _id mapping refs #873
1 parent 06d072b commit 87d97dd

File tree

12 files changed

+86
-40
lines changed

12 files changed

+86
-40
lines changed

basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/open-api/patch-mongodb-annotations.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
---
2-
- op: add
3-
path: /components/schemas/AssetAdministrationShellDescriptor/x-class-extra-annotation
4-
value: '@org.springframework.data.mongodb.core.mapping.Document(collection = "aasdescriptors")'
52
- op: add
63
path: /components/schemas/AssetAdministrationShellDescriptor/allOf/1/properties/id/x-field-extra-annotation
74
value: '@org.springframework.data.annotation.Id'

basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/configuration/MongoDbConfiguration.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.AasRegistryStorageFeature;
3333
import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.CursorEncodingRegistryStorage;
3434
import org.eclipse.digitaltwin.basyx.aasregistry.service.storage.mongodb.MongoDbAasRegistryStorage;
35+
import org.springframework.beans.factory.annotation.Value;
3536
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3637
import org.springframework.context.annotation.Bean;
3738
import org.springframework.context.annotation.Configuration;
@@ -51,12 +52,15 @@
5152
@Log4j2
5253
public class MongoDbConfiguration {
5354

55+
@Value("${basyx.aasregistry.mongodb.collectionName:submodeldescriptors}")
56+
private String collectionName;
57+
5458
@Bean
5559
public AasRegistryStorage createStorage(MongoTemplate template, List<AasRegistryStorageFeature> features) {
5660
log.info("Creating mongodb storage");
5761
log.info("Creating mongodb indices");
5862
initializeIndices(template);
59-
AasRegistryStorage storage = new CursorEncodingRegistryStorage(new MongoDbAasRegistryStorage(template));
63+
AasRegistryStorage storage = new CursorEncodingRegistryStorage(new MongoDbAasRegistryStorage(template, collectionName));
6064
return applyFeatures(storage, features);
6165

6266
}
@@ -70,7 +74,7 @@ private AasRegistryStorage applyFeatures(AasRegistryStorage storage, List<AasReg
7074
}
7175

7276
private void initializeIndices(MongoTemplate template) {
73-
IndexOperations ops = template.indexOps(AssetAdministrationShellDescriptor.class);
77+
IndexOperations ops = template.indexOps(collectionName);
7478
initializeGetShellDescriptorsIndices(ops);
7579
initializeExtensionIndices(ops);
7680
}

basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/aasregistry/service/storage/mongodb/MongoDbAasRegistryStorage.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,18 @@ public class MongoDbAasRegistryStorage implements AasRegistryStorage {
8080
private static final String SUBMODEL_DESCRIPTORS_ID = "submodelDescriptors._id";
8181
private static final String ASSET_TYPE = "assetType";
8282
private static final String ASSET_KIND = "assetKind";
83-
83+
8484
private final MongoTemplate template;
8585

86+
private final String collectionName;
87+
8688
@Override
8789
public CursorResult<List<AssetAdministrationShellDescriptor>> getAllAasDescriptors(@NonNull PaginationInfo pRequest, @NonNull DescriptorFilter filter) {
8890
List<AggregationOperation> allAggregations = new LinkedList<>();
8991
applyFilter(filter, allAggregations);
9092
applySorting(allAggregations);
9193
applyPagination(pRequest, allAggregations);
92-
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(Aggregation.newAggregation(allAggregations), AssetAdministrationShellDescriptor.class, AssetAdministrationShellDescriptor.class);
94+
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, AssetAdministrationShellDescriptor.class);
9395
List<AssetAdministrationShellDescriptor> foundDescriptors = results.getMappedResults();
9496
String cursor = resolveCursor(pRequest, foundDescriptors, AssetAdministrationShellDescriptor::getId);
9597
return new CursorResult<>(cursor, foundDescriptors);
@@ -146,7 +148,7 @@ public Optional<Criteria> createFilterCriteria(DescriptorFilter filter) {
146148

147149
@Override
148150
public AssetAdministrationShellDescriptor getAasDescriptor(@NonNull String aasDescriptorId) throws AasDescriptorNotFoundException {
149-
AssetAdministrationShellDescriptor descriptor = template.findById(aasDescriptorId, AssetAdministrationShellDescriptor.class);
151+
AssetAdministrationShellDescriptor descriptor = template.findById(aasDescriptorId, AssetAdministrationShellDescriptor.class, collectionName);
150152
if (descriptor == null) {
151153
throw new AasDescriptorNotFoundException(aasDescriptorId);
152154
}
@@ -156,7 +158,7 @@ public AssetAdministrationShellDescriptor getAasDescriptor(@NonNull String aasDe
156158
@Override
157159
public void insertAasDescriptor(@Valid AssetAdministrationShellDescriptor descr) throws AasDescriptorAlreadyExistsException {
158160
try {
159-
template.insert(descr);
161+
template.insert(descr, collectionName);
160162
} catch (org.springframework.dao.DuplicateKeyException ex) {
161163
throw new AasDescriptorAlreadyExistsException(descr.getId());
162164
}
@@ -169,7 +171,7 @@ public void replaceAasDescriptor(@NonNull String aasDescriptorId, @NonNull Asset
169171
moveInTransaction(aasDescriptorId, descriptor);
170172
} else {
171173
Query query = Query.query(Criteria.where(ID).is(aasDescriptorId));
172-
AssetAdministrationShellDescriptor replaced = template.findAndReplace(query, descriptor);
174+
AssetAdministrationShellDescriptor replaced = template.findAndReplace(query, descriptor, collectionName);
173175
if (replaced == null) {
174176
throw new AasDescriptorNotFoundException(aasDescriptorId);
175177
}
@@ -180,10 +182,10 @@ private void moveInTransaction(@NonNull String aasDescriptorId, @NonNull AssetAd
180182
SessionScoped scoped = template.withSession(ClientSessionOptions.builder().build());
181183
boolean removed = scoped.execute(operations -> {
182184
Query query = Query.query(Criteria.where(ID).is(aasDescriptorId));
183-
if (operations.remove(query, AssetAdministrationShellDescriptor.class).getDeletedCount() == 0) {
185+
if (operations.remove(query, AssetAdministrationShellDescriptor.class, collectionName).getDeletedCount() == 0) {
184186
return false;
185187
}
186-
operations.save(descriptor);
188+
operations.save(descriptor, collectionName);
187189
return true;
188190
});
189191
if (!removed) {
@@ -194,14 +196,14 @@ private void moveInTransaction(@NonNull String aasDescriptorId, @NonNull AssetAd
194196
@Override
195197
public void removeAasDescriptor(@NonNull String aasDescriptorId) throws AasDescriptorNotFoundException {
196198
Query query = Query.query(Criteria.where(ID).is(aasDescriptorId));
197-
if (template.remove(query, AssetAdministrationShellDescriptor.class).getDeletedCount() == 0) {
199+
if (template.remove(query, AssetAdministrationShellDescriptor.class, collectionName).getDeletedCount() == 0) {
198200
throw new AasDescriptorNotFoundException(aasDescriptorId);
199201
}
200202
}
201203

202204
@Override
203205
public CursorResult<List<SubmodelDescriptor>> getAllSubmodels(@NonNull String aasDescriptorId, @NonNull PaginationInfo pRequest) throws AasDescriptorNotFoundException {
204-
if (!template.exists(Query.query(Criteria.where(ID).is(aasDescriptorId)), AssetAdministrationShellDescriptor.class)) {
206+
if (!template.exists(Query.query(Criteria.where(ID).is(aasDescriptorId)), collectionName)) {
205207
throw new AasDescriptorNotFoundException(aasDescriptorId);
206208
}
207209
List<AggregationOperation> allAggregations = new LinkedList<>();
@@ -210,7 +212,7 @@ public CursorResult<List<SubmodelDescriptor>> getAllSubmodels(@NonNull String aa
210212
allAggregations.add(Aggregation.replaceRoot(SUBMODEL_DESCRIPTORS));
211213
this.applySorting(allAggregations);
212214
this.applyPagination(pRequest, allAggregations);
213-
AggregationResults<SubmodelDescriptor> results = template.aggregate(Aggregation.newAggregation(allAggregations), AssetAdministrationShellDescriptor.class, SubmodelDescriptor.class);
215+
AggregationResults<SubmodelDescriptor> results = template.aggregate(Aggregation.newAggregation(allAggregations), collectionName, SubmodelDescriptor.class);
214216
List<SubmodelDescriptor> submodels = results.getMappedResults();
215217
String cursor = resolveCursor(pRequest, submodels, SubmodelDescriptor::getId);
216218
return new CursorResult<>(cursor, submodels);
@@ -222,7 +224,7 @@ public SubmodelDescriptor getSubmodel(@NonNull String aasDescriptorId, @NonNull
222224
all.add(Aggregation.match(Criteria.where(ID).is(aasDescriptorId)));
223225
ArrayOperators.Filter filter = ArrayOperators.arrayOf(SUBMODEL_DESCRIPTORS).filter().as(SUBMODEL_DESCRIPTORS).by(ComparisonOperators.valueOf(SUBMODEL_DESCRIPTORS_ID).equalToValue(submodelId));
224226
all.add(Aggregation.project().and(filter).as(SUBMODEL_DESCRIPTORS));
225-
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(Aggregation.newAggregation(all), AssetAdministrationShellDescriptor.class, AssetAdministrationShellDescriptor.class);
227+
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(Aggregation.newAggregation(all), collectionName, AssetAdministrationShellDescriptor.class);
226228
List<AssetAdministrationShellDescriptor> aasDescriptors = results.getMappedResults();
227229
if (aasDescriptors.isEmpty()) {
228230
throw new AasDescriptorNotFoundException(aasDescriptorId);
@@ -239,7 +241,7 @@ public void insertSubmodel(@NonNull String aasDescriptorId, @NonNull SubmodelDes
239241
Criteria criteria = Criteria.where(ID).is(aasDescriptorId).and(SUBMODEL_DESCRIPTORS_ID).ne(submodel.getId());
240242
Query query = Query.query(criteria);
241243
UpdateDefinition def = new Update().push(SUBMODEL_DESCRIPTORS, submodel);
242-
AssetAdministrationShellDescriptor descr = template.findAndModify(query, def, AssetAdministrationShellDescriptor.class);
244+
AssetAdministrationShellDescriptor descr = template.findAndModify(query, def, AssetAdministrationShellDescriptor.class, collectionName);
243245
assertInsertPerformed(descr, aasDescriptorId, submodel.getId());
244246
}
245247

@@ -248,7 +250,7 @@ public void replaceSubmodel(@NonNull String aasDescriptorId, @NonNull String sub
248250
Criteria criteria = Criteria.where(ID).is(aasDescriptorId).and(SUBMODEL_DESCRIPTORS).elemMatch(Criteria.where(ID).is(submodelId));
249251
Query query = Query.query(criteria);
250252
UpdateDefinition def = Update.update(MATCHING_SUBMODEL_DESCRIPTORS, submodel);
251-
AssetAdministrationShellDescriptor descr = template.findAndModify(query, def, AssetAdministrationShellDescriptor.class);
253+
AssetAdministrationShellDescriptor descr = template.findAndModify(query, def, AssetAdministrationShellDescriptor.class, collectionName);
252254
assertReplacePerformed(descr, aasDescriptorId, submodelId);
253255
}
254256

@@ -271,7 +273,7 @@ public void removeSubmodel(@NonNull String aasDescriptorId, @NonNull String subm
271273
AggregationExpression notEquals = ComparisonOperators.valueOf(SUBMODEL_DESCRIPTORS_ID).notEqualToValue(submodelId);
272274
AggregationExpression filterArray = ArrayOperators.arrayOf(SUBMODEL_DESCRIPTORS).filter().as(SUBMODEL_DESCRIPTORS).by(notEquals);
273275
AggregationUpdate update = AggregationUpdate.update().set(SUBMODEL_DESCRIPTORS).toValue(filterArray);
274-
AssetAdministrationShellDescriptor old = template.findAndModify(Query.query(Criteria.where(ID).is(aasDescriptorId)), update, AssetAdministrationShellDescriptor.class);
276+
AssetAdministrationShellDescriptor old = template.findAndModify(Query.query(Criteria.where(ID).is(aasDescriptorId)), update, AssetAdministrationShellDescriptor.class, collectionName);
275277
if (old == null) {
276278
throw new AasDescriptorNotFoundException(submodelId);
277279
}
@@ -298,7 +300,7 @@ private boolean containsSubmodel(AssetAdministrationShellDescriptor old, String
298300
public Set<String> clear() {
299301
Query query = Query.query(Criteria.where(ID).exists(true));
300302
query.fields().include(ID);
301-
List<AssetAdministrationShellDescriptor> list = template.findAllAndRemove(query, AssetAdministrationShellDescriptor.class);
303+
List<AssetAdministrationShellDescriptor> list = template.findAllAndRemove(query, AssetAdministrationShellDescriptor.class, collectionName);
302304
return list.stream().map(AssetAdministrationShellDescriptor::getId).collect(Collectors.toSet());
303305
}
304306

@@ -309,7 +311,7 @@ public ShellDescriptorSearchResponse searchAasDescriptors(@NonNull ShellDescript
309311
GroupedQueries grouped = ShellDescriptorSearchRequests.groupQueries(dQuery);
310312
Criteria mongoCriteria = qBuilder.buildCriteria(grouped);
311313

312-
long total = template.count(Query.query(mongoCriteria), AssetAdministrationShellDescriptor.class);
314+
long total = template.count(Query.query(mongoCriteria), AssetAdministrationShellDescriptor.class, collectionName);
313315

314316
List<AggregationOperation> aggregationOps = new LinkedList<>();
315317
MatchOperation matchOp = Aggregation.match(mongoCriteria);
@@ -319,7 +321,7 @@ public ShellDescriptorSearchResponse searchAasDescriptors(@NonNull ShellDescript
319321
qBuilder.withProjection(grouped.getQueriesInsideSubmodel(), aggregationOps);
320322

321323
Aggregation aggregation = Aggregation.newAggregation(aggregationOps);
322-
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(aggregation, AssetAdministrationShellDescriptor.class, AssetAdministrationShellDescriptor.class);
324+
AggregationResults<AssetAdministrationShellDescriptor> results = template.aggregate(aggregation, collectionName, AssetAdministrationShellDescriptor.class);
323325

324326
List<AssetAdministrationShellDescriptor> descriptors = results.getMappedResults();
325327
return new ShellDescriptorSearchResponse(total, descriptors);

basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/MongoDbAasRegistryStorageTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void whenGetByAasID_NotAllDocumentsScannedButIndexUsed() {
112112
}
113113

114114
private void testIndexFilter(AssetKind kind, String type) {
115-
MongoDbAasRegistryStorage storage = new MongoDbAasRegistryStorage(template);
115+
MongoDbAasRegistryStorage storage = new MongoDbAasRegistryStorage(template, "aasdescriptors");
116116
Optional<Criteria> criteriaOpt = storage.createFilterCriteria(new DescriptorFilter(kind, type));
117117
assertThat(criteriaOpt).isNotEmpty();
118118
Criteria criteria = criteriaOpt.get();

basyx.aasregistry/basyx.aasregistry-service-mongodb-storage/src/test/java/org/eclipse/digitaltwin/basyx/aasregistry/service/tests/TestConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class TestConfiguration extends AbstractMongoClientConfiguration {
4141

4242
@Bean
4343
public AasRegistryStorage storage(MongoTemplate template) {
44-
return new CursorEncodingRegistryStorage(new MongoDbAasRegistryStorage(template));
44+
return new CursorEncodingRegistryStorage(new MongoDbAasRegistryStorage(template, "aasdescriptors"));
4545
}
4646

4747
@Bean

basyx.aasregistry/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,24 @@
116116
</plugin>
117117
</plugins>
118118
</pluginManagement>
119+
120+
<plugins>
121+
<plugin>
122+
<groupId>org.apache.maven.plugins</groupId>
123+
<artifactId>maven-compiler-plugin</artifactId>
124+
<configuration>
125+
<source>${java.version}</source>
126+
<target>${java.version}</target>
127+
<annotationProcessorPaths>
128+
<path>
129+
<groupId>org.projectlombok</groupId>
130+
<artifactId>lombok</artifactId>
131+
<version>${lombok.maven-plugin.lombok.version}</version>
132+
</path>
133+
</annotationProcessorPaths>
134+
</configuration>
135+
</plugin>
136+
</plugins>
119137
</build>
120138
<dependencyManagement>
121139
<dependencies>

basyx.submodelregistry/basyx.submodelregistry-service-basetests/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<groupId>org.eclipse.digitaltwin.basyx</groupId>
8181
<artifactId>basyx.authorization</artifactId>
8282
<classifier>tests</classifier>
83+
<scope>compile</scope>
8384
</dependency>
8485
<dependency>
8586
<groupId>org.eclipse.digitaltwin.basyx</groupId>

basyx.submodelregistry/basyx.submodelregistry-service-basetests/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/tests/integration/AuthorizedSubmodelRegistryTestSuite.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.springframework.boot.test.context.SpringBootTest;
4040
import org.springframework.security.core.context.SecurityContextHolder;
4141
import org.springframework.http.HttpStatus;
42+
4243
import org.eclipse.digitaltwin.basyx.authorization.AccessTokenProvider;
4344
import org.eclipse.digitaltwin.basyx.authorization.DummyCredential;
4445
import org.eclipse.digitaltwin.basyx.authorization.DummyCredentialStore;
@@ -494,4 +495,4 @@ private AccessTokenProvider getAccessTokenProvider() {
494495
return new AccessTokenProvider(authenticaltionServerTokenEndpoint, clientId);
495496
}
496497

497-
}
498+
}

basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/open-api/patch-mongodb-annotations.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
- op: add
2-
path: /components/schemas/SubmodelDescriptor/x-class-extra-annotation
3-
value: '@org.springframework.data.mongodb.core.mapping.Document(collection = "submodeldescriptors")'
41
- op: add
52
path: /components/schemas/SubmodelDescriptor/allOf/1/properties/id/x-field-extra-annotation
63
value: '@org.springframework.data.annotation.Id'

basyx.submodelregistry/basyx.submodelregistry-service-mongodb-storage/src/main/java/org/eclipse/digitaltwin/basyx/submodelregistry/service/configuration/MongoDbConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.eclipse.digitaltwin.basyx.submodelregistry.service.storage.SubmodelRegistryStorage;
3030
import org.eclipse.digitaltwin.basyx.submodelregistry.service.storage.SubmodelRegistryStorageFeature;
3131
import org.eclipse.digitaltwin.basyx.submodelregistry.service.storage.mongodb.MongoDbSubmodelRegistryStorage;
32+
import org.springframework.beans.factory.annotation.Value;
3233
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3334
import org.springframework.context.annotation.Bean;
3435
import org.springframework.context.annotation.Configuration;
@@ -45,11 +46,15 @@
4546
@Log4j2
4647
public class MongoDbConfiguration {
4748

49+
50+
@Value("${basyx.submodelregistry.mongodb.collectionName:submodeldescriptors}")
51+
public String collectionName;
52+
4853
@Bean
4954
public SubmodelRegistryStorage createSubmodelRegistryStorage(MongoTemplate template, List<SubmodelRegistryStorageFeature> features) {
5055
log.info("Creating mongodb storage");
5156

52-
SubmodelRegistryStorage storage = new CursorEncodingRegistryStorage(new MongoDbSubmodelRegistryStorage(template));
57+
SubmodelRegistryStorage storage = new CursorEncodingRegistryStorage(new MongoDbSubmodelRegistryStorage(template, collectionName));
5358

5459
return applyFeatures(storage, features);
5560
}

0 commit comments

Comments
 (0)