opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -875,6 +875,22 @@ .getRequestControl(PagedResultsControl.DECODER); ServerSideSortRequestControl sortRequest = searchOperation .getRequestControl(ServerSideSortRequestControl.DECODER); if(sortRequest != null && !sortRequest.containsSortKeys() && sortRequest.isCritical()) { /** If the control's criticality field is true then the server SHOULD do the following: return unavailableCriticalExtension as a return code in the searchResultDone message; include the sortKeyResponseControl in the searchResultDone message, and not send back any search result entries. */ searchOperation.addResponseControl( new ServerSideSortResponseControl( LDAPResultCode.NO_SUCH_ATTRIBUTE, null)); searchOperation.setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION); return; } VLVRequestControl vlvRequest = searchOperation .getRequestControl(VLVRequestControl.DECODER); @@ -1043,28 +1059,47 @@ if (sortRequest != null) { try { entryIDList = EntryIDSetSorter.sort(this, entryIDList, searchOperation, sortRequest.getSortOrder(), vlvRequest); searchOperation.addResponseControl( new ServerSideSortResponseControl(LDAPResultCode.SUCCESS, null)); } catch (DirectoryException de) { searchOperation.addResponseControl( new ServerSideSortResponseControl( de.getResultCode().getIntValue(), null)); if (sortRequest.isCritical()) try { throw de; //If the sort key is not present, the sorting will generate the //default ordering. VLV search request goes through as if //this sort key was not found in the user entry. entryIDList = EntryIDSetSorter.sort(this, entryIDList, searchOperation, sortRequest.getSortOrder(), vlvRequest); if(sortRequest.containsSortKeys()) { searchOperation.addResponseControl( new ServerSideSortResponseControl( LDAPResultCode.SUCCESS, null)); } else { /* There is no sort key associated with the sort control. Since it came here it means that the critificality is false so let the server return all search results unsorted and include the sortKeyResponseControl inthe searchResultDone message. */ searchOperation.addResponseControl( new ServerSideSortResponseControl (LDAPResultCode.NO_SUCH_ATTRIBUTE, null)); } } catch (DirectoryException de) { searchOperation.addResponseControl( new ServerSideSortResponseControl( de.getResultCode().getIntValue(), null)); if (sortRequest.isCritical()) { throw de; } } } } } // If requested, construct and return a fictitious entry containing // debug information, and no other entries. opends/src/server/org/opends/server/controls/ServerSideSortRequestControl.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2009 Sun Microsystems, Inc. */ package org.opends.server.controls; import org.opends.messages.Message; @@ -115,8 +115,11 @@ DirectoryServer.getAttributeType(attrName, false); if (attrType == null) { Message message = INFO_SORTREQ_CONTROL_UNDEFINED_ATTR.get(attrName); throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); //This attribute is not defined in the schema. There is no point //iterating over the next attribute and return a partially sorted //result. return new ServerSideSortRequestControl(isCritical, new SortOrder(sortKeys.toArray(new SortKey[0]))); } OrderingMatchingRule orderingRule = null; @@ -351,6 +354,23 @@ } /** * Indicates whether the sort control contains Sort keys. * * <P> A Sort control may not contain sort keys if the attribute type * is not recognized by the server </P> * * @return <CODE>true</CODE> if the control contains sort keys * or <CODE>false</CODE> if it does not. * * @throws DirectoryException If a problem occurs while trying to make the * determination. */ public boolean containsSortKeys() throws DirectoryException { return getSortOrder().getSortKeys().length!=0; } /** * Writes this control's value to an ASN.1 writer. The value (if any) must * be written as an ASN1OctetString. * @@ -438,9 +458,10 @@ DirectoryServer.getAttributeType(decodedKey[0].toLowerCase(), false); if (attrType == null) { Message message = INFO_SORTREQ_CONTROL_UNDEFINED_ATTR.get(decodedKey[0]); throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); //This attribute is not defined in the schema. There is no point //iterating over the next attribute and return a partially sorted //result. return new SortOrder(sortKeys.toArray(new SortKey[0])); } OrderingMatchingRule orderingRule = null; opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ServerSideSortControlTestCase.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2009 Sun Microsystems, Inc. */ package org.opends.server.controls; @@ -718,13 +718,13 @@ /** * Tests performing an internal search using the server-side sort control with * Tests performing an internal search using the CRITICAL server-side sort control with * an undefined attribute type. * * @throws Exception If an unexpected problem occurred. */ @Test() public void testInternalSearchUndefinedAttribute() public void testCriticalSortWithUndefinedAttribute() throws Exception { populateDB(); @@ -744,7 +744,7 @@ null, null); internalSearch.run(); assertFalse(internalSearch.getResultCode() == ResultCode.SUCCESS); assertEquals(internalSearch.getResultCode(), ResultCode.UNAVAILABLE_CRITICAL_EXTENSION); } @@ -779,5 +779,53 @@ internalSearch.run(); assertFalse(internalSearch.getResultCode() == ResultCode.SUCCESS); } /** * Tests performing an internal search using the non-critical server-side * sort control to sort the entries * * @throws Exception If an unexpected problem occurred. */ @Test() public void testNonCriticalSortWithUndefinedAttribute() throws Exception { populateDB(); InternalClientConnection conn = InternalClientConnection.getRootConnection(); ArrayList<Control> requestControls = new ArrayList<Control>(); requestControls.add(new ServerSideSortRequestControl(false, "bad_sort:caseExactOrderingMatch")); InternalSearchOperation internalSearch = new InternalSearchOperation(conn, conn.nextOperationID(), conn.nextMessageID(), requestControls, DN.decode("dc=example,dc=com"), SearchScope.WHOLE_SUBTREE, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, SearchFilter.createFilterFromString("(objectClass=person)"), null, null); internalSearch.run(); assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS); List<Control> responseControls = internalSearch.getResponseControls(); assertNotNull(responseControls); assertEquals(responseControls.size(), 1); ServerSideSortResponseControl responseControl; Control c = responseControls.get(0); if(c instanceof ServerSideSortResponseControl) { responseControl = (ServerSideSortResponseControl)c; } else { responseControl = ServerSideSortResponseControl.DECODER.decode( c.isCritical(), ((LDAPControl)c).getValue()); } assertEquals(responseControl.getResultCode(), 16); } } opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
@@ -2311,7 +2311,7 @@ throws Exception { TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); String[] args = { "-h", "127.0.0.1", @@ -2325,7 +2325,7 @@ "(objectClass=*)" }; assertFalse(LDAPSearch.mainSearch(args, false, null, null) == 0); assertTrue(LDAPSearch.mainSearch(args, false, null, null) == 0); }