Search in sources :

Example 1 with AbortedTransactionExtendedResult

use of com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult in project ldapsdk by pingidentity.

the class ResultUtils method formatUnsolicitedNotification.

/**
 * Adds a multi-line string representation of the provided unsolicited
 * notification to the given list.
 *
 * @param  lines         The list to which the lines should be added.
 * @param  notification  The unsolicited notification to be formatted.
 * @param  comment       Indicates whether to prefix each line with an
 *                       octothorpe to indicate that it is a comment.
 * @param  indent        The number of spaces to indent each line.
 * @param  maxWidth      The maximum length of each line in characters,
 *                       including the comment prefix and indent.
 */
public static void formatUnsolicitedNotification(@NotNull final List<String> lines, @NotNull final ExtendedResult notification, final boolean comment, final int indent, final int maxWidth) {
    final String prefix = createPrefix(comment, indent);
    final String indentPrefix = prefix + "     ";
    boolean includeRawValue = true;
    final String oid = notification.getOID();
    if (oid != null) {
        if (oid.equals(NoticeOfDisconnectionExtendedResult.NOTICE_OF_DISCONNECTION_RESULT_OID)) {
            wrap(lines, INFO_RESULT_UTILS_NOTICE_OF_DISCONNECTION_HEADER.get(), prefix, maxWidth);
            wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), indentPrefix, maxWidth);
        } else if (oid.equals(AbortedTransactionExtendedResult.ABORTED_TRANSACTION_RESULT_OID)) {
            wrap(lines, INFO_RESULT_UTILS_ABORTED_TXN_HEADER.get(), prefix, maxWidth);
            wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), indentPrefix, maxWidth);
            try {
                final AbortedTransactionExtendedResult r = new AbortedTransactionExtendedResult(notification);
                final String txnID;
                if (StaticUtils.isPrintableString(r.getTransactionID().getValue())) {
                    txnID = r.getTransactionID().stringValue();
                } else {
                    txnID = "0x" + StaticUtils.toHex(r.getTransactionID().getValue());
                }
                wrap(lines, INFO_RESULT_UTILS_TXN_ID_HEADER.get(txnID), indentPrefix, maxWidth);
                includeRawValue = false;
            } catch (final Exception e) {
                Debug.debugException(e);
            }
        } else {
            wrap(lines, INFO_RESULT_UTILS_UNSOLICITED_NOTIFICATION_HEADER.get(), prefix, maxWidth);
            wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), indentPrefix, maxWidth);
        }
    } else {
        wrap(lines, INFO_RESULT_UTILS_UNSOLICITED_NOTIFICATION_HEADER.get(), prefix, maxWidth);
    }
    wrap(lines, INFO_RESULT_UTILS_RESULT_CODE.get(String.valueOf(notification.getResultCode())), indentPrefix, maxWidth);
    final String diagnosticMessage = notification.getDiagnosticMessage();
    if (diagnosticMessage != null) {
        wrap(lines, INFO_RESULT_UTILS_DIAGNOSTIC_MESSAGE.get(diagnosticMessage), indentPrefix, maxWidth);
    }
    final String matchedDN = notification.getMatchedDN();
    if (matchedDN != null) {
        wrap(lines, INFO_RESULT_UTILS_MATCHED_DN.get(matchedDN), indentPrefix, maxWidth);
    }
    final String[] referralURLs = notification.getReferralURLs();
    if (referralURLs != null) {
        for (final String referralURL : referralURLs) {
            wrap(lines, INFO_RESULT_UTILS_REFERRAL_URL.get(referralURL), indentPrefix, maxWidth);
        }
    }
    if (includeRawValue) {
        final ASN1OctetString value = notification.getValue();
        if ((value != null) && (value.getValueLength() > 0)) {
            wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_RAW_VALUE_HEADER.get(), indentPrefix, maxWidth);
            // We'll ignore the maximum width for this portion of the output.
            for (final String line : StaticUtils.stringToLines(StaticUtils.toHexPlusASCII(value.getValue(), 0))) {
                lines.add(prefix + "          " + line);
            }
        }
    }
    // If there are any controls, then display them.  We'll interpret any
    // controls that we can, but will fall back to a general display for any
    // that we don't recognize or can't parse.
    final Control[] controls = notification.getResponseControls();
    if (controls != null) {
        for (final Control c : controls) {
            formatResponseControl(lines, c, comment, indent + 5, maxWidth);
        }
    }
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) IntermediateClientResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.IntermediateClientResponseControl) TransactionSettingsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.TransactionSettingsResponseControl) Control(com.unboundid.ldap.sdk.Control) UniquenessResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.UniquenessResponseControl) SimplePagedResultsControl(com.unboundid.ldap.sdk.controls.SimplePagedResultsControl) PasswordValidationDetailsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.PasswordValidationDetailsResponseControl) VirtualListViewResponseControl(com.unboundid.ldap.sdk.controls.VirtualListViewResponseControl) GetPasswordPolicyStateIssuesResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetPasswordPolicyStateIssuesResponseControl) AccountUsableResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.AccountUsableResponseControl) GetServerIDResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetServerIDResponseControl) SoftDeleteResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteResponseControl) PasswordExpiredControl(com.unboundid.ldap.sdk.controls.PasswordExpiredControl) PasswordExpiringControl(com.unboundid.ldap.sdk.controls.PasswordExpiringControl) PostReadResponseControl(com.unboundid.ldap.sdk.controls.PostReadResponseControl) GetAuthorizationEntryResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetAuthorizationEntryResponseControl) ServerSideSortResponseControl(com.unboundid.ldap.sdk.controls.ServerSideSortResponseControl) MatchingEntryCountResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.MatchingEntryCountResponseControl) GeneratePasswordResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GeneratePasswordResponseControl) EntryChangeNotificationControl(com.unboundid.ldap.sdk.controls.EntryChangeNotificationControl) GetUserResourceLimitsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetUserResourceLimitsResponseControl) AssuredReplicationResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.AssuredReplicationResponseControl) ContentSyncStateControl(com.unboundid.ldap.sdk.controls.ContentSyncStateControl) GetRecentLoginHistoryResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetRecentLoginHistoryResponseControl) JoinResultControl(com.unboundid.ldap.sdk.unboundidds.controls.JoinResultControl) GetBackendSetIDResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetBackendSetIDResponseControl) PasswordPolicyResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.PasswordPolicyResponseControl) PreReadResponseControl(com.unboundid.ldap.sdk.controls.PreReadResponseControl) AuthorizationIdentityResponseControl(com.unboundid.ldap.sdk.controls.AuthorizationIdentityResponseControl) ContentSyncDoneControl(com.unboundid.ldap.sdk.controls.ContentSyncDoneControl) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LDAPException(com.unboundid.ldap.sdk.LDAPException) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult)

