mirror of https://github.com/apache/cloudstack.git
veeam-control-service: fix vm pagination (#13383)
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>
This commit is contained in:
parent
9f281c4851
commit
89b2b030e0
|
|
@ -22,6 +22,8 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
|
@ -31,6 +33,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ListQuery {
|
||||
private static final Pattern PAGE_CLAUSE_PATTERN = Pattern.compile("(?i)\\bpage\\s+(\\d+)\\b");
|
||||
|
||||
boolean allContent;
|
||||
Long max;
|
||||
Long page;
|
||||
|
|
@ -53,6 +57,14 @@ public class ListQuery {
|
|||
this.max = max;
|
||||
}
|
||||
|
||||
public Long getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public void setPage(Long page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public void setSearch(Map<String, String> search) {
|
||||
this.search = search;
|
||||
}
|
||||
|
|
@ -108,10 +120,13 @@ public class ListQuery {
|
|||
query.setFollow(follow);
|
||||
Map<String, String> searchItems = getSearchMap(request.getParameter("search"));
|
||||
if (!searchItems.isEmpty()) {
|
||||
try {
|
||||
query.setMax(Long.parseLong(searchItems.get("page")));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore invalid page and keep default null value.
|
||||
String pageValue = searchItems.get("page");
|
||||
if (StringUtils.isNotBlank(pageValue)) {
|
||||
try {
|
||||
query.setPage(Long.parseLong(pageValue));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore invalid page and keep default null value.
|
||||
}
|
||||
}
|
||||
query.setSearch(searchItems);
|
||||
}
|
||||
|
|
@ -119,39 +134,19 @@ public class ListQuery {
|
|||
return query;
|
||||
}
|
||||
|
||||
// Parse search clause. Only keep items which use simple '=' operator, and ignore others. For example:
|
||||
// name=myvm and status=up --> {name=myvm, status=up}
|
||||
// name=myvm and status!=down --> {name=myvm} (ignore status!=down because it uses '!=' operator)
|
||||
// Parse search clause. For now, only extract the oVirt paging clause.
|
||||
// Examples:
|
||||
// page 3 --> {page=3}
|
||||
// sortby name page 2 --> {page=2}
|
||||
@NotNull
|
||||
private static Map<String, String> getSearchMap(String searchClause) {
|
||||
Map<String, String> searchItems = new LinkedHashMap<>();
|
||||
if (StringUtils.isBlank(searchClause)) {
|
||||
return searchItems;
|
||||
}
|
||||
String[] terms = searchClause.trim().split("(?i)\\s+and\\s+");
|
||||
for (String term : terms) {
|
||||
if (term == null) {
|
||||
continue;
|
||||
}
|
||||
String trimmedTerm = term.trim();
|
||||
if (trimmedTerm.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int eqIdx = trimmedTerm.indexOf('=');
|
||||
if (eqIdx <= 0 || eqIdx != trimmedTerm.lastIndexOf('=')) {
|
||||
continue;
|
||||
}
|
||||
char prev = trimmedTerm.charAt(eqIdx - 1);
|
||||
if (prev == '!' || prev == '<' || prev == '>') {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = trimmedTerm.substring(0, eqIdx).trim();
|
||||
String value = trimmedTerm.substring(eqIdx + 1).trim();
|
||||
if (!key.isEmpty() && !value.isEmpty()) {
|
||||
searchItems.put(key, value);
|
||||
}
|
||||
Matcher matcher = PAGE_CLAUSE_PATTERN.matcher(searchClause);
|
||||
if (matcher.find()) {
|
||||
searchItems.put("page", matcher.group(1));
|
||||
}
|
||||
return searchItems;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,18 +67,18 @@ public class ListQueryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testFromRequest_SearchParserIgnoresNonEqualsAndUsesPageValueAsMaxCurrentBehavior() {
|
||||
public void testFromRequest_SearchParserExtractsPageOnly() {
|
||||
final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"name=vm and page=3 and status!=down and x>=1"}));
|
||||
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"sortby name page 3"}));
|
||||
when(request.getParameter("all_content")).thenReturn(null);
|
||||
when(request.getParameter("max")).thenReturn(null);
|
||||
when(request.getParameter("follow")).thenReturn(null);
|
||||
when(request.getParameter("search")).thenReturn("name=vm and page=3 and status!=down and x>=1");
|
||||
when(request.getParameter("search")).thenReturn("sortby name page 3");
|
||||
|
||||
final ListQuery query = ListQuery.fromRequest(request);
|
||||
|
||||
// Document existing behavior: when search contains page=..., max is set from it.
|
||||
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getLimit());
|
||||
// Only page key is extracted from search clause in oVirt format "page N"
|
||||
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getPage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue