/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
* Portions copyright 2011-2012 ForgeRock AS
*/
package org.opends.server.core;
import static org.opends.server.util.ServerConstants.OID_LDUP_SUBENTRIES;
import static org.testng.Assert.*;
import java.io.IOException;
import java.net.Socket;
import java.util.*;
import org.opends.server.TestCaseUtils;
import org.opends.server.controls.MatchedValuesControl;
import org.opends.server.controls.MatchedValuesFilter;
import org.opends.server.controls.SubentriesControl;
import org.opends.server.plugins.InvocationCounterPlugin;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.BindRequestProtocolOp;
import org.opends.server.protocols.ldap.BindResponseProtocolOp;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPConstants;
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPMessage;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
import org.opends.server.tools.LDAPModify;
import org.opends.server.tools.LDAPWriter;
import org.opends.server.types.Attribute;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.Entry;
import org.opends.server.types.LDAPException;
import org.opends.server.types.Operation;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.SearchScope;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.StaticUtils;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class SearchOperationTestCase extends OperationTestCase
{
private static final String SUFFIX = "dc=example,dc=com";
private static final String BASE = "o=Test Core Search,dc=example,dc=com";
private Entry testEntry;
private int ldapAttrCount;
@BeforeClass
public void setUp() throws Exception
{
TestCaseUtils.startServer();
TestCaseUtils.clearJEBackend(true,"userRoot","dc=example,dc=com");
InternalClientConnection connection =
InternalClientConnection.getRootConnection();
// Add the suffix entry.
DN suffixDN = DN.decode(SUFFIX);
if (DirectoryServer.getEntry(suffixDN) == null)
{
Entry suffixEntry = StaticUtils.createEntry(suffixDN);
AddOperation addOperation =
connection.processAdd(suffixEntry.getDN(),
suffixEntry.getObjectClasses(),
suffixEntry.getUserAttributes(),
suffixEntry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(suffixEntry.getDN()));
}
// Add a search base entry.
DN baseDN = DN.decode(BASE);
if (DirectoryServer.getEntry(baseDN) == null)
{
Entry baseEntry = StaticUtils.createEntry(baseDN);
AddOperation addOperation =
connection.processAdd(baseEntry.getDN(),
baseEntry.getObjectClasses(),
baseEntry.getUserAttributes(),
baseEntry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(baseEntry.getDN()));
}
// Add a test ldapsubentry.
Entry ldapSubentry = TestCaseUtils.makeEntry(
"dn: cn=subentry," + BASE,
"objectclass: ldapsubentry");
AddOperation addOperation =
connection.processAdd(ldapSubentry.getDN(),
ldapSubentry.getObjectClasses(),
ldapSubentry.getUserAttributes(),
ldapSubentry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(ldapSubentry.getDN()));
// Add a test entry.
testEntry = TestCaseUtils.makeEntry(
"dn: uid=rogasawara," + BASE,
"userpassword: password",
"objectclass: top",
"objectclass: person",
"objectclass: organizationalPerson",
"objectclass: inetOrgPerson",
"uid: rogasawara",
"mail: rogasawara@airius.co.jp",
"givenname;lang-ja:: 44Ot44OJ44OL44O8",
"sn;lang-ja:: 5bCP56yg5Y6f",
"cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==",
"title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==",
"preferredlanguage: ja",
"givenname:: 44Ot44OJ44OL44O8",
"sn:: 5bCP56yg5Y6f",
"cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==",
"title:: 5Za25qWt6YOoIOmDqOmVtw==",
"givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8",
"sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ",
"cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==",
"title;lang-ja;phonetic:: " +
"44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==",
"givenname;lang-en: Rodney",
"sn;lang-en: Ogasawara",
"cn;lang-en: Rodney Ogasawara",
"title;lang-en: Sales, Director"
);
// Calculate the total number of LDAP attributes in this entry.
ldapAttrCount = 1; // For the objectclass attribute.
for (Attribute a : testEntry.getAttributes())
{
ldapAttrCount += a.size();
}
// The add operation changes the attributes, so let's duplicate the entry.
Entry duplicateEntry = testEntry.duplicate(false);
addOperation =
connection.processAdd(duplicateEntry.getDN(),
duplicateEntry.getObjectClasses(),
duplicateEntry.getUserAttributes(),
duplicateEntry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(testEntry.getDN()));
// Add a test referral entry.
Entry referralEntry = TestCaseUtils.makeEntry(
"dn: ou=People," + BASE,
"objectclass: extensibleobject",
"objectclass: referral",
"ref: ldap://hostb/OU=People,O=MNN,C=US",
"ref: ldap://hostc/OU=People,O=MNN,C=US");
addOperation =
connection.processAdd(referralEntry.getDN(),
referralEntry.getObjectClasses(),
referralEntry.getUserAttributes(),
referralEntry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(referralEntry.getDN()));
Entry level1Entry = TestCaseUtils.makeEntry(
"dn: ou=level1," + BASE,
"objectclass: top",
"objectclass: organizationalunit",
"ou: level1");
addOperation =
connection.processAdd(level1Entry.getDN(),
level1Entry.getObjectClasses(),
level1Entry.getUserAttributes(),
level1Entry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(level1Entry.getDN()));
Entry level2Entry = TestCaseUtils.makeEntry(
"dn: ou=level2,ou=level1," + BASE,
"objectclass: top",
"objectclass: organizationalunit",
"ou: level2");
addOperation =
connection.processAdd(level2Entry.getDN(),
level2Entry.getObjectClasses(),
level2Entry.getUserAttributes(),
level2Entry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(level2Entry.getDN()));
Entry referral2Entry = TestCaseUtils.makeEntry(
"dn: ou=level3,ou=level2,ou=level1," + BASE,
"objectclass: extensibleobject",
"objectclass: referral",
"ref: ldap://hostb/OU=People,O=MNN,C=US",
"ref: ldap://hostc/OU=People,O=MNN,C=US",
"ref: ldap://hostd/OU=People,O=MNN,C=US");
addOperation =
connection.processAdd(referral2Entry.getDN(),
referral2Entry.getObjectClasses(),
referral2Entry.getUserAttributes(),
referral2Entry.getOperationalAttributes());
assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
assertNotNull(DirectoryServer.getEntry(referral2Entry.getDN()));
}
@Override
protected Operation[] createTestOperations() throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
return new Operation[]
{
new SearchOperationBasis(conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
-1,
-1,
false,
LDAPFilter.decode("(objectclass=*)"),
null)
};
}
/**
* Invokes a number of operation methods on the provided search operation
* for which all processing has been completed.
*
* @param searchOperation The operation to be tested.
*/
private void examineCompletedOperation(SearchOperation searchOperation)
{
assertTrue(searchOperation.getProcessingStartTime() > 0);
assertTrue(searchOperation.getProcessingStopTime() > 0);
assertTrue(searchOperation.getProcessingTime() >= 0);
assertNotNull(searchOperation.getResponseLogElements());
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
ensurePostReponseHasRun();
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
private Entry searchInternalForSingleEntry(
InternalSearchOperation searchOperation)
{
InvocationCounterPlugin.resetAllCounters();
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
examineCompletedOperation(searchOperation);
return searchOperation.getSearchEntries().getFirst();
}
private SearchResultEntryProtocolOp searchExternalForSingleEntry(
SearchRequestProtocolOp searchRequest,
ArrayList<Control> controls)
throws Exception
{
// Establish a connection to the server.
Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
try
{
org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
TestCaseUtils.configureSocket(s);
bindAsManager(w, r);
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request
// to ensure that any remaining post-response processing from the previous
// operation has completed.
assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
InvocationCounterPlugin.resetAllCounters();
long searchRequests = ldapStatistics.getSearchRequests();
long searchEntries = ldapStatistics.getSearchResultEntries();
long searchReferences = ldapStatistics.getSearchResultReferences();
long searchesDone = ldapStatistics.getSearchResultsDone();
LDAPMessage message;
message = new LDAPMessage(2, searchRequest, controls);
w.writeMessage(message);
SearchResultEntryProtocolOp searchResultEntry = null;
SearchResultDoneProtocolOp searchResultDone = null;
while (searchResultDone == null && (message = r.readMessage()) != null)
{
switch (message.getProtocolOpType())
{
case LDAPConstants.OP_TYPE_SEARCH_RESULT_ENTRY:
searchResultEntry = message.getSearchResultEntryProtocolOp();
searchEntries++;
break;
case LDAPConstants.OP_TYPE_SEARCH_RESULT_REFERENCE:
searchReferences++;
break;
case LDAPConstants.OP_TYPE_SEARCH_RESULT_DONE:
searchResultDone = message.getSearchResultDoneProtocolOp();
assertEquals(searchResultDone.getResultCode(),
LDAPResultCode.SUCCESS);
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
searchesDone++;
break;
}
}
TestCaseUtils.quiesceServer();
assertEquals(ldapStatistics.getSearchRequests(), searchRequests+1);
assertEquals(ldapStatistics.getSearchResultEntries(), searchEntries);
assertEquals(ldapStatistics.getSearchResultReferences(),
searchReferences);
assertEquals(ldapStatistics.getSearchResultsDone(), searchesDone);
return searchResultEntry;
}
finally
{
s.close();
}
}
private void bindAsManager(LDAPWriter w, org.opends.server.tools.LDAPReader r)
throws IOException, LDAPException, ASN1Exception, InterruptedException
{
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request to
// ensure that any remaining post-response processing from the previous
// operation has completed.
assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
InvocationCounterPlugin.resetAllCounters();
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(
ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
w.writeMessage(message);
message = r.readMessage();
BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
}
@Test
public void testSearchInternal() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=*)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 4);
assertEquals(searchOperation.getReferencesSent(), 2);
assertEquals(searchOperation.getErrorMessage().length(), 0);
examineCompletedOperation(searchOperation);
}
@Test
public void testSearchInternalUnspecifiedAttributes() throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses(), testEntry.getObjectClasses());
// Search results contain objectClass as an attribute.
assertEquals(resultEntry.getUserAttributes().size(),
testEntry.getUserAttributes().size() + 1);
assertEquals(resultEntry.getOperationalAttributes().size(), 0);
}
@Test
public void testSearchInternalUnspecifiedAttributesOmitValues()
throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
true,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses().size(), 0);
assertEquals(resultEntry.getUserAttributes().size(),
testEntry.getUserAttributes().size() + 1);
assertEquals(resultEntry.getOperationalAttributes().size(), 0);
}
@Test
public void testSearchInternalAllOperationalAttributes() throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("+");
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses().size(), 0);
assertEquals(resultEntry.getUserAttributes().size(), 0);
assertTrue(resultEntry.getOperationalAttributes().size() > 0);
}
@Test
public void testSearchInternalAllUserAndOperationalAttributes()
throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("*");
attributes.add("+");
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses(), testEntry.getObjectClasses());
assertTrue(resultEntry.getOperationalAttributes().size() > 0);
// Search results contain objectClass as an attribute.
assertEquals(resultEntry.getUserAttributes().size(),
testEntry.getUserAttributes().size() + 1);
}
@Test
public void testSearchInternalAllUserAttributesPlusSelectedOperational()
throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("*");
attributes.add("createtimestamp");
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses(), testEntry.getObjectClasses());
// Search results contain objectClass as an attribute.
assertEquals(resultEntry.getUserAttributes().size(),
testEntry.getUserAttributes().size() + 1);
assertEquals(resultEntry.getOperationalAttributes().size(), 1);
}
@Test
public void testSearchInternalSelectedAttributes()
throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("uid");
attributes.add("createtimestamp");
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes, null);
Entry resultEntry = searchInternalForSingleEntry(searchOperation);
assertEquals(resultEntry.getObjectClasses().size(), 0);
assertEquals(resultEntry.getUserAttributes().size(), 1);
assertEquals(resultEntry.getOperationalAttributes().size(), 1);
}
@Test
public void testSearchExternalUnspecifiedAttributes() throws Exception
{
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
}
@Test
public void testSearchExternalAllUserAttributes() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("*");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
}
@Test
public void testSearchExternalUnspecifiedAttributesOmitValues()
throws Exception
{
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
true,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
// The attributes will include the objectclass type.
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
for (LDAPAttribute a : searchResultEntry.getAttributes())
{
assertEquals(a.getValues().size(), 0);
}
}
@Test
public void testSearchExternalAllUserAttributesOmitValues() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("*");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
true,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
// The attributes will include the objectclass type.
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
for (LDAPAttribute a : searchResultEntry.getAttributes())
{
assertEquals(a.getValues().size(), 0);
}
}
@Test
public void testSearchExternalObjectClassAttribute() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("objectclass");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 1);
assertEquals(searchResultEntry.getAttributes().
getFirst().getValues().size(), 4);
}
@Test
public void testSearchExternalObjectClassAttributeOmitValues()
throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("objectclass");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
true,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 1);
assertEquals(searchResultEntry.getAttributes().
getFirst().getValues().size(), 0);
}
@Test
public void testSearchExternalSelectedAttributes() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("uid");
attributes.add("createtimestamp");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 2);
}
@Test
public void testSearchExternalAttributeWithSubtypes() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("title");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 4);
}
@Test
public void testSearchExternalAttributeWithSubtypesOmitValues()
throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("title");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
true,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 4);
for (LDAPAttribute a : searchResultEntry.getAttributes())
{
assertEquals(a.getValues().size(), 0);
}
}
@Test
public void testSearchExternalAttributeWithOptions() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("title;lang-ja;phonetic");
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 1);
}
@Test
public void testSearchExternalMatchedValues() throws Exception
{
// Add a matched values control.
LDAPFilter ldapFilter = LDAPFilter.decode("(title=*director*)");
MatchedValuesFilter matchedValuesFilter =
MatchedValuesFilter.createFromLDAPFilter(ldapFilter);
ArrayList<MatchedValuesFilter> filters =
new ArrayList<MatchedValuesFilter>();
filters.add(matchedValuesFilter);
MatchedValuesControl mvc = new MatchedValuesControl(true, filters);
ArrayList<Control> controls = new ArrayList<Control>();
controls.add(mvc);
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null);
SearchResultEntryProtocolOp searchResultEntry =
searchExternalForSingleEntry(searchRequest, controls);
// Per RFC 3876, an attribute that has no values selected is returned
// with an empty set of values. We should therefore expect all the
// attributes but only one value.
int valueCount = 0;
for (LDAPAttribute a : searchResultEntry.getAttributes())
{
valueCount += a.getValues().size();
}
assertEquals(valueCount, 1);
}
@Test
public void testSearchInternalReferences() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=inetorgperson)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getReferencesSent(), 2);
assertEquals(searchOperation.getErrorMessage().length(), 0);
examineCompletedOperation(searchOperation);
List<SearchResultReference> references =
searchOperation.getSearchReferences();
assertEquals(references.size(), 2);
// One contains 2 URLs, the other contains 3. Cannot guarantee
// ordering of the returned references, so just check the total is correct.
int urls = references.get(0).getReferralURLs().size() +
references.get(1).getReferralURLs().size();
assertEquals(urls, 5);
}
/**
* This does a single-level search that finds one referral object, but
* not the one in a deeper subtree.
*
* @throws Exception
*/
@Test
public void testSearchSingleDeepReferences() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.SINGLE_LEVEL,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(ou=*)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getReferencesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
examineCompletedOperation(searchOperation);
List<SearchResultReference> references =
searchOperation.getSearchReferences();
assertEquals(references.size(), 1);
List<String> referrals = references.get(0).getReferralURLs();
assertEquals(referrals.size(), 2);
}
@Test
public void testSearchInternalSubEntryEqualityFilter() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=ldapsubentry)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
}
@Test
public void testSearchInternalSubEntryControl() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
Collections.singletonList((Control)new SubentriesControl(true, true)),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=*)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
}
@Test
public void testSearchInternalLegacySubEntryControl() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation = new InternalSearchOperation(conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
Collections.singletonList((Control) new LDAPControl(
OID_LDUP_SUBENTRIES, true)), ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE, DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE, Integer.MAX_VALUE, false,
LDAPFilter.decode("(objectclass=*)"), null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
}
@Test
public void testSearchInternalSubEntryAndFilter() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(&(cn=*)(objectclass=ldapsubentry))"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(&(&(cn=*)(objectclass=ldapsubentry)))"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 1);
assertEquals(searchOperation.getErrorMessage().length(), 0);
}
@Test
public void testSearchInternalSubEntryOrFilter() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf(BASE),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(|(objectclass=ldapsubentry)(objectclass=top))"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getEntriesSent(), 5);
assertEquals(searchOperation.getErrorMessage().length(), 0);
}
@Test
public void testSearchInternalMatchedDN() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
TestCaseUtils.initializeTestBackend(true);
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf("ou=nonexistent,o=test"),
SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=*)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.NO_SUCH_OBJECT);
assertNotNull(searchOperation.getMatchedDN());
}
/**
* Determines how attributes should be filtered in search operations.
*/
private enum AttributeFilterType {
DEFAULT, WILDCARDS, ENUMERATED;
}
/**
* Returns test data for testSearchInternalAttributeFilters.
*
* @return The test data.
*/
@DataProvider(name = "testSearchInternalAttributeFilters")
public Object[][] createTestSearchInternalAttributeFiltersData()
{
// It was quicker to cut n paste...
return new Object[][] {
{AttributeFilterType.DEFAULT, false, false, false},
{AttributeFilterType.DEFAULT, false, false, true},
{AttributeFilterType.DEFAULT, false, true, false},
{AttributeFilterType.DEFAULT, false, true, true},
{AttributeFilterType.DEFAULT, true, false, false},
{AttributeFilterType.DEFAULT, true, false, true},
{AttributeFilterType.DEFAULT, true, true, false},
{AttributeFilterType.DEFAULT, true, true, true},
{AttributeFilterType.WILDCARDS, false, false, false},
{AttributeFilterType.WILDCARDS, false, false, true},
{AttributeFilterType.WILDCARDS, false, true, false},
{AttributeFilterType.WILDCARDS, false, true, true},
{AttributeFilterType.WILDCARDS, true, false, false},
{AttributeFilterType.WILDCARDS, true, false, true},
{AttributeFilterType.WILDCARDS, true, true, false},
{AttributeFilterType.WILDCARDS, true, true, true},
{AttributeFilterType.ENUMERATED, false, false, false},
{AttributeFilterType.ENUMERATED, false, false, true},
{AttributeFilterType.ENUMERATED, false, true, false},
{AttributeFilterType.ENUMERATED, false, true, true},
{AttributeFilterType.ENUMERATED, true, false, false},
{AttributeFilterType.ENUMERATED, true, false, true},
{AttributeFilterType.ENUMERATED, true, true, false},
{AttributeFilterType.ENUMERATED, true, true, true},
};
}
/**
* Tests that attribute filtering is performed correctly for real and
* virtual attributes when various combinations of typesOnly, and the
* real-attributes-only and virtual-attributes-only controls are used
* (issues 3446 and 3726).
*
* @param filterType
* Specifies how attributes should be filtered.
* @param typesOnly
* Strip attribute values.
* @param stripVirtualAttributes
* Strip virtual attributes.
* @param stripRealAttributes
* Strip real attributes.
* @throws Exception
* If an unexpected problem occurs.
*/
@Test(dataProvider = "testSearchInternalAttributeFilters")
public void testSearchInternalAttributeFilters(
AttributeFilterType filterType, boolean typesOnly,
boolean stripVirtualAttributes, boolean stripRealAttributes)
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
// Real attributes (these are all user attributes).
List<String> realAttrTypes =
Arrays.asList("objectclass", "uid", "cn", "sn", "givenname",
"userpassword");
// Virtual attributes (these are all operational attributes).
List<String> virtualAttrTypes =
Arrays.asList("numsubordinates", "hassubordinates",
"subschemasubentry", "entrydn", "ismemberof");
String userDNString = "uid=test.user,o=test";
DN userDN = DN.decode(userDNString);
TestCaseUtils.addEntry("dn: " + userDNString,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Entry userEntry = DirectoryServer.getEntry(userDN);
assertNotNull(userEntry);
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
switch (filterType)
{
case DEFAULT:
// Only user attributes.
attributes = null;
break;
case WILDCARDS:
attributes.add("*");
attributes.add("+");
break;
case ENUMERATED:
attributes.addAll(realAttrTypes);
attributes.addAll(virtualAttrTypes);
break;
}
List<Control> controls = new LinkedList<Control>();
if (stripRealAttributes)
{
controls.add(new LDAPControl(ServerConstants.OID_VIRTUAL_ATTRS_ONLY,
false));
}
if (stripVirtualAttributes)
{
controls.add(new LDAPControl(ServerConstants.OID_REAL_ATTRS_ONLY,
false));
}
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation search =
conn.processSearch(userDNString, SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, // Size limit
0, // Time limit
typesOnly, // Types only
"(objectClass=*)", attributes, controls, null);
assertEquals(search.getResultCode(), ResultCode.SUCCESS);
LinkedList<SearchResultEntry> entries = search.getSearchEntries();
assertEquals(entries.size(), 1);
Entry entry = entries.getFirst();
assertEquals(entry.getDN(), userDN);
// Check real attributes.
List<String> messages = new LinkedList<String>();
for (String attrType : realAttrTypes)
{
List<Attribute> attrList = entry.getAttribute(attrType);
if (stripRealAttributes)
{
if (attrList != null)
{
messages.add("Unexpected real attribute: " + attrType);
}
}
else
{
if (attrList == null)
{
messages.add("Missing real attribute: " + attrType);
}
else
{
Attribute attr = attrList.get(0);
if (typesOnly)
{
if (!attr.isEmpty())
{
messages.add("Unexpected non-empty real attribute: "
+ attrType);
}
}
else
{
if (attr.isEmpty())
{
messages.add("Unexpected empty real attribute: "
+ attrType);
}
}
}
}
}
// Check virtual (operational) attributes.
for (String attrType : virtualAttrTypes)
{
List<Attribute> attrList = entry.getAttribute(attrType);
if (stripVirtualAttributes)
{
if (attrList != null)
{
messages.add("Unexpected virtual attribute: " + attrType);
}
}
else if (filterType == AttributeFilterType.DEFAULT)
{
if (attrList != null)
{
messages.add("Unexpected operational attribute: " + attrType);
}
}
else if (attrType.equals("ismemberof"))
{
// isMemberOf should never be returned as user is not in any
// groups.
if (attrList != null)
{
messages.add("Unexpected isMemberOf attribute");
}
}
else
{
if (attrList == null)
{
messages.add("Missing virtual attribute: " + attrType);
}
else
{
Attribute attr = attrList.get(0);
if (typesOnly)
{
if (!attr.isEmpty())
{
messages.add("Unexpected non-empty virtual attribute: "
+ attrType);
}
}
else
{
if (attr.isEmpty())
{
messages.add("Unexpected empty virtual attribute: "
+ attrType);
}
}
}
}
}
assertTrue(messages.isEmpty(), "Entry invalid: " + messages);
}
/**
* Returns test data for testSearchInternalUserAttributeNames.
*
* @return The test data.
*/
@DataProvider(name = "testSearchInternalUserAttributeNames")
public Object[][] createTestSearchInternalUserAttributeNamesData()
{
// First array is the requested attributes.
// Second array is the expected attribute names in the entry.
return new Object[][] {
{
Arrays.<String>asList(),
Arrays.asList("objectClass", "cn", "cn;lang-fr") },
{
Arrays.asList("*", "+"),
Arrays.asList("objectClass", "cn", "cn;lang-fr", "entryDN",
"createTimestamp") },
{
Arrays.asList("objectClass", "cn", "cn;lang-fr", "entryDN",
"createTimestamp"),
Arrays.asList("objectClass", "cn", "cn;lang-fr", "entryDN",
"createTimestamp") },
{
Arrays.asList("OBJECTCLASS", "commonName", "commonName;LANG-FR", "entrydn",
"CREATETIMESTAMP"),
Arrays.asList("OBJECTCLASS", "commonName",
"commonName;LANG-FR", "entrydn", "CREATETIMESTAMP") },
{
Arrays.asList("*", "+", "OBJECTCLASS", "commonName",
"commonName;LANG-FR", "entrydn", "CREATETIMESTAMP"),
Arrays.asList("OBJECTCLASS", "commonName",
"commonName;LANG-FR", "entrydn", "CREATETIMESTAMP") },
{ Arrays.asList("name"),
Arrays.asList("givenName", "sn", "cn", "cn;lang-fr") },
{ Arrays.asList("name;lang-fr"), Arrays.asList("cn;lang-fr") },
{ Arrays.asList("name;LANG-FR"), Arrays.asList("cn;LANG-FR") }, };
}
/**
* Tests that attributes are returned from internal searches using the
* attribute name requested by the user.
*
* @param requestedAttributes
* The list of requested attributes names.
* @param expectedAttributes
* The list of expected attribute names.
* @throws Exception
* If an unexpected problem occurs.
*/
@Test(dataProvider = "testSearchInternalUserAttributeNames")
public void testSearchInternalUserAttributeNames(
List<String> requestedAttributes, List<String> expectedAttributes)
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
String userDNString = "uid=test.user,o=test";
DN userDN = DN.decode(userDNString);
TestCaseUtils.addEntry("dn: " + userDNString,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"cn;lang-fr: Test Usager",
"userPassword: password");
Entry userEntry = DirectoryServer.getEntry(userDN);
assertNotNull(userEntry);
LinkedHashSet<String> attributes =
new LinkedHashSet<String>(requestedAttributes);
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation search =
conn.processSearch(userDNString, SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES, 0, // Size limit
0, // Time limit
false, // Types only
"(objectClass=*)", attributes);
assertEquals(search.getResultCode(), ResultCode.SUCCESS);
LinkedList<SearchResultEntry> entries = search.getSearchEntries();
assertEquals(entries.size(), 1);
Entry entry = entries.getFirst();
assertEquals(entry.getDN(), userDN);
// Check all expected attributes are present and have
// the user requested name.
List<Attribute> attrList = entry.getAttributes();
Set<String> actualNames = new HashSet<String>();
for (Attribute attribute : attrList)
{
actualNames.add(attribute.getNameWithOptions());
}
assertTrue(actualNames.containsAll(expectedAttributes),
"Expected: " + expectedAttributes + " got " + actualNames);
}
/**
* Tests that attributes are returned from external searches using the
* attribute name requested by the user.
*
* @param requestedAttributes
* The list of requested attributes names.
* @param expectedAttributes
* The list of expected attribute names.
* @throws Exception
* If an unexpected problem occurs.
*/
@Test(dataProvider = "testSearchInternalUserAttributeNames")
public void testSearchExternalUserAttributeNames(
List<String> requestedAttributes, List<String> expectedAttributes)
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
String userDNString = "uid=test.user,o=test";
DN userDN = DN.decode(userDNString);
TestCaseUtils.addEntry("dn: " + userDNString,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"cn;lang-fr: Test Usager",
"userPassword: password");
Entry userEntry = DirectoryServer.getEntry(userDN);
assertNotNull(userEntry);
LinkedHashSet<String> attributes =
new LinkedHashSet<String>(requestedAttributes);
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(
ByteString.valueOf(userDNString),
SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=*)"),
attributes);
SearchResultEntryProtocolOp entry =
searchExternalForSingleEntry(searchRequest, null);
assertEquals(entry.getDN(), userDN);
// Check all expected attributes are present and have
// the user requested name.
LinkedList<LDAPAttribute> attrList = entry.getAttributes();
Set<String> actualNames = new HashSet<String>();
for (LDAPAttribute attribute : attrList)
{
actualNames.add(attribute.getAttributeType());
}
assertTrue(actualNames.containsAll(expectedAttributes),
"Expected: " + expectedAttributes + " got " + actualNames);
}
/**
* Tests the one-level search with a lower allid threshold value.
*/
@Test()
public void testOneLevelSearchWithAllIDThreshold() throws Exception
{
//Set a lower value for allid threshold. We set 2.
setAllIdThreshold(2);
//Add entries.
String filePath = TestCaseUtils.createTempFile(
"dn: ou=unit1,dc=example,dc=com\n" +
"objectclass: top\n" +
"objectclass: organizationalUnit\n" +
"ou: unit1\n" +
"\n" +
"dn: ou=unit2,dc=example,dc=com\n" +
"objectclass: top\n" +
"objectclass: organizationalUnit\n" +
"ou: unit2\n" +
"\n" +
"dn: ou=unit3,dc=example,dc=com\n" +
"objectclass: top\n" +
"objectclass: organizationalUnit\n" +
"ou: unit3\n");
String[] args = new String []
{
"-h", "127.0.0.1",
"-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
"-D","cn=directory manager",
"-w","password",
"-a",
"-f", filePath
};
int err = LDAPModify.mainModify(args, false, null,null);
assertEquals(err,0);
//Search for the entries.
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
InternalSearchOperation searchOperation =
new InternalSearchOperation(
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
new ArrayList<Control>(),
ByteString.valueOf("dc=example,dc=com"),
SearchScope.SINGLE_LEVEL,
DereferencePolicy.NEVER_DEREF_ALIASES,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
false,
LDAPFilter.decode("(objectclass=organizationalUnit)"),
null, null);
searchOperation.run();
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(searchOperation.getSearchEntries().size(),3);
//restore the allid threshold.
setAllIdThreshold(4000);
}
//Sets a value of the allid threshold.
private void setAllIdThreshold(int value) throws Exception
{
//Change the allid threshold value.
String filePath = TestCaseUtils.createTempFile(
"dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
"changetype: modify",
"delete: ds-cfg-index-entry-limit",
"-",
"add: ds-cfg-index-entry-limit",
"ds-cfg-index-entry-limit: "+value
);
String[] args = new String []
{
"-h", "127.0.0.1",
"-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
"-D","cn=directory manager",
"-w","password",
"-a",
"-f", filePath
};
int err = LDAPModify.mainModify(args, false, null,null);
assertEquals(err, 0);
}
}