You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ranger.apache.org by "yunyezhang-work (via GitHub)" <gi...@apache.org> on 2025/11/28 01:49:51 UTC

[PR] RANGER-5406 Support export policies in a segmented manner [ranger]

yunyezhang-work opened a new pull request, #748:
URL: https://github.com/apache/ranger/pull/748

   ## What changes were proposed in this pull request?
   In big data production environments, customers create a massive number of policies, often reaching hundreds of thousands or even millions. Exporting the entire set of policies for disaster recovery would result in an enormous data volume and extremely slow import speeds into the backup cluster.  Our current experimental data shows that importing 10,000 policies via the API is very memory-intensive and takes approximately 15 minutes. Importing 100,000 policies via the API will take 2.5h or even longer.
   
   With an even larger number of policies, memory consumption will increase significantly, and insufficient memory can cause import interruptions. Therefore, we recommend modifying the API to allow for segmented export. This will save memory and ensure data reliability when importing to other clusters for disaster recovery.
   
   
   ## How was this patch tested?
   To manually test this feature, you can send an HTTP request to the ranger. Using a shell command as an example:
   
   Without the segmentation parameter, calling the export API `getPoliciesInJson` will export all policies. As shown in the figure, there are 18 policies in this environment for hdfs-xxx.
   `curl -u$USER:$PASSWORD -XGET "http://$RANGER_HOST:$RANGER_PORT/service/plugins/policies/exportJson?serviceName=$SERVICE&checkPoliciesExists=true" -v -o export.json`
   
   Adding the segmentation parameter will export the policies for the specified start and end position range. As shown in the figure, policies 1-5 of hdfs-xxx are exported.
   `curl -u$USER:$PASSWORD -XGET "http://$RANGER_HOST:$RANGER_PORT/service/plugins/policies/exportJson?serviceName=$SERVICE&checkPoliciesExists=true&beginIndex=$BEGIN_INDEX&offsetIndex=$OFFSET_INDEX" -v -o export_${BEGIN_INDEX}_${OFFSET_INDEX}.json`
   <img width="1209" height="271" alt="image" src="https://github.com/user-attachments/assets/59af97c0-35be-441b-a471-5c8bc125b0f7" />
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2572830151


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -4298,6 +4308,45 @@ private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, Searc
         return ret;
     }
 
+    private List<RangerPolicy> getRangerPoliciesInRange(List<RangerPolicy> policyList, SearchFilter filter) {
+        List<RangerPolicy> retList = null;
+        if (CollectionUtils.isNotEmpty(policyList)) {
+            int totalCount = policyList.size();
+            int startIndex = filter.getBeginIndex();
+            int pageSize = filter.getOffset();

Review Comment:
   Is this(int pageSize = filter.getOffset();) intentional , i think either you have to change the variable name or the call different method.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "yunyezhang-work (via GitHub)" <gi...@apache.org>.
yunyezhang-work commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2599278223


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -4298,6 +4308,40 @@ private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, Searc
         return ret;
     }
 
+    private List<RangerPolicy> getRangerPoliciesInRange(List<RangerPolicy> policyList, SearchFilter filter) {
+        List<RangerPolicy> retList = null;
+        if (CollectionUtils.isNotEmpty(policyList)) {
+            int totalCount = policyList.size();
+            int startIndex = filter.getBeginIndex();
+            int offset = filter.getOffset();
+            int toIndex = Math.min(startIndex + offset, totalCount);
+            LOG.info("==>totalCount: {}, startIndex:{}, offsetSize: {}, toIndex: {}" , totalCount, startIndex, offset, toIndex);
+            String sortType = filter.getSortType();
+            String sortBy = filter.getSortBy();
+
+            if (StringUtils.isNotEmpty(sortBy) && StringUtils.isNotEmpty(sortType)) {
+                // By default policyList is sorted by policyId in asc order, So handling only desc case.
+                if (SearchFilter.POLICY_ID.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    }
+                } else if (SearchFilter.POLICY_NAME.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.ASC.name().equalsIgnoreCase(sortType) || SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    } else {
+                        LOG.info("Invalid or Unsupported sortType : {}", sortType);
+                    }
+                } else {
+                    LOG.info("Invalid or Unsupported sortBy property : {}" , sortBy);
+                }
+            }
+
+            retList = new ArrayList<>(policyList.subList(startIndex, toIndex));
+
+        }
+        return retList;

