Search in sources :

Example 16 with LDAPResponse

use of com.unboundid.ldap.protocol.LDAPResponse in project ldapsdk by pingidentity.

the class LDAPConnectionReader method readResponse.

/**
 * Reads a response from the server, blocking if necessary until the response
 * has been received.  This should only be used for connections operating in
 * synchronous mode.
 *
 * @param  messageID  The message ID for the response to be read.  Any
 *                    response read with a different message ID will be
 *                    discarded, unless it is an unsolicited notification in
 *                    which case it will be provided to any registered
 *                    unsolicited notification handler.
 *
 * @return  The response read from the server.
 *
 * @throws  LDAPException  If a problem occurs while reading the response.
 */
@NotNull()
@SuppressWarnings("deprecation")
LDAPResponse readResponse(final int messageID) throws LDAPException {
    while (true) {
        try {
            final LDAPResponse response = LDAPMessage.readLDAPResponseFrom(asn1StreamReader, false, connection.getCachedSchema());
            if (response == null) {
                return new ConnectionClosedResponse(ResultCode.SERVER_DOWN, null);
            }
            connection.setLastCommunicationTime();
            if (response.getMessageID() == messageID) {
                return response;
            }
            if ((response instanceof ExtendedResult) && (response.getMessageID() == 0)) {
                // This is an intermediate response message, so handle it
                // appropriately.
                ExtendedResult extendedResult = (ExtendedResult) response;
                final String oid = extendedResult.getOID();
                if (NoticeOfDisconnectionExtendedResult.NOTICE_OF_DISCONNECTION_RESULT_OID.equals(oid)) {
                    extendedResult = new NoticeOfDisconnectionExtendedResult(extendedResult);
                    connection.setDisconnectInfo(DisconnectType.SERVER_CLOSED_WITH_NOTICE, extendedResult.getDiagnosticMessage(), null);
                } else if (com.unboundid.ldap.sdk.unboundidds.extensions.InteractiveTransactionAbortedExtendedResult.INTERACTIVE_TRANSACTION_ABORTED_RESULT_OID.equals(oid)) {
                    extendedResult = new com.unboundid.ldap.sdk.unboundidds.extensions.InteractiveTransactionAbortedExtendedResult(extendedResult);
                }
                final UnsolicitedNotificationHandler handler = connection.getConnectionOptions().getUnsolicitedNotificationHandler();
                if (handler == null) {
                    if (Debug.debugEnabled(DebugType.LDAP)) {
                        Debug.debug(Level.WARNING, DebugType.LDAP, WARN_READER_UNHANDLED_UNSOLICITED_NOTIFICATION.get(response));
                    }
                } else {
                    handler.handleUnsolicitedNotification(connection, extendedResult);
                }
                continue;
            }
            if (Debug.debugEnabled(DebugType.LDAP)) {
                Debug.debug(Level.WARNING, DebugType.LDAP, WARN_READER_DISCARDING_UNEXPECTED_RESPONSE.get(response, messageID));
            }
        } catch (final LDAPException le) {
            // If the cause was a SocketTimeoutException, then we shouldn't
            // terminate the connection, but we should propagate the failure to
            // the client with the appropriate result.
            final Throwable t = le.getCause();
            if ((t != null) && (t instanceof SocketTimeoutException)) {
                Debug.debugException(Level.FINEST, le);
                throw new LDAPException(ResultCode.TIMEOUT, le.getMessage(), le);
            } else {
                Debug.debugException(le);
            }
            // We should terminate the connection regardless of the type of
            // exception, but might want to customize the debug message.
            final String message;
            Level debugLevel = Level.SEVERE;
            if (t == null) {
                connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, le.getMessage(), t);
                message = le.getMessage();
                debugLevel = Level.WARNING;
            } else if (t instanceof IOException) {
                connection.setDisconnectInfo(DisconnectType.IO_ERROR, le.getMessage(), t);
                message = ERR_READER_CLOSING_DUE_TO_IO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
                debugLevel = Level.WARNING;
            } else if (t instanceof ASN1Exception) {
                connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, le.getMessage(), t);
                message = ERR_READER_CLOSING_DUE_TO_ASN1_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
            } else {
                connection.setDisconnectInfo(DisconnectType.LOCAL_ERROR, le.getMessage(), t);
                message = ERR_READER_CLOSING_DUE_TO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
            }
            Debug.debug(debugLevel, DebugType.LDAP, message, t);
            @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
            if (!autoReconnect) {
                closeRequested = true;
            }
            closeInternal(true, message);
            throw le;
        } catch (final Exception e) {
            Debug.debugException(e);
            // We should terminate the connection regardless of the type of
            // exception, but might want to customize the debug message.
            final String message;
            Level debugLevel = Level.SEVERE;
            if (e instanceof IOException) {
                connection.setDisconnectInfo(DisconnectType.IO_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_IO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
                debugLevel = Level.WARNING;
            } else if (e instanceof ASN1Exception) {
                connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_ASN1_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
            } else {
                connection.setDisconnectInfo(DisconnectType.LOCAL_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
            }
            Debug.debug(debugLevel, DebugType.LDAP, message, e);
            @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
            if (!autoReconnect) {
                closeRequested = true;
            }
            closeInternal(true, message);
            throw new LDAPException(ResultCode.SERVER_DOWN, message, e);
        }
    }
}
Also used : ASN1Exception(com.unboundid.asn1.ASN1Exception) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) SocketTimeoutException(java.net.SocketTimeoutException) ASN1Exception(com.unboundid.asn1.ASN1Exception) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) Level(java.util.logging.Level) LDAPResponse(com.unboundid.ldap.protocol.LDAPResponse) NotNull(com.unboundid.util.NotNull)

Example 17 with LDAPResponse

use of com.unboundid.ldap.protocol.LDAPResponse in project ldapsdk by pingidentity.

the class LDAPConnectionReader method run.

/**
 * Operates in a loop, reading data from the server and decoding the
 * responses, and associating them with their corresponding requests.
 */
@Override()
@SuppressWarnings("deprecation")
public void run() {
    boolean reconnect = false;
    thread = Thread.currentThread();
    while (!closeRequested) {
        try {
            final LDAPResponse response;
            try {
                response = LDAPMessage.readLDAPResponseFrom(asn1StreamReader, true, connection.getCachedSchema());
            } catch (final LDAPException le) {
                final Throwable t = le.getCause();
                if ((t != null) && (t instanceof SocketTimeoutException)) {
                    // This is rarely a problem, so we can make the debug message for
                    // this exception only visible at a verbose log level.
                    final SocketTimeoutException ste = (SocketTimeoutException) t;
                    Debug.debugException(Level.FINEST, ste);
                    if (sslSocketFactory != null) {
                        final LDAPConnectionOptions connectionOptions = connection.getConnectionOptions();
                        try {
                            final int responseTimeoutMillis = (int) connectionOptions.getResponseTimeoutMillis();
                            if (responseTimeoutMillis > 0) {
                                InternalSDKHelper.setSoTimeout(connection, responseTimeoutMillis);
                            } else {
                                InternalSDKHelper.setSoTimeout(connection, 0);
                            }
                            final SSLSocket sslSocket;
                            synchronized (sslSocketFactory) {
                                sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, connection.getConnectedAddress(), socket.getPort(), true);
                                sslSocket.startHandshake();
                            }
                            connectionOptions.getSSLSocketVerifier().verifySSLSocket(connection.getConnectedAddress(), socket.getPort(), sslSocket);
                            inputStream = new BufferedInputStream(sslSocket.getInputStream(), DEFAULT_INPUT_BUFFER_SIZE);
                            asn1StreamReader = new ASN1StreamReader(inputStream, connectionOptions.getMaxMessageSize());
                            startTLSOutputStream = sslSocket.getOutputStream();
                            socket = sslSocket;
                            connection.getConnectionInternals(true).setSocket(sslSocket);
                            startTLSSleeper.wakeup();
                        } catch (final Exception e) {
                            Debug.debugException(e);
                            connection.setDisconnectInfo(DisconnectType.SECURITY_PROBLEM, StaticUtils.getExceptionMessage(e), e);
                            startTLSException = e;
                            closeRequested = true;
                            if (thread != null) {
                                thread.setName(thread.getName() + " (closed)");
                                thread = null;
                            }
                            closeInternal(true, StaticUtils.getExceptionMessage(e));
                            startTLSSleeper.wakeup();
                            return;
                        }
                        sslSocketFactory = null;
                    }
                    continue;
                }
                if (closeRequested || connection.closeRequested() || (connection.getDisconnectType() != null)) {
                    // This exception resulted from the connection being closed in a way
                    // that we already knew about.  We don't want to debug it at the
                    // same level as a newly-detected invalidity.
                    closeRequested = true;
                    Debug.debugException(Level.FINEST, le);
                } else {
                    Debug.debugException(le);
                }
                // We should terminate the connection regardless of the type of
                // exception, but might want to customize the debug message.
                final String message;
                Level debugLevel = Level.SEVERE;
                if (t == null) {
                    connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, le.getMessage(), t);
                    message = le.getMessage();
                    debugLevel = Level.WARNING;
                } else if ((t instanceof InterruptedIOException) && socket.isClosed()) {
                    connection.setDisconnectInfo(DisconnectType.SERVER_CLOSED_WITHOUT_NOTICE, le.getMessage(), t);
                    message = ERR_READER_CLOSING_DUE_TO_INTERRUPTED_IO.get(connection.getHostPort());
                    debugLevel = Level.WARNING;
                } else if (t instanceof IOException) {
                    connection.setDisconnectInfo(DisconnectType.IO_ERROR, le.getMessage(), t);
                    message = ERR_READER_CLOSING_DUE_TO_IO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
                    debugLevel = Level.WARNING;
                } else if (t instanceof ASN1Exception) {
                    connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, le.getMessage(), t);
                    message = ERR_READER_CLOSING_DUE_TO_ASN1_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
                } else {
                    connection.setDisconnectInfo(DisconnectType.LOCAL_ERROR, le.getMessage(), t);
                    message = ERR_READER_CLOSING_DUE_TO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(t));
                }
                Debug.debug(debugLevel, DebugType.LDAP, message, t);
                // If the connection is configured to try to auto-reconnect, then set
                // things up to do that.  Otherwise, terminate the connection.
                @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
                if ((!closeRequested) && autoReconnect) {
                    reconnect = true;
                    break;
                } else {
                    closeRequested = true;
                    if (thread != null) {
                        thread.setName(thread.getName() + " (closed)");
                        thread = null;
                    }
                    closeInternal(true, message);
                    return;
                }
            }
            if (response == null) {
                // This should only happen if the socket has been closed.
                connection.setDisconnectInfo(DisconnectType.SERVER_CLOSED_WITHOUT_NOTICE, null, null);
                @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
                if ((!closeRequested) && (!connection.unbindRequestSent()) && autoReconnect) {
                    reconnect = true;
                    break;
                } else {
                    closeRequested = true;
                    if (thread != null) {
                        thread.setName(thread.getName() + " (closed)");
                        thread = null;
                    }
                    closeInternal(true, null);
                    return;
                }
            }
            connection.setLastCommunicationTime();
            Debug.debugLDAPResult(response, connection);
            logResponse(response);
            final ResponseAcceptor responseAcceptor;
            if ((response instanceof SearchResultEntry) || (response instanceof SearchResultReference)) {
                responseAcceptor = acceptorMap.get(response.getMessageID());
            } else if (response instanceof IntermediateResponse) {
                final IntermediateResponse ir = (IntermediateResponse) response;
                responseAcceptor = acceptorMap.get(response.getMessageID());
                IntermediateResponseListener l = null;
                if (responseAcceptor instanceof LDAPRequest) {
                    final LDAPRequest r = (LDAPRequest) responseAcceptor;
                    l = r.getIntermediateResponseListener();
                } else if (responseAcceptor instanceof IntermediateResponseListener) {
                    l = (IntermediateResponseListener) responseAcceptor;
                }
                if (l == null) {
                    Debug.debug(Level.WARNING, DebugType.LDAP, WARN_INTERMEDIATE_RESPONSE_WITH_NO_LISTENER.get(String.valueOf(ir)));
                } else {
                    try {
                        l.intermediateResponseReturned(ir);
                    } catch (final Exception e) {
                        Debug.debugException(e);
                    }
                }
                continue;
            } else {
                responseAcceptor = acceptorMap.remove(response.getMessageID());
            }
            if (responseAcceptor == null) {
                if ((response instanceof ExtendedResult) && (response.getMessageID() == 0)) {
                    // This is an intermediate response message, so handle it
                    // appropriately.
                    ExtendedResult extendedResult = (ExtendedResult) response;
                    final String oid = extendedResult.getOID();
                    if (NoticeOfDisconnectionExtendedResult.NOTICE_OF_DISCONNECTION_RESULT_OID.equals(oid)) {
                        extendedResult = new NoticeOfDisconnectionExtendedResult(extendedResult);
                        connection.setDisconnectInfo(DisconnectType.SERVER_CLOSED_WITH_NOTICE, extendedResult.getDiagnosticMessage(), null);
                    } else if (com.unboundid.ldap.sdk.unboundidds.extensions.InteractiveTransactionAbortedExtendedResult.INTERACTIVE_TRANSACTION_ABORTED_RESULT_OID.equals(oid)) {
                        extendedResult = new com.unboundid.ldap.sdk.unboundidds.extensions.InteractiveTransactionAbortedExtendedResult(extendedResult);
                    }
                    final UnsolicitedNotificationHandler handler = connection.getConnectionOptions().getUnsolicitedNotificationHandler();
                    if (handler == null) {
                        if (Debug.debugEnabled(DebugType.LDAP)) {
                            Debug.debug(Level.WARNING, DebugType.LDAP, WARN_READER_UNHANDLED_UNSOLICITED_NOTIFICATION.get(response));
                        }
                    } else {
                        handler.handleUnsolicitedNotification(connection, extendedResult);
                    }
                    continue;
                }
                if (Debug.debugEnabled(DebugType.LDAP)) {
                    Debug.debug(Level.WARNING, DebugType.LDAP, WARN_READER_NO_ACCEPTOR.get(response));
                }
                continue;
            }
            try {
                responseAcceptor.responseReceived(response);
            } catch (final LDAPException le) {
                Debug.debugException(le);
                Debug.debug(Level.WARNING, DebugType.LDAP, ERR_READER_ACCEPTOR_ERROR.get(String.valueOf(response), connection.getHostPort(), StaticUtils.getExceptionMessage(le)), le);
            }
        } catch (final Exception e) {
            Debug.debugException(e);
            // We should terminate the connection regardless of the type of
            // exception, but might want to customize the debug message.
            final String message;
            Level debugLevel = Level.SEVERE;
            if (e instanceof IOException) {
                connection.setDisconnectInfo(DisconnectType.IO_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_IO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
                debugLevel = Level.WARNING;
            } else if (e instanceof ASN1Exception) {
                connection.setDisconnectInfo(DisconnectType.DECODE_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_ASN1_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
            } else {
                connection.setDisconnectInfo(DisconnectType.LOCAL_ERROR, null, e);
                message = ERR_READER_CLOSING_DUE_TO_EXCEPTION.get(connection.getHostPort(), StaticUtils.getExceptionMessage(e));
            }
            Debug.debug(debugLevel, DebugType.LDAP, message, e);
            // If the connection is configured to try to auto-reconnect, then set
            // things up to do that.  Otherwise, terminate the connection.
            @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
            if (autoReconnect) {
                reconnect = true;
                break;
            } else {
                closeRequested = true;
                if (thread != null) {
                    thread.setName(thread.getName() + " (closed)");
                    thread = null;
                }
                closeInternal(true, message);
                return;
            }
        }
    }
    if (thread != null) {
        thread.setName(constructThreadName(null));
        thread = null;
    }
    if (reconnect && (!connection.closeRequested())) {
        try {
            connection.setNeedsReconnect();
        } catch (final Exception e) {
            Debug.debugException(e);
        }
    } else {
        // Ensure that the connection has properly been closed.
        closeInternal(true, null);
    }
}
Also used : InterruptedIOException(java.io.InterruptedIOException) SSLSocket(javax.net.ssl.SSLSocket) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) BufferedInputStream(java.io.BufferedInputStream) ASN1StreamReader(com.unboundid.asn1.ASN1StreamReader) LDAPResponse(com.unboundid.ldap.protocol.LDAPResponse) ASN1Exception(com.unboundid.asn1.ASN1Exception) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) SocketTimeoutException(java.net.SocketTimeoutException) ASN1Exception(com.unboundid.asn1.ASN1Exception) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) Level(java.util.logging.Level)

Example 18 with LDAPResponse

use of com.unboundid.ldap.protocol.LDAPResponse in project ldapsdk by pingidentity.

the class ModifyDNRequest method process.

/**
 * Sends this modify DN request to the directory server over the provided
 * connection and returns the associated response.
 *
 * @param  connection  The connection to use to communicate with the directory
 *                     server.
 * @param  depth       The current referral depth for this request.  It should
 *                     always be one for the initial request, and should only
 *                     be incremented when following referrals.
 *
 * @return  An LDAP result object that provides information about the result
 *          of the modify DN processing.
 *
 * @throws  LDAPException  If a problem occurs while sending the request or
 *                         reading the response.
 */
@Override()
@NotNull()
protected LDAPResult process(@NotNull final LDAPConnection connection, final int depth) throws LDAPException {
    if (connection.synchronousMode()) {
        @SuppressWarnings("deprecation") final boolean autoReconnect = connection.getConnectionOptions().autoReconnect();
        return processSync(connection, depth, autoReconnect);
    }
    final long requestTime = System.nanoTime();
    processAsync(connection, null);
    try {
        // Wait for and process the response.
        final LDAPResponse response;
        try {
            final long responseTimeout = getResponseTimeoutMillis(connection);
            if (responseTimeout > 0) {
                response = responseQueue.poll(responseTimeout, TimeUnit.MILLISECONDS);
            } else {
                response = responseQueue.take();
            }
        } catch (final InterruptedException ie) {
            Debug.debugException(ie);
            Thread.currentThread().interrupt();
            throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_MODDN_INTERRUPTED.get(connection.getHostPort()), ie);
        }
        return handleResponse(connection, response, requestTime, depth, false);
    } finally {
        connection.deregisterResponseAcceptor(messageID);
    }
}
Also used : LDAPResponse(com.unboundid.ldap.protocol.LDAPResponse) NotNull(com.unboundid.util.NotNull)