Example 2 with AbortedTransactionExtendedResult

use of com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult in project ldapsdk by pingidentity.

the class ResultUtilsTestCase method getFormatUnsolicitedNotificationData.

/**
 * Retrieves a set of data for testing the
 * {@code formatUnsolicitedNotification} method.
 *
 * @return  The test data.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
@DataProvider(name = "formatUnsolicitedNotificationData")
public Iterator<Object[]> getFormatUnsolicitedNotificationData() throws Exception {
    final LinkedList<Object[]> resultList = new LinkedList<Object[]>();
    // A notice of disconnection.
    resultList.add(new Object[] { new NoticeOfDisconnectionExtendedResult(ResultCode.SERVER_DOWN, "The server is shutting down."), Arrays.asList("#      Notice of Disconnection Unsolicited Notification", "#           Extended Result OID:  1.3.6.1.4.1.1466.20036", "#           Result Code:  81 (server down)", "#           Diagnostic Message:  The server is shutting down.") });
    // An aborted transaction with a printable transaction ID.
    resultList.add(new Object[] { new AbortedTransactionExtendedResult(new ASN1OctetString("txnID"), ResultCode.OTHER, "The transaction was active for too long.", null, null, null), Arrays.asList("#      Aborted Transaction Unsolicited Notification", "#           Extended Result OID:  1.3.6.1.1.21.4", "#           Transaction ID:  txnID", "#           Result Code:  80 (other)", "#           Diagnostic Message:  The transaction was active " + "for too long.") });
    // An aborted transaction with a non-printable transaction ID.
    resultList.add(new Object[] { new AbortedTransactionExtendedResult(new ASN1OctetString(new byte[] { 0x01, 0x23, 0x45 }), ResultCode.OTHER, "The transaction was active for too long.", null, null, null), Arrays.asList("#      Aborted Transaction Unsolicited Notification", "#           Extended Result OID:  1.3.6.1.1.21.4", "#           Transaction ID:  0x012345", "#           Result Code:  80 (other)", "#           Diagnostic Message:  The transaction was active " + "for too long.") });
    // A generic unsolicited notification with neither an OID nor a value but
    // with all other elements.
    final String[] singleReferralURL = { "ldap://ds.example.com:389/dc=example,dc=com" };
    final Control[] singleResponseControl = { new Control("1.2.3.4") };
    resultList.add(new Object[] { new ExtendedResult(0, ResultCode.SUCCESS, "diag", "dc=example,dc=com", singleReferralURL, null, null, singleResponseControl), Arrays.asList("#      Unsolicited Notification", "#           Result Code:  0 (success)", "#           Diagnostic Message:  diag", "#           Matched DN:  dc=example,dc=com", "#           Referral URL:  " + "ldap://ds.example.com:389/dc=example,dc=com", "#           Response Control:", "#                OID:  1.2.3.4", "#                Is Critical:  false") });
    // A generic unsolicited notification with all elements.
    final String[] multipleReferralURLs = { "ldap://ds1.example.com:389/dc=example,dc=com", "ldap://ds2.example.com:389/dc=example,dc=com" };
    final Control[] multipleResponseControls = { new Control("1.2.3.4"), new Control("1.2.3.5", true, new ASN1OctetString("control value")) };
    resultList.add(new Object[] { new ExtendedResult(0, ResultCode.SUCCESS, "diag", "dc=example,dc=com", multipleReferralURLs, "5.6.7.8", new ASN1OctetString("extended operation value"), multipleResponseControls), Arrays.asList("#      Unsolicited Notification", "#           Extended Result OID:  5.6.7.8", "#           Result Code:  0 (success)", "#           Diagnostic Message:  diag", "#           Matched DN:  dc=example,dc=com", "#           Referral URL:  " + "ldap://ds1.example.com:389/dc=example,dc=com", "#           Referral URL:  " + "ldap://ds2.example.com:389/dc=example,dc=com", "#           Extended Result Raw Value:", "#                65 78 74 65 6e 64 65 64 20 6f 70 65 72 61 " + "74 69   extended operati", "#                6f 6e 20 76 61 6c 75 " + "65                           on value", "#           Response Control:", "#                OID:  1.2.3.4", "#                Is Critical:  false", "#           Response Control:", "#                OID:  1.2.3.5", "#                Is Critical:  true", "#                Raw Value:", "#                     63 6f 6e 74 72 6f 6c 20 76 61 6c 75 " + "65            control value") });
    return resultList.iterator();
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) IntermediateClientResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.IntermediateClientResponseControl) TransactionSettingsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.TransactionSettingsResponseControl) Control(com.unboundid.ldap.sdk.Control) UniquenessResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.UniquenessResponseControl) SimplePagedResultsControl(com.unboundid.ldap.sdk.controls.SimplePagedResultsControl) PasswordValidationDetailsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.PasswordValidationDetailsResponseControl) VirtualListViewResponseControl(com.unboundid.ldap.sdk.controls.VirtualListViewResponseControl) GetPasswordPolicyStateIssuesResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetPasswordPolicyStateIssuesResponseControl) AccountUsableResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.AccountUsableResponseControl) GetServerIDResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetServerIDResponseControl) SoftDeleteResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteResponseControl) PasswordExpiredControl(com.unboundid.ldap.sdk.controls.PasswordExpiredControl) PasswordExpiringControl(com.unboundid.ldap.sdk.controls.PasswordExpiringControl) PostReadResponseControl(com.unboundid.ldap.sdk.controls.PostReadResponseControl) GetAuthorizationEntryResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetAuthorizationEntryResponseControl) ServerSideSortResponseControl(com.unboundid.ldap.sdk.controls.ServerSideSortResponseControl) MatchingEntryCountResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.MatchingEntryCountResponseControl) GeneratePasswordResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GeneratePasswordResponseControl) EntryChangeNotificationControl(com.unboundid.ldap.sdk.controls.EntryChangeNotificationControl) GetUserResourceLimitsResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetUserResourceLimitsResponseControl) AssuredReplicationResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.AssuredReplicationResponseControl) ContentSyncStateControl(com.unboundid.ldap.sdk.controls.ContentSyncStateControl) GetRecentLoginHistoryResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetRecentLoginHistoryResponseControl) JoinResultControl(com.unboundid.ldap.sdk.unboundidds.controls.JoinResultControl) GetBackendSetIDResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.GetBackendSetIDResponseControl) PasswordPolicyResponseControl(com.unboundid.ldap.sdk.unboundidds.controls.PasswordPolicyResponseControl) PreReadResponseControl(com.unboundid.ldap.sdk.controls.PreReadResponseControl) AuthorizationIdentityResponseControl(com.unboundid.ldap.sdk.controls.AuthorizationIdentityResponseControl) ContentSyncDoneControl(com.unboundid.ldap.sdk.controls.ContentSyncDoneControl) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) ExtendedResult(com.unboundid.ldap.sdk.ExtendedResult) StartTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.StartTransactionExtendedResult) NoticeOfDisconnectionExtendedResult(com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult) MultiUpdateExtendedResult(com.unboundid.ldap.sdk.unboundidds.extensions.MultiUpdateExtendedResult) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) EndTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.EndTransactionExtendedResult) PasswordModifyExtendedResult(com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LinkedList(java.util.LinkedList) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) DataProvider(org.testng.annotations.DataProvider)

Example 3 with AbortedTransactionExtendedResult

use of com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult 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;
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LDAPException(com.unboundid.ldap.sdk.LDAPException) LDAPMessage(com.unboundid.ldap.protocol.LDAPMessage) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) TransactionSpecificationRequestControl(com.unboundid.ldap.sdk.controls.TransactionSpecificationRequestControl) ObjectPair(com.unboundid.util.ObjectPair) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) Nullable(com.unboundid.util.Nullable)

Example 4 with AbortedTransactionExtendedResult

use of com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult in project ldapsdk by pingidentity.

the class TransactionExtendedOperationHandler method handleStartTransaction.

/**
 * Performs the appropriate processing for a start transaction extended
 * request.
 *
 * @param  handler    The in-memory request handler that received the request.
 * @param  messageID  The message ID for the associated request.
 * @param  request    The extended request that was received.
 *
 * @return  The result for the extended operation processing.
 */
@NotNull()
private static StartTransactionExtendedResult handleStartTransaction(@NotNull final InMemoryRequestHandler handler, final int messageID, @NotNull final ExtendedRequest request) {
    // If there is already an active transaction on the associated connection,
    // then make sure it gets aborted.
    final Map<String, Object> connectionState = handler.getConnectionState();
    final ObjectPair<?, ?> existingTxnInfo = (ObjectPair<?, ?>) connectionState.remove(STATE_VARIABLE_TXN_INFO);
    if (existingTxnInfo != null) {
        final ASN1OctetString txnID = (ASN1OctetString) existingTxnInfo.getFirst();
        try {
            handler.getClientConnection().sendUnsolicitedNotification(new AbortedTransactionExtendedResult(txnID, ResultCode.CONSTRAINT_VIOLATION, ERR_TXN_EXTOP_TXN_ABORTED_BY_NEW_START_TXN.get(txnID.stringValue()), null, null, null));
        } catch (final LDAPException le) {
            Debug.debugException(le);
            return new StartTransactionExtendedResult(new ExtendedResult(le));
        }
    }
    // request.
    try {
        new StartTransactionExtendedRequest(request);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        return new StartTransactionExtendedResult(messageID, ResultCode.PROTOCOL_ERROR, le.getMessage(), null, null, null, null);
    }
    // Create a new object with information to use for the transaction.  It will
    // include the transaction ID and a list of LDAP messages that are part of
    // the transaction.  Store it in the connection state.
    final ASN1OctetString txnID = new ASN1OctetString(String.valueOf(TXN_ID_COUNTER.getAndIncrement()));
    final List<LDAPMessage> requestList = new ArrayList<>(10);
    final ObjectPair<ASN1OctetString, List<LDAPMessage>> txnInfo = new ObjectPair<>(txnID, requestList);
    connectionState.put(STATE_VARIABLE_TXN_INFO, txnInfo);
    // Return the response to the client.
    return new StartTransactionExtendedResult(messageID, ResultCode.SUCCESS, INFO_TXN_EXTOP_CREATED_TXN.get(txnID.stringValue()), null, null, txnID, null);
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LDAPMessage(com.unboundid.ldap.protocol.LDAPMessage) ArrayList(java.util.ArrayList) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LDAPException(com.unboundid.ldap.sdk.LDAPException) StartTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.StartTransactionExtendedResult) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) ExtendedResult(com.unboundid.ldap.sdk.ExtendedResult) EndTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.EndTransactionExtendedResult) StartTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.StartTransactionExtendedResult) StartTransactionExtendedRequest(com.unboundid.ldap.sdk.extensions.StartTransactionExtendedRequest) ArrayList(java.util.ArrayList) List(java.util.List) ObjectPair(com.unboundid.util.ObjectPair) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) NotNull(com.unboundid.util.NotNull)

Example 5 with AbortedTransactionExtendedResult

use of com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult in project ldapsdk by pingidentity.

the class TransactionExtendedOperationHandler method handleEndTransaction.

/**
 * Performs the appropriate processing for an end transaction extended
 * request.
 *
 * @param  handler    The in-memory request handler that received the request.
 * @param  messageID  The message ID for the associated request.
 * @param  request    The extended request that was received.
 *
 * @return  The result for the extended operation processing.
 */
@NotNull()
private static EndTransactionExtendedResult handleEndTransaction(@NotNull final InMemoryRequestHandler handler, final int messageID, @NotNull final ExtendedRequest request) {
    // Get information about any transaction currently in progress on the
    // connection.  If there isn't one, then fail.
    final Map<String, Object> connectionState = handler.getConnectionState();
    final ObjectPair<?, ?> txnInfo = (ObjectPair<?, ?>) connectionState.remove(STATE_VARIABLE_TXN_INFO);
    if (txnInfo == null) {
        return new EndTransactionExtendedResult(messageID, ResultCode.CONSTRAINT_VIOLATION, ERR_TXN_EXTOP_END_NO_ACTIVE_TXN.get(), null, null, null, null, null);
    }
    // Make sure that we can decode the end transaction request.
    final ASN1OctetString existingTxnID = (ASN1OctetString) txnInfo.getFirst();
    final EndTransactionExtendedRequest endTxnRequest;
    try {
        endTxnRequest = new EndTransactionExtendedRequest(request);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        try {
            handler.getClientConnection().sendUnsolicitedNotification(new AbortedTransactionExtendedResult(existingTxnID, ResultCode.PROTOCOL_ERROR, ERR_TXN_EXTOP_ABORTED_BY_MALFORMED_END_TXN.get(existingTxnID.stringValue()), null, null, null));
        } catch (final LDAPException le2) {
            Debug.debugException(le2);
        }
        return new EndTransactionExtendedResult(messageID, ResultCode.PROTOCOL_ERROR, le.getMessage(), null, null, null, null, null);
    }
    // Make sure that the transaction ID of the existing transaction matches the
    // transaction ID from the end transaction request.
    final ASN1OctetString targetTxnID = endTxnRequest.getTransactionID();
    if (!existingTxnID.stringValue().equals(targetTxnID.stringValue())) {
        // transaction has been aborted.
        try {
            handler.getClientConnection().sendUnsolicitedNotification(new AbortedTransactionExtendedResult(existingTxnID, ResultCode.CONSTRAINT_VIOLATION, ERR_TXN_EXTOP_ABORTED_BY_WRONG_END_TXN.get(existingTxnID.stringValue(), targetTxnID.stringValue()), null, null, null));
        } catch (final LDAPException le) {
            Debug.debugException(le);
            return new EndTransactionExtendedResult(messageID, le.getResultCode(), le.getMessage(), le.getMatchedDN(), le.getReferralURLs(), null, null, le.getResponseControls());
        }
        return new EndTransactionExtendedResult(messageID, ResultCode.CONSTRAINT_VIOLATION, ERR_TXN_EXTOP_END_WRONG_TXN.get(targetTxnID.stringValue(), existingTxnID.stringValue()), null, null, null, null, null);
    }
    // If the transaction should be aborted, then we can just send the response.
    if (!endTxnRequest.commit()) {
        return new EndTransactionExtendedResult(messageID, ResultCode.SUCCESS, INFO_TXN_EXTOP_END_TXN_ABORTED.get(existingTxnID.stringValue()), null, null, null, null, null);
    }
    // If we've gotten here, then we'll try to commit the transaction.  First,
    // get a snapshot of the current state so that we can roll back to it if
    // necessary.
    final InMemoryDirectoryServerSnapshot snapshot = handler.createSnapshot();
    boolean rollBack = true;
    try {
        // Create a map to hold information about response controls from
        // operations processed as part of the transaction.
        final List<?> requestMessages = (List<?>) txnInfo.getSecond();
        final Map<Integer, Control[]> opResponseControls = new LinkedHashMap<>(StaticUtils.computeMapCapacity(requestMessages.size()));
        // Iterate through the requests that have been submitted as part of the
        // transaction and attempt to process them.
        ResultCode resultCode = ResultCode.SUCCESS;
        String diagnosticMessage = null;
        String failedOpType = null;
        Integer failedOpMessageID = null;
        txnOpLoop: for (final Object o : requestMessages) {
            final LDAPMessage m = (LDAPMessage) o;
            switch(m.getProtocolOpType()) {
                case LDAPMessage.PROTOCOL_OP_TYPE_ADD_REQUEST:
                    final LDAPMessage addResponseMessage = handler.processAddRequest(m.getMessageID(), m.getAddRequestProtocolOp(), m.getControls());
                    final AddResponseProtocolOp addResponseOp = addResponseMessage.getAddResponseProtocolOp();
                    final List<Control> addControls = addResponseMessage.getControls();
                    if ((addControls != null) && (!addControls.isEmpty())) {
                        final Control[] controls = new Control[addControls.size()];
                        addControls.toArray(controls);
                        opResponseControls.put(m.getMessageID(), controls);
                    }
                    if (addResponseOp.getResultCode() != ResultCode.SUCCESS_INT_VALUE) {
                        resultCode = ResultCode.valueOf(addResponseOp.getResultCode());
                        diagnosticMessage = addResponseOp.getDiagnosticMessage();
                        failedOpType = INFO_TXN_EXTOP_OP_TYPE_ADD.get();
                        failedOpMessageID = m.getMessageID();
                        break txnOpLoop;
                    }
                    break;
                case LDAPMessage.PROTOCOL_OP_TYPE_DELETE_REQUEST:
                    final LDAPMessage deleteResponseMessage = handler.processDeleteRequest(m.getMessageID(), m.getDeleteRequestProtocolOp(), m.getControls());
                    final DeleteResponseProtocolOp deleteResponseOp = deleteResponseMessage.getDeleteResponseProtocolOp();
                    final List<Control> deleteControls = deleteResponseMessage.getControls();
                    if ((deleteControls != null) && (!deleteControls.isEmpty())) {
                        final Control[] controls = new Control[deleteControls.size()];
                        deleteControls.toArray(controls);
                        opResponseControls.put(m.getMessageID(), controls);
                    }
                    if (deleteResponseOp.getResultCode() != ResultCode.SUCCESS_INT_VALUE) {
                        resultCode = ResultCode.valueOf(deleteResponseOp.getResultCode());
                        diagnosticMessage = deleteResponseOp.getDiagnosticMessage();
                        failedOpType = INFO_TXN_EXTOP_OP_TYPE_DELETE.get();
                        failedOpMessageID = m.getMessageID();
                        break txnOpLoop;
                    }
                    break;
                case LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_REQUEST:
                    final LDAPMessage modifyResponseMessage = handler.processModifyRequest(m.getMessageID(), m.getModifyRequestProtocolOp(), m.getControls());
                    final ModifyResponseProtocolOp modifyResponseOp = modifyResponseMessage.getModifyResponseProtocolOp();
                    final List<Control> modifyControls = modifyResponseMessage.getControls();
                    if ((modifyControls != null) && (!modifyControls.isEmpty())) {
                        final Control[] controls = new Control[modifyControls.size()];
                        modifyControls.toArray(controls);
                        opResponseControls.put(m.getMessageID(), controls);
                    }
                    if (modifyResponseOp.getResultCode() != ResultCode.SUCCESS_INT_VALUE) {
                        resultCode = ResultCode.valueOf(modifyResponseOp.getResultCode());
                        diagnosticMessage = modifyResponseOp.getDiagnosticMessage();
                        failedOpType = INFO_TXN_EXTOP_OP_TYPE_MODIFY.get();
                        failedOpMessageID = m.getMessageID();
                        break txnOpLoop;
                    }
                    break;
                case LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST:
                    final LDAPMessage modifyDNResponseMessage = handler.processModifyDNRequest(m.getMessageID(), m.getModifyDNRequestProtocolOp(), m.getControls());
                    final ModifyDNResponseProtocolOp modifyDNResponseOp = modifyDNResponseMessage.getModifyDNResponseProtocolOp();
                    final List<Control> modifyDNControls = modifyDNResponseMessage.getControls();
                    if ((modifyDNControls != null) && (!modifyDNControls.isEmpty())) {
                        final Control[] controls = new Control[modifyDNControls.size()];
                        modifyDNControls.toArray(controls);
                        opResponseControls.put(m.getMessageID(), controls);
                    }
                    if (modifyDNResponseOp.getResultCode() != ResultCode.SUCCESS_INT_VALUE) {
                        resultCode = ResultCode.valueOf(modifyDNResponseOp.getResultCode());
                        diagnosticMessage = modifyDNResponseOp.getDiagnosticMessage();
                        failedOpType = INFO_TXN_EXTOP_OP_TYPE_MODIFY_DN.get();
                        failedOpMessageID = m.getMessageID();
                        break txnOpLoop;
                    }
                    break;
            }
        }
        if (resultCode == ResultCode.SUCCESS) {
            diagnosticMessage = INFO_TXN_EXTOP_COMMITTED.get(existingTxnID.stringValue());
            rollBack = false;
        } else {
            diagnosticMessage = ERR_TXN_EXTOP_COMMIT_FAILED.get(existingTxnID.stringValue(), failedOpType, failedOpMessageID, diagnosticMessage);
        }
        return new EndTransactionExtendedResult(messageID, resultCode, diagnosticMessage, null, null, failedOpMessageID, opResponseControls, null);
    } finally {
        if (rollBack) {
            handler.restoreSnapshot(snapshot);
        }
    }
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) DeleteResponseProtocolOp(com.unboundid.ldap.protocol.DeleteResponseProtocolOp) LDAPMessage(com.unboundid.ldap.protocol.LDAPMessage) EndTransactionExtendedRequest(com.unboundid.ldap.sdk.extensions.EndTransactionExtendedRequest) AddResponseProtocolOp(com.unboundid.ldap.protocol.AddResponseProtocolOp) ModifyDNResponseProtocolOp(com.unboundid.ldap.protocol.ModifyDNResponseProtocolOp) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LinkedHashMap(java.util.LinkedHashMap) LDAPException(com.unboundid.ldap.sdk.LDAPException) ModifyResponseProtocolOp(com.unboundid.ldap.protocol.ModifyResponseProtocolOp) ArrayList(java.util.ArrayList) List(java.util.List) EndTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.EndTransactionExtendedResult) ResultCode(com.unboundid.ldap.sdk.ResultCode) ObjectPair(com.unboundid.util.ObjectPair) AbortedTransactionExtendedResult(com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult) NotNull(com.unboundid.util.NotNull)

