Skip to content

Commit 54c5e56

Browse files
committed
Adds Pagination on Backend
1 parent da98fcd commit 54c5e56

4 files changed

Lines changed: 72 additions & 20 deletions

File tree

  • basyx.submodelrepository/basyx.submodelrepository-backend/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/backend
  • basyx.submodelservice

basyx.submodelrepository/basyx.submodelrepository-backend/src/main/java/org/eclipse/digitaltwin/basyx/submodelrepository/backend/CrudSubmodelRepository.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,7 @@ public CursorResult<List<Submodel>> getAllSubmodels(PaginationInfo pInfo) {
9292

9393
@Override
9494
public CursorResult<List<Submodel>> getAllSubmodels(String semanticId, PaginationInfo pInfo) {
95-
Iterable<Submodel> iterable = submodelBackend.findAll();
96-
List<Submodel> submodels = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
97-
98-
List<Submodel> filteredSubmodels = submodels.stream()
99-
.filter((submodel) -> {
100-
return submodel.getSemanticId() != null &&
101-
submodel.getSemanticId().getKeys().stream().filter((key) -> {
102-
return key.getValue().equals(semanticId);
103-
}).findAny().isPresent();
104-
})
105-
.collect(Collectors.toList());
106-
107-
TreeMap<String, Submodel> submodelMap = filteredSubmodels.stream().collect(Collectors.toMap(Submodel::getId, submodel -> submodel, (a, b) -> a, TreeMap::new));
108-
109-
PaginationSupport<Submodel> paginationSupport = new PaginationSupport<>(submodelMap, Submodel::getId);
110-
111-
return paginationSupport.getPaged(pInfo);
95+
return submodelBackend.getSubmodels(semanticId, pInfo);
11296
}
11397

11498
@Override

basyx.submodelservice/basyx.submodelservice-backend-inmemory/src/main/java/org/eclipse/digitaltwin/basyx/submodelservice/InMemorySubmodelBackend.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.List;
4444
import java.util.TreeMap;
4545
import java.util.stream.Collectors;
46+
import java.util.stream.StreamSupport;
4647

4748
/**
4849
* Implements the SubmodelService as in-memory variant
@@ -57,6 +58,27 @@ public InMemorySubmodelBackend() {
5758
super(Submodel::getId);
5859
}
5960

61+
@Override
62+
public CursorResult<List<Submodel>> getSubmodels(String semanticId, PaginationInfo pInfo) {
63+
Iterable<Submodel> iterable = findAll();
64+
List<Submodel> submodels = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
65+
66+
List<Submodel> filteredSubmodels = submodels.stream()
67+
.filter((submodel) -> {
68+
return submodel.getSemanticId() != null &&
69+
submodel.getSemanticId().getKeys().stream().filter((key) -> {
70+
return key.getValue().equals(semanticId);
71+
}).findAny().isPresent();
72+
})
73+
.collect(Collectors.toList());
74+
75+
TreeMap<String, Submodel> submodelMap = filteredSubmodels.stream().collect(Collectors.toMap(Submodel::getId, submodel -> submodel, (a, b) -> a, TreeMap::new));
76+
77+
PaginationSupport<Submodel> paginationSupport = new PaginationSupport<>(submodelMap, Submodel::getId);
78+
79+
return paginationSupport.getPaged(pInfo);
80+
}
81+
6082
@Override
6183
public CursorResult<List<SubmodelElement>> getSubmodelElements(String submodelId, PaginationInfo pInfo) {
6284
List<SubmodelElement> allSubmodels = getSubmodel(submodelId).getSubmodelElements();

basyx.submodelservice/basyx.submodelservice-backend-mongodb/src/main/java/org/eclipse/digitaltwin/basyx/submodelservice/backend/MongoDbSubmodelOperations.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.eclipse.digitaltwin.basyx.submodelservice.value.SubmodelElementValue;
4646
import org.eclipse.digitaltwin.basyx.submodelservice.value.factory.SubmodelElementValueMapperFactory;
4747
import org.eclipse.digitaltwin.basyx.submodelservice.value.mapper.ValueMapper;
48+
import org.springframework.data.domain.Sort;
4849
import org.springframework.data.mongodb.core.BulkOperations;
4950
import org.springframework.data.mongodb.core.MongoOperations;
5051
import org.springframework.data.mongodb.core.aggregation.Aggregation;
@@ -74,24 +75,53 @@ public MongoDbSubmodelOperations(MongoOperations mongoOperations) {
7475
this.collectionName = mongoOperations.getCollectionName(Submodel.class);
7576
}
7677

78+
@Override
79+
public CursorResult<List<Submodel>> getSubmodels(String semanticId, PaginationInfo pInfo) {
80+
List<AggregationOperation> ops = new ArrayList<>();
81+
82+
ops.add(Aggregation.match(Criteria.where("semanticId.keys.value").is(semanticId)));
83+
84+
if (hasCursor(pInfo)) {
85+
ops.add(Aggregation.match(Criteria.where("_id").gt(pInfo.getCursor())));
86+
}
87+
88+
ops.add(Aggregation.sort(Sort.by(Sort.Direction.ASC, "_id")));
89+
90+
if (hasLimit(pInfo)) {
91+
ops.add(Aggregation.limit(pInfo.getLimit()));
92+
}
93+
94+
Aggregation aggregation = Aggregation.newAggregation(ops);
95+
AggregationResults<Submodel> results =
96+
mongoOperations.aggregate(aggregation, collectionName, Submodel.class);
97+
98+
List<Submodel> submodels = results.getMappedResults();
99+
100+
String nextCursor = submodels.isEmpty()
101+
? null
102+
: submodels.get(submodels.size() - 1).getId();
103+
104+
return new CursorResult<>(nextCursor, submodels);
105+
}
106+
77107
@Override
78108
public CursorResult<List<SubmodelElement>> getSubmodelElements(String submodelId, PaginationInfo pInfo) throws ElementDoesNotExistException {
79109
List<AggregationOperation> ops = new ArrayList<>();
80110

81111
ops.add(Aggregation.match(Criteria.where("_id").is(submodelId)));
82112

83-
if (pInfo.getCursor() != null && !pInfo.getCursor().isEmpty()) {
113+
if (hasCursor(pInfo)) {
84114
Document addCursorIndex = new Document("$addFields",
85115
new Document("cursorIndex", new Document("$cond", Arrays.asList(new Document("$eq", Arrays.asList(new Document("$indexOfArray", Arrays.asList("$" + SUBMODEL_ELEMENTS_KEY + ".idShort", pInfo.getCursor())), -1)), 0,
86116
new Document("$add", Arrays.asList(new Document("$indexOfArray", Arrays.asList("$" + SUBMODEL_ELEMENTS_KEY + ".idShort", pInfo.getCursor())), 1))))));
87117
ops.add(context -> addCursorIndex);
88118

89-
int limit = (pInfo.getLimit() != null && pInfo.getLimit() > 0) ? pInfo.getLimit() : Integer.MAX_VALUE;
119+
int limit = hasLimit(pInfo) ? pInfo.getLimit() : Integer.MAX_VALUE;
90120

91121
Document projectSlice = new Document("$project", new Document(SUBMODEL_ELEMENTS_KEY, new Document("$slice", Arrays.asList("$" + SUBMODEL_ELEMENTS_KEY, "$cursorIndex", limit))));
92122
ops.add(context -> projectSlice);
93123
} else {
94-
if (pInfo.getLimit() != null && pInfo.getLimit() > 0) {
124+
if (hasLimit(pInfo)) {
95125
Document projectSlice = new Document("$project", new Document(SUBMODEL_ELEMENTS_KEY, new Document("$slice", Arrays.asList("$" + SUBMODEL_ELEMENTS_KEY, 0, pInfo.getLimit()))));
96126
ops.add(context -> projectSlice);
97127
}
@@ -116,6 +146,14 @@ public CursorResult<List<SubmodelElement>> getSubmodelElements(String submodelId
116146
return new CursorResult<>(nextCursor, elements);
117147
}
118148

149+
private static boolean hasLimit(PaginationInfo pInfo) {
150+
return pInfo.getLimit() != null && pInfo.getLimit() > 0;
151+
}
152+
153+
private static boolean hasCursor(PaginationInfo pInfo) {
154+
return pInfo.getCursor() != null && !pInfo.getCursor().isEmpty();
155+
}
156+
119157
@Override
120158
public SubmodelElement getSubmodelElement(String submodelId, String idShortPath) throws ElementDoesNotExistException {
121159
List<AggregationOperation> ops = MongoFilterBuilder.buildAggregationOperations(submodelId, idShortPath);

basyx.submodelservice/basyx.submodelservice-backend/src/main/java/org/eclipse/digitaltwin/basyx/submodelservice/backend/SubmodelOperations.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
*/
4343
public interface SubmodelOperations {
4444

45+
/**
46+
* Retrieves all Submodels with pagination support.
47+
*
48+
* @param pInfo the pagination information
49+
* @return a {@code CursorResult} containing a list of Submodels
50+
*/
51+
CursorResult<List<Submodel>> getSubmodels(String semanticId, PaginationInfo pInfo);
52+
4553
/**
4654
* Retrieves all Submodel Elements for the given Submodel.
4755
*

0 commit comments

Comments
 (0)