Review Comment:
   Your suggestion is more comprehensive. I have updated the code.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "yunyezhang-work (via GitHub)" <gi...@apache.org>.
yunyezhang-work commented on PR #748:
URL: https://github.com/apache/ranger/pull/748#issuecomment-3635021752

   @kumaab @mneethiraj Please review this PR regarding feature optimization for the export interface.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2597177244


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -4298,6 +4308,40 @@ private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, Searc
         return ret;
     }
 
+    private List<RangerPolicy> getRangerPoliciesInRange(List<RangerPolicy> policyList, SearchFilter filter) {
+        List<RangerPolicy> retList = null;
+        if (CollectionUtils.isNotEmpty(policyList)) {
+            int totalCount = policyList.size();
+            int startIndex = filter.getBeginIndex();
+            int offset = filter.getOffset();
+            int toIndex = Math.min(startIndex + offset, totalCount);
+            LOG.info("==>totalCount: {}, startIndex:{}, offsetSize: {}, toIndex: {}" , totalCount, startIndex, offset, toIndex);
+            String sortType = filter.getSortType();
+            String sortBy = filter.getSortBy();
+
+            if (StringUtils.isNotEmpty(sortBy) && StringUtils.isNotEmpty(sortType)) {
+                // By default policyList is sorted by policyId in asc order, So handling only desc case.
+                if (SearchFilter.POLICY_ID.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    }
+                } else if (SearchFilter.POLICY_NAME.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.ASC.name().equalsIgnoreCase(sortType) || SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    } else {
+                        LOG.info("Invalid or Unsupported sortType : {}", sortType);
+                    }
+                } else {
+                    LOG.info("Invalid or Unsupported sortBy property : {}" , sortBy);
+                }
+            }
+
+            retList = new ArrayList<>(policyList.subList(startIndex, toIndex));
+
+        }
+        return retList;

Review Comment:
   Returning `null` when the input list is empty can lead to `NullPointerException` for callers that don't explicitly check for null. I suggest returning an empty list instead of `null`.
   
   option 1 
   
   if (CollectionUtils.isEmpty(policyList)) {
           return Collections.emptyList();
       }
   
   or
   
   option  2
   
   return retList != null ? retList : Collections.emptyList();
   
   My suggestion is to use the option 1.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2572780338


##########
security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java:
##########
@@ -239,14 +239,30 @@ public SearchFilter extractCommonCriteriasForFilter(HttpServletRequest request,
                 "Invalid value for parameter startIndex", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.START_INDEX);
 
         startIndex = startIndex < 0 ? 0 : startIndex;
+        logger.info("==> setStartIndex={}" , startIndex);
 
         ret.setStartIndex(startIndex);
 
         int pageSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.PAGE_SIZE), configUtil.getDefaultMaxRows(),
                 "Invalid value for parameter pageSize", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.PAGE_SIZE);
-
+        logger.info("==> setMaxRows={}" , pageSize);
+        logger.info("==> DefaultMaxRows={}" , configUtil.getDefaultMaxRows());
         ret.setMaxRows(validatePageSize(pageSize));
 
+        int beginIndex = restErrorUtil.parseInt(request.getParameter(SearchFilter.BEGIN_INDEX), 0,
+                "Invalid value for parameter beginIndex", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.BEGIN_INDEX);
+        beginIndex = beginIndex < 0 ? startIndex : beginIndex;
+        logger.info("==> setBeginIndex={}" , beginIndex);
+        ret.setBeginIndex(beginIndex);
+
+        int offsetSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.OFFSET), 0,
+                "Invalid value for parameter offset", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.OFFSET);
+        logger.info("==> setOffsetIndex={}" , offsetSize);
+        offsetSize = offsetSize < 0 ? pageSize : offsetSize;

Review Comment:
   what will happen if offsetSize > pagesize ?. I can see that code does not handle this condition.
   
   Currently, the code allows the client to send an `offset` value larger than `pageSize` (e.g., pageSize=10 & offset=57), and it is accepted without any adjustment or validation.
   
   This will causes real problems:
   1. The results are no longer page-aligned 
   2.`startIndex`, `beginIndex`, and `offset` can end up with different values (since they are set independently), leading to inconsistent behavior.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2599421852


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -149,20 +149,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
+import java.util.*;

