From e2935e2eff5cc2fcc357f1d8f059343752ee76d5 Mon Sep 17 00:00:00 2001 From: Roman Babenko Date: Mon, 29 Oct 2018 00:41:42 +0100 Subject: [PATCH] Fix continuation token being invalidated by delete. --- .../testing/s3mock/FileStoreController.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/com/adobe/testing/s3mock/FileStoreController.java b/server/src/main/java/com/adobe/testing/s3mock/FileStoreController.java index 242bf556e..46e100bf0 100644 --- a/server/src/main/java/com/adobe/testing/s3mock/FileStoreController.java +++ b/server/src/main/java/com/adobe/testing/s3mock/FileStoreController.java @@ -346,6 +346,14 @@ public ListBucketResultV2 listObjectsInsideBucketV2(@PathVariable final String b final List contents = getBucketContents(bucketName, prefix); List filteredContents = getFilteredBucketContents(contents, startAfter); + Collections.sort(filteredContents, new Comparator() { + @Override + public int compare(BucketContents lhs, BucketContents rhs) { + // -1 - less than, 1 - greater than, 0 - equal, all inversed for descending + return String.CASE_INSENSITIVE_ORDER.compare(lhs.getKey(),rhs.getKey()); + } + }); + final Set commonPrefixes = new HashSet<>(); if (delimiter != null) { collapseCommonPrefixes(prefix, delimiter, filteredContents, commonPrefixes); @@ -354,13 +362,12 @@ public ListBucketResultV2 listObjectsInsideBucketV2(@PathVariable final String b String nextContinuationToken = null; boolean isTruncated = false; - int itemsToSkipForThisRequest = 0; - if (continuationToken != null) { - itemsToSkipForThisRequest = Integer.parseInt( - fileStorePagingStateCache.get(continuationToken).get().toString()); - filteredContents = filteredContents.subList(itemsToSkipForThisRequest, - filteredContents.size()); + String continuationKey = fileStorePagingStateCache.get(continuationToken).get().toString(); + filteredContents = filteredContents + .stream() + .filter(p -> p.getKey().compareTo(continuationKey) > 0) + .collect(Collectors.toList()); fileStorePagingStateCache.evict(continuationToken); } @@ -369,7 +376,7 @@ public ListBucketResultV2 listObjectsInsideBucketV2(@PathVariable final String b isTruncated = true; nextContinuationToken = UUID.randomUUID().toString(); fileStorePagingStateCache.put(nextContinuationToken, - String.valueOf(itemsToSkipForThisRequest + maxKeys)); + filteredContents.get(maxKeys - 1).getKey()); filteredContents = filteredContents.subList(0, maxKeys); }