Search in sources :

Example 11 with Transaction

use of org.jaffa.transaction.domain.Transaction in project jaffa-framework by jaffa-projects.

the class TransactionDependency method postUpdate.

@Override
public void postUpdate() throws PostUpdateFailedException {
    super.postUpdate();
    // then UPDATE TRANSACTIONS SET STATUS='O' WHERE ID={thisTransactionDependency.transactionId} and STATUS='H'
    if (isModified(TransactionDependencyMeta.STATUS) && Status.S.toString().equals(getStatus())) {
        try {
            if (log.isDebugEnabled()) {
                log.debug("TransactionDependency status has changed to S. Will Open parent Transaction if no other Open TransactionDependency record exists");
            }
            TransactionMessageDAO transactionDAO = getTransactionDAO();
            Transaction transaction = transactionDAO.getTransaction(getTransactionId());
            if (transaction != null && Transaction.Status.H.toString().equals(transaction.getStatus())) {
                long count = transactionDAO.getOpenTransactionDependencyCount(transaction.getId());
                if (count == 0) {
                    transaction.setStatus(Transaction.Status.O.toString());
                    getUOW().update(transaction);
                }
            }
        } catch (Exception e) {
            String s = "Exception in opening parent Transaction when the associated dependencies have all been satisfied. This is being done for the TransactionDependency instance " + this;
            ApplicationExceptions appExps = ExceptionHelper.extractApplicationExceptions(e);
            if (appExps != null) {
                if (log.isDebugEnabled())
                    log.debug(s, appExps);
            } else {
                log.error(s, e);
            }
            throw new PostUpdateFailedException(new String[] { s }, e);
        }
    }
}
Also used : ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) Transaction(org.jaffa.transaction.domain.Transaction) TransactionMessageDAO(org.jaffa.transaction.daos.TransactionMessageDAO) InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException) DuplicateKeyException(org.jaffa.exceptions.DuplicateKeyException) FrameworkException(org.jaffa.exceptions.FrameworkException) RelatedDomainObjectFoundException(org.jaffa.exceptions.RelatedDomainObjectFoundException)

Example 12 with Transaction

use of org.jaffa.transaction.domain.Transaction in project jaffa-framework by jaffa-projects.

the class TransactionField method findTransactionObject.

/**
 * Finds the related foreign Transaction object.
 * If checkExistenceOnly is false, then the foreign object will be fetched and assigned to the corresponding member variable of this class.
 * If checkExistenceOnly is true, then a mere existence check is performed for the foreign object, as oppposed to fetching all the values for that object.
 */
private void findTransactionObject(boolean checkExistenceOnly) throws ValidationException, FrameworkException {
    // TODO this is generated...
    if ((m_transactionObject == null) && (getTransactionId() != null)) {
        Transaction transaction = getTransactionDAO().getTransaction(getTransactionId());
        Number count = null;
        if (checkExistenceOnly) {
            if (transaction != null) {
                count = 1;
            }
        } else {
            m_transactionObject = transaction;
        }
        if ((m_transactionObject == null) && ((count == null) || (count.intValue() <= 0))) {
            throw new InvalidForeignKeyException(TransactionFieldMeta.META_TRANSACTION_ID.getLabelToken(), new Object[] { TransactionMeta.getLabelToken(), TransactionMeta.META_ID.getLabelToken() });
        }
    }
}
Also used : Transaction(org.jaffa.transaction.domain.Transaction) InvalidForeignKeyException(org.jaffa.datatypes.exceptions.InvalidForeignKeyException)

Example 13 with Transaction

use of org.jaffa.transaction.domain.Transaction in project jaffa-framework by jaffa-projects.

the class TransactionAdmin method resubmitMessage.

/**
 * NOTE: Each graph is expected to contain messageId. It may also contain the optional queueMetaData.queueSystemId and type, which may help optimize the process.
 */