Review Comment:
   We have a wildcard import `import java.util.*;` I suspect this was added automatically by the IDE (very common!).
   
   While it works, explicit imports are preferred (better readability, avoids conflicts, and required by our Checkstyle config).
   
   Could you please replace it with specific imports and run:
   
   mvn clean install
   
   the above will report any checkstyle volations.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "yunyezhang-work (via GitHub)" <gi...@apache.org>.
yunyezhang-work commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2589806314


##########
security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java:
##########
@@ -239,14 +239,30 @@ public SearchFilter extractCommonCriteriasForFilter(HttpServletRequest request,
                 "Invalid value for parameter startIndex", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.START_INDEX);
 
         startIndex = startIndex < 0 ? 0 : startIndex;
+        logger.info("==> setStartIndex={}" , startIndex);
 
         ret.setStartIndex(startIndex);
 
         int pageSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.PAGE_SIZE), configUtil.getDefaultMaxRows(),
                 "Invalid value for parameter pageSize", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.PAGE_SIZE);
-
+        logger.info("==> setMaxRows={}" , pageSize);
+        logger.info("==> DefaultMaxRows={}" , configUtil.getDefaultMaxRows());
         ret.setMaxRows(validatePageSize(pageSize));
 
+        int beginIndex = restErrorUtil.parseInt(request.getParameter(SearchFilter.BEGIN_INDEX), 0,
+                "Invalid value for parameter beginIndex", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.BEGIN_INDEX);
+        beginIndex = beginIndex < 0 ? startIndex : beginIndex;
+        logger.info("==> setBeginIndex={}" , beginIndex);
+        ret.setBeginIndex(beginIndex);
+
+        int offsetSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.OFFSET), 0,
+                "Invalid value for parameter offset", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.OFFSET);
+        logger.info("==> setOffsetIndex={}" , offsetSize);
+        offsetSize = offsetSize < 0 ? pageSize : offsetSize;

Review Comment:
   Thank you for your reply. The offset design here allows exporting any number of policies, within the limit of the total number of policies. In a production environment, if the number of policies is too large (e.g., over 500,000), and the segmentation is limited to a specific page size (e.g., 500), then many exports would be needed to complete the data export. There was ambiguity between page size and offset in my previous code submission. This ambiguity has now been fixed.
   For example, if the current service only has 210 policies, even if the offset is set to 300, only these 210 policies can be exported.
   <img width="3480" height="494" alt="Clipboard_Screenshot_1764866595" src="https://github.com/user-attachments/assets/b14fbd4e-f36c-4881-aa81-8ac9b4b8c629" />
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "yunyezhang-work (via GitHub)" <gi...@apache.org>.
yunyezhang-work commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2603259615


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -149,20 +149,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
+import java.util.*;

Review Comment:
   In my latest submission, I provided more detailed import code. Please review it.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2572830432


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -4298,6 +4308,45 @@ private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, Searc
         return ret;
     }
 