Aggregations

ASN1OctetString (com.unboundid.asn1.ASN1OctetString)5 AbortedTransactionExtendedResult (com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult)5 LDAPException (com.unboundid.ldap.sdk.LDAPException)4 LDAPMessage (com.unboundid.ldap.protocol.LDAPMessage)3 EndTransactionExtendedResult (com.unboundid.ldap.sdk.extensions.EndTransactionExtendedResult)3 ObjectPair (com.unboundid.util.ObjectPair)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Control (com.unboundid.ldap.sdk.Control)2 ExtendedResult (com.unboundid.ldap.sdk.ExtendedResult)2 AuthorizationIdentityResponseControl (com.unboundid.ldap.sdk.controls.AuthorizationIdentityResponseControl)2 ContentSyncDoneControl (com.unboundid.ldap.sdk.controls.ContentSyncDoneControl)2 ContentSyncStateControl (com.unboundid.ldap.sdk.controls.ContentSyncStateControl)2 EntryChangeNotificationControl (com.unboundid.ldap.sdk.controls.EntryChangeNotificationControl)2 PasswordExpiredControl (com.unboundid.ldap.sdk.controls.PasswordExpiredControl)2 PasswordExpiringControl (com.unboundid.ldap.sdk.controls.PasswordExpiringControl)2 PostReadResponseControl (com.unboundid.ldap.sdk.controls.PostReadResponseControl)2 PreReadResponseControl (com.unboundid.ldap.sdk.controls.PreReadResponseControl)2 ServerSideSortResponseControl (com.unboundid.ldap.sdk.controls.ServerSideSortResponseControl)2 SimplePagedResultsControl (com.unboundid.ldap.sdk.controls.SimplePagedResultsControl)2