Search in sources :

Example 1 with RollbackFailureException

use of org.broadleafcommerce.core.workflow.state.RollbackFailureException in project BroadleafCommerce by BroadleafCommerce.

the class CommitTaxRollbackHandler method rollbackState.

@Override
public void rollbackState(Activity<ProcessContext<CheckoutSeed>> activity, ProcessContext<CheckoutSeed> processContext, Map<String, Object> stateConfiguration) throws RollbackFailureException {
    ProcessContext<CheckoutSeed> ctx = processContext;
    Order order = ctx.getSeedData().getOrder();
    try {
        taxService.cancelTax(order);
    } catch (TaxException e) {
        throw new RollbackFailureException("An exception occured cancelling taxes for order id: " + order.getId(), e);
    }
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) RollbackFailureException(org.broadleafcommerce.core.workflow.state.RollbackFailureException) TaxException(org.broadleafcommerce.core.pricing.service.exception.TaxException)

Example 2 with RollbackFailureException

use of org.broadleafcommerce.core.workflow.state.RollbackFailureException in project BroadleafCommerce by BroadleafCommerce.

the class DecrementInventoryRollbackHandler method rollbackState.

@Override
public void rollbackState(Activity<ProcessContext<CheckoutSeed>> activity, ProcessContext<CheckoutSeed> processContext, Map<String, Object> stateConfiguration) throws RollbackFailureException {
    if (shouldExecute(activity, processContext, stateConfiguration)) {
        String orderId = "(Not Known)";
        if (stateConfiguration.get(ROLLBACK_BLC_ORDER_ID) != null) {
            orderId = String.valueOf(stateConfiguration.get(ROLLBACK_BLC_ORDER_ID));
        }
        @SuppressWarnings("unchecked") Map<Sku, Integer> inventoryToIncrement = (Map<Sku, Integer>) stateConfiguration.get(ROLLBACK_BLC_INVENTORY_DECREMENTED);
        @SuppressWarnings("unchecked") Map<Sku, Integer> inventoryToDecrement = (Map<Sku, Integer>) stateConfiguration.get(ROLLBACK_BLC_INVENTORY_INCREMENTED);
        Map<String, Object> contextualInformation = new HashMap<>();
        contextualInformation.put(ContextualInventoryService.ROLLBACK_STATE_KEY, stateConfiguration.get(EXTENDED_ROLLBACK_STATE));
        contextualInformation.put(ContextualInventoryService.ORDER_KEY, processContext.getSeedData().getOrder());
        if (inventoryToIncrement != null && !inventoryToIncrement.isEmpty()) {
            try {
                inventoryService.incrementInventory(inventoryToIncrement, contextualInformation);
            } catch (Exception ex) {
                RollbackFailureException rfe = new RollbackFailureException("An unexpected error occured in the error handler of the checkout workflow trying to compensate for inventory. This happend for order ID: " + orderId + ". This should be corrected manually!", ex);
                rfe.setActivity(activity);
                rfe.setProcessContext(processContext);
                rfe.setStateItems(stateConfiguration);
                throw rfe;
            }
        }
        if (inventoryToDecrement != null && !inventoryToDecrement.isEmpty()) {
            try {
                inventoryService.decrementInventory(inventoryToDecrement, contextualInformation);
            } catch (InventoryUnavailableException e) {
                // This is an awkward, unlikely state.  I just added some inventory, but something happened, and I want to remove it, but it's already gone!
                RollbackFailureException rfe = new RollbackFailureException("While trying roll back (decrement) inventory, we found that there was none left decrement.", e);
                rfe.setActivity(activity);
                rfe.setProcessContext(processContext);
                rfe.setStateItems(stateConfiguration);
                throw rfe;
            } catch (RuntimeException ex) {
                LOG.error("An unexpected error occured in the error handler of the checkout workflow trying to compensate for inventory. This happend for order ID: " + StringUtil.sanitize(orderId) + ". This should be corrected manually!", ex);
                RollbackFailureException rfe = new RollbackFailureException("An unexpected error occured in the error handler of the checkout workflow " + "trying to compensate for inventory. This happend for order ID: " + orderId + ". This should be corrected manually!", ex);
                rfe.setActivity(activity);
                rfe.setProcessContext(processContext);
                rfe.setStateItems(stateConfiguration);
                throw rfe;
            }
        }
    }
}
Also used : RollbackFailureException(org.broadleafcommerce.core.workflow.state.RollbackFailureException) HashMap(java.util.HashMap) InventoryUnavailableException(org.broadleafcommerce.core.inventory.service.InventoryUnavailableException) InventoryUnavailableException(org.broadleafcommerce.core.inventory.service.InventoryUnavailableException) RollbackFailureException(org.broadleafcommerce.core.workflow.state.RollbackFailureException) Sku(org.broadleafcommerce.core.catalog.domain.Sku) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with RollbackFailureException

use of org.broadleafcommerce.core.workflow.state.RollbackFailureException in project BroadleafCommerce by BroadleafCommerce.

the class ConfirmPaymentsRollbackHandler method rollbackState.

@Override
public void rollbackState(Activity<ProcessContext<CheckoutSeed>> activity, ProcessContext<CheckoutSeed> processContext, Map<String, Object> stateConfiguration) throws RollbackFailureException {
    CheckoutSeed seed = processContext.getSeedData();
    if (paymentConfigurationServiceProvider == null) {
        throw new RollbackFailureException("There is no rollback service configured for the payment gateway configuration, cannot rollback unconfirmed" + " payments");
    }
    Map<OrderPayment, PaymentTransaction> rollbackResponseTransactions = new HashMap<>();
    Collection<PaymentTransaction> transactions = (Collection<PaymentTransaction>) stateConfiguration.get(ValidateAndConfirmPaymentActivity.ROLLBACK_TRANSACTIONS);
    if (CollectionUtils.isNotEmpty(transactions)) {
        for (PaymentTransaction tx : transactions) {
            PaymentRequestDTO rollbackRequest = transactionToPaymentRequestDTOService.translatePaymentTransaction(tx.getAmount(), tx);
            PaymentGatewayConfigurationService cfg = paymentConfigurationServiceProvider.getGatewayConfigurationService(tx.getOrderPayment().getGatewayType());
            try {
                PaymentResponseDTO responseDTO = null;
                if (PaymentTransactionType.AUTHORIZE.equals(tx.getType())) {
                    if (cfg.getRollbackService() != null) {
                        responseDTO = cfg.getRollbackService().rollbackAuthorize(rollbackRequest);
                    }
                } else if (PaymentTransactionType.AUTHORIZE_AND_CAPTURE.equals(tx.getType())) {
                    if (cfg.getRollbackService() != null) {
                        responseDTO = cfg.getRollbackService().rollbackAuthorizeAndCapture(rollbackRequest);
                    }
                } else {
                    LOG.warn("The transaction with id " + tx.getId() + " will NOT be rolled back as it is not an AUTHORIZE or AUTHORIZE_AND_CAPTURE transaction but is" + " of type " + tx.getType() + ". If you need to roll back transactions of this type then provide a customized rollback handler for" + " confirming transactions.");
                }
                if (responseDTO != null) {
                    PaymentTransaction transaction = orderPaymentService.createTransaction();
                    transaction.setAmount(responseDTO.getAmount());
                    transaction.setRawResponse(responseDTO.getRawResponse());
                    transaction.setSuccess(responseDTO.isSuccessful());
                    transaction.setType(responseDTO.getPaymentTransactionType());
                    transaction.setParentTransaction(tx);
                    transaction.setOrderPayment(tx.getOrderPayment());
                    transaction.setAdditionalFields(responseDTO.getResponseMap());
                    rollbackResponseTransactions.put(tx.getOrderPayment(), transaction);
                    if (!responseDTO.isSuccessful()) {
                        LOG.fatal("Unable to rollback transaction with id " + tx.getId() + ". The call was unsuccessful with" + " raw response: " + responseDTO.getRawResponse());
                    }
                }
            } catch (PaymentException e) {
                throw new RollbackFailureException("The transaction with id " + tx.getId() + " encountered and exception when it was attempted to roll back" + " its confirmation", e);
            }
        }
        Order order = seed.getOrder();
        List<OrderPayment> paymentsToInvalidate = new ArrayList<>();
        // Add the new rollback transactions to the appropriate payment and mark the payment as invalid.
        // If there was a failed transaction rolling back we will need to throw a RollbackFailureException after saving the
        // Transaction Response to the DB
        boolean rollbackFailure = false;
        for (OrderPayment payment : order.getPayments()) {
            if (rollbackResponseTransactions.containsKey(payment)) {
                PaymentTransaction rollbackTX = rollbackResponseTransactions.get(payment);
                payment.addTransaction(rollbackTX);
                payment = orderPaymentService.save(payment);
                paymentsToInvalidate.add(payment);
                if (!rollbackTX.getSuccess()) {
                    rollbackFailure = true;
                }
            }
        }
        for (OrderPayment payment : paymentsToInvalidate) {
            paymentGatewayCheckoutService.markPaymentAsInvalid(payment.getId());
            orderPaymentService.save(payment);
        }
        if (rollbackFailure) {
            throw new RollbackFailureException("The ConfirmPaymentsRollbackHandler encountered and exception when it " + "attempted to roll back a transaction on one of the payments. Please see LOG for details.");
        }
        try {
            processContext.getSeedData().setOrder(orderService.save(order, false));
        } catch (PricingException e) {
            throw new RollbackFailureException("Unable to save the order with invalidated payments.");
        }
    }
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) RollbackFailureException(org.broadleafcommerce.core.workflow.state.RollbackFailureException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment) PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) PaymentException(org.broadleafcommerce.common.vendor.service.exception.PaymentException) PricingException(org.broadleafcommerce.core.pricing.service.exception.PricingException) Collection(java.util.Collection) PaymentRequestDTO(org.broadleafcommerce.common.payment.dto.PaymentRequestDTO) PaymentGatewayConfigurationService(org.broadleafcommerce.common.payment.service.PaymentGatewayConfigurationService) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 4 with RollbackFailureException

