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;
}
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);
}
}
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;
}
}
}
}
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);
}
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);
}
}
}
Aggregations