Search in sources :

Example 16 with Message

use of org.apache.directory.api.ldap.model.message.Message in project directory-ldap-api by apache.

the class LdapNetworkConnection method connect.

// -------------------------- The methods ---------------------------//
/**
 * {@inheritDoc}
 */
@Override
public boolean connect() throws LdapException {
    if ((ldapSession != null) && connected.get()) {
        // No need to connect if we already have a connected session
        return true;
    }
    // Create the connector if needed
    if (connector == null) {
        createConnector();
    }
    // Build the connection address
    SocketAddress address = new InetSocketAddress(config.getLdapHost(), config.getLdapPort());
    // And create the connection future
    timeout = config.getTimeout();
    long maxRetry = System.currentTimeMillis() + timeout;
    ConnectFuture connectionFuture = null;
    boolean interrupted = false;
    while (maxRetry > System.currentTimeMillis() && !interrupted) {
        connectionFuture = connector.connect(address);
        boolean result = false;
        // Wait until it's established
        try {
            result = connectionFuture.await(timeout);
        } catch (InterruptedException e) {
            connector.dispose();
            connector = null;
            LOG.debug(I18n.msg(I18n.MSG_03221_INTERRUPTED_WAITING_FOR_CONNECTION, config.getLdapHost(), config.getLdapPort()), e);
            interrupted = true;
            throw new LdapOtherException(e.getMessage(), e);
        } finally {
            if (result) {
                boolean isConnected = connectionFuture.isConnected();
                if (!isConnected) {
                    Throwable connectionException = connectionFuture.getException();
                    if ((connectionException instanceof ConnectException) || (connectionException instanceof UnresolvedAddressException)) {
                        // We know that there was a permanent error such as "connection refused".
                        if (LOG.isDebugEnabled()) {
                            LOG.debug(I18n.msg(I18n.MSG_03245_CONNECTION_ERROR, connectionFuture.getException().getMessage()));
                        }
                    }
                    if (LOG.isDebugEnabled()) {
                        LOG.debug(I18n.msg(I18n.MSG_03244_CONNECTION_RETRYING));
                    }
                    // Wait 500 ms and retry
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        connector = null;
                        LOG.debug(I18n.msg(I18n.MSG_03221_INTERRUPTED_WAITING_FOR_CONNECTION, config.getLdapHost(), config.getLdapPort()), e);
                        interrupted = true;
                        throw new LdapOtherException(e.getMessage(), e);
                    }
                } else {
                    break;
                }
            }
        }
    }
    if (connectionFuture == null) {
        connector.dispose();
        throw new InvalidConnectionException("Cannot connect");
    }
    boolean isConnected = connectionFuture.isConnected();
    if (!isConnected) {
        // disposing connector if not connected
        try {
            close();
        } catch (IOException ioe) {
        // Nothing to do
        }
        Throwable e = connectionFuture.getException();
        if (e != null) {
            StringBuilder message = new StringBuilder("Cannot connect to the server: ");
            // (most of the time no message is associated with this exception)
            if ((e instanceof UnresolvedAddressException) && (e.getMessage() == null)) {
                message.append("Hostname '");
                message.append(config.getLdapHost());
                message.append("' could not be resolved.");
                throw new InvalidConnectionException(message.toString(), e);
            }
            // Default case
            message.append(e.getMessage());
            throw new InvalidConnectionException(message.toString(), e);
        }
        return false;
    }
    // Get the close future for this session
    CloseFuture closeFuture = connectionFuture.getSession().getCloseFuture();
    // Add a listener to close the session in the session.
    closeFuture.addListener(new IoFutureListener<IoFuture>() {

        @Override
        public void operationComplete(IoFuture future) {
            // Process all the waiting operations and cancel them
            LOG.debug(I18n.msg(I18n.MSG_03238_NOD_RECEIVED));
            for (ResponseFuture<?> responseFuture : futureMap.values()) {
                LOG.debug(I18n.msg(I18n.MSG_03235_CLOSING, responseFuture));
                responseFuture.cancel();
                try {
                    if (responseFuture instanceof AddFuture) {
                        ((AddFuture) responseFuture).set(AddNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof BindFuture) {
                        ((BindFuture) responseFuture).set(BindNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof CompareFuture) {
                        ((CompareFuture) responseFuture).set(CompareNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof DeleteFuture) {
                        ((DeleteFuture) responseFuture).set(DeleteNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof ExtendedFuture) {
                        ((ExtendedFuture) responseFuture).set(ExtendedNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof ModifyFuture) {
                        ((ModifyFuture) responseFuture).set(ModifyNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof ModifyDnFuture) {
                        ((ModifyDnFuture) responseFuture).set(ModifyDnNoDResponse.PROTOCOLERROR);
                    } else if (responseFuture instanceof SearchFuture) {
                        ((SearchFuture) responseFuture).set(SearchNoDResponse.PROTOCOLERROR);
                    }
                } catch (InterruptedException e) {
                    LOG.error(I18n.err(I18n.ERR_03202_ERROR_PROCESSING_NOD, responseFuture), e);
                }
                futureMap.remove(messageId.get());
            }
            futureMap.clear();
        }
    });
    // Get back the session
    ldapSession = connectionFuture.getSession();
    connected.set(true);
    // Store the container into the session if we don't have one
    @SuppressWarnings("unchecked") LdapMessageContainer<MessageDecorator<? extends Message>> container = (LdapMessageContainer<MessageDecorator<? extends Message>>) ldapSession.getAttribute(LdapDecoder.MESSAGE_CONTAINER_ATTR);
    if (container != null) {
        if ((schemaManager != null) && !(container.getBinaryAttributeDetector() instanceof SchemaBinaryAttributeDetector)) {
            container.setBinaryAttributeDetector(new SchemaBinaryAttributeDetector(schemaManager));
        }
    } else {
        BinaryAttributeDetector atDetector = new DefaultConfigurableBinaryAttributeDetector();
        if (schemaManager != null) {
            atDetector = new SchemaBinaryAttributeDetector(schemaManager);
        }
        ldapSession.setAttribute(LdapDecoder.MESSAGE_CONTAINER_ATTR, new LdapMessageContainer<MessageDecorator<? extends Message>>(codec, atDetector));
    }
    // Initialize the MessageId
    messageId.set(0);
    // And return
    return true;
}
Also used : LdapMessageContainer(org.apache.directory.api.ldap.codec.api.LdapMessageContainer) ModifyFuture(org.apache.directory.ldap.client.api.future.ModifyFuture) Message(org.apache.directory.api.ldap.model.message.Message) InetSocketAddress(java.net.InetSocketAddress) IoFuture(org.apache.mina.core.future.IoFuture) ConnectFuture(org.apache.mina.core.future.ConnectFuture) BindFuture(org.apache.directory.ldap.client.api.future.BindFuture) ModifyDnFuture(org.apache.directory.ldap.client.api.future.ModifyDnFuture) InvalidConnectionException(org.apache.directory.ldap.client.api.exception.InvalidConnectionException) DefaultConfigurableBinaryAttributeDetector(org.apache.directory.api.ldap.codec.api.DefaultConfigurableBinaryAttributeDetector) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) CompareFuture(org.apache.directory.ldap.client.api.future.CompareFuture) SchemaBinaryAttributeDetector(org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector) LdapOtherException(org.apache.directory.api.ldap.model.exception.LdapOtherException) ConnectException(java.net.ConnectException) CloseFuture(org.apache.mina.core.future.CloseFuture) ResponseFuture(org.apache.directory.ldap.client.api.future.ResponseFuture) ExtendedFuture(org.apache.directory.ldap.client.api.future.ExtendedFuture) IOException(java.io.IOException) SchemaBinaryAttributeDetector(org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector) DefaultConfigurableBinaryAttributeDetector(org.apache.directory.api.ldap.codec.api.DefaultConfigurableBinaryAttributeDetector) BinaryAttributeDetector(org.apache.directory.api.ldap.codec.api.BinaryAttributeDetector) DeleteFuture(org.apache.directory.ldap.client.api.future.DeleteFuture) MessageDecorator(org.apache.directory.api.ldap.codec.api.MessageDecorator) AddFuture(org.apache.directory.ldap.client.api.future.AddFuture) SearchFuture(org.apache.directory.ldap.client.api.future.SearchFuture)

Example 17 with Message

use of org.apache.directory.api.ldap.model.message.Message in project directory-ldap-api by apache.

the class AddControl method action.

/**
 * {@inheritDoc}
 */
public void action(LdapMessageContainer<MessageDecorator<? extends Message>> container) throws DecoderException {
    TLV tlv = container.getCurrentTLV();
    // We have to handle the special case of a 0 length OID
    if (tlv.getLength() == 0) {
        String msg = I18n.err(I18n.ERR_04097_NULL_CONTROL_OID);
        LOG.error(msg);
        // This will generate a PROTOCOL_ERROR
        throw new DecoderException(msg);
    }
    byte[] value = tlv.getValue().getData();
    String oidValue = Strings.asciiBytesToString(value);
    // The OID is encoded as a String, not an Object Id
    if (!Oid.isOid(oidValue)) {
        String msg = I18n.err(I18n.ERR_04098_INVALID_CONTROL_OID, oidValue);
        LOG.error(msg);
        // This will generate a PROTOCOL_ERROR
        throw new DecoderException(msg);
    }
    Message message = container.getMessage();
    Control control = container.getLdapCodecService().newControl(oidValue);
    message.addControl(control);
    // We can have an END transition
    container.setGrammarEndAllowed(true);
    if (IS_DEBUG) {
        LOG.debug("Control OID : {}", oidValue);
    }
}
Also used : DecoderException(org.apache.directory.api.asn1.DecoderException) Control(org.apache.directory.api.ldap.model.message.Control) Message(org.apache.directory.api.ldap.model.message.Message) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 18 with Message

use of org.apache.directory.api.ldap.model.message.Message in project directory-ldap-api by apache.

the class SearchRequestDecorator method unstackFilters.

/**
 * This method is used to clear the filter's stack for terminated elements. An element
 * is considered as terminated either if :
 *  - it's a final element (ie an element which cannot contains a Filter)
 *  - its current length equals its expected length.
 *
 * @param container The container being decoded
 */
@SuppressWarnings("unchecked")
public void unstackFilters(Asn1Container container) {
    LdapMessageContainer<MessageDecorator<Message>> ldapMessageContainer = (LdapMessageContainer<MessageDecorator<Message>>) container;
    TLV tlv = ldapMessageContainer.getCurrentTLV();
    TLV localParent = tlv.getParent();
    Filter localFilter = terminalFilter;
    // The parent has been completed, so fold it
    while ((localParent != null) && (localParent.getExpectedLength() == 0)) {
        int parentTlvId = localFilter.getParent() != null ? localFilter.getParent().getTlvId() : localFilter.getParentTlvId();
        if (localParent.getId() != parentTlvId) {
            localParent = localParent.getParent();
        } else {
            Filter filterParent = localFilter.getParent();
            // pushed on the stack, so we need to get its parent's parent
            if (localFilter instanceof PresentFilter) {
                if (filterParent == null) {
                    // We don't have parent, get out
                    break;
                }
                filterParent = filterParent.getParent();
            } else {
                filterParent = filterParent.getParent();
            }
            if (filterParent != null) {
                // The parent is a filter ; it will become the new currentFilter
                // and we will loop again.
                localFilter = currentFilter;
                currentFilter = filterParent;
                localParent = localParent.getParent();
            } else {
                // We can stop the recursion, we have reached the searchResult Object
                break;
            }
        }
    }
}
Also used : LdapMessageContainer(org.apache.directory.api.ldap.codec.api.LdapMessageContainer) MessageDecorator(org.apache.directory.api.ldap.codec.api.MessageDecorator) Message(org.apache.directory.api.ldap.model.message.Message) PresentFilter(org.apache.directory.api.ldap.codec.search.PresentFilter) AttributeValueAssertionFilter(org.apache.directory.api.ldap.codec.search.AttributeValueAssertionFilter) AndFilter(org.apache.directory.api.ldap.codec.search.AndFilter) ConnectorFilter(org.apache.directory.api.ldap.codec.search.ConnectorFilter) SubstringFilter(org.apache.directory.api.ldap.codec.search.SubstringFilter) NotFilter(org.apache.directory.api.ldap.codec.search.NotFilter) OrFilter(org.apache.directory.api.ldap.codec.search.OrFilter) PresentFilter(org.apache.directory.api.ldap.codec.search.PresentFilter) ExtensibleMatchFilter(org.apache.directory.api.ldap.codec.search.ExtensibleMatchFilter) Filter(org.apache.directory.api.ldap.codec.search.Filter) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 19 with Message

use of org.apache.directory.api.ldap.model.message.Message in project directory-ldap-api by apache.

the class AddReferral method action.

/**
 * {@inheritDoc}
 */
public void action(LdapMessageContainer<MessageDecorator<? extends Message>> container) throws DecoderException {
    TLV tlv = container.getCurrentTLV();
    Message response = container.getMessage();
    LdapResult ldapResult = ((ResultResponse) response).getLdapResult();
    Referral referral = ldapResult.getReferral();
    if (tlv.getLength() == 0) {
        referral.addLdapUrl("");
    } else {
        if (ldapResult.getResultCode() == ResultCodeEnum.REFERRAL) {
            try {
                String url = Strings.utf8ToString(tlv.getValue().getData());
                referral.addLdapUrl(new LdapUrl(url).toString());
            } catch (LdapURLEncodingException luee) {
                String badUrl = Strings.utf8ToString(tlv.getValue().getData());
                LOG.error(I18n.err(I18n.ERR_04015, badUrl, luee.getMessage()));
                throw new DecoderException(I18n.err(I18n.ERR_04016, luee.getMessage()), luee);
            }
        } else {
            LOG.warn("The Referral error message is not allowed when havind an error code no equals to REFERRAL");
            referral.addLdapUrl(LdapUrl.EMPTY_URL.toString());
        }
    }
    if (IS_DEBUG) {
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (String url : ldapResult.getReferral().getLdapUrls()) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append(", ");
            }
            sb.append(url);
        }
        LOG.debug("The referral error message is set to " + sb.toString());
    }
    // We can have an END transition
    container.setGrammarEndAllowed(true);
}
Also used : ResultResponse(org.apache.directory.api.ldap.model.message.ResultResponse) LdapUrl(org.apache.directory.api.ldap.model.url.LdapUrl) LdapURLEncodingException(org.apache.directory.api.ldap.model.exception.LdapURLEncodingException) DecoderException(org.apache.directory.api.asn1.DecoderException) LdapResult(org.apache.directory.api.ldap.model.message.LdapResult) Message(org.apache.directory.api.ldap.model.message.Message) Referral(org.apache.directory.api.ldap.model.message.Referral) TLV(org.apache.directory.api.asn1.ber.tlv.TLV)

Example 20 with Message

use of org.apache.directory.api.ldap.model.message.Message in project directory-ldap-api by apache.

the class LdapProtocolDecoder method decode.

/**
 * Decode an incoming buffer into LDAP messages. The result can be 0, 1 or many
 * LDAP messages, which will be stored into the array the caller has created.
 *
 * @param buffer The incoming byte buffer
 * @param messageContainer The LdapMessageContainer which will be used to store the
 * message being decoded. If the message is not fully decoded, the ucrrent state
 * is stored into this container
 * @param decodedMessages The list of decoded messages
 * @throws Exception If the decoding failed
 */
private void decode(ByteBuffer buffer, LdapMessageContainer<MessageDecorator<? extends Message>> messageContainer, List<Message> decodedMessages) throws DecoderException {
    buffer.mark();
    while (buffer.hasRemaining()) {
        try {
            if (IS_DEBUG) {
                CODEC_LOG.debug(I18n.msg(I18n.MSG_14000_DECODING_PDU));
                int size = buffer.limit();
                int position = buffer.position();
                int pduLength = size - position;
                byte[] array = new byte[pduLength];
                System.arraycopy(buffer.array(), position, array, 0, pduLength);
                if (array.length == 0) {
                    CODEC_LOG.debug(I18n.msg(I18n.MSG_14001_NULL_BUFFER));
                } else {
                    CODEC_LOG.debug(Strings.dumpBytes(array));
                }
            }
            asn1Decoder.decode(buffer, messageContainer);
            if (messageContainer.getState() == TLVStateEnum.PDU_DECODED) {
                if (IS_DEBUG) {
                    CODEC_LOG.debug(I18n.msg(I18n.MSG_14002_DECODED_LDAP_MESSAGE, messageContainer.getMessage()));
                }
                Message message = messageContainer.getMessage();
                decodedMessages.add(message);
                messageContainer.clean();
            }
        } catch (ResponseCarryingException rce) {
            buffer.clear();
            messageContainer.clean();
            // Transform the DecoderException message to a MessageException
            ResponseCarryingMessageException rcme = new ResponseCarryingMessageException(rce.getMessage(), rce);
            rcme.setResponse(rce.getResponse());
            throw rcme;
        } catch (DecoderException de) {
            buffer.clear();
            messageContainer.clean();
            // TODO : This is certainly not the way we should handle such an exception !
            throw new ResponseCarryingException(de.getMessage(), de);
        }
    }
}
Also used : DecoderException(org.apache.directory.api.asn1.DecoderException) ResponseCarryingException(org.apache.directory.api.ldap.codec.api.ResponseCarryingException) Message(org.apache.directory.api.ldap.model.message.Message) ResponseCarryingMessageException(org.apache.directory.api.ldap.model.exception.ResponseCarryingMessageException)

Aggregations

Message (org.apache.directory.api.ldap.model.message.Message)30 DecoderException (org.apache.directory.api.asn1.DecoderException)26 LdapMessageContainer (org.apache.directory.api.ldap.codec.api.LdapMessageContainer)24 ByteBuffer (java.nio.ByteBuffer)22 AbstractCodecServiceTest (org.apache.directory.api.ldap.codec.osgi.AbstractCodecServiceTest)21 Test (org.junit.Test)21 Asn1Decoder (org.apache.directory.api.asn1.ber.Asn1Decoder)20 ResponseCarryingException (org.apache.directory.api.ldap.codec.api.ResponseCarryingException)16 MessageDecorator (org.apache.directory.api.ldap.codec.api.MessageDecorator)11 Asn1Container (org.apache.directory.api.asn1.ber.Asn1Container)3 TLV (org.apache.directory.api.asn1.ber.tlv.TLV)3 ModifyDnRequestDecorator (org.apache.directory.api.ldap.codec.decorators.ModifyDnRequestDecorator)3 AddResponseImpl (org.apache.directory.api.ldap.model.message.AddResponseImpl)3 ModifyDnResponseImpl (org.apache.directory.api.ldap.model.message.ModifyDnResponseImpl)3 IOException (java.io.IOException)2 ConnectException (java.net.ConnectException)2 UnresolvedAddressException (java.nio.channels.UnresolvedAddressException)2 ArrayList (java.util.ArrayList)2 SchemaBinaryAttributeDetector (org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector)2 CompareRequestDecorator (org.apache.directory.api.ldap.codec.decorators.CompareRequestDecorator)2