From d3520312a9ee993c50354b7c6f6b383d3611135d Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 15 Jan 2016 11:01:00 +0000
Subject: [PATCH] OPENDJ-2609 NoSuchElementException on ldapsearch --sortorder when using corresponding vlv index

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java         |   17 +++++++++++------
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java |   20 ++++++++++++++++++--
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
index 8512ece..ca052f2 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2016 ForgeRock AS
  */
 package org.opends.server.backends.pluggable;
 
@@ -49,6 +49,7 @@
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.forgerock.opendj.ldap.schema.MatchingRule;
+import org.forgerock.util.Reject;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn.Scope;
 import org.opends.server.admin.std.server.BackendVLVIndexCfg;
@@ -508,9 +509,12 @@
   {
     try (Cursor<ByteString, ByteString> cursor = txn.openCursor(getName()))
     {
-      final long[] selectedIDs = readRange(cursor, getEntryCount(txn), debugBuilder);
-      return newDefinedSet(selectedIDs);
+      if (cursor.next())
+      {
+        return newDefinedSet(readRange(cursor, getEntryCount(txn), debugBuilder));
+      }
     }
+    return null;
   }
 
   private int getEntryCount(final ReadableTransaction txn)
@@ -695,23 +699,24 @@
     }
   }
 
-  private long[] readRange(final Cursor<ByteString, ByteString> cursor, final int count,
+  private long[] readRange(final Cursor<ByteString, ByteString> definedCursor, final int count,
       final StringBuilder debugBuilder)
   {
+    Reject.ifFalse(definedCursor.isDefined(), "Expected a defined cursor");
     long[] selectedIDs = new long[count];
     int selectedPos = 0;
     if (count > 0)
     {
       do
       {
-        final ByteString key = cursor.getKey();
+        final ByteString key = definedCursor.getKey();
         if (logger.isTraceEnabled())
         {
           logSearchKeyResult(key);
         }
         selectedIDs[selectedPos++] = decodeEntryIDFromVLVKey(key);
       }
-      while (selectedPos < count && cursor.next());
+      while (selectedPos < count && definedCursor.next());
       if (selectedPos < count)
       {
         /*
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java
index efe076e..4640bd3 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/ControlsTestCase.java
@@ -21,7 +21,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2015 ForgeRock AS
+ *      Copyright 2015-2016 ForgeRock AS
  */
 package org.opends.server.backends.pluggable;
 
@@ -78,7 +78,6 @@
 @SuppressWarnings("javadoc")
 public class ControlsTestCase extends DirectoryServerTestCase
 {
-
   private static final String BACKEND_BASE_DN = "dc=pluggable-vlv,dc=com";
   private static final String BACKEND_NAME = "pluggable-vlv";
   private static final String VLV_FILTER = "(objectClass=person)";
@@ -406,6 +405,23 @@
     assertThat(vlvResponse.getVLVResultCode()).isEqualTo(LDAPResultCode.OFFSET_RANGE_ERROR);
   }
 
+  @Test
+  public void serverSideSortControlShouldUseVlvIndex() throws Exception
+  {
+    final SearchRequest request =
+        newSearchRequest(BACKEND_BASE_DN, SearchScope.WHOLE_SUBTREE, VLV_FILTER)
+        .addControl(new ServerSideSortRequestControl(mangleSortOrder(SORT_ORDER_1)));
+    final InternalSearchOperation internalSearch = getRootConnection().processSearch(request);
+
+    assertThat(internalSearch.getResultCode()).isEqualTo(ResultCode.SUCCESS);
+    assertThat(getDNs(internalSearch.getSearchEntries())).isEqualTo(getDNs(USERS_BY_SORT_ORDER_1));
+
+    final List<Control> responseControls = internalSearch.getResponseControls();
+    assertThat(responseControls).hasSize(1);
+    final ServerSideSortResponseControl sortResponse = getServerSideSortResponseControl(responseControls);
+    assertThat(sortResponse.getResultCode()).isEqualTo(LDAPResultCode.SUCCESS);
+  }
+
   @DataProvider
   private Object[][] unindexedVlvByAssertionDataProvider()
   {

--
Gitblit v1.10.0