public MessageAdminResponse[] resubmitMessage(MessageGraph[] graphs) {
    if (log.isDebugEnabled()) {
        log.debug("Input to resubmitMessage: " + Arrays.toString(graphs));
    }
    Collection<MessageAdminResponse> output = null;
    String[] types = TransactionEngine.getInstance().getAccessibleTypeNames();
    Arrays.sort(types);
    for (MessageGraph graph : graphs) {
        if (graph.getQueueMetaData() == null || graph.getQueueMetaData().getQueueSystemId() == null || graph.getQueueMetaData().getQueueSystemId().equals(QUEUE_SYSTEM_ID)) {
            if (graph.getType() == null || (types != null && Arrays.binarySearch(types, graph.getType()) >= 0)) {
                UOW uow = null;
                try {
                    String graphType = graph.getType();
                    String messageId = graph.getMessageId();
                    if (graphType != null && !TransactionEngine.getInstance().hasAdminAccess(graphType)) {
                        throw new ApplicationExceptions(new ApplicationException("error.Jaffa.Transaction.Transaction.noAdminAccess", new Object[] { graphType }));
                    }
                    uow = new UOW();
                    Transaction transaction = transactionDAO.getTransaction(messageId);
                    if (transaction != null) {
                        if (!TransactionEngine.getInstance().hasAdminAccess(transaction.getType())) {
                            throw new ApplicationExceptions(new ApplicationException("error.Jaffa.Transaction.Transaction.noAdminAccess", new Object[] { transaction.getType() }));
                        }
                        if (Transaction.Status.E.toString().equals(transaction.getStatus())) {
                            if (log.isDebugEnabled()) {
                                log.debug("Resubmitting ERROR message " + messageId);
                            }
                            transaction.setStatus(Transaction.Status.O.toString());
                            transaction.setErrorMessage(null);
                            transactionDAO.save(uow, transaction);
                            uow.commit();
                        } else {
                            if (log.isDebugEnabled()) {
                                log.debug("Resubmission cannot be performed since message " + messageId + " is not in ERROR status anymore");
                            }
                        }
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("Resubmission cannot be performed since message " + messageId + " not found");
                        }
                    }
                } catch (Exception e) {
                    MessageAdminResponse response = new MessageAdminResponse();
                    response.setSource(graph);
                    ApplicationExceptions appExps = ExceptionHelper.extractApplicationExceptions(e);
                    if (appExps != null) {
                        if (log.isDebugEnabled()) {
                            log.debug("Error while resubmitting Message " + graph, appExps);
                        }
                        response.setErrors(ServiceError.generate(appExps));
                    } else {
                        log.error("Internal Error while resubmitting Message " + graph, e);
                        response.setErrors(ServiceError.generate(e));
                    }
                    if (output == null) {
                        output = new LinkedList<MessageAdminResponse>();
                    }
                    output.add(response);
                } finally {
                    if (uow != null) {
                        try {
                            uow.rollback();
                        } catch (Exception ignore) {
                        }
                    }
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Message " + graph + " will not be resubmitted by this implementation, since the queue does not belong to this implementation");
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Message " + graph + " will not be resubmitted by this implementation, since the input queueSystemId does not match this system");
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("Output from resubmitMessage: " + output);
    }
    return output != null && output.size() > 0 ? output.toArray(new MessageAdminResponse[output.size()]) : null;
}
Also used : ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) ApplicationException(org.jaffa.exceptions.ApplicationException) Transaction(org.jaffa.transaction.domain.Transaction) MessageAdminResponse(org.jaffa.qm.apis.data.MessageAdminResponse) MessageGraph(org.jaffa.qm.apis.data.MessageGraph) UOW(org.jaffa.persistence.UOW) IllegalPersistentStateRuntimeException(org.jaffa.persistence.exceptions.IllegalPersistentStateRuntimeException) JaffaMessagingFrameworkException(org.jaffa.modules.messaging.services.JaffaMessagingFrameworkException) PostLoadFailedException(org.jaffa.persistence.exceptions.PostLoadFailedException) FrameworkException(org.jaffa.exceptions.FrameworkException) QueryFailedException(org.jaffa.persistence.exceptions.QueryFailedException) ApplicationException(org.jaffa.exceptions.ApplicationException) LinkedList(java.util.LinkedList)

Example 14 with Transaction

use of org.jaffa.transaction.domain.Transaction in project jaffa-framework by jaffa-projects.

the class TransactionAdmin method deleteMessage.

// ///////////////////////////////// Add in intercept for delete
/**
 * NOTE: Each graph is expected to contain messageId. It may also contain the optional queueMetaData.queueSystemId and type, which may help optimize the process.
 */
public MessageAdminResponse[] deleteMessage(MessageGraph[] graphs) {
    if (log.isDebugEnabled()) {
        log.debug("Input to deleteMessage: " + Arrays.toString(graphs));
    }
    Collection<MessageAdminResponse> output = null;
    String[] types = TransactionEngine.getInstance().getAccessibleTypeNames();
    Arrays.sort(types);
    for (MessageGraph graph : graphs) {
        if (graph.getQueueMetaData() == null || graph.getQueueMetaData().getQueueSystemId() == null || graph.getQueueMetaData().getQueueSystemId().equals(QUEUE_SYSTEM_ID)) {
            if (graph.getType() == null || (types != null && Arrays.binarySearch(types, graph.getType()) >= 0)) {
                UOW uow = null;
                try {
                    String graphType = graph.getType();
                    String messageId = graph.getMessageId();
                    if (graphType != null && !TransactionEngine.getInstance().hasAdminAccess(graphType)) {
                        throw new ApplicationExceptions(new ApplicationException("error.Jaffa.Transaction.Transaction.noAdminAccess", new Object[] { graphType }));
                    }
                    uow = new UOW();
                    Transaction transaction = transactionDAO.getTransaction(messageId);
                    if (!TransactionEngine.getInstance().hasAdminAccess(transaction.getType())) {
                        throw new ApplicationExceptions(new ApplicationException("error.Jaffa.Transaction.Transaction.noAdminAccess", new Object[] { transaction.getType() }));
                    }
                    if (transaction != null) {
                        // Invoke Message Handler class to perform onDelete process
                        invokeHandler(uow, transaction, "onDelete");
                        if (log.isDebugEnabled()) {
                            log.debug("Deleting message " + messageId);
                        }
                        transactionDAO.delete(uow, transaction);
                        uow.commit();
                    } else {
                        if (log.isDebugEnabled()) {
                            log.debug("Delete cannot be performed since message " + messageId + " not found");
                        }
                    }
                } catch (Exception e) {
                    MessageAdminResponse response = new MessageAdminResponse();
                    response.setSource(graph);
                    ApplicationExceptions appExps = ExceptionHelper.extractApplicationExceptions(e);
                    if (appExps != null) {
                        if (log.isDebugEnabled()) {
                            log.debug("Error while deleting Message " + graph, appExps);
                        }
                        response.setErrors(ServiceError.generate(appExps));
                    } else {
                        log.error("Internal Error while deleting Message " + graph, e);
                        response.setErrors(ServiceError.generate(e));
                    }
                    if (output == null) {
                        output = new LinkedList<MessageAdminResponse>();
                    }
                    output.add(response);
                } finally {
                    if (uow != null) {
                        try {
                            uow.rollback();
                        } catch (Exception ignore) {
                        }
                    }
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Message " + graph + " will not be deleted by this implementation, since the queue does not belong to this implementation");
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Message " + graph + " will not be deleted by this implementation, since the input queueSystemId does not match this system");
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("Output from deleteMessage: " + output);
    }
    return output != null && output.size() > 0 ? output.toArray(new MessageAdminResponse[output.size()]) : null;
}
Also used : ApplicationExceptions(org.jaffa.exceptions.ApplicationExceptions) ApplicationException(org.jaffa.exceptions.ApplicationException) Transaction(org.jaffa.transaction.domain.Transaction) MessageAdminResponse(org.jaffa.qm.apis.data.MessageAdminResponse) MessageGraph(org.jaffa.qm.apis.data.MessageGraph) UOW(org.jaffa.persistence.UOW) IllegalPersistentStateRuntimeException(org.jaffa.persistence.exceptions.IllegalPersistentStateRuntimeException) JaffaMessagingFrameworkException(org.jaffa.modules.messaging.services.JaffaMessagingFrameworkException) PostLoadFailedException(org.jaffa.persistence.exceptions.PostLoadFailedException) FrameworkException(org.jaffa.exceptions.FrameworkException) QueryFailedException(org.jaffa.persistence.exceptions.QueryFailedException) ApplicationException(org.jaffa.exceptions.ApplicationException) LinkedList(java.util.LinkedList)

Example 15 with Transaction

use of org.jaffa.transaction.domain.Transaction in project jaffa-framework by jaffa-projects.

the class TransactionConsumer method process.

/**
 * This method is invoked directly when processing a Transaction synchronously.
 * It'll invoke the handler associated with the input transaction's payload, as obtained from the transaction configuration file.
 * In case of an error, the status of the transaction will be set to 'E'.
 *
 * @param uow                the provided uow.
 * @param transactionId      the transaction ID.
 * @param unsavedTransaction the transaction if available, otherwise null.
 */
public UOW process(UOW uow, String transactionId, Transaction unsavedTransaction) throws Exception {
    if (log.isDebugEnabled()) {
        log.debug("Processing Transaction " + transactionId);
    }
    // Update Transaction status to I
    Boolean postImmediate = Parser.parseBoolean((String) ContextManagerFactory.instance().getProperty(Transaction.RULE_POST_IMMEDIATE));
    // If the postImmediate is true then we shall make the update to the transaction within same scope of the UOW as this must be synchronous transaction
    if (postImmediate != null && postImmediate.booleanValue()) {
        if (unsavedTransaction == null) {
            // This transaction must already be in the database.
            TransactionEngine.getInstance().updateTransactionStatusToInProcess(uow, transactionId);
        } else {
            uow.flush();
            unsavedTransaction.setStatus(Transaction.Status.I.name());
        }
    } else {
        TransactionEngine.getInstance().updateTransactionStatusToInProcess(transactionId);
    }
    boolean createdLoggingContext = false;
    try {
        Transaction transaction = unsavedTransaction != null ? unsavedTransaction : Transaction.findByPK(uow, transactionId);
        Object dataBean = transaction.getTransactionPayloadObject() != null ? transaction.getTransactionPayloadObject().moldInternalPayload() : null;
        TransactionInfo transactionInfo = null;
        if (dataBean != null) {
            // Load transaction configuration
            transactionInfo = ConfigurationService.getInstance().getTransactionInfo(dataBean);
            // Sets Log4J's MDC to enable BusinessEventLogging
            LoggingService.setLoggingContext(dataBean, transactionInfo, transaction);
            createdLoggingContext = true;
            if (log.isInfoEnabled()) {
                log.info(MessageHelper.findMessage("label.Jaffa.Transaction.TransactionConsumer.start", null));
            }
            int retryLimit = readRule(RULE_RETRY_LIMIT, DEFAULT_RETRY_LIMIT);
            int retrySleepTimeInMillis = readRule(RULE_RETRY_SLEEP_TIME, DEFAULT_RETRY_SLEEP_TIME);
            int retryCount = 0;
            while (true) {
                try {
                    // Invokes the handler as specified by the 'toClass and toMethod' combination in the transaction configuration
                    invokeHandler(uow, transactionInfo, dataBean);
                    break;
                } catch (Exception e) {
                    if (postImmediate == null || !postImmediate.booleanValue()) {
                        // Retry only if the exception is listed as a retryable exception
                        String[] exceptions = readRule(RETRY_EXCEPTION_RULE, DEFAULT_RETRY_EXCEPTIONS);
                        Exception ex = null;
                        Class<Exception> clazz = null;
                        for (String exceptionName : exceptions) {
                            if (log.isDebugEnabled()) {
                                log.debug("Exception: " + exceptionName + " defined as a retryable exception.");
                            }
                            clazz = (Class<Exception>) Class.forName(exceptionName);
                            ex = clazz.cast(ExceptionHelper.extractException(e, clazz));
                            if (ex != null) {
                                break;
                            }
                        }
                        if (ex != null && ++retryCount <= retryLimit) {
                            if (log.isDebugEnabled()) {
                                log.debug(clazz.getSimpleName() + " encountered. Will sleep for " + retrySleepTimeInMillis + " milliseconds and then retry", e);
                            }
                            uow.rollback();
                            Thread.sleep(retrySleepTimeInMillis);
                            uow = new UOW();
                            if (log.isDebugEnabled()) {
                                log.debug("Retry#" + retryCount);
                            }
                        } else {
                            throw e;
                        }
                    } else {
                        throw e;
                    }
                }
            }
            if (log.isInfoEnabled()) {
                log.info(MessageHelper.findMessage("label.Jaffa.Transaction.TransactionConsumer.success", null));
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("There is no payload for the Transaction. Hence nothing to process.");
            }
        }
        TransactionField[] transactionFields = transaction.getTransactionFieldArray();
        boolean keep = false;
        if (transactionFields != null) {
            for (TransactionField tField : transactionFields) {
                if (KEEP.equals(tField.getFieldName()) && Boolean.parseBoolean(tField.getValue())) {
                    keep = true;
                    break;
                }
            }
        }
        if (log.isDebugEnabled()) {
            log.info("Finished with transaction: " + transactionId);
        }
        // Commit the UOW if it isn't a post immediate to catch any exceptions that might occur
        if (postImmediate == null || !postImmediate.booleanValue()) {
            if (keep) // Update Transaction status to S
            {
                TransactionEngine.getInstance().updateTransactionStatusToSatisfied(uow, transactionId);
            } else // Delete Transaction Record
            {
                TransactionEngine.getInstance().deleteTransaction(uow, transactionId);
            }
            try {
                uow.commit();
            } catch (Exception e) {
                log.error("Error committing UOW in TransactionConsumer.process", e);
                throw e;
            }
        } else {
            uow.flush();
            TransactionMessageDAOFactory.getTransactionMessageDAO().delete(uow, transaction);
        }
        if (log.isDebugEnabled()) {
            log.debug("Successfully processed Transaction " + transaction);
        }
    } catch (Exception e) {
        // Update Transaction status to E
        if (log.isInfoEnabled()) {
            log.info(MessageHelper.findMessage("label.Jaffa.Transaction.TransactionConsumer.error", null));
        }
        // Rollback the UOW if there is an error
        if (postImmediate == null || !postImmediate.booleanValue()) {
            try {
                uow.rollback();
            } catch (Exception exception) {
                log.error("Error rolling back UOW in transaction consumer");
            }
        }
        // Only need to update the transaction if the process is being run asynchronously.
        if (postImmediate == null || !postImmediate.booleanValue()) {
            // release the UOWs connection before creating a new one to move this transaction to the error state
            uow.rollback();
            // Update Transaction status to E
            TransactionEngine.getInstance().updateTransactionStatusToError(transactionId, e);
            log.error(MessageHelper.findMessage("label.Jaffa.Transaction.TransactionConsumer.error", null), e);
        }
        throw e;
    } finally {
        // Unset the Logging context
        if (createdLoggingContext) {
            LoggingService.unsetLoggingContext();
        }
    }
    return uow;
}
Also used : Transaction(org.jaffa.transaction.domain.Transaction) TransactionInfo(org.jaffa.transaction.services.configdomain.TransactionInfo) TransactionField(org.jaffa.transaction.domain.TransactionField) UOW(org.jaffa.persistence.UOW)

Aggregations

Transaction (org.jaffa.transaction.domain.Transaction)31 UOW (org.jaffa.persistence.UOW)19 TransactionCriteria (org.jaffa.transaction.apis.data.TransactionCriteria)14 TransactionFieldCriteria (org.jaffa.transaction.apis.data.TransactionFieldCriteria)14 AtomicCriteria (org.jaffa.persistence.AtomicCriteria)13 Criteria (org.jaffa.persistence.Criteria)13 ArrayList (java.util.ArrayList)11 FrameworkException (org.jaffa.exceptions.FrameworkException)10 ApplicationException (org.jaffa.exceptions.ApplicationException)9 HashMap (java.util.HashMap)8 LinkedHashMap (java.util.LinkedHashMap)8 ApplicationExceptions (org.jaffa.exceptions.ApplicationExceptions)8 Map (java.util.Map)7 LinkedList (java.util.LinkedList)5 InvalidForeignKeyException (org.jaffa.datatypes.exceptions.InvalidForeignKeyException)5 JaffaMessagingFrameworkException (org.jaffa.modules.messaging.services.JaffaMessagingFrameworkException)4 TransactionMessageDAO (org.jaffa.transaction.daos.TransactionMessageDAO)4 List (java.util.List)3 DomainObjectNotFoundException (org.jaffa.exceptions.DomainObjectNotFoundException)3 IllegalPersistentStateRuntimeException (org.jaffa.persistence.exceptions.IllegalPersistentStateRuntimeException)3