Skip to content

Commit 859da50

Browse files
committed
veeam-control-service: fix vm pagination
Only consider page in pagination for search clause https://ovirt.github.io/ovirt-engine-api-model/4.5/#_pagination Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 6bc83a3 commit 859da50

2 files changed

Lines changed: 31 additions & 36 deletions

File tree

  • plugins/integrations/veeam-control-service/src

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/request/ListQuery.java

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.List;
2323
import java.util.Map;
2424
import java.util.stream.Collectors;
25+
import java.util.regex.Matcher;
26+
import java.util.regex.Pattern;
2527

2628
import javax.servlet.http.HttpServletRequest;
2729

@@ -31,6 +33,8 @@
3133
import org.jetbrains.annotations.NotNull;
3234

3335
public class ListQuery {
36+
private static final Pattern PAGE_CLAUSE_PATTERN = Pattern.compile("(?i)\\bpage\\s+(\\d+)\\b");
37+
3438
boolean allContent;
3539
Long max;
3640
Long page;
@@ -53,6 +57,14 @@ public void setMax(Long max) {
5357
this.max = max;
5458
}
5559

60+
public Long getPage() {
61+
return page;
62+
}
63+
64+
public void setPage(Long page) {
65+
this.page = page;
66+
}
67+
5668
public void setSearch(Map<String, String> search) {
5769
this.search = search;
5870
}
@@ -108,50 +120,33 @@ public static ListQuery fromRequest(HttpServletRequest request) {
108120
query.setFollow(follow);
109121
Map<String, String> searchItems = getSearchMap(request.getParameter("search"));
110122
if (!searchItems.isEmpty()) {
111-
try {
112-
query.setMax(Long.parseLong(searchItems.get("page")));
113-
} catch (NumberFormatException e) {
114-
// Ignore invalid page and keep default null value.
123+
String pageValue = searchItems.get("page");
124+
if (StringUtils.isNotBlank(pageValue)) {
125+
try {
126+
query.setPage(Long.parseLong(pageValue));
127+
} catch (NumberFormatException e) {
128+
// Ignore invalid page and keep default null value.
129+
}
115130
}
116131
query.setSearch(searchItems);
117132
}
118133

119134
return query;
120135
}
121136

122-
// Parse search clause. Only keep items which use simple '=' operator, and ignore others. For example:
123-
// name=myvm and status=up --> {name=myvm, status=up}
124-
// name=myvm and status!=down --> {name=myvm} (ignore status!=down because it uses '!=' operator)
137+
// Parse search clause. For now, only extract the oVirt paging clause.
138+
// Examples:
139+
// page 3 --> {page=3}
140+
// sortby name page 2 --> {page=2}
125141
@NotNull
126142
private static Map<String, String> getSearchMap(String searchClause) {
127143
Map<String, String> searchItems = new LinkedHashMap<>();
128144
if (StringUtils.isBlank(searchClause)) {
129145
return searchItems;
130146
}
131-
String[] terms = searchClause.trim().split("(?i)\\s+and\\s+");
132-
for (String term : terms) {
133-
if (term == null) {
134-
continue;
135-
}
136-
String trimmedTerm = term.trim();
137-
if (trimmedTerm.isEmpty()) {
138-
continue;
139-
}
140-
141-
int eqIdx = trimmedTerm.indexOf('=');
142-
if (eqIdx <= 0 || eqIdx != trimmedTerm.lastIndexOf('=')) {
143-
continue;
144-
}
145-
char prev = trimmedTerm.charAt(eqIdx - 1);
146-
if (prev == '!' || prev == '<' || prev == '>') {
147-
continue;
148-
}
149-
150-
String key = trimmedTerm.substring(0, eqIdx).trim();
151-
String value = trimmedTerm.substring(eqIdx + 1).trim();
152-
if (!key.isEmpty() && !value.isEmpty()) {
153-
searchItems.put(key, value);
154-
}
147+
Matcher matcher = PAGE_CLAUSE_PATTERN.matcher(searchClause);
148+
if (matcher.find()) {
149+
searchItems.put("page", matcher.group(1));
155150
}
156151
return searchItems;
157152
}

plugins/integrations/veeam-control-service/src/test/java/org/apache/cloudstack/veeam/api/request/ListQueryTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,18 @@ public void testFromRequest_ParsesAllContentMaxAndFollow() {
6767
}
6868

6969
@Test
70-
public void testFromRequest_SearchParserIgnoresNonEqualsAndUsesPageValueAsMaxCurrentBehavior() {
70+
public void testFromRequest_SearchParserExtractsPageOnly() {
7171
final HttpServletRequest request = mock(HttpServletRequest.class);
72-
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"name=vm and page=3 and status!=down and x>=1"}));
72+
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"sortby name page 3"}));
7373
when(request.getParameter("all_content")).thenReturn(null);
7474
when(request.getParameter("max")).thenReturn(null);
7575
when(request.getParameter("follow")).thenReturn(null);
76-
when(request.getParameter("search")).thenReturn("name=vm and page=3 and status!=down and x>=1");
76+
when(request.getParameter("search")).thenReturn("sortby name page 3");
7777

7878
final ListQuery query = ListQuery.fromRequest(request);
7979

80-
// Document existing behavior: when search contains page=..., max is set from it.
81-
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getLimit());
80+
// Only page key is extracted from search clause in oVirt format "page N"
81+
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getPage());
8282
}
8383

8484
@Test

0 commit comments

Comments
 (0)