From 97a278742576929ec8c6e63d570a1cc00f38c543 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Mon, 05 Feb 2007 04:13:38 +0000
Subject: [PATCH] Update the ldapsearch tool to provide support for using the simple paged results control.
---
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java | 111 ++++++++++++++++++++++++++-
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java | 12 ++
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java | 53 +++++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java | 57 ++++++++++++++
4 files changed, 224 insertions(+), 9 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
index 0244cc9..37731ce 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -7518,6 +7518,47 @@
/**
+ * The message ID for the message that will be used as the description for the
+ * command-line option that includes the simple paged results control in the
+ * request. This does not take any arguments.
+ */
+ public static final int MSGID_DESCRIPTION_SIMPLE_PAGE_SIZE =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 790;
+
+
+
+ /**
+ * The message ID for the message that will be used if an attempt is made to
+ * use the simple paged results control in conjunction with multiple search
+ * filters. This does not take any arguments.
+ */
+ public static final int MSGID_PAGED_RESULTS_REQUIRES_SINGLE_FILTER =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 791;
+
+
+
+ /**
+ * The message ID for the message that will be used if an error occurs while
+ * attempting to decode the simple paged results response control from the
+ * server. This takes a single argument, which is a message explaining the
+ * problem that occurred.
+ */
+ public static final int MSGID_PAGED_RESULTS_CANNOT_DECODE =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 792;
+
+
+
+ /**
+ * The message ID for the message that will be used if the simple paged
+ * results control is not found in the response from the server. This does
+ * not take any arguments.
+ */
+ public static final int MSGID_PAGED_RESULTS_RESPONSE_NOT_FOUND =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 793;
+
+
+
+ /**
* Associates a set of generic messages with the message IDs defined in this
* class.
*/
@@ -7949,6 +7990,9 @@
"authorization ID");
registerMessage(MSGID_DESCRIPTION_PSEARCH_INFO,
"Use the persistent search control");
+ registerMessage(MSGID_DESCRIPTION_SIMPLE_PAGE_SIZE,
+ "Use the simple paged results control with the given " +
+ "page size");
registerMessage(MSGID_DESCRIPTION_REPORT_AUTHZID,
"Use the authorization identity control");
registerMessage(MSGID_DESCRIPTION_USE_PWP_CONTROL,
@@ -8279,6 +8323,15 @@
"Invalid scope %s specified for the search request.");
registerMessage(MSGID_SEARCH_NO_FILTERS,
"No filters specified for the search request.");
+ registerMessage(MSGID_PAGED_RESULTS_REQUIRES_SINGLE_FILTER,
+ "The simple paged results control may only be used with " +
+ "a single search filter.");
+ registerMessage(MSGID_PAGED_RESULTS_CANNOT_DECODE,
+ "Unable to decode the simple paged results control from " +
+ "the search response: %s.");
+ registerMessage(MSGID_PAGED_RESULTS_RESPONSE_NOT_FOUND,
+ "The simple paged results response control was not found " +
+ "in the search result done message from the server.");
registerMessage(MSGID_PSEARCH_MISSING_DESCRIPTOR,
"The request to use the persistent search control did " +
"not include a descriptor that indicates the options to " +
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
index fd9a4ad..cfde1b7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.server.tools;
@@ -42,6 +42,7 @@
import org.opends.server.controls.EntryChangeNotificationControl;
import org.opends.server.controls.MatchedValuesControl;
import org.opends.server.controls.MatchedValuesFilter;
+import org.opends.server.controls.PagedResultsControl;
import org.opends.server.controls.PersistentSearchChangeType;
import org.opends.server.controls.PersistentSearchControl;
import org.opends.server.core.DirectoryServer;
@@ -93,6 +94,9 @@
+ // The set of response controls for the search.
+ private ArrayList<LDAPControl> responseControls;
+
// The message ID counter to use for requests.
private AtomicInteger nextMessageID;
@@ -117,6 +121,7 @@
this.nextMessageID = nextMessageID;
this.out = out;
this.err = err;
+ responseControls = new ArrayList<LDAPControl>();
}
@@ -175,14 +180,14 @@
ASN1Element element = connection.getASN1Reader().readElement();
LDAPMessage responseMessage =
LDAPMessage.decode(ASN1Sequence.decodeAsSequence(element));
- ArrayList<LDAPControl> controls = responseMessage.getControls();
+ responseControls = responseMessage.getControls();
opType = responseMessage.getProtocolOpType();
switch(opType)
{
case OP_TYPE_SEARCH_RESULT_ENTRY:
- for (LDAPControl c : controls)
+ for (LDAPControl c : responseControls)
{
if (c.getOID().equals(OID_ENTRY_CHANGE_NOTIFICATION))
{
@@ -287,6 +292,7 @@
responseMessage.getSearchResultDoneProtocolOp();
resultCode = searchOp.getResultCode();
errorMessage = searchOp.getErrorMessage();
+
break;
default:
// FIXME - throw exception?
@@ -462,6 +468,18 @@
}
/**
+ * Retrieves the set of response controls included in the last search result
+ * done message.
+ *
+ * @return The set of response controls included in the last search result
+ * done message.
+ */
+ public ArrayList<LDAPControl> getResponseControls()
+ {
+ return responseControls;
+ }
+
+ /**
* The main method for LDAPSearch tool.
*
* @param args The command-line arguments provided to this program.
@@ -554,6 +572,7 @@
FileBasedArgument keyStorePasswordFile = null;
FileBasedArgument trustStorePasswordFile = null;
IntegerArgument port = null;
+ IntegerArgument simplePageSize = null;
IntegerArgument sizeLimit = null;
IntegerArgument timeLimit = null;
IntegerArgument version = null;
@@ -706,6 +725,13 @@
null, null, MSGID_DESCRIPTION_PSEARCH_INFO);
argParser.addArgument(pSearchInfo);
+ simplePageSize = new IntegerArgument("simplepagesize", null,
+ "simplePageSize", false, false, true,
+ "{numEntries}", 1000, null, true, 1,
+ false, 0,
+ MSGID_DESCRIPTION_SIMPLE_PAGE_SIZE);
+ argParser.addArgument(simplePageSize);
+
assertionFilter = new StringArgument("assertionfilter", null,
"assertionFilter", false, false,
true, "{filter}", null, null,
@@ -1297,10 +1323,81 @@
connectionOptions, out, err);
connection.connectToHost(bindDNValue, bindPasswordValue, nextMessageID);
- LDAPSearch ldapSearch = new LDAPSearch(nextMessageID, out, err);
- int matchingEntries = ldapSearch.executeSearch(connection, baseDNValue,
- filters, attributes,
- searchOptions, wrapColumn);
+ int matchingEntries = 0;
+ if (simplePageSize.isPresent())
+ {
+ if (filters.size() > 1)
+ {
+ int msgID = MSGID_PAGED_RESULTS_REQUIRES_SINGLE_FILTER;
+ String message = getMessage(msgID);
+ throw new LDAPException(CLIENT_SIDE_PARAM_ERROR, msgID, message);
+ }
+
+ int pageSize = simplePageSize.getIntValue();
+ ASN1OctetString cookieValue = new ASN1OctetString();
+ ArrayList<LDAPControl> origControls = searchOptions.getControls();
+
+ while (true)
+ {
+ ArrayList<LDAPControl> newControls =
+ new ArrayList<LDAPControl>(origControls.size()+1);
+ newControls.addAll(origControls);
+ newControls.add(new LDAPControl(
+ new PagedResultsControl(true, pageSize, cookieValue)));
+ searchOptions.setControls(newControls);
+
+ LDAPSearch ldapSearch = new LDAPSearch(nextMessageID, out, err);
+ matchingEntries += ldapSearch.executeSearch(connection, baseDNValue,
+ filters, attributes,
+ searchOptions,
+ wrapColumn);
+
+ ArrayList<LDAPControl> responseControls =
+ ldapSearch.getResponseControls();
+ boolean responseFound = false;
+ for (LDAPControl c :responseControls)
+ {
+ if (c.getOID().equals(OID_PAGED_RESULTS_CONTROL))
+ {
+ try
+ {
+ PagedResultsControl control =
+ new PagedResultsControl(c.isCritical(), c.getValue());
+ responseFound = true;
+ cookieValue = control.getCookie();
+ break;
+ }
+ catch (LDAPException le)
+ {
+ int msgID = MSGID_PAGED_RESULTS_CANNOT_DECODE;
+ String message = getMessage(msgID, le.getMessage());
+ throw new LDAPException(CLIENT_SIDE_DECODING_ERROR, msgID,
+ message, le);
+ }
+ }
+ }
+
+ if (! responseFound)
+ {
+ int msgID = MSGID_PAGED_RESULTS_RESPONSE_NOT_FOUND;
+ String message = getMessage(msgID);
+ throw new LDAPException(CLIENT_SIDE_CONTROL_NOT_FOUND, msgID,
+ message);
+ }
+ else if (cookieValue.value().length == 0)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ LDAPSearch ldapSearch = new LDAPSearch(nextMessageID, out, err);
+ matchingEntries = ldapSearch.executeSearch(connection, baseDNValue,
+ filters, attributes,
+ searchOptions, wrapColumn);
+ }
+
if (countEntries.isPresent())
{
return matchingEntries;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java
index 1fdda1f..5a9165f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.server.tools;
@@ -141,6 +141,16 @@
}
/**
+ * Specifies the set of controls to apply to the operation.
+ *
+ * @param controls The set of controls to apply to the operation.
+ */
+ public void setControls(ArrayList<LDAPControl> controls)
+ {
+ this.controls = controls;
+ }
+
+ /**
* Set the encoding.
*
* @param encodingStr The encoding to use for string values.
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
index 46f47aa..522bf5a 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.server.tools;
@@ -1471,6 +1471,61 @@
/**
+ * Tests the use of the simple paged results control.
+ *
+ * @throws Exception If an unexpectd problem occurs.
+ */
+ @Test()
+ public void testSimplePagedResults()
+ throws Exception
+ {
+ TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com");
+
+ TestCaseUtils.addEntries(
+ "dn: cn=device 1,dc=example,dc=com",
+ "objectClass: top",
+ "objectClass: device",
+ "cn: device 1",
+ "",
+ "dn: cn=device 2,dc=example,dc=com",
+ "objectClass: top",
+ "objectClass: device",
+ "cn: device 2",
+ "",
+ "dn: cn=device 3,dc=example,dc=com",
+ "objectClass: top",
+ "objectClass: device",
+ "cn: device 3",
+ "",
+ "dn: cn=device 4,dc=example,dc=com",
+ "objectClass: top",
+ "objectClass: device",
+ "cn: device 4",
+ "",
+ "dn: cn=device 5,dc=example,dc=com",
+ "objectClass: top",
+ "objectClass: device",
+ "cn: device 5");
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-b", "dc=example,dc=com",
+ "-s", "one",
+ "--simplePageSize", "2",
+ "--countEntries",
+ "(objectClass=*)"
+ };
+
+ assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 5);
+ }
+
+
+
+ /**
* Tests the LDAPSearch tool with the "--help" option.
*/
@Test()
--
Gitblit v1.10.0