mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
05.13.2007 97a278742576929ec8c6e63d570a1cc00f38c543
Update the ldapsearch tool to provide support for using the simple paged
results control.

OpenDS Issue Number: 1204
4 files modified
233 ■■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java 53 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java 111 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolOptions.java 12 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java 57 ●●●●● patch | view | raw | blame | history
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 " +
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;
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.
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()