Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for using SearchResultHandler with send. #270

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.handler;

/**
* Base class for search result handlers.
*
* @author Middleware Services
*/
public abstract class AbstractSearchResultHandler implements SearchResultHandler
{

/** Handler usage. */
private final Usage usage;


/**
* Creates a new abstract search result handler.
*
* @param u handler usage
*/
public AbstractSearchResultHandler(final Usage u)
{
usage = u;
}


@Override
public Usage getUsage()
{
return usage;
}


@Override
public String toString()
{
return getClass().getName() + "@" + hashCode() + "::" + "usage=" + usage;
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/FreezeResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@
*
* @author Middleware Services
*/
public class FreezeResultHandler implements SearchResultHandler
public class FreezeResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 859;


/** Default constructor. */
public FreezeResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new freeze result handler.
*
* @param u handler usage
*/
public FreezeResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse response)
{
Expand All @@ -30,20 +48,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof FreezeResultHandler;
if (o instanceof FreezeResultHandler) {
final FreezeResultHandler v = (FreezeResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/MergeResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,31 @@
*
* @author Miguel Martinez de Espronceda
*/
public class MergeResultHandler implements SearchResultHandler
public class MergeResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 857;


/** Default constructor. */
public MergeResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new merge result handler.
*
* @param u handler usage
*/
public MergeResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse searchResponse)
{
Expand Down Expand Up @@ -82,20 +100,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof MergeResultHandler;
if (o instanceof MergeResultHandler) {
final MergeResultHandler v = (MergeResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
25 changes: 24 additions & 1 deletion core/src/main/java/org/ldaptive/handler/SearchResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,27 @@
*
* @author Middleware Services
*/
public interface SearchResultHandler extends Function<SearchResponse, SearchResponse> {}
public interface SearchResultHandler extends Function<SearchResponse, SearchResponse>
{


/** Intended usage of the handler. */
enum Usage {
/** Use this handler with {@link org.ldaptive.SearchOperation#send()}*/
ASYNC,

/** Use this handler with {@link org.ldaptive.SearchOperation#execute()}*/
SYNC
}


/**
* Returns the usage for this handler.
*
* @return handler usage
*/
default Usage getUsage()
{
return Usage.SYNC;
}
}
30 changes: 26 additions & 4 deletions core/src/main/java/org/ldaptive/handler/SortResultHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@
*
* @author Middleware Services
*/
public class SortResultHandler implements SearchResultHandler
public class SortResultHandler extends AbstractSearchResultHandler
{

/** hash code seed. */
private static final int HASH_CODE_SEED = 853;


/** Default constructor. */
public SortResultHandler()
{
this(Usage.SYNC);
}


/**
* Creates a new sort result handler.
*
* @param u handler usage
*/
public SortResultHandler(final Usage u)
{
super(u);
}


@Override
public SearchResponse apply(final SearchResponse response)
{
Expand All @@ -29,20 +47,24 @@ public boolean equals(final Object o)
if (o == this) {
return true;
}
return o instanceof SortResultHandler;
if (o instanceof SortResultHandler) {
final SortResultHandler v = (SortResultHandler) o;
return LdapUtils.areEqual(getUsage(), v.getUsage());
}
return false;
}


@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED);
return LdapUtils.computeHashCode(HASH_CODE_SEED, getUsage());
}


@Override
public String toString()
{
return "[" + getClass().getName() + "@" + hashCode() + "]";
return "[" + super.toString() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,27 @@ public SearchResponse await()
SearchResponse done = super.await();
if (onSearchResult != null) {
for (SearchResultHandler func : onSearchResult) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
throw (LdapException) ex.getCause();
if (func.getUsage() == SearchResultHandler.Usage.SYNC) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
throw (LdapException) ex.getCause();
}
throw new IllegalStateException("Search result handler " + func + " threw exception", ex);
}
throw new IllegalStateException("Search result handler " + func + " threw exception", ex);
}
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done) &&
// FollowSearchReferralHandler can be used as a referral handler and a search result handler for convenience
// allow it to modify the search response
!(ResultCode.REFERRAL == done.getResultCode() && FollowSearchReferralHandler.class.equals(func.getClass())))
{
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done) &&
// FollowSearchReferralHandler can be used as a referral handler and a search result handler for convenience
// allow it to modify the search response
!(ResultCode.REFERRAL == done.getResultCode() && FollowSearchReferralHandler.class.equals(func.getClass())))
{
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
}
done = handlerResponse;
}
done = handlerResponse;
}
}
super.evaluateThrowCondition(done);
Expand Down Expand Up @@ -324,11 +326,33 @@ public void result(final SearchResponse r)
processResult(r);
r.addEntries(result.getEntries());
r.addReferences(result.getReferences());
SearchResponse done = r;
if (SORT_RESULTS) {
finalizeResult(SearchResponse.sort(r));
} else {
finalizeResult(r);
done = SearchResponse.sort(r);
}
if (onSearchResult != null) {
for (SearchResultHandler func : onSearchResult) {
if (func.getUsage() == SearchResultHandler.Usage.ASYNC) {
final SearchResponse handlerResponse;
try {
handlerResponse = func.apply(done);
if (handlerResponse == null) {
throw new IllegalStateException("Search result handler " + func + " returned null result");
} else if (!handlerResponse.equalsResult(done)) {
throw new IllegalStateException("Cannot modify search result instance with handler " + func);
}
done = handlerResponse;
} catch (Exception ex) {
if (ex.getCause() instanceof LdapException) {
exception((LdapException) ex.getCause());
} else {
logger.warn("Search result function {} in handle {} threw an exception", func, this, ex);
}
}
}
}
}
finalizeResult(done);
}


Expand Down
31 changes: 31 additions & 0 deletions integration/src/test/java/org/ldaptive/SearchOperationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.ldaptive.ad.control.ForceUpdateControl;
import org.ldaptive.ad.control.GetStatsControl;
Expand Down Expand Up @@ -42,6 +45,7 @@
import org.ldaptive.handler.NoOpEntryHandler;
import org.ldaptive.handler.RecursiveResultHandler;
import org.ldaptive.handler.ResultPredicate;
import org.ldaptive.handler.SearchResultHandler;
import org.ldaptive.referral.DefaultReferralConnectionFactory;
import org.ldaptive.referral.FollowSearchReferralHandler;
import org.ldaptive.referral.FollowSearchResultReferenceHandler;
Expand Down Expand Up @@ -1091,6 +1095,33 @@ public void mergeDuplicateSearch(
final SearchResponse result = search.execute(sr);
// ignore the case of member and contactPerson; some directories return those in mixed case
LdapEntryAssert.assertThat(result.getEntry()).isSame(convertLdifToEntry(expected), "member", "contactPerson");

// perform search again using send operation
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<SearchResponse> ref = new AtomicReference<>();
search.setSearchResultHandlers(
new MergeResultHandler(SearchResultHandler.Usage.ASYNC),
new SearchResultHandler() {
@Override
public SearchResponse apply(final SearchResponse sr)
{
ref.set(sr);
latch.countDown();
return sr;
}
@Override
public Usage getUsage()
{
return Usage.ASYNC;
}
});

search.send(sr);
if (!latch.await(Duration.ofSeconds(5).toMillis(), TimeUnit.MILLISECONDS)) {
fail("No results received");
}
// ignore the case of member and contactPerson; some directories return those in mixed case
LdapEntryAssert.assertThat(ref.get().getEntry()).isSame(convertLdifToEntry(expected), "member", "contactPerson");
}


Expand Down