use of com.unboundid.ldap.protocol.SearchResultDoneProtocolOp in project ldapsdk by pingidentity.
the class UNBOUNDIDTESTServer method run.
/**
* Performs the processing for this server.
*/
@Override()
public void run() {
try {
serverSocket = new ServerSocket(0);
listenPort = serverSocket.getLocalPort();
while (!stopRequested.get()) {
// Accept a connection from a client.
clientSocket = serverSocket.accept();
final InputStream inputStream = clientSocket.getInputStream();
final OutputStream outputStream = clientSocket.getOutputStream();
final ASN1StreamReader asn1Reader = new ASN1StreamReader(inputStream, 0);
// The client must first send an UNBOUNDID-TEST bind request with no
// credentials.
LDAPMessage requestMessage = LDAPMessage.readFrom(asn1Reader, false);
BindRequestProtocolOp bindRequestOp = requestMessage.getBindRequestProtocolOp();
assertEquals(bindRequestOp.getSASLMechanism(), "UNBOUNDID-TEST");
assertNull(bindRequestOp.getSASLCredentials());
// Return a "SASL bind in progress" response.
LDAPMessage responseMessage = new LDAPMessage(requestMessage.getMessageID(), new BindResponseProtocolOp(ResultCode.SASL_BIND_IN_PROGRESS_INT_VALUE, null, null, null, null));
outputStream.write(responseMessage.encode().encode());
outputStream.flush();
// The next request must be an UNBOUNDID-TEST bind request with
// credentials. We won't do anything to validate the credentials, but
// we will look at the third element to see what QoP the client
// requested.
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
bindRequestOp = requestMessage.getBindRequestProtocolOp();
assertEquals(bindRequestOp.getSASLMechanism(), "UNBOUNDID-TEST");
assertNotNull(bindRequestOp.getSASLCredentials());
final ASN1Sequence credSequence = ASN1Sequence.decodeAsSequence(bindRequestOp.getSASLCredentials().getValue());
final ASN1Element[] credElements = credSequence.elements();
final SASLQualityOfProtection qop = SASLQualityOfProtection.forName(ASN1OctetString.decodeAsOctetString(credElements[2]).stringValue());
assertNotNull(qop);
final boolean qopEncode = ((qop == SASLQualityOfProtection.AUTH_INT) || (qop == SASLQualityOfProtection.AUTH_CONF));
// Return a "success" response. Include server SASL credentials with
// the requested QoP.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new BindResponseProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null, new ASN1OctetString(qop.toString())));
outputStream.write(responseMessage.encode().encode());
outputStream.flush();
// request.
if (qopEncode) {
for (int i = 0; i < 4; i++) {
inputStream.read();
}
}
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
final SearchRequestProtocolOp searchRequestOp = requestMessage.getSearchRequestProtocolOp();
assertEquals(searchRequestOp.getBaseDN(), "");
assertEquals(searchRequestOp.getScope(), SearchScope.BASE);
assertEquals(searchRequestOp.getFilter(), Filter.createPresenceFilter("objectClass"));
assertEquals(searchRequestOp.getAttributes(), Arrays.asList("1.1"));
// Return a search result entry message with a DN but no attributes.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new SearchResultEntryProtocolOp("", Collections.<Attribute>emptyList()));
byte[] messageBytes = responseMessage.encode().encode();
if (qopEncode) {
// Since we know it's a tiny response, we know the length will be
// less than 127 bytes, so we can cheat.
outputStream.write(0);
outputStream.write(0);
outputStream.write(0);
outputStream.write(messageBytes.length);
}
outputStream.write(messageBytes);
outputStream.flush();
// Return a "success" search result done message.
responseMessage = new LDAPMessage(requestMessage.getMessageID(), new SearchResultDoneProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null));
messageBytes = responseMessage.encode().encode();
if (qopEncode) {
// Since we know it's a tiny response, we know the length will be
// less than 127 bytes, so we can cheat.
outputStream.write(0);
outputStream.write(0);
outputStream.write(0);
outputStream.write(messageBytes.length);
}
outputStream.write(messageBytes);
outputStream.flush();
// The next request should be an unbind request.
if (qopEncode) {
for (int i = 0; i < 4; i++) {
inputStream.read();
}
}
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
final UnbindRequestProtocolOp unbindRequestOp = requestMessage.getUnbindRequestProtocolOp();
// Close the connection.
try {
asn1Reader.close();
} catch (final Exception e) {
}
try {
outputStream.close();
} catch (final Exception e) {
}
try {
clientSocket.close();
} catch (final Exception e) {
}
clientSocket = null;
}
} catch (final Exception e) {
stopServer();
}
}
use of com.unboundid.ldap.protocol.SearchResultDoneProtocolOp in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processSearchRequest.
/**
* Attempts to process the provided search request. The attempt will fail
* if any of the following conditions is true:
* <UL>
* <LI>There is a problem with any of the request controls.</LI>
* <LI>The modify DN request contains a malformed target DN, new RDN, or
* new superior DN.</LI>
* <LI>The new DN of the entry would conflict with the DN of an existing
* entry.</LI>
* <LI>The new DN of the entry would exist outside the set of defined
* base DNs.</LI>
* <LI>The new DN of the entry is not a defined base DN and does not exist
* immediately below an existing entry.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the
* search request.
* @param request The search request that was included in the LDAP
* message that was received.
* @param controls The set of controls included in the LDAP message.
* It may be empty if there were no controls, but will
* not be {@code null}.
* @param entryList A list to which to add search result entries
* intended for return to the client. It must not be
* {@code null}.
* @param referenceList A list to which to add search result references
* intended for return to the client. It must not be
* {@code null}.
*
* @return The {@link LDAPMessage} containing the response to send to the
* client. The protocol op in the {@code LDAPMessage} must be an
* {@code SearchResultDoneProtocolOp}.
*/
@NotNull()
LDAPMessage processSearchRequest(final int messageID, @NotNull final SearchRequestProtocolOp request, @NotNull final List<Control> controls, @NotNull final List<SearchResultEntry> entryList, @NotNull final List<SearchResultReference> referenceList) {
synchronized (entryMap) {
// Sleep before processing, if appropriate.
final long processingStartTime = System.currentTimeMillis();
sleepBeforeProcessing();
// Look at the filter and see if it contains any unsupported elements.
try {
ensureFilterSupported(request.getFilter());
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// Look at the time limit for the search request and see if sleeping
// would have caused us to exceed that time limit. It's extremely
// unlikely that any search in the in-memory directory server would take
// a second or more to complete, and that's the minimum time limit that
// can be requested, so there's no need to check the time limit in most
// cases. However, someone may want to force a "time limit exceeded"
// response by configuring a delay that is greater than the requested time
// limit, so we should check now to see if that's been exceeded.
final long timeLimitMillis = 1000L * request.getTimeLimit();
if (timeLimitMillis > 0L) {
final long timeLimitExpirationTime = processingStartTime + timeLimitMillis;
if (System.currentTimeMillis() >= timeLimitExpirationTime) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.TIME_LIMIT_EXCEEDED_INT_VALUE, null, ERR_MEM_HANDLER_TIME_LIMIT_EXCEEDED.get(), null));
}
}
// Process the provided request controls.
final Map<String, Control> controlMap;
try {
controlMap = RequestControlPreProcessor.processControls(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_REQUEST, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
final ArrayList<Control> responseControls = new ArrayList<>(1);
// If this operation type is not allowed, then reject it.
final boolean isInternalOp = controlMap.containsKey(OID_INTERNAL_OPERATION_REQUEST_CONTROL);
if ((!isInternalOp) && (!config.getAllowedOperationTypes().contains(OperationType.SEARCH))) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.UNWILLING_TO_PERFORM_INT_VALUE, null, ERR_MEM_HANDLER_SEARCH_NOT_ALLOWED.get(), null));
}
// client is authenticated.
if ((authenticatedDN.isNullDN() && config.getAuthenticationRequiredOperationTypes().contains(OperationType.SEARCH))) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.INSUFFICIENT_ACCESS_RIGHTS_INT_VALUE, null, ERR_MEM_HANDLER_SEARCH_REQUIRES_AUTH.get(), null));
}
// Get the parsed base DN.
final DN baseDN;
final Schema schema = schemaRef.get();
try {
baseDN = new DN(request.getBaseDN(), schema);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.INVALID_DN_SYNTAX_INT_VALUE, null, ERR_MEM_HANDLER_SEARCH_MALFORMED_BASE.get(request.getBaseDN(), le.getMessage()), null));
}
// See if the search base or one of its superiors is a smart referral.
final boolean hasManageDsaIT = controlMap.containsKey(ManageDsaITRequestControl.MANAGE_DSA_IT_REQUEST_OID);
if (!hasManageDsaIT) {
final Entry referralEntry = findNearestReferral(baseDN);
if (referralEntry != null) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.REFERRAL_INT_VALUE, referralEntry.getDN(), INFO_MEM_HANDLER_REFERRAL_ENCOUNTERED.get(), getReferralURLs(baseDN, referralEntry)));
}
}
// Make sure that the base entry exists. It may be the root DSE or
// subschema subentry.
final Entry baseEntry;
boolean includeChangeLog = true;
if (baseDN.isNullDN()) {
baseEntry = generateRootDSE();
includeChangeLog = false;
} else if (baseDN.equals(subschemaSubentryDN)) {
baseEntry = subschemaSubentryRef.get();
} else {
baseEntry = entryMap.get(baseDN);
}
if (baseEntry == null) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.NO_SUCH_OBJECT_INT_VALUE, getMatchedDNString(baseDN), ERR_MEM_HANDLER_SEARCH_BASE_DOES_NOT_EXIST.get(request.getBaseDN()), null));
}
// controls.
try {
handleAssertionRequestControl(controlMap, baseEntry);
handleProxiedAuthControl(controlMap);
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), null, le.getMessage(), null));
}
// Determine whether to include subentries in search results.
final boolean includeSubEntries;
final boolean includeNonSubEntries;
final SearchScope scope = request.getScope();
if (scope == SearchScope.BASE) {
includeSubEntries = true;
includeNonSubEntries = true;
} else if (controlMap.containsKey(DraftLDUPSubentriesRequestControl.SUBENTRIES_REQUEST_OID)) {
includeSubEntries = true;
includeNonSubEntries = false;
} else if (controlMap.containsKey(RFC3672SubentriesRequestControl.SUBENTRIES_REQUEST_OID)) {
includeSubEntries = true;
final RFC3672SubentriesRequestControl c = (RFC3672SubentriesRequestControl) controlMap.get(RFC3672SubentriesRequestControl.SUBENTRIES_REQUEST_OID);
includeNonSubEntries = (!c.returnOnlySubEntries());
} else if (baseEntry.hasObjectClass("ldapSubEntry") || baseEntry.hasObjectClass("inheritableLDAPSubEntry")) {
includeSubEntries = true;
includeNonSubEntries = true;
} else if (filterIncludesLDAPSubEntry(request.getFilter())) {
includeSubEntries = true;
includeNonSubEntries = true;
} else {
includeSubEntries = false;
includeNonSubEntries = true;
}
// Create a temporary list to hold all of the entries to be returned.
// These entries will not have been pared down based on the requested
// attributes.
final List<Entry> fullEntryList = new ArrayList<>(entryMap.size());
findEntriesAndRefs: {
// Check the scope. If it is a base-level search, then we only need to
// examine the base entry. Otherwise, we'll have to scan the entire
// entry map.
final Filter filter = request.getFilter();
if (scope == SearchScope.BASE) {
try {
if (filter.matchesEntry(baseEntry, schema)) {
processSearchEntry(baseEntry, includeSubEntries, includeNonSubEntries, includeChangeLog, hasManageDsaIT, fullEntryList, referenceList);
}
} catch (final Exception e) {
Debug.debugException(e);
}
break findEntriesAndRefs;
}
// set.
if ((scope == SearchScope.ONE) && baseDN.isNullDN()) {
for (final DN dn : baseDNs) {
final Entry e = entryMap.get(dn);
if (e != null) {
try {
if (filter.matchesEntry(e, schema)) {
processSearchEntry(e, includeSubEntries, includeNonSubEntries, includeChangeLog, hasManageDsaIT, fullEntryList, referenceList);
}
} catch (final Exception ex) {
Debug.debugException(ex);
}
}
}
break findEntriesAndRefs;
}
// Try to use indexes to process the request. If we can't use any
// indexes to get a candidate list, then just iterate over all the
// entries. It's not necessary to consider the root DSE for non-base
// scopes.
final Set<DN> candidateDNs = indexSearch(filter);
if (candidateDNs == null) {
for (final Map.Entry<DN, ReadOnlyEntry> me : entryMap.entrySet()) {
final DN dn = me.getKey();
final Entry entry = me.getValue();
try {
if (dn.matchesBaseAndScope(baseDN, scope)) {
if (filter.matchesEntry(entry, schema) || (((!hasManageDsaIT) && entry.hasObjectClass("referral") && entry.hasAttribute("ref")))) {
processSearchEntry(entry, includeSubEntries, includeNonSubEntries, includeChangeLog, hasManageDsaIT, fullEntryList, referenceList);
}
}
} catch (final Exception e) {
Debug.debugException(e);
}
}
} else {
for (final DN dn : candidateDNs) {
try {
if (!dn.matchesBaseAndScope(baseDN, scope)) {
continue;
}
final Entry entry = entryMap.get(dn);
if (filter.matchesEntry(entry, schema) || (((!hasManageDsaIT) && entry.hasObjectClass("referral") && entry.hasAttribute("ref")))) {
processSearchEntry(entry, includeSubEntries, includeNonSubEntries, includeChangeLog, hasManageDsaIT, fullEntryList, referenceList);
}
} catch (final Exception e) {
Debug.debugException(e);
}
}
}
}
// If the request included the server-side sort request control, then sort
// the matching entries appropriately.
final ServerSideSortRequestControl sortRequestControl = (ServerSideSortRequestControl) controlMap.get(ServerSideSortRequestControl.SERVER_SIDE_SORT_REQUEST_OID);
if (sortRequestControl != null) {
final EntrySorter entrySorter = new EntrySorter(false, schema, sortRequestControl.getSortKeys());
final SortedSet<Entry> sortedEntrySet = entrySorter.sort(fullEntryList);
fullEntryList.clear();
fullEntryList.addAll(sortedEntrySet);
responseControls.add(new ServerSideSortResponseControl(ResultCode.SUCCESS, null));
}
// If the request included the simple paged results control, then handle
// it.
final SimplePagedResultsControl pagedResultsControl = (SimplePagedResultsControl) controlMap.get(SimplePagedResultsControl.PAGED_RESULTS_OID);
if (pagedResultsControl != null) {
final int totalSize = fullEntryList.size();
final int pageSize = pagedResultsControl.getSize();
final ASN1OctetString cookie = pagedResultsControl.getCookie();
final int offset;
if ((cookie == null) || (cookie.getValueLength() == 0)) {
// This is the first request in the series, so start at the beginning
// of the list.
offset = 0;
} else {
// offset within the result list at which to start the next batch.
try {
final ASN1Integer offsetInteger = ASN1Integer.decodeAsInteger(cookie.getValue());
offset = offsetInteger.intValue();
} catch (final Exception e) {
Debug.debugException(e);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.PROTOCOL_ERROR_INT_VALUE, null, ERR_MEM_HANDLER_MALFORMED_PAGED_RESULTS_COOKIE.get(), null), responseControls);
}
}
// Create an iterator that will be used to remove entries from the
// result set that are outside of the requested page of results.
int pos = 0;
final Iterator<Entry> iterator = fullEntryList.iterator();
// offset.
while (iterator.hasNext() && (pos < offset)) {
iterator.next();
iterator.remove();
pos++;
}
// Next, skip over the entries that should be returned.
int keptEntries = 0;
while (iterator.hasNext() && (keptEntries < pageSize)) {
iterator.next();
pos++;
keptEntries++;
}
// to include in the response. Otherwise, use an empty cookie.
if (iterator.hasNext()) {
responseControls.add(new SimplePagedResultsControl(totalSize, new ASN1OctetString(new ASN1Integer(pos).encode()), false));
while (iterator.hasNext()) {
iterator.next();
iterator.remove();
}
} else {
responseControls.add(new SimplePagedResultsControl(totalSize, new ASN1OctetString(), false));
}
}
// If the request includes the virtual list view request control, then
// handle it.
final VirtualListViewRequestControl vlvRequest = (VirtualListViewRequestControl) controlMap.get(VirtualListViewRequestControl.VIRTUAL_LIST_VIEW_REQUEST_OID);
if (vlvRequest != null) {
final int totalEntries = fullEntryList.size();
final ASN1OctetString assertionValue = vlvRequest.getAssertionValue();
// Figure out the position of the target entry in the list.
int offset = vlvRequest.getTargetOffset();
if (assertionValue == null) {
// The offset is one-based, so we need to adjust it for the list's
// zero-based offset. Also, make sure to put it within the bounds of
// the list.
offset--;
offset = Math.max(0, offset);
offset = Math.min(fullEntryList.size(), offset);
} else {
final SortKey primarySortKey = sortRequestControl.getSortKeys()[0];
final Entry testEntry = new Entry("cn=test", schema, new Attribute(primarySortKey.getAttributeName(), assertionValue));
final EntrySorter entrySorter = new EntrySorter(false, schema, primarySortKey);
offset = fullEntryList.size();
for (int i = 0; i < fullEntryList.size(); i++) {
if (entrySorter.compare(fullEntryList.get(i), testEntry) >= 0) {
offset = i;
break;
}
}
}
// Get the start and end positions based on the before and after counts.
final int beforeCount = Math.max(0, vlvRequest.getBeforeCount());
final int afterCount = Math.max(0, vlvRequest.getAfterCount());
final int start = Math.max(0, (offset - beforeCount));
final int end = Math.min(fullEntryList.size(), (offset + afterCount + 1));
// Create an iterator to use to alter the list so that it only contains
// the appropriate set of entries.
int pos = 0;
final Iterator<Entry> iterator = fullEntryList.iterator();
while (iterator.hasNext()) {
iterator.next();
if ((pos < start) || (pos >= end)) {
iterator.remove();
}
pos++;
}
// Create the appropriate response control.
responseControls.add(new VirtualListViewResponseControl((offset + 1), totalEntries, ResultCode.SUCCESS, null));
}
// Process the set of requested attributes so that we can pare down the
// entries.
final SearchEntryParer parer = new SearchEntryParer(request.getAttributes(), schema);
final int sizeLimit;
if (request.getSizeLimit() > 0) {
sizeLimit = Math.min(request.getSizeLimit(), maxSizeLimit);
} else {
sizeLimit = maxSizeLimit;
}
int entryCount = 0;
for (final Entry e : fullEntryList) {
entryCount++;
if (entryCount > sizeLimit) {
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.SIZE_LIMIT_EXCEEDED_INT_VALUE, null, ERR_MEM_HANDLER_SEARCH_SIZE_LIMIT_EXCEEDED.get(), null), responseControls);
}
final Entry trimmedEntry = parer.pareEntry(e);
if (request.typesOnly()) {
final Entry typesOnlyEntry = new Entry(trimmedEntry.getDN(), schema);
for (final Attribute a : trimmedEntry.getAttributes()) {
typesOnlyEntry.addAttribute(new Attribute(a.getName()));
}
entryList.add(new SearchResultEntry(typesOnlyEntry));
} else {
entryList.add(new SearchResultEntry(trimmedEntry));
}
}
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.SUCCESS_INT_VALUE, null, null, null), responseControls);
}
}
use of com.unboundid.ldap.protocol.SearchResultDoneProtocolOp in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processSearchRequest.
/**
* Attempts to process the provided search request. The attempt will fail
* if any of the following conditions is true:
* <UL>
* <LI>There is a problem with any of the request controls.</LI>
* <LI>The modify DN request contains a malformed target DN, new RDN, or
* new superior DN.</LI>
* <LI>The new DN of the entry would conflict with the DN of an existing
* entry.</LI>
* <LI>The new DN of the entry would exist outside the set of defined
* base DNs.</LI>
* <LI>The new DN of the entry is not a defined base DN and does not exist
* immediately below an existing entry.</LI>
* </UL>
*
* @param messageID The message ID of the LDAP message containing the search
* request.
* @param request The search request that was included in the LDAP message
* that was received.
* @param controls The set of controls included in the LDAP message. It
* may be empty if there were no controls, but will not be
* {@code null}.
*
* @return The {@link LDAPMessage} containing the response to send to the
* client. The protocol op in the {@code LDAPMessage} must be an
* {@code SearchResultDoneProtocolOp}.
*/
@Override()
@NotNull()
public LDAPMessage processSearchRequest(final int messageID, @NotNull final SearchRequestProtocolOp request, @NotNull final List<Control> controls) {
synchronized (entryMap) {
final List<SearchResultEntry> entryList = new ArrayList<>(entryMap.size());
final List<SearchResultReference> referenceList = new ArrayList<>(entryMap.size());
final LDAPMessage returnMessage = processSearchRequest(messageID, request, controls, entryList, referenceList);
for (final SearchResultEntry e : entryList) {
try {
connection.sendSearchResultEntry(messageID, e, e.getControls());
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
}
}
for (final SearchResultReference r : referenceList) {
try {
connection.sendSearchResultReference(messageID, new SearchResultReferenceProtocolOp(StaticUtils.toList(r.getReferralURLs())), r.getControls());
} catch (final LDAPException le) {
Debug.debugException(le);
return new LDAPMessage(messageID, new SearchResultDoneProtocolOp(le.getResultCode().intValue(), le.getMatchedDN(), le.getDiagnosticMessage(), StaticUtils.toList(le.getReferralURLs())), le.getResponseControls());
}
}
return returnMessage;
}
}
use of com.unboundid.ldap.protocol.SearchResultDoneProtocolOp in project ldapsdk by pingidentity.
the class JSONAccessLogRequestHandler method processSearchRequest.
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public LDAPMessage processSearchRequest(final int messageID, @NotNull final SearchRequestProtocolOp request, @NotNull final List<Control> controls) {
final long opID = nextOperationID.getAndIncrement();
final JSONBuffer buffer = getRequestHeader("search", opID, messageID);
buffer.appendString("base", request.getBaseDN());
buffer.appendNumber("scope", request.getScope().intValue());
buffer.appendString("filter", request.getFilter().toString());
buffer.beginArray("requested-attributes");
for (final String requestedAttribute : request.getAttributes()) {
buffer.appendString(requestedAttribute);
}
buffer.endArray();
buffer.endObject();
logHandler.publish(new LogRecord(Level.INFO, buffer.toString()));
logHandler.flush();
final AtomicLong entryCounter = new AtomicLong(0L);
entryCounts.put(messageID, entryCounter);
try {
final long startTimeNanos = System.nanoTime();
final LDAPMessage responseMessage = requestHandler.processSearchRequest(messageID, request, controls);
final long eTimeNanos = System.nanoTime() - startTimeNanos;
final SearchResultDoneProtocolOp protocolOp = responseMessage.getSearchResultDoneProtocolOp();
generateResponse(buffer, "search", opID, messageID, protocolOp.getResultCode(), protocolOp.getDiagnosticMessage(), protocolOp.getMatchedDN(), protocolOp.getReferralURLs(), eTimeNanos);
buffer.appendNumber("entries-returned", entryCounter.get());
buffer.endObject();
logHandler.publish(new LogRecord(Level.INFO, buffer.toString()));
logHandler.flush();
return responseMessage;
} finally {
entryCounts.remove(messageID);
}
}
use of com.unboundid.ldap.protocol.SearchResultDoneProtocolOp in project ldapsdk by pingidentity.
the class LDAPListenerClientConnection method run.
/**
* Operates in a loop, waiting for a request to arrive from the client and
* handing it off to the request handler for processing. This method is for
* internal use only and must not be invoked by external callers.
*/
@InternalUseOnly()
@Override()
public void run() {
try {
while (true) {
final LDAPMessage requestMessage;
try {
requestMessage = LDAPMessage.readFrom(asn1Reader, false);
if (requestMessage == null) {
// so we won't notify the exception handler.
try {
close();
} catch (final IOException ioe) {
Debug.debugException(ioe);
}
return;
}
} catch (final LDAPException le) {
// This indicates that the client sent a malformed request.
Debug.debugException(le);
close(le);
return;
}
try {
final int messageID = requestMessage.getMessageID();
final List<Control> controls = requestMessage.getControls();
LDAPMessage responseMessage;
switch(requestMessage.getProtocolOpType()) {
case LDAPMessage.PROTOCOL_OP_TYPE_ABANDON_REQUEST:
requestHandler.processAbandonRequest(messageID, requestMessage.getAbandonRequestProtocolOp(), controls);
responseMessage = null;
break;
case LDAPMessage.PROTOCOL_OP_TYPE_ADD_REQUEST:
try {
responseMessage = requestHandler.processAddRequest(messageID, requestMessage.getAddRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new AddResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_BIND_REQUEST:
try {
responseMessage = requestHandler.processBindRequest(messageID, requestMessage.getBindRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new BindResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null, null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_COMPARE_REQUEST:
try {
responseMessage = requestHandler.processCompareRequest(messageID, requestMessage.getCompareRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new CompareResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_DELETE_REQUEST:
try {
responseMessage = requestHandler.processDeleteRequest(messageID, requestMessage.getDeleteRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new DeleteResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_REQUEST:
try {
responseMessage = requestHandler.processExtendedRequest(messageID, requestMessage.getExtendedRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new ExtendedResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null, null, null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST:
try {
responseMessage = requestHandler.processModifyRequest(messageID, requestMessage.getModifyRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new ModifyResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST:
try {
responseMessage = requestHandler.processModifyDNRequest(messageID, requestMessage.getModifyDNRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new ModifyDNResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_REQUEST:
try {
responseMessage = requestHandler.processSearchRequest(messageID, requestMessage.getSearchRequestProtocolOp(), controls);
} catch (final Exception e) {
Debug.debugException(e);
responseMessage = new LDAPMessage(messageID, new SearchResultDoneProtocolOp(ResultCode.OTHER_INT_VALUE, null, ERR_CONN_REQUEST_HANDLER_FAILURE.get(StaticUtils.getExceptionMessage(e)), null));
}
break;
case LDAPMessage.PROTOCOL_OP_TYPE_UNBIND_REQUEST:
requestHandler.processUnbindRequest(messageID, requestMessage.getUnbindRequestProtocolOp(), controls);
close();
return;
default:
close(new LDAPException(ResultCode.PROTOCOL_ERROR, ERR_CONN_INVALID_PROTOCOL_OP_TYPE.get(StaticUtils.toHex(requestMessage.getProtocolOpType()))));
return;
}
if (responseMessage != null) {
try {
sendMessage(responseMessage);
} catch (final LDAPException le) {
Debug.debugException(le);
close(le);
return;
}
}
} catch (final Throwable t) {
close(new LDAPException(ResultCode.LOCAL_ERROR, ERR_CONN_EXCEPTION_IN_REQUEST_HANDLER.get(String.valueOf(requestMessage), StaticUtils.getExceptionMessage(t))));
StaticUtils.throwErrorOrRuntimeException(t);
}
}
} finally {
if (listener != null) {
listener.connectionClosed(this);
}
}
}
Aggregations