diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java index 46c8148015e1..253aa0402f23 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java @@ -299,9 +299,8 @@ private class VolumeIterator implements Iterator { @Override public boolean hasNext() { - if(!currentIterator.hasNext()) { - currentIterator = getNextListOfVolumes( - currentValue != null ? currentValue.getName() : null) + if (!currentIterator.hasNext() && currentValue != null) { + currentIterator = getNextListOfVolumes(currentValue.getName()) .iterator(); } return currentIterator.hasNext(); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java index 6d02a3df1056..bdc31e5f155e 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java @@ -807,33 +807,33 @@ public List listTrash(String volumeName, String bucketName, @Override public List listVolumes(String userName, String prefix, String startKey, int maxKeys) throws IOException { - List result = Lists.newArrayList(); - UserVolumeInfo volumes; + if (StringUtil.isBlank(userName)) { throw new OMException("User name is required to list Volumes.", ResultCodes.USER_NOT_FOUND); } - volumes = getVolumesByUser(userName); - if (volumes == null || volumes.getVolumeNamesCount() == 0) { - return result; - } + final List result = Lists.newArrayList(); + final List volumes = getVolumesByUser(userName) + .getVolumeNamesList(); - boolean startKeyFound = Strings.isNullOrEmpty(startKey); - for (String volumeName : volumes.getVolumeNamesList()) { - if (!Strings.isNullOrEmpty(prefix)) { - if (!volumeName.startsWith(prefix)) { - continue; - } - } + int index = 0; + if (!Strings.isNullOrEmpty(startKey)) { + index = volumes.indexOf( + startKey.startsWith(OzoneConsts.OM_KEY_PREFIX) ? + startKey.substring(1) : + startKey); - if (!startKeyFound && volumeName.equals(startKey)) { - startKeyFound = true; - continue; - } - if (startKeyFound && result.size() < maxKeys) { - OmVolumeArgs volumeArgs = - getVolumeTable().get(this.getVolumeKey(volumeName)); + // Exclude the startVolume as part of the result. + index = index != -1 ? index + 1 : index; + } + final String startChar = prefix == null ? "" : prefix; + + while (index != -1 && index < volumes.size() && result.size() < maxKeys) { + final String volumeName = volumes.get(index); + if (volumeName.startsWith(startChar)) { + final OmVolumeArgs volumeArgs = getVolumeTable() + .get(getVolumeKey(volumeName)); if (volumeArgs == null) { // Could not get volume info by given volume name, // since the volume name is loaded from db, @@ -844,6 +844,7 @@ public List listVolumes(String userName, } result.add(volumeArgs); } + index++; } return result; diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java index de78b4fc76de..6a09f12bb338 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java @@ -51,7 +51,8 @@ public class ListVolumeHandler extends Handler { private int maxVolumes; @Option(names = {"--start", "-s"}, - description = "The first volume to start the listing") + description = "The volume to start the listing from.\n" + + "This will be excluded from the result.") private String startVolume; @Option(names = {"--prefix", "-p"}, diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmMetadataManager.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmMetadataManager.java index e0e4c61d3e54..6802afcd620e 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmMetadataManager.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmMetadataManager.java @@ -24,6 +24,7 @@ import org.apache.hadoop.hdds.utils.db.cache.CacheValue; import org.apache.hadoop.ozone.om.helpers.OmBucketInfo; import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; +import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs; import org.apache.hadoop.ozone.om.request.TestOMRequestUtils; import org.junit.Assert; import org.junit.Before; @@ -55,6 +56,39 @@ public void setup() throws Exception { folder.getRoot().getAbsolutePath()); omMetadataManager = new OmMetadataManagerImpl(ozoneConfiguration); } + + @Test + public void testListVolumes() throws Exception { + String ownerName = "owner"; + OmVolumeArgs.Builder argsBuilder = OmVolumeArgs.newBuilder() + .setAdminName("admin") + .setOwnerName(ownerName); + + String volName; + OmVolumeArgs omVolumeArgs; + for (int i = 0; i < 50; i++) { + volName = "vol" + i; + omVolumeArgs = argsBuilder + .setVolume(volName) + .build(); + + TestOMRequestUtils.addVolumeToOM(omMetadataManager, omVolumeArgs); + TestOMRequestUtils.addUserToDB(volName, ownerName, omMetadataManager); + } + + // Test list volumes with setting startVolume that + // was not part of the result. + String prefix = ""; + int totalVol = omMetadataManager + .listVolumes(ownerName, prefix, null, 100) + .size(); + int startOrder = 10; + String startVolume = "vol" + startOrder; + List volumeList = omMetadataManager.listVolumes(ownerName, + prefix, startVolume, 100); + Assert.assertEquals(volumeList.size(), totalVol - startOrder - 1); + } + @Test public void testListBuckets() throws Exception { diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java index 6ceced4077e5..49c204dcc665 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMRequestUtils.java @@ -302,13 +302,22 @@ public static List< HddsProtos.KeyValue> getMetadataList() { */ public static void addUserToDB(String volumeName, String ownerName, OMMetadataManager omMetadataManager) throws Exception { - OzoneManagerProtocolProtos.UserVolumeInfo userVolumeInfo = - OzoneManagerProtocolProtos.UserVolumeInfo - .newBuilder() - .addVolumeNames(volumeName) - .setObjectID(1) - .setUpdateID(1) - .build(); + + OzoneManagerProtocolProtos.UserVolumeInfo userVolumeInfo = omMetadataManager + .getUserTable().get(omMetadataManager.getUserKey(ownerName)); + if (userVolumeInfo == null) { + userVolumeInfo = OzoneManagerProtocolProtos.UserVolumeInfo + .newBuilder() + .addVolumeNames(volumeName) + .setObjectID(1) + .setUpdateID(1) + .build(); + } else { + userVolumeInfo = userVolumeInfo.toBuilder() + .addVolumeNames(volumeName) + .build(); + } + omMetadataManager.getUserTable().put( omMetadataManager.getUserKey(ownerName), userVolumeInfo); }