+    private List<RangerPolicy> getRangerPoliciesInRange(List<RangerPolicy> policyList, SearchFilter filter) {
+        List<RangerPolicy> retList = null;
+        if (CollectionUtils.isNotEmpty(policyList)) {
+            int totalCount = policyList.size();
+            int startIndex = filter.getBeginIndex();
+            int pageSize = filter.getOffset();
+            int toIndex = Math.min(startIndex + pageSize, totalCount);
+            LOG.info("==>totalCount: {}, startIndex:{}, pageSize: {}, toIndex: {}" , totalCount, startIndex, pageSize, toIndex);
+            String sortType = filter.getSortType();
+            String sortBy = filter.getSortBy();
+
+            if (StringUtils.isNotEmpty(sortBy) && StringUtils.isNotEmpty(sortType)) {

Review Comment:
   The sorting conditions for POLICY_NAME can be simplified since both ASC and DESC call the same comparator method



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "vyommani (via GitHub)" <gi...@apache.org>.
vyommani commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2572832140


##########
security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java:
##########
@@ -4298,6 +4308,45 @@ private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, Searc
         return ret;
     }
 
+    private List<RangerPolicy> getRangerPoliciesInRange(List<RangerPolicy> policyList, SearchFilter filter) {
+        List<RangerPolicy> retList = null;
+        if (CollectionUtils.isNotEmpty(policyList)) {
+            int totalCount = policyList.size();
+            int startIndex = filter.getBeginIndex();
+            int pageSize = filter.getOffset();
+            int toIndex = Math.min(startIndex + pageSize, totalCount);
+            LOG.info("==>totalCount: {}, startIndex:{}, pageSize: {}, toIndex: {}" , totalCount, startIndex, pageSize, toIndex);
+            String sortType = filter.getSortType();
+            String sortBy = filter.getSortBy();
+
+            if (StringUtils.isNotEmpty(sortBy) && StringUtils.isNotEmpty(sortType)) {
+                // By default policyList is sorted by policyId in asc order, So handling only desc case.
+                if (SearchFilter.POLICY_ID.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    }
+                } else if (SearchFilter.POLICY_NAME.equalsIgnoreCase(sortBy)) {
+                    if (SORT_ORDER.ASC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    } else if (SORT_ORDER.DESC.name().equalsIgnoreCase(sortType)) {
+                        policyList.sort(this.getPolicyComparator(sortBy, sortType));
+                    } else {
+                        LOG.info("Invalid or Unsupported sortType : {}", sortType);
+                    }
+                } else {
+                    LOG.info("Invalid or Unsupported sortBy property : {}" , sortBy);
+                }
+            }
+
+            retList = new ArrayList<RangerPolicy>();

Review Comment:
   This manual copying can be simplified using subList(). You could either create a new list with new ArrayList<>(policyList.subList(startIndex, toIndex)) or return the sublist view directly. I'd recommend creating a new list to avoid exposing a mutable reference to the internal collection.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] RANGER-5406 Support export policies in a segmented manner [ranger]

Posted by "yunyezhang-work (via GitHub)" <gi...@apache.org>.
yunyezhang-work commented on code in PR #748:
URL: https://github.com/apache/ranger/pull/748#discussion_r2589806314


##########
security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java:
##########
@@ -239,14 +239,30 @@ public SearchFilter extractCommonCriteriasForFilter(HttpServletRequest request,
                 "Invalid value for parameter startIndex", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.START_INDEX);
 
         startIndex = startIndex < 0 ? 0 : startIndex;
+        logger.info("==> setStartIndex={}" , startIndex);
 
         ret.setStartIndex(startIndex);
 
         int pageSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.PAGE_SIZE), configUtil.getDefaultMaxRows(),
                 "Invalid value for parameter pageSize", MessageEnums.INVALID_INPUT_DATA, null, SearchFilter.PAGE_SIZE);
-
+        logger.info("==> setMaxRows={}" , pageSize);
+        logger.info("==> DefaultMaxRows={}" , configUtil.getDefaultMaxRows());
         ret.setMaxRows(validatePageSize(pageSize));
 
+        int beginIndex = restErrorUtil.parseInt(request.getParameter(SearchFilter.BEGIN_INDEX), 0,
+                "Invalid value for parameter beginIndex", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.BEGIN_INDEX);
+        beginIndex = beginIndex < 0 ? startIndex : beginIndex;
+        logger.info("==> setBeginIndex={}" , beginIndex);
+        ret.setBeginIndex(beginIndex);
+
+        int offsetSize = restErrorUtil.parseInt(request.getParameter(SearchFilter.OFFSET), 0,
+                "Invalid value for parameter offset", MessageEnums.INVALID_INPUT_DATA, null,
+                SearchFilter.OFFSET);
+        logger.info("==> setOffsetIndex={}" , offsetSize);
+        offsetSize = offsetSize < 0 ? pageSize : offsetSize;

Review Comment:
   Thank you for your reply. The offset design here allows exporting any number of policies, within the limit of the total number of policies. In a production environment, if the number of policies is too large (e.g., over 500,000), and the segmentation is limited to a specific page size (e.g., 500), then many exports would be needed to complete the data export. There was ambiguity between page size and offset in my previous code submission. This ambiguity has now been fixed.
   For example, if the current service only has 210 policies, even if the offset is set to 300, only these 210 policies can be exported.
   <img width="3480" height="494" alt="Clipboard_Screenshot_1764866366" src="https://github.com/user-attachments/assets/a0af1c88-51ee-48c4-847b-abde81a074ec" />



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@ranger.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org