Example 19 with LDAPResponse

use of com.unboundid.ldap.protocol.LDAPResponse in project ldapsdk by pingidentity.

the class ModifyDNRequest method processSync.

/**
 * Processes this modify DN operation in synchronous mode, in which the same
 * thread will send the request and read the response.
 *
 * @param  connection  The connection to use to communicate with the directory
 *                     server.
 * @param  depth       The current referral depth for this request.  It should
 *                     always be one for the initial request, and should only
 *                     be incremented when following referrals.
 * @param  allowRetry  Indicates whether the request may be re-tried on a
 *                     re-established connection if the initial attempt fails
 *                     in a way that indicates the connection is no longer
 *                     valid and autoReconnect is true.
 *
 * @return  An LDAP result object that provides information about the result
 *          of the modify DN processing.
 *
 * @throws  LDAPException  If a problem occurs while sending the request or
 *                         reading the response.
 */
@NotNull()
private LDAPResult processSync(@NotNull final LDAPConnection connection, final int depth, final boolean allowRetry) throws LDAPException {
    // Create the LDAP message.
    messageID = connection.nextMessageID();
    final LDAPMessage message = new LDAPMessage(messageID, this, getControls());
    // Send the request to the server.
    final long requestTime = System.nanoTime();
    Debug.debugLDAPRequest(Level.INFO, this, messageID, connection);
    final LDAPConnectionLogger logger = connection.getConnectionOptions().getConnectionLogger();
    if (logger != null) {
        logger.logModifyDNRequest(connection, messageID, this);
    }
    connection.getConnectionStatistics().incrementNumModifyDNRequests();
    try {
        connection.sendMessage(message, getResponseTimeoutMillis(connection));
    } catch (final LDAPException le) {
        Debug.debugException(le);
        if (allowRetry) {
            final LDAPResult retryResult = reconnectAndRetry(connection, depth, le.getResultCode());
            if (retryResult != null) {
                return retryResult;
            }
        }
        throw le;
    }
    while (true) {
        final LDAPResponse response;
        try {
            response = connection.readResponse(messageID);
        } catch (final LDAPException le) {
            Debug.debugException(le);
            if ((le.getResultCode() == ResultCode.TIMEOUT) && connection.getConnectionOptions().abandonOnTimeout()) {
                connection.abandon(messageID);
            }
            if (allowRetry) {
                final LDAPResult retryResult = reconnectAndRetry(connection, depth, le.getResultCode());
                if (retryResult != null) {
                    return retryResult;
                }
            }
            throw le;
        }
        if (response instanceof IntermediateResponse) {
            final IntermediateResponseListener listener = getIntermediateResponseListener();
            if (listener != null) {
                listener.intermediateResponseReturned((IntermediateResponse) response);
            }
        } else {
            return handleResponse(connection, response, requestTime, depth, allowRetry);
        }
    }
}
Also used : LDAPMessage(com.unboundid.ldap.protocol.LDAPMessage) LDAPResponse(com.unboundid.ldap.protocol.LDAPResponse) NotNull(com.unboundid.util.NotNull)

Example 20 with LDAPResponse

use of com.unboundid.ldap.protocol.LDAPResponse in project ldapsdk by pingidentity.

the class ModifyRequest method processSync.

/**
 * Processes this modify operation in synchronous mode, in which the same
 * thread will send the request and read the response.
 *
 * @param  connection  The connection to use to communicate with the directory
 *                     server.
 * @param  depth       The current referral depth for this request.  It should
 *                     always be one for the initial request, and should only
 *                     be incremented when following referrals.
 * @param  allowRetry  Indicates whether the request may be re-tried on a
 *                     re-established connection if the initial attempt fails
 *                     in a way that indicates the connection is no longer
 *                     valid and autoReconnect is true.
 *
 * @return  An LDAP result object that provides information about the result
 *          of the modify processing.
 *
 * @throws  LDAPException  If a problem occurs while sending the request or
 *                         reading the response.
 */
@NotNull()
private LDAPResult processSync(@NotNull final LDAPConnection connection, final int depth, final boolean allowRetry) throws LDAPException {
    // Create the LDAP message.
    messageID = connection.nextMessageID();
    final LDAPMessage message = new LDAPMessage(messageID, this, getControls());
    // Send the request to the server.
    final long requestTime = System.nanoTime();
    Debug.debugLDAPRequest(Level.INFO, this, messageID, connection);
    final LDAPConnectionLogger logger = connection.getConnectionOptions().getConnectionLogger();
    if (logger != null) {
        logger.logModifyRequest(connection, messageID, this);
    }
    connection.getConnectionStatistics().incrementNumModifyRequests();
    try {
        connection.sendMessage(message, getResponseTimeoutMillis(connection));
    } catch (final LDAPException le) {
        Debug.debugException(le);
        if (allowRetry) {
            final LDAPResult retryResult = reconnectAndRetry(connection, depth, le.getResultCode());
            if (retryResult != null) {
                return retryResult;
            }
        }
        throw le;
    }
    while (true) {
        final LDAPResponse response;
        try {
            response = connection.readResponse(messageID);
        } catch (final LDAPException le) {
            Debug.debugException(le);
            if ((le.getResultCode() == ResultCode.TIMEOUT) && connection.getConnectionOptions().abandonOnTimeout()) {
                connection.abandon(messageID);
            }
            if (allowRetry) {
                final LDAPResult retryResult = reconnectAndRetry(connection, depth, le.getResultCode());
                if (retryResult != null) {
                    return retryResult;
                }
            }
            throw le;
        }
        if (response instanceof IntermediateResponse) {
            final IntermediateResponseListener listener = getIntermediateResponseListener();
            if (listener != null) {
                listener.intermediateResponseReturned((IntermediateResponse) response);
            }
        } else {
            return handleResponse(connection, response, requestTime, depth, allowRetry);
        }
    }
}
Also used : LDAPMessage(com.unboundid.ldap.protocol.LDAPMessage) LDAPResponse(com.unboundid.ldap.protocol.LDAPResponse) NotNull(com.unboundid.util.NotNull)

Aggregations

LDAPResponse (com.unboundid.ldap.protocol.LDAPResponse)23 NotNull (com.unboundid.util.NotNull)21 LDAPMessage (com.unboundid.ldap.protocol.LDAPMessage)10 ASN1Exception (com.unboundid.asn1.ASN1Exception)2 ASN1OctetString (com.unboundid.asn1.ASN1OctetString)2 NoticeOfDisconnectionExtendedResult (com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult)2 IOException (java.io.IOException)2 InterruptedIOException (java.io.InterruptedIOException)2 SocketTimeoutException (java.net.SocketTimeoutException)2 Level (java.util.logging.Level)2 ASN1StreamReader (com.unboundid.asn1.ASN1StreamReader)1 StartTLSExtendedRequest (com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest)1 BufferedInputStream (java.io.BufferedInputStream)1 Socket (java.net.Socket)1 HashSet (java.util.HashSet)1 SSLSocket (javax.net.ssl.SSLSocket)1