use of org.broadleafcommerce.core.workflow.state.RollbackFailureException in project BroadleafCommerce by BroadleafCommerce.

the class SequenceProcessor method doActivities.

@Override
public <P extends ProcessContext<U>> P doActivities(T seedData) throws WorkflowException {
    if (LOG.isDebugEnabled()) {
        LOG.debug(getBeanName() + " processor is running..");
    }
    ActivityStateManager activityStateManager = getBeanFactory().getBean(ActivityStateManager.class, "blActivityStateManager");
    if (activityStateManager == null) {
        throw new IllegalStateException("Unable to find an instance of ActivityStateManager registered under bean id blActivityStateManager");
    }
    ProcessContext<U> context = null;
    RollbackStateLocal rollbackStateLocal = new RollbackStateLocal();
    rollbackStateLocal.setThreadId(String.valueOf(Thread.currentThread().getId()));
    rollbackStateLocal.setWorkflowId(getBeanName());
    RollbackStateLocal.setRollbackStateLocal(rollbackStateLocal);
    try {
        // retrieve injected by Spring
        List<Activity<ProcessContext<U>>> activities = getActivities();
        // retrieve a new instance of the Workflow ProcessContext
        context = createContext(seedData);
        for (Activity<ProcessContext<U>> activity : activities) {
            if (activity.shouldExecute(context)) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("running activity:" + activity.getBeanName() + " using arguments:" + context);
                }
                try {
                    context = activity.execute(context);
                } catch (Throwable activityException) {
                    RollbackFailureException rollbackFailure = null;
                    if (getAutoRollbackOnError()) {
                        LOG.info(String.format("Exception ocurred in %s, executing rollback handlers", rollbackStateLocal.getWorkflowId()));
                        try {
                            ActivityStateManagerImpl.getStateManager().rollbackAllState();
                        } catch (Throwable rollbackException) {
                            LOG.fatal(String.format("There was an exception rolling back %s", rollbackStateLocal.getWorkflowId()), rollbackException);
                            if (rollbackException instanceof RollbackFailureException) {
                                rollbackFailure = (RollbackFailureException) rollbackException;
                            } else {
                                rollbackFailure = new RollbackFailureException(rollbackException);
                            }
                            LOG.error(String.format("The original cause of the rollback for %s was", rollbackStateLocal.getWorkflowId()), activityException);
                            rollbackFailure.setOriginalWorkflowException(activityException);
                            throw rollbackFailure;
                        }
                    }
                    ErrorHandler errorHandler = activity.getErrorHandler();
                    if (errorHandler == null) {
                        getDefaultErrorHandler().handleError(context, activityException);
                        break;
                    } else {
                        errorHandler.handleError(context, activityException);
                    }
                }
                // ensure its ok to continue the process
                if (processShouldStop(context, activity)) {
                    break;
                }
                // register the RollbackHandler
                if (activity.getRollbackHandler() != null && activity.getAutomaticallyRegisterRollbackHandler()) {
                    ActivityStateManagerImpl.getStateManager().registerState(activity, context, activity.getRollbackRegion(), activity.getRollbackHandler(), activity.getStateConfiguration());
                }
            } else {
                LOG.debug("Not executing activity: " + activity.getBeanName() + " based on the context: " + context);
            }
        }
    } finally {
        rollbackStateLocal = RollbackStateLocal.getRollbackStateLocal();
        if (rollbackStateLocal != null && rollbackStateLocal.getWorkflowId().equals(getBeanName())) {
            activityStateManager.clearAllState();
        }
    }
    LOG.debug(getBeanName() + " processor is done.");
    return (P) context;
}
Also used : RollbackFailureException(org.broadleafcommerce.core.workflow.state.RollbackFailureException) ActivityStateManager(org.broadleafcommerce.core.workflow.state.ActivityStateManager) RollbackStateLocal(org.broadleafcommerce.core.workflow.state.RollbackStateLocal)

