This is an automated email from the ASF dual-hosted git repository.

weizhouapache pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 89b2b030e02 veeam-control-service: fix vm pagination (#13383)
89b2b030e02 is described below

commit 89b2b030e024fb9ebcfe49b6bea900be29fa6fcb
Author: Abhishek Kumar <[email protected]>
AuthorDate: Tue Jul 7 16:38:58 2026 +0530

    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 <[email protected]>
---
 .../cloudstack/veeam/api/request/ListQuery.java    | 57 ++++++++++------------
 .../veeam/api/request/ListQueryTest.java           | 10 ++--
 2 files changed, 31 insertions(+), 36 deletions(-)

diff --git 
a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/request/ListQuery.java
 
b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/request/ListQuery.java
index f57edf76e04..1cb560a3d89 100644
--- 
a/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/request/ListQuery.java
+++ 
b/plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/request/ListQuery.java
@@ -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;
     }
diff --git 
a/plugins/integrations/veeam-control-service/src/test/java/org/apache/cloudstack/veeam/api/request/ListQueryTest.java
 
b/plugins/integrations/veeam-control-service/src/test/java/org/apache/cloudstack/veeam/api/request/ListQueryTest.java
index 16fbd02669c..a6d8bfef1d4 100644
--- 
a/plugins/integrations/veeam-control-service/src/test/java/org/apache/cloudstack/veeam/api/request/ListQueryTest.java
+++ 
b/plugins/integrations/veeam-control-service/src/test/java/org/apache/cloudstack/veeam/api/request/ListQueryTest.java
@@ -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

Reply via email to