use of com.unboundid.util.Nullable in project ldapsdk by pingidentity.
the class InMemoryRequestHandler method processTransactionRequest.
/**
* Determines whether the provided set of controls includes a transaction
* specification request control. If so, then it will verify that it
* references a valid transaction for the client. If the request is part of a
* valid transaction, then the transaction specification request control will
* be removed and the request will be stashed in the client connection state
* so that it can be retrieved and processed when the transaction is
* committed.
*
* @param messageID The message ID for the request to be processed.
* @param request The protocol op for the request to be processed.
* @param controls The set of controls for the request to be processed.
*
* @return The transaction ID for the associated transaction, or {@code null}
* if the request is not part of any transaction.
*
* @throws LDAPException If the transaction specification request control is
* present but does not refer to a valid transaction
* for the associated client connection.
*/
@SuppressWarnings("unchecked")
@Nullable()
private ASN1OctetString processTransactionRequest(final int messageID, @NotNull final ProtocolOp request, @NotNull final Map<String, Control> controls) throws LDAPException {
final TransactionSpecificationRequestControl txnControl = (TransactionSpecificationRequestControl) controls.remove(TransactionSpecificationRequestControl.TRANSACTION_SPECIFICATION_REQUEST_OID);
if (txnControl == null) {
return null;
}
// See if the client has an active transaction. If not, then fail.
final ASN1OctetString txnID = txnControl.getTransactionID();
final ObjectPair<ASN1OctetString, List<LDAPMessage>> txnInfo = (ObjectPair<ASN1OctetString, List<LDAPMessage>>) connectionState.get(TransactionExtendedOperationHandler.STATE_VARIABLE_TXN_INFO);
if (txnInfo == null) {
throw new LDAPException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, ERR_MEM_HANDLER_TXN_CONTROL_WITHOUT_TXN.get(txnID.stringValue()));
}
// Make sure that the active transaction has a transaction ID that matches
// the transaction ID from the control. If not, then abort the existing
// transaction and fail.
final ASN1OctetString existingTxnID = txnInfo.getFirst();
if (!txnID.stringValue().equals(existingTxnID.stringValue())) {
connectionState.remove(TransactionExtendedOperationHandler.STATE_VARIABLE_TXN_INFO);
connection.sendUnsolicitedNotification(new AbortedTransactionExtendedResult(existingTxnID, ResultCode.CONSTRAINT_VIOLATION, ERR_MEM_HANDLER_TXN_ABORTED_BY_CONTROL_TXN_ID_MISMATCH.get(existingTxnID.stringValue(), txnID.stringValue()), null, null, null));
throw new LDAPException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION, ERR_MEM_HANDLER_TXN_CONTROL_ID_MISMATCH.get(txnID.stringValue(), existingTxnID.stringValue()));
}
// Stash the request in the transaction state information so that it will
// be processed when the transaction is committed.
txnInfo.getSecond().add(new LDAPMessage(messageID, request, new ArrayList<>(controls.values())));
return txnID;
}
use of com.unboundid.util.Nullable in project ldapsdk by pingidentity.
the class ASN1StreamReader method readBigInteger.
/**
* Reads an ASN.1 integer element from the input stream and returns the value
* as a {@code BigInteger}.
*
* @return The {@code BigInteger} value of the ASN.1 integer element read, or
* {@code null} if the end of the input stream was reached before any
* data could be read. If {@code null} is returned, then the input
* stream will have been closed.
*
* @throws IOException If a problem occurs while reading from the input
* stream, if the end of the input stream is reached in
* the middle of the element, or or if an attempt is
* made to read an element larger than the maximum
* allowed size.
*
* @throws ASN1Exception If the data read cannot be parsed as an ASN.1
* integer element.
*/
@Nullable()
public BigInteger readBigInteger() throws IOException, ASN1Exception {
final int type = readType();
if (type < 0) {
return null;
}
final int length = readLength();
if (length == 0) {
throw new ASN1Exception(ERR_BIG_INTEGER_DECODE_EMPTY_VALUE.get());
}
final byte[] valueBytes = new byte[length];
for (int i = 0; i < length; i++) {
final int byteRead = read(false);
if (byteRead < 0) {
throw new IOException(ERR_READ_END_BEFORE_VALUE_END.get());
}
valueBytes[i] = (byte) byteRead;
}
final BigInteger bigIntegerValue = new BigInteger(valueBytes);
totalBytesRead += length;
Debug.debugASN1Read(Level.INFO, "BigInteger", type, length, bigIntegerValue);
return bigIntegerValue;
}
use of com.unboundid.util.Nullable in project ldapsdk by pingidentity.
the class ASN1StreamReader method readUTCTime.
/**
* Reads an ASN.1 UTC time element from the input stream and returns the value
* as a {@code Date}.
*
* @return The {@code Date} value of the ASN.1 UTC time element read, or
* {@code null} if the end of the input stream was reached before any
* data could be read. If {@code null} is returned, then the input
* stream will have been closed.
*
* @throws IOException If a problem occurs while reading from the input
* stream, if the end of the input stream is reached in
* the middle of the element, or or if an attempt is
* made to read an element larger than the maximum
* allowed size.
*
* @throws ASN1Exception If the data read cannot be parsed as an ASN.1 UTC
* time element.
*/
@Nullable()
public Date readUTCTime() throws IOException, ASN1Exception {
final int type = readType();
if (type < 0) {
return null;
}
final int length = readLength();
int valueBytesRead = 0;
int bytesRemaining = length;
final byte[] value = new byte[length];
while (valueBytesRead < length) {
final int bytesRead = read(value, valueBytesRead, bytesRemaining);
if (bytesRead < 0) {
throw new IOException(ERR_READ_END_BEFORE_VALUE_END.get());
}
valueBytesRead += bytesRead;
bytesRemaining -= bytesRead;
}
totalBytesRead += length;
final String timestamp = StaticUtils.toUTF8String(value);
final Date date = new Date(ASN1UTCTime.decodeTimestamp(timestamp));
Debug.debugASN1Read(Level.INFO, "UTCTime", type, length, timestamp);
return date;
}
use of com.unboundid.util.Nullable in project ldapsdk by pingidentity.
the class ASN1StreamReader method readGeneralizedTime.
/**
* Reads an ASN.1 generalized time element from the input stream and returns
* the value as a {@code Date}.
*
* @return The {@code Date} value of the ASN.1 generalized time element read,
* or {@code null} if the end of the input stream was reached before
* any data could be read. If {@code null} is returned, then the
* input stream will have been closed.
*
* @throws IOException If a problem occurs while reading from the input
* stream, if the end of the input stream is reached in
* the middle of the element, or or if an attempt is
* made to read an element larger than the maximum
* allowed size.
*
* @throws ASN1Exception If the data read cannot be parsed as an ASN.1
* generalized time element.
*/
@Nullable()
public Date readGeneralizedTime() throws IOException, ASN1Exception {
final int type = readType();
if (type < 0) {
return null;
}
final int length = readLength();
int valueBytesRead = 0;
int bytesRemaining = length;
final byte[] value = new byte[length];
while (valueBytesRead < length) {
final int bytesRead = read(value, valueBytesRead, bytesRemaining);
if (bytesRead < 0) {
throw new IOException(ERR_READ_END_BEFORE_VALUE_END.get());
}
valueBytesRead += bytesRead;
bytesRemaining -= bytesRead;
}
totalBytesRead += length;
final String timestamp = StaticUtils.toUTF8String(value);
final Date date = new Date(ASN1GeneralizedTime.decodeTimestamp(timestamp));
Debug.debugASN1Read(Level.INFO, "GeneralizedTime", type, length, timestamp);
return date;
}
use of com.unboundid.util.Nullable in project ldapsdk by pingidentity.
the class LDAPMessage method readFrom.
/**
* Reads an LDAP message from the provided ASN.1 stream reader.
*
* @param reader The ASN.1 stream reader from which the LDAP
* message should be read.
* @param ignoreSocketTimeout Indicates whether to ignore socket timeout
* exceptions caught during processing. This
* should be {@code true} when the associated
* connection is operating in asynchronous mode,
* and {@code false} when operating in
* synchronous mode. In either case, exceptions
* will not be ignored for the first read, since
* that will be handled by the connection reader.
*
* @return The decoded LDAP message, or {@code null} if the end of the input
* stream has been reached.
*
* @throws LDAPException If an error occurs while attempting to read or
* decode the LDAP message.
*/
@Nullable()
public static LDAPMessage readFrom(@NotNull final ASN1StreamReader reader, final boolean ignoreSocketTimeout) throws LDAPException {
final ASN1StreamReaderSequence messageSequence;
try {
reader.setIgnoreSocketTimeout(false, ignoreSocketTimeout);
messageSequence = reader.beginSequence();
if (messageSequence == null) {
return null;
}
} catch (final IOException ioe) {
if (!((ioe instanceof SocketTimeoutException) || (ioe instanceof InterruptedIOException))) {
Debug.debugException(ioe);
}
throw new LDAPException(ResultCode.SERVER_DOWN, ERR_MESSAGE_IO_ERROR.get(StaticUtils.getExceptionMessage(ioe)), ioe);
} catch (final Exception e) {
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MESSAGE_CANNOT_DECODE.get(StaticUtils.getExceptionMessage(e)), e);
}
try {
reader.setIgnoreSocketTimeout(ignoreSocketTimeout, ignoreSocketTimeout);
final int messageID = reader.readInteger();
final ProtocolOp protocolOp;
final byte protocolOpType = (byte) reader.peek();
switch(protocolOpType) {
case PROTOCOL_OP_TYPE_BIND_REQUEST:
protocolOp = new BindRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_BIND_RESPONSE:
protocolOp = new BindResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_UNBIND_REQUEST:
protocolOp = new UnbindRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_SEARCH_REQUEST:
protocolOp = new SearchRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_SEARCH_RESULT_ENTRY:
protocolOp = new SearchResultEntryProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_SEARCH_RESULT_REFERENCE:
protocolOp = new SearchResultReferenceProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE:
protocolOp = new SearchResultDoneProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_MODIFY_REQUEST:
protocolOp = new ModifyRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_MODIFY_RESPONSE:
protocolOp = new ModifyResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_ADD_REQUEST:
protocolOp = new AddRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_ADD_RESPONSE:
protocolOp = new AddResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_DELETE_REQUEST:
protocolOp = new DeleteRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_DELETE_RESPONSE:
protocolOp = new DeleteResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST:
protocolOp = new ModifyDNRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_MODIFY_DN_RESPONSE:
protocolOp = new ModifyDNResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_COMPARE_REQUEST:
protocolOp = new CompareRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_COMPARE_RESPONSE:
protocolOp = new CompareResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_ABANDON_REQUEST:
protocolOp = new AbandonRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_EXTENDED_REQUEST:
protocolOp = new ExtendedRequestProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_EXTENDED_RESPONSE:
protocolOp = new ExtendedResponseProtocolOp(reader);
break;
case PROTOCOL_OP_TYPE_INTERMEDIATE_RESPONSE:
protocolOp = new IntermediateResponseProtocolOp(reader);
break;
default:
throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MESSAGE_INVALID_PROTOCOL_OP_TYPE.get(StaticUtils.toHex(protocolOpType)));
}
final ArrayList<Control> controls = new ArrayList<>(5);
if (messageSequence.hasMoreElements()) {
final ASN1StreamReaderSequence controlSequence = reader.beginSequence();
while (controlSequence.hasMoreElements()) {
controls.add(Control.readFrom(reader));
}
}
return new LDAPMessage(messageID, protocolOp, controls);
} catch (final LDAPException le) {
Debug.debugException(le);
throw le;
} catch (final IOException ioe) {
Debug.debugException(ioe);
if ((ioe instanceof SocketTimeoutException) || (ioe instanceof InterruptedIOException)) {
// connection to be terminated.
throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MESSAGE_CANNOT_DECODE.get(StaticUtils.getExceptionMessage(ioe)));
} else {
throw new LDAPException(ResultCode.SERVER_DOWN, ERR_MESSAGE_IO_ERROR.get(StaticUtils.getExceptionMessage(ioe)), ioe);
}
} catch (final Exception e) {
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MESSAGE_CANNOT_DECODE.get(StaticUtils.getExceptionMessage(e)), e);
}
}
Aggregations