Aggregations

RollbackFailureException (org.broadleafcommerce.core.workflow.state.RollbackFailureException)4 HashMap (java.util.HashMap)2 Order (org.broadleafcommerce.core.order.domain.Order)2 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Map (java.util.Map)1 PaymentRequestDTO (org.broadleafcommerce.common.payment.dto.PaymentRequestDTO)1 PaymentResponseDTO (org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)1 PaymentGatewayConfigurationService (org.broadleafcommerce.common.payment.service.PaymentGatewayConfigurationService)1 PaymentException (org.broadleafcommerce.common.vendor.service.exception.PaymentException)1 Sku (org.broadleafcommerce.core.catalog.domain.Sku)1 InventoryUnavailableException (org.broadleafcommerce.core.inventory.service.InventoryUnavailableException)1 OrderPayment (org.broadleafcommerce.core.payment.domain.OrderPayment)1 PaymentTransaction (org.broadleafcommerce.core.payment.domain.PaymentTransaction)1 PricingException (org.broadleafcommerce.core.pricing.service.exception.PricingException)1 TaxException (org.broadleafcommerce.core.pricing.service.exception.TaxException)1 ActivityStateManager (org.broadleafcommerce.core.workflow.state.ActivityStateManager)1 RollbackStateLocal (org.broadleafcommerce.core.workflow.state.RollbackStateLocal)1