org.ldaptive.provider.opendj.OpenDJConnection Maven / Gradle / Ivy
/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.provider.opendj;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.Connection;
import org.forgerock.opendj.ldap.ConnectionEventListener;
import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.FutureResult;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.Modification;
import org.forgerock.opendj.ldap.ReferralException;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.controls.Control;
import org.forgerock.opendj.ldap.requests.DigestMD5SASLBindRequest;
import org.forgerock.opendj.ldap.requests.ExternalSASLBindRequest;
import org.forgerock.opendj.ldap.requests.GSSAPISASLBindRequest;
import org.forgerock.opendj.ldap.requests.GenericExtendedRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SASLBindRequest;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.requests.SimpleBindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.GenericExtendedResult;
import org.forgerock.opendj.ldap.responses.IntermediateResponse;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
import org.ldaptive.AddRequest;
import org.ldaptive.BindRequest;
import org.ldaptive.CompareRequest;
import org.ldaptive.DeleteRequest;
import org.ldaptive.DerefAliases;
import org.ldaptive.LdapEntry;
import org.ldaptive.LdapException;
import org.ldaptive.ModifyDnRequest;
import org.ldaptive.ModifyRequest;
import org.ldaptive.Request;
import org.ldaptive.Response;
import org.ldaptive.ResultCode;
import org.ldaptive.SearchEntry;
import org.ldaptive.SearchReference;
import org.ldaptive.async.AsyncRequest;
import org.ldaptive.control.RequestControl;
import org.ldaptive.control.ResponseControl;
import org.ldaptive.extended.ExtendedRequest;
import org.ldaptive.extended.ExtendedResponse;
import org.ldaptive.extended.ExtendedResponseFactory;
import org.ldaptive.extended.UnsolicitedNotificationListener;
import org.ldaptive.intermediate.IntermediateResponseFactory;
import org.ldaptive.provider.ProviderUtils;
import org.ldaptive.provider.SearchItem;
import org.ldaptive.provider.SearchIterator;
import org.ldaptive.provider.SearchListener;
import org.ldaptive.sasl.DigestMd5Config;
import org.ldaptive.sasl.QualityOfProtection;
import org.ldaptive.sasl.SaslConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* OpenDJ provider implementation of ldap operations.
*
* @author Middleware Services
*/
public class OpenDJConnection implements org.ldaptive.provider.ProviderConnection
{
/** Logger for this class. */
protected final Logger logger = LoggerFactory.getLogger(getClass());
/** Ldap connection. */
private Connection connection;
/** Provider configuration. */
private final OpenDJProviderConfig config;
/** Connection event listener for unsolicited notifications. */
private final AggregateUnsolicitedNotificationListener notificationListener =
new AggregateUnsolicitedNotificationListener();
/**
* Creates a new opendj ldap connection.
*
* @param c ldap connection
* @param pc provider configuration
*/
public OpenDJConnection(final Connection c, final OpenDJProviderConfig pc)
{
connection = c;
config = pc;
connection.addConnectionEventListener(notificationListener);
}
/**
* Returns the underlying ldap connection.
*
* @return ldap connection
*/
public Connection getLdapConnection()
{
return connection;
}
@Override
public void close(final RequestControl[] controls)
throws LdapException
{
if (connection != null) {
final org.forgerock.opendj.ldap.requests.UnbindRequest ur = Requests.newUnbindRequest();
if (controls != null) {
for (Control c : config.getControlProcessor().processRequestControls(controls)) {
ur.addControl(c);
}
}
try {
connection.close(ur, "Close requested by client");
} finally {
connection = null;
}
}
}
@Override
public Response bind(final BindRequest request)
throws LdapException
{
Response response;
if (request.getSaslConfig() != null) {
response = saslBind(request);
} else if (request.getDn() == null && request.getCredential() == null) {
response = anonymousBind(request);
} else {
response = simpleBind(request);
}
return response;
}
/**
* Performs an anonymous bind.
*
* @param request to bind with
*
* @return bind response
*
* @throws LdapException if an error occurs
*/
protected Response anonymousBind(final BindRequest request)
throws LdapException
{
Response response = null;
try {
final SimpleBindRequest sbr = Requests.newSimpleBindRequest();
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
sbr.addControl(c);
}
}
final BindResult result = connection.bind(sbr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
/**
* Performs a simple bind.
*
* @param request to bind with
*
* @return bind response
*
* @throws LdapException if an error occurs
*/
protected Response simpleBind(final BindRequest request)
throws LdapException
{
Response response = null;
try {
final SimpleBindRequest sbr = Requests.newSimpleBindRequest(request.getDn(), request.getCredential().getChars());
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
sbr.addControl(c);
}
}
final BindResult result = connection.bind(sbr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
/**
* Performs a sasl bind.
*
* @param request to bind with
*
* @return bind response
*
* @throws LdapException if an error occurs
*/
protected Response saslBind(final BindRequest request)
throws LdapException
{
Response response = null;
SASLBindRequest sbr;
final SaslConfig sc = request.getSaslConfig();
switch (sc.getMechanism()) {
case EXTERNAL:
sbr = Requests.newExternalSASLBindRequest();
((ExternalSASLBindRequest) sbr).setAuthorizationID(sc.getAuthorizationId());
break;
case DIGEST_MD5:
sbr = Requests.newDigestMD5SASLBindRequest(
request.getDn() != null ?
request.getDn() : "", request.getCredential() != null ? request.getCredential().getBytes() : null);
String digestMd5Realm = sc instanceof DigestMd5Config ? ((DigestMd5Config) sc).getRealm() : null;
if (digestMd5Realm == null && request.getDn().contains("@")) {
digestMd5Realm = request.getDn().substring(request.getDn().indexOf("@") + 1);
}
if (digestMd5Realm != null) {
((DigestMD5SASLBindRequest) sbr).setRealm(digestMd5Realm);
}
break;
case CRAM_MD5:
throw new UnsupportedOperationException("CRAM-MD5 not supported");
// LDAP reports: error: SASL bind in progress (tag=99)
/*
* sbr = Requests.newCRAMMD5SASLBindRequest(
* request.getDn() != null ? request.getDn() : "",
* request.getCredential() != null ?
* request.getCredential().getBytes() : null);
* break;
*/
case GSSAPI:
throw new UnsupportedOperationException("GSSAPI not supported");
/*
* sbr = Requests.newGSSAPISASLBindRequest(
* request.getDn() != null ? request.getDn() : "",
* request.getCredential() != null ?
* request.getCredential().getBytes() : new byte[0]);
* ((GSSAPISASLBindRequest) sbr).setAuthorizationID(
* sc.getAuthorizationId());
* final String gssApiRealm = sc instanceof GssApiConfig
* ? ((GssApiConfig) sc).getRealm() : null;
* if (gssApiRealm != null) {
* ((GSSAPISASLBindRequest) sbr).setRealm(gssApiRealm);
* }
* if (sc.getQualityOfProtection() != null) {
* ((GSSAPISASLBindRequest) sbr).addQOP(
* getQualityOfProtection(sc.getQualityOfProtection()));
* }
* break;
*/
default:
throw new IllegalArgumentException("Unknown SASL authentication mechanism: " + sc.getMechanism());
}
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
sbr.addControl(c);
}
}
try {
final BindResult result = connection.bind(sbr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
/**
* Returns the SASL quality of protection string for the supplied enum.
*
* @param qop quality of protection enum
*
* @return SASL quality of protection string
*/
protected static String getQualityOfProtection(final QualityOfProtection qop)
{
String name;
switch (qop) {
case AUTH:
name = GSSAPISASLBindRequest.QOP_AUTH;
break;
case AUTH_INT:
name = GSSAPISASLBindRequest.QOP_AUTH_INT;
break;
case AUTH_CONF:
name = GSSAPISASLBindRequest.QOP_AUTH_CONF;
break;
default:
throw new IllegalArgumentException("Unknown SASL quality of protection: " + qop);
}
return name;
}
@Override
public Response add(final AddRequest request)
throws LdapException
{
Response response = null;
try {
final OpenDJUtils util = new OpenDJUtils();
final org.forgerock.opendj.ldap.requests.AddRequest ar = Requests.newAddRequest(
util.fromLdapEntry(new LdapEntry(request.getDn(), request.getLdapAttributes())));
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
ar.addControl(c);
}
}
final Result result = connection.add(ar);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public Response compare(final CompareRequest request)
throws LdapException
{
Response response = null;
try {
final OpenDJUtils util = new OpenDJUtils();
org.forgerock.opendj.ldap.requests.CompareRequest cr;
if (request.getAttribute().isBinary()) {
cr = Requests.newCompareRequest(
request.getDn(),
request.getAttribute().getName(),
util.fromBinaryValues(request.getAttribute().getBinaryValues())[0]);
} else {
cr = Requests.newCompareRequest(
request.getDn(),
request.getAttribute().getName(),
util.fromStringValues(request.getAttribute().getStringValues())[0]);
}
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
cr.addControl(c);
}
}
final CompareResult result = connection.compare(cr);
response = createResponse(request, result.matched(), result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public Response delete(final DeleteRequest request)
throws LdapException
{
Response response = null;
try {
final org.forgerock.opendj.ldap.requests.DeleteRequest dr = Requests.newDeleteRequest(request.getDn());
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
dr.addControl(c);
}
}
final Result result = connection.delete(dr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public Response modify(final ModifyRequest request)
throws LdapException
{
Response response = null;
try {
final OpenDJUtils util = new OpenDJUtils();
final org.forgerock.opendj.ldap.requests.ModifyRequest mr = Requests.newModifyRequest(request.getDn());
for (Modification m : util.fromAttributeModification(request.getAttributeModifications())) {
mr.addModification(m);
}
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
mr.addControl(c);
}
}
final Result result = connection.modify(mr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public Response modifyDn(final ModifyDnRequest request)
throws LdapException
{
Response response = null;
try {
final org.forgerock.opendj.ldap.requests.ModifyDNRequest mdr = Requests.newModifyDNRequest(
request.getDn(),
request.getNewDn());
mdr.setDeleteOldRDN(request.getDeleteOldRDn());
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
mdr.addControl(c);
}
}
final Result result = connection.modifyDN(mdr);
response = createResponse(request, null, result);
} catch (ReferralException e) {
response = createResponse(request, null, e.getResult());
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public SearchIterator search(final org.ldaptive.SearchRequest request)
throws LdapException
{
final OpenDJSearchIterator i = new OpenDJSearchIterator(request);
i.initialize();
return i;
}
@Override
public void searchAsync(final org.ldaptive.SearchRequest request, final SearchListener listener)
throws LdapException
{
final OpenDJAsyncSearchListener l = new OpenDJAsyncSearchListener(request, listener);
l.initialize();
}
@Override
public void abandon(final int messageId, final RequestControl[] controls)
throws LdapException
{
final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(messageId);
if (controls != null) {
for (Control c : config.getControlProcessor().processRequestControls(controls)) {
ar.addControl(c);
}
}
connection.abandonAsync(ar);
}
@Override
public Response> extendedOperation(final ExtendedRequest request)
throws LdapException
{
Response> response = null;
try {
GenericExtendedRequest er;
final byte[] requestBerValue = request.encode();
if (requestBerValue == null) {
er = Requests.newGenericExtendedRequest(request.getOID());
} else {
er = Requests.newGenericExtendedRequest(request.getOID(), ByteString.wrap(requestBerValue));
}
if (request.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(request.getControls())) {
er.addControl(c);
}
}
final GenericExtendedResult result = connection.extendedRequest(er);
final byte[] responseBerValue = result.getValue() != null ? result.getValue().toByteArray() : null;
final ExtendedResponse> extRes = ExtendedResponseFactory.createExtendedResponse(
request.getOID(),
result.getOID(),
responseBerValue);
response = createResponse(request, extRes.getValue(), result);
} catch (ErrorResultException e) {
processErrorResultException(request, e);
}
return response;
}
@Override
public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener)
{
notificationListener.addUnsolicitedNotificationListener(listener);
}
@Override
public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener)
{
notificationListener.removeUnsolicitedNotificationListener(listener);
}
/**
* Creates an operation response with the supplied response data.
*
* @param type of response
* @param request containing controls
* @param result of the operation
* @param ldapResult provider result
*
* @return operation response
*/
protected Response createResponse(final Request request, final T result, final Result ldapResult)
{
final List ctls = ldapResult.getControls();
final List urls = ldapResult.getReferralURIs();
return
new Response<>(
result,
ResultCode.valueOf(ldapResult.getResultCode().intValue()),
ldapResult.getDiagnosticMessage(),
ldapResult.getMatchedDN(),
config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])),
urls.toArray(new String[urls.size()]),
-1);
}
/**
* Determines if the supplied error result exception should result in an operation retry.
*
* @param request that produced the exception
* @param e that was produced
*
* @throws LdapException wrapping the error result exception
*/
protected void processErrorResultException(final Request request, final ErrorResultException e)
throws LdapException
{
final List ctls = e.getResult().getControls();
final List urls = e.getResult().getReferralURIs();
ProviderUtils.throwOperationException(
config.getOperationExceptionResultCodes(),
e,
e.getResult().getResultCode().intValue(),
e.getResult().getMatchedDN(),
config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])),
urls.toArray(new String[urls.size()]),
true);
}
/** Search iterator for opendj search results. */
protected class OpenDJSearchIterator extends AbstractOpenDJSearch implements SearchIterator
{
/** Response data. */
private org.ldaptive.Response response;
/** Search result iterator. */
private SearchResultIterator resultIterator;
/**
* Creates a new opendj search iterator.
*
* @param sr search request
*/
public OpenDJSearchIterator(final org.ldaptive.SearchRequest sr)
{
super(sr);
}
/**
* Initializes this opendj search iterator.
*
* @throws LdapException if an error occurs
*/
public void initialize()
throws LdapException
{
resultIterator = search(connection, request);
}
/**
* Executes an ldap search.
*
* @param conn to search with
* @param sr to read properties from
*
* @return ldap search results
*
* @throws LdapException if an error occurs
*/
protected SearchResultIterator search(final Connection conn, final org.ldaptive.SearchRequest sr)
throws LdapException
{
final SearchRequest opendjSr = getSearchRequest(sr);
if (sr.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(sr.getControls())) {
opendjSr.addControl(c);
}
}
final SearchResultIterator i = new SearchResultIterator();
try {
conn.search(opendjSr, i);
} catch (ErrorResultException e) {
final ResultCode rc = ignoreSearchException(config.getSearchIgnoreResultCodes(), e);
if (rc == null) {
processErrorResultException(request, e);
}
}
return i;
}
@Override
public boolean hasNext()
throws LdapException
{
if (resultIterator == null || response != null) {
return false;
}
final boolean more = resultIterator.hasNext();
if (!more) {
final Result result = resultIterator.getResult();
logger.trace("reading search result: {}", result);
response = createResponse(request, null, result);
}
return more;
}
@Override
public SearchItem next()
throws LdapException
{
return resultIterator.next();
}
@Override
public org.ldaptive.Response getResponse()
{
return response;
}
@Override
public void close()
throws LdapException {}
/** Search results handler for storing entries returned by a search operation. */
protected class SearchResultIterator implements SearchResultHandler
{
/** Search items. */
protected final Queue queue = new ArrayDeque<>();
/** Search result. */
private Result result;
/**
* Returns the next search item from the queue.
*
* @return search item
*/
public SearchItem next()
{
return queue.poll();
}
/**
* Returns the result of the search.
*
* @return search result
*/
public Result getResult()
{
return result;
}
/**
* Whether the queue is empty.
*
* @return whether the queue is empty
*/
public boolean hasNext()
{
return !queue.isEmpty();
}
@Override
public void handleErrorResult(final ErrorResultException e)
{
logger.trace("reading error result: {}", e);
result = e.getResult();
}
@Override
public void handleResult(final Result r)
{
logger.trace("reading result: {}", r);
result = r;
}
@Override
public boolean handleEntry(final SearchResultEntry entry)
{
return queue.add(processSearchResultEntry(entry));
}
@Override
public boolean handleReference(final SearchResultReference ref)
{
return queue.add(processSearchResultReference(ref));
}
}
}
/** Search listener for opendj id async search results. */
protected class OpenDJAsyncSearchListener extends AbstractOpenDJSearch
implements SearchResultHandler, IntermediateResponseHandler
{
/** Search result listener. */
private final SearchListener listener;
/**
* Creates a new opendj async search listener.
*
* @param sr search request
* @param sl search listener
*/
public OpenDJAsyncSearchListener(final org.ldaptive.SearchRequest sr, final SearchListener sl)
{
super(sr);
listener = sl;
}
/**
* Initializes this opendj async search listener.
*
* @throws LdapException if an error occurs
*/
public void initialize()
throws LdapException
{
search(connection, request);
}
/**
* Executes an asynchronous ldap search.
*
* @param conn to search with
* @param sr to read properties from
*
* @throws LdapException if an error occurs
*/
protected void search(final Connection conn, final org.ldaptive.SearchRequest sr)
throws LdapException
{
final SearchRequest opendjSr = getSearchRequest(sr);
if (sr.getControls() != null) {
for (Control c : config.getControlProcessor().processRequestControls(sr.getControls())) {
opendjSr.addControl(c);
}
}
final FutureResult result = conn.searchAsync(opendjSr, this, this);
listener.asyncRequestReceived(new OpenDJAsyncRequest(result));
}
@Override
public void handleErrorResult(final ErrorResultException e)
{
logger.trace("reading error result: {}", e);
final List ctls = e.getResult().getControls();
final List urls = e.getResult().getReferralURIs();
listener.exceptionReceived(
new LdapException(
e.getMessage(),
new Exception(e.getCause()),
ResultCode.valueOf(e.getResult().getResultCode().intValue()),
e.getResult().getMatchedDN(),
config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()])),
urls.toArray(new String[urls.size()])));
}
@Override
public void handleResult(final Result r)
{
logger.trace("reading result: {}", r);
final org.ldaptive.Response response = createResponse(request, null, r);
listener.responseReceived(response);
}
@Override
public boolean handleEntry(final SearchResultEntry entry)
{
listener.searchItemReceived(processSearchResultEntry(entry));
return true;
}
@Override
public boolean handleReference(final SearchResultReference ref)
{
listener.searchItemReceived(processSearchResultReference(ref));
return true;
}
@Override
public boolean handleIntermediateResponse(final IntermediateResponse res)
{
listener.searchItemReceived(processIntermediateResponse(res));
return true;
}
}
/** Common search functionality for opendj iterators and listeners. */
protected abstract class AbstractOpenDJSearch
{
/** Search request. */
protected final org.ldaptive.SearchRequest request;
/** Utility class. */
protected final OpenDJUtils util;
/**
* Creates a new abstract opendj search.
*
* @param sr search request
*/
public AbstractOpenDJSearch(final org.ldaptive.SearchRequest sr)
{
request = sr;
util = new OpenDJUtils(request.getSortBehavior());
util.setBinaryAttributes(request.getBinaryAttributes());
}
/**
* Returns an opendj search request object configured with the supplied search request.
*
* @param sr search request containing configuration to create opendj search request
*
* @return search request
*/
protected SearchRequest getSearchRequest(final org.ldaptive.SearchRequest sr)
{
final SearchRequest opendjSr = Requests.newSearchRequest(
sr.getBaseDn(),
getSearchScope(sr.getSearchScope()),
sr.getSearchFilter() != null ? sr.getSearchFilter().format() : null,
sr.getReturnAttributes());
opendjSr.setDereferenceAliasesPolicy(getDereferencePolicy(sr.getDerefAliases()));
opendjSr.setSizeLimit((int) sr.getSizeLimit());
opendjSr.setTimeLimit((int) sr.getTimeLimit().getSeconds());
opendjSr.setTypesOnly(sr.getTypesOnly());
return opendjSr;
}
/**
* Returns the opendj search scope for the supplied search scope.
*
* @param ss search scope
*
* @return opendj search scope
*/
protected SearchScope getSearchScope(final org.ldaptive.SearchScope ss)
{
SearchScope scope = null;
if (ss == org.ldaptive.SearchScope.OBJECT) {
scope = SearchScope.BASE_OBJECT;
} else if (ss == org.ldaptive.SearchScope.ONELEVEL) {
scope = SearchScope.SINGLE_LEVEL;
} else if (ss == org.ldaptive.SearchScope.SUBTREE) {
scope = SearchScope.WHOLE_SUBTREE;
}
return scope;
}
/**
* Returns the opendj deference policy for the supplied deref aliases.
*
* @param deref deref aliases
*
* @return dereference policy
*/
protected DereferenceAliasesPolicy getDereferencePolicy(final DerefAliases deref)
{
DereferenceAliasesPolicy policy = DereferenceAliasesPolicy.NEVER;
if (deref == DerefAliases.ALWAYS) {
policy = DereferenceAliasesPolicy.ALWAYS;
} else if (deref == DerefAliases.FINDING) {
policy = DereferenceAliasesPolicy.FINDING_BASE;
} else if (deref == DerefAliases.NEVER) {
policy = DereferenceAliasesPolicy.NEVER;
} else if (deref == DerefAliases.SEARCHING) {
policy = DereferenceAliasesPolicy.IN_SEARCHING;
}
return policy;
}
/**
* Determines whether the supplied ldap exception should be ignored.
*
* @param ignoreResultCodes to match against the exception
* @param e ldap exception to match
*
* @return result code that should be ignored or null
*/
protected ResultCode ignoreSearchException(final ResultCode[] ignoreResultCodes, final ErrorResultException e)
{
ResultCode ignore = null;
if (ignoreResultCodes != null && ignoreResultCodes.length > 0) {
for (ResultCode rc : ignoreResultCodes) {
if (e.getResult().getResultCode().intValue() == rc.value()) {
logger.debug("Ignoring ldap exception", e);
ignore = rc;
break;
}
}
}
return ignore;
}
/**
* Processes the response controls on the supplied entry and returns a corresponding search item.
*
* @param entry to process
*
* @return search item
*/
protected SearchItem processSearchResultEntry(final SearchResultEntry entry)
{
logger.trace("reading search entry: {}", entry);
ResponseControl[] respControls = null;
if (entry.getControls() != null && entry.getControls().size() > 0) {
final List ctls = entry.getControls();
respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()]));
}
final SearchEntry se = util.toSearchEntry(entry, respControls, -1);
return new SearchItem(se);
}
/**
* Processes the response controls on the supplied reference and returns a corresponding search item.
*
* @param ref to process
*
* @return search item
*/
protected SearchItem processSearchResultReference(final SearchResultReference ref)
{
logger.trace("reading search reference: {}", ref);
ResponseControl[] respControls = null;
if (ref.getControls() != null && ref.getControls().size() > 0) {
final List ctls = ref.getControls();
respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()]));
}
final SearchReference sr = new SearchReference(-1, respControls, ref.getURIs());
return new SearchItem(sr);
}
/**
* Processes the response controls on the supplied response and returns a corresponding search item.
*
* @param res to process
*
* @return search item
*/
protected SearchItem processIntermediateResponse(final IntermediateResponse res)
{
logger.trace("reading intermediate response: {}", res);
ResponseControl[] respControls = null;
if (res.getControls() != null && res.getControls().size() > 0) {
final List ctls = res.getControls();
respControls = config.getControlProcessor().processResponseControls(ctls.toArray(new Control[ctls.size()]));
}
final org.ldaptive.intermediate.IntermediateResponse ir = IntermediateResponseFactory.createIntermediateResponse(
res.getOID(),
res.getValue().toByteArray(),
respControls,
-1);
return new SearchItem(ir);
}
}
/** Async request to invoke abandons. */
protected class OpenDJAsyncRequest implements AsyncRequest
{
/** Future result. */
private final FutureResult result;
/**
* Creates a new OpenDJ async request.
*
* @param r future result from an async operation
*/
public OpenDJAsyncRequest(final FutureResult r)
{
result = r;
}
@Override
public int getMessageId()
{
return result.getRequestID();
}
@Override
public void abandon()
throws LdapException
{
final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(result.getRequestID());
connection.abandonAsync(ar);
}
@Override
public void abandon(final RequestControl[] controls)
throws LdapException
{
final org.forgerock.opendj.ldap.requests.AbandonRequest ar = Requests.newAbandonRequest(result.getRequestID());
if (controls != null) {
for (Control c : config.getControlProcessor().processRequestControls(controls)) {
ar.addControl(c);
}
}
connection.abandonAsync(ar);
}
}
/** Allows the use of multiple unsolicited notification listeners per connection. */
protected class AggregateUnsolicitedNotificationListener implements ConnectionEventListener
{
/** Listeners to receive unsolicited notifications. */
private final List listeners = new ArrayList<>();
/**
* Adds an unsolicited notification listener to this listener.
*
* @param listener to receive unsolicited notifications
*/
public void addUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener)
{
synchronized (listeners) {
listeners.add(listener);
}
}
/**
* Removes an unsolicited notification listener from this listener.
*
* @param listener to stop receiving unsolicited notifications
*/
public void removeUnsolicitedNotificationListener(final UnsolicitedNotificationListener listener)
{
synchronized (listeners) {
listeners.remove(listener);
}
}
@Override
public void handleConnectionClosed() {}
@Override
public void handleConnectionError(final boolean b, final ErrorResultException e) {}
@Override
public void handleUnsolicitedNotification(final ExtendedResult extendedResult)
{
logger.debug("Unsolicited notification received: {}", extendedResult);
synchronized (listeners) {
final Response response = createResponse(null, null, extendedResult);
for (UnsolicitedNotificationListener listener : listeners) {
listener.notificationReceived(extendedResult.getOID(), response);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy