From dff791d6bdd93ee5127094248f5e3cbc0d529653 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 16 Nov 2006 01:32:41 +0000
Subject: [PATCH] Update the ldapsearch tool to provide a --countEntries option that can be used to count the number of matching entries. The count will be displayed as a comment at the end of the results, and will also be used as the exit code for the tool. This addresses issue #1013.
---
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java | 46 +++++-
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPDeleteTestCase.java | 75 ++++++++++
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearchOptions.java | 26 +++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPModifyTestCase.java | 138 +++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java | 23 +++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java | 91 +++++++++++++
6 files changed, 390 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 49f1f79..e7b3fec 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
@@ -7323,6 +7323,25 @@
/**
+ * The message ID for the message that will be used as the description of the
+ * countEntries property. This does not take any arguments.
+ */
+ public static final int MSGID_DESCRIPTION_COUNT_ENTRIES =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 750;
+
+
+
+ /**
+ * The message ID for the message that will be used to provide the number of
+ * matching entries for a search request. This takes a single argument, which
+ * is the number of matching entries.
+ */
+ public static final int MSGID_LDAPSEARCH_MATCHING_ENTRY_COUNT =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 751;
+
+
+
+ /**
* Associates a set of generic messages with the message IDs defined in this
* class.
*/
@@ -7999,6 +8018,8 @@
"SASL bind options");
registerMessage(MSGID_DESCRIPTION_DONT_WRAP,
"Do not wrap long lines");
+ registerMessage(MSGID_DESCRIPTION_COUNT_ENTRIES,
+ "Count the number of entries returned by the server");
registerMessage(MSGID_LDAPAUTH_PROPERTY_DESCRIPTION_KDC,
"Specifies the KDC to use for the Kerberos " +
"authentication.");
@@ -9428,6 +9449,8 @@
"# The account is locked.");
registerMessage(MSGID_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK,
"# Time until the account is unlocked: %s.");
+ registerMessage(MSGID_LDAPSEARCH_MATCHING_ENTRY_COUNT,
+ "# Total number of matching entries: %d.");
registerMessage(MSGID_TOOL_CONFLICTING_ARGS,
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 538b086..525fbe9 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
@@ -130,18 +130,24 @@
* @param searchOptions The constraints for the search.
* @param wrapColumn The column at which to wrap long lines.
*
+ * @return The number of matching entries returned by the server. If there
+ * were multiple search filters provided, then this will be the
+ * total number of matching entries for all searches.
+ *
* @throws IOException If a problem occurs while attempting to communicate
* with the Directory Server.
*
* @throws LDAPException If the Directory Server returns an error response.
*/
- public void executeSearch(LDAPConnection connection, String baseDN,
- ArrayList<LDAPFilter> filters,
- LinkedHashSet<String> attributes,
- LDAPSearchOptions searchOptions,
- int wrapColumn )
+ public int executeSearch(LDAPConnection connection, String baseDN,
+ ArrayList<LDAPFilter> filters,
+ LinkedHashSet<String> attributes,
+ LDAPSearchOptions searchOptions,
+ int wrapColumn )
throws IOException, LDAPException
{
+ int matchingEntries = 0;
+
for (LDAPFilter filter: filters)
{
ASN1OctetString asn1OctetStr = new ASN1OctetString(baseDN);
@@ -267,6 +273,7 @@
StringBuilder sb = new StringBuilder();
toLDIF(searchEntryOp, sb, wrapColumn, typesOnly);
out.println(sb.toString());
+ matchingEntries++;
break;
case OP_TYPE_SEARCH_RESULT_REFERENCE:
@@ -312,6 +319,15 @@
throw new IOException(ae.getMessage());
}
}
+
+ if (searchOptions.countMatchingEntries())
+ {
+ int msgID = MSGID_LDAPSEARCH_MATCHING_ENTRY_COUNT;
+ String message = getMessage(msgID, matchingEntries);
+ out.println(message);
+ out.println();
+ }
+ return matchingEntries;
}
/**
@@ -522,6 +538,7 @@
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
BooleanArgument continueOnError = null;
+ BooleanArgument countEntries = null;
BooleanArgument dontWrap = null;
BooleanArgument noop = null;
BooleanArgument reportAuthzID = null;
@@ -741,6 +758,10 @@
MSGID_DESCRIPTION_DONT_WRAP);
argParser.addArgument(dontWrap);
+ countEntries = new BooleanArgument("countentries", null, "countEntries",
+ MSGID_DESCRIPTION_COUNT_ENTRIES);
+ argParser.addArgument(countEntries);
+
continueOnError =
new BooleanArgument("continueOnError", 'c', "continueOnError",
MSGID_DESCRIPTION_CONTINUE_ON_ERROR);
@@ -935,6 +956,7 @@
searchOptions.setVerbose(verbose.isPresent());
searchOptions.setContinueOnError(continueOnError.isPresent());
searchOptions.setEncoding(encodingStr.getValue());
+ searchOptions.setCountMatchingEntries(countEntries.isPresent());
try
{
searchOptions.setTimeLimit(timeLimit.getIntValue());
@@ -1276,8 +1298,17 @@
connection.connectToHost(bindDNValue, bindPasswordValue, nextMessageID);
LDAPSearch ldapSearch = new LDAPSearch(nextMessageID, out, err);
- ldapSearch.executeSearch(connection, baseDNValue, filters, attributes,
- searchOptions, wrapColumn);
+ int matchingEntries = ldapSearch.executeSearch(connection, baseDNValue,
+ filters, attributes,
+ searchOptions, wrapColumn);
+ if (countEntries.isPresent())
+ {
+ return matchingEntries;
+ }
+ else
+ {
+ return 0;
+ }
} catch(LDAPException le)
{
@@ -1303,7 +1334,6 @@
connection.close();
}
}
- return 0;
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearchOptions.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearchOptions.java
index 0d84db0..8913370 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearchOptions.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearchOptions.java
@@ -56,6 +56,7 @@
private int sizeLimit = 0;
private int timeLimit = 0;
private boolean typesOnly = false;
+ private boolean countMatchingEntries = false;
/**
* Creates the options instance.
@@ -228,5 +229,30 @@
this.typesOnly = typesOnly;
}
+
+ /**
+ * Indicates whether to report the number of matching entries returned by the
+ * server.
+ *
+ * @return {@code true} if the number of matching entries should be reported,
+ * or {@code false} if not.
+ */
+ public boolean countMatchingEntries()
+ {
+ return countMatchingEntries;
+ }
+
+
+ /**
+ * Specifies whether to report the number of matching entries returned by the
+ * server.
+ *
+ * @param countMatchingEntries Specifies whether to report the number of
+ * matching entries returned by the server.
+ */
+ public void setCountMatchingEntries(boolean countMatchingEntries)
+ {
+ this.countMatchingEntries = countMatchingEntries;
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPDeleteTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPDeleteTestCase.java
index 844c7a4..23eb329 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPDeleteTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPDeleteTestCase.java
@@ -798,6 +798,52 @@
/**
+ * Tests a subtree delete operation using an alternate name for the control.
+ *
+ * @throws Exception If an unexpectd problem occurs.
+ */
+ @Test()
+ public void testSubtreeDeleteAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry e = TestCaseUtils.makeEntry(
+ "dn: uid=test.user,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: test.user",
+ "givenName: Test",
+ "sn: User",
+ "cn: Test User",
+ "userPassword: password");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+ AddOperation addOperation =
+ conn.processAdd(e.getDN(), e.getObjectClasses(), e.getUserAttributes(),
+ e.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "subtreedelete:true",
+ "o=test"
+ };
+
+ assertEquals(LDAPDelete.mainDelete(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests a simple delete using the client-side no-op option.
*
* @throws Exception If an unexpectd problem occurs.
@@ -844,7 +890,34 @@
"o=test"
};
- LDAPDelete.mainDelete(args, false, null, null);
+ assertEquals(LDAPDelete.mainDelete(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
+ * Tests a simple delete using the server-side no-op control with an alternate
+ * name for the no-op control.
+ *
+ * @throws Exception If an unexpectd problem occurs.
+ */
+ @Test()
+ public void testDeleteServerSideNoOpAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "no-op:true",
+ "o=test"
+ };
+
+ assertEquals(LDAPDelete.mainDelete(args, false, null, System.err), 0);
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPModifyTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPModifyTestCase.java
index 5419bed..8145442 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPModifyTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPModifyTestCase.java
@@ -882,6 +882,33 @@
/**
+ * Tests a simple modify operation using LDAP No-Op control with an alternate
+ * name.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testModifyLDAPNoOpAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "no-op:true",
+ "-f", modifyFilePath
+ };
+
+ assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests a simple add operation using LDAP No-Op control.
*
* @throws Exception If an unexpected problem occurs.
@@ -915,6 +942,40 @@
/**
+ * Tests a simple add operation using LDAP No-Op control with an alternate
+ * name.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testAddLDAPNoOpAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ String path = TestCaseUtils.createTempFile(
+ "dn: ou=People,o=test",
+ "changetype: add",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "no-op:true",
+ "-f", path
+ };
+
+ assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests a simple delete operation using LDAP No-Op control.
*
* @throws Exception If an unexpected problem occurs.
@@ -945,6 +1006,37 @@
/**
+ * Tests a simple delete operation using LDAP No-Op control with an alternate
+ * name.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDeleteLDAPNoOpAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ String path = TestCaseUtils.createTempFile(
+ "dn: o=test",
+ "changetype: delete");
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "no-op:true",
+ "-f", path
+ };
+
+ assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests a simple modify DN operation using LDAP No-Op control.
*
* @throws Exception If an unexpected problem occurs.
@@ -990,6 +1082,52 @@
/**
+ * Tests a simple modify DN operation using LDAP No-Op control with an
+ * alternate name.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testModifyDNLDAPNoOpAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry e = TestCaseUtils.makeEntry(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+ AddOperation addOperation =
+ conn.processAdd(e.getDN(), e.getObjectClasses(),
+ e.getUserAttributes(), e.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+ String path = TestCaseUtils.createTempFile(
+ "dn: ou=People,o=test",
+ "changetype: moddn",
+ "newRDN: ou=Users",
+ "deleteOldRDN: 1");
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-J", "no-op:true",
+ "-f", path
+ };
+
+ assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests a simple modify operation using the LDAP assertion control in which
* the assertion is true.
*
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 e587352..46f47aa 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
@@ -1271,6 +1271,33 @@
/**
+ * Tests with the account usability control with an alternate name for an
+ * authenticated search.
+ */
+ @Test()
+ public void testAccountUsabilityControlAltName()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "-b", "o=test",
+ "-s", "base",
+ "-J", "accountusable:true",
+ "(objectClass=*)"
+ };
+
+ assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
+ }
+
+
+
+ /**
* Tests with the LDAP assertion control in which the assertion is true.
*/
@Test()
@@ -1350,6 +1377,70 @@
/**
+ * Tests the use of the LDAP subentries control.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testSubentriesControl()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+
+ Entry e = TestCaseUtils.makeEntry("dn: cn=test,o=test",
+ "objectClass: top",
+ "objectClass: ldapSubEntry",
+ "cn: test");
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+ AddOperation addOperation =
+ conn.processAdd(e.getDN(), e.getObjectClasses(), e.getUserAttributes(),
+ e.getOperationalAttributes());
+ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
+
+ String[] args =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-b", "o=test",
+ "-s", "sub",
+ "--countEntries",
+ "(objectClass=*)"
+ };
+
+ assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 1);
+
+ args = new String[]
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-b", "o=test",
+ "-s", "sub",
+ "--countEntries",
+ "-J", OID_LDAP_SUBENTRIES + ":true",
+ "(objectClass=*)"
+ };
+
+ assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 2);
+
+ args = new String[]
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-b", "o=test",
+ "-s", "sub",
+ "--countEntries",
+ "-J", "subentries:true",
+ "(objectClass=*)"
+ };
+
+ assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 2);
+ }
+
+
+
+ /**
* Tests the inclusion of multiple arbitrary controls in the request to the
* server.
*
--
Gitblit v1.10.0