Skip to content

Commit

Permalink
payment: Fixes #378
Browse files Browse the repository at this point in the history
Removed unsued fields or setters from PaymentStateContext.
Documented the fields and when/why they get updated
Cleanup (removed protected filed attribute,...)
  • Loading branch information
sbrossie committed Sep 9, 2015
1 parent 96f1342 commit 4f8a23f
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 70 deletions.
Expand Up @@ -37,31 +37,40 @@


public class PaymentStateContext { public class PaymentStateContext {


// HACK
protected UUID paymentMethodId; // The following fields (paymentId, transactionId, amount, currency) may take their value from the paymentTransactionModelDao *when they are not already set*
protected UUID attemptId; private PaymentTransactionModelDao paymentTransactionModelDao;

// Initialized in CTOR or only set through paymentTransactionModelDao
// Stateful objects created by the callbacks and passed to the other following callbacks in the automaton private UUID paymentId;
protected List<PaymentTransactionModelDao> onLeavingStateExistingTransactions; private UUID transactionId;
protected PaymentTransactionModelDao paymentTransactionModelDao;
protected PaymentTransactionInfoPlugin paymentTransactionInfoPlugin; // Can be overriden by control plugin
protected BigDecimal amount; private BigDecimal amount;
protected String paymentExternalKey; private Currency currency;
protected String paymentTransactionExternalKey; private UUID paymentMethodId;
protected Currency currency; private Iterable<PluginProperty> properties;
protected Iterable<PluginProperty> properties;
protected boolean skipOperationForUnknownTransaction; // Set in the doOperationCallback when coming back from payment plugin

private PaymentTransactionInfoPlugin paymentTransactionInfoPlugin;
// Can be updated later via paymentTransactionModelDao (e.g. for auth or purchase)
protected final UUID paymentId; // Set in the control layer in the leavingState callback
protected final UUID transactionId; private String paymentExternalKey;
protected final Account account; private String paymentTransactionExternalKey;
protected final TransactionType transactionType;
protected final boolean shouldLockAccountAndDispatch; // Set in the control layer after creating the attempt in the enteringState callback
protected final InternalCallContext internalCallContext; private UUID attemptId;
protected final CallContext callContext;
protected final boolean isApiPayment; // This is purely a performance improvement to avoid fetching the existing transactions for that payment throughout the state machine
protected final OperationResult overridePluginOperationResult; private List<PaymentTransactionModelDao> onLeavingStateExistingTransactions;

// Immutable
private final Account account;
private final TransactionType transactionType;
private final boolean shouldLockAccountAndDispatch;
private final OperationResult overridePluginOperationResult;
private final InternalCallContext internalCallContext;
private final CallContext callContext;
private final boolean isApiPayment;


// Use to create new transactions only // Use to create new transactions only
public PaymentStateContext(final boolean isApiPayment, @Nullable final UUID paymentId, @Nullable final String paymentTransactionExternalKey, final TransactionType transactionType, public PaymentStateContext(final boolean isApiPayment, @Nullable final UUID paymentId, @Nullable final String paymentTransactionExternalKey, final TransactionType transactionType,
Expand Down Expand Up @@ -95,7 +104,6 @@ public PaymentStateContext(final boolean isApiPayment, @Nullable final UUID paym
this.internalCallContext = internalCallContext; this.internalCallContext = internalCallContext;
this.callContext = callContext; this.callContext = callContext;
this.onLeavingStateExistingTransactions = ImmutableList.of(); this.onLeavingStateExistingTransactions = ImmutableList.of();
this.skipOperationForUnknownTransaction = false;
} }


public boolean isApiPayment() { public boolean isApiPayment() {
Expand All @@ -112,6 +120,18 @@ public PaymentTransactionModelDao getPaymentTransactionModelDao() {


public void setPaymentTransactionModelDao(final PaymentTransactionModelDao paymentTransactionModelDao) { public void setPaymentTransactionModelDao(final PaymentTransactionModelDao paymentTransactionModelDao) {
this.paymentTransactionModelDao = paymentTransactionModelDao; this.paymentTransactionModelDao = paymentTransactionModelDao;
if (paymentId == null) {
this.paymentId = paymentTransactionModelDao.getPaymentId();
}
if (transactionId == null) {
this.transactionId = paymentTransactionModelDao.getId();
}
if (amount == null) {
this.amount = paymentTransactionModelDao.getAmount();
}
if (currency == null) {
this.currency = paymentTransactionModelDao.getCurrency();
}
} }


public List<PaymentTransactionModelDao> getOnLeavingStateExistingTransactions() { public List<PaymentTransactionModelDao> getOnLeavingStateExistingTransactions() {
Expand All @@ -131,11 +151,11 @@ public void setPaymentTransactionInfoPlugin(final PaymentTransactionInfoPlugin p
} }


public UUID getPaymentId() { public UUID getPaymentId() {
return paymentId != null ? paymentId : (paymentTransactionModelDao != null ? paymentTransactionModelDao.getPaymentId() : null); return paymentId;
} }


public UUID getTransactionId() { public UUID getTransactionId() {
return transactionId != null ? transactionId : (paymentTransactionModelDao != null ? paymentTransactionModelDao.getId() : null); return transactionId;
} }


public String getPaymentExternalKey() { public String getPaymentExternalKey() {
Expand Down Expand Up @@ -171,13 +191,11 @@ public void setAttemptId(final UUID attemptId) {
} }


public BigDecimal getAmount() { public BigDecimal getAmount() {
// For a complete operation, if the amount isn't specified, take the original amount on the transaction return amount;
return amount == null && paymentTransactionModelDao != null ? paymentTransactionModelDao.getAmount() : amount;
} }


public Currency getCurrency() { public Currency getCurrency() {
// For a complete operation, if the currency isn't specified, take the original currency on the transaction return currency;
return currency == null && paymentTransactionModelDao != null ? paymentTransactionModelDao.getCurrency() : currency;
} }


public TransactionType getTransactionType() { public TransactionType getTransactionType() {
Expand All @@ -204,11 +222,16 @@ public CallContext getCallContext() {
return callContext; return callContext;
} }


public boolean isSkipOperationForUnknownTransaction() { public void setAmount(final BigDecimal adjustedAmount) {
return skipOperationForUnknownTransaction; this.amount = adjustedAmount;
}

public void setCurrency(final Currency currency) {
this.currency = currency;
} }


public void setSkipOperationForUnknownTransaction(final boolean skipOperationForUnknownTransaction) { public void setProperties(final Iterable<PluginProperty> properties) {
this.skipOperationForUnknownTransaction = skipOperationForUnknownTransaction; this.properties = properties;
} }

} }
Expand Up @@ -79,7 +79,7 @@ public void leavingState(final State state) throws OperationException {
// //
// We don't serialize any properties at this stage to avoid serializing sensitive information. // We don't serialize any properties at this stage to avoid serializing sensitive information.
// However, if after going through the control plugins, the attempt end up in RETRIED state, // However, if after going through the control plugins, the attempt end up in RETRIED state,
// the properties will be serialized in the enteringState( callback (any plugin that sets a // the properties will be serialized in the enteringState callback (any plugin that sets a
// retried date is responsible to correctly remove sensitive information such as CVV, ...) // retried date is responsible to correctly remove sensitive information such as CVV, ...)
// //
final byte[] serializedProperties = PluginPropertySerializer.serialize(ImmutableList.<PluginProperty>of()); final byte[] serializedProperties = PluginPropertySerializer.serialize(ImmutableList.<PluginProperty>of());
Expand Down
Expand Up @@ -72,17 +72,6 @@ public void setResult(final Payment result) {
this.result = result; this.result = result;
} }


public void setAmount(final BigDecimal adjustedAmount) {
this.amount = adjustedAmount;
}

public void setCurrency(final Currency currency) {
this.currency = currency;
}

public void setProperties(final Iterable<PluginProperty> properties) {
this.properties = properties;
}


public PaymentTransaction getCurrentTransaction() { public PaymentTransaction getCurrentTransaction() {
if (result == null || result.getTransactions() == null) { if (result == null || result.getTransactions() == null) {
Expand All @@ -91,7 +80,7 @@ public PaymentTransaction getCurrentTransaction() {
return Iterables.tryFind(result.getTransactions(), new Predicate<PaymentTransaction>() { return Iterables.tryFind(result.getTransactions(), new Predicate<PaymentTransaction>() {
@Override @Override
public boolean apply(final PaymentTransaction input) { public boolean apply(final PaymentTransaction input) {
return ((DefaultPaymentTransaction) input).getAttemptId().equals(attemptId); return ((DefaultPaymentTransaction) input).getAttemptId().equals(getAttemptId());
} }
}).orNull(); }).orNull();
} }
Expand Down
Expand Up @@ -17,8 +17,6 @@


package org.killbill.billing.payment.core.sm.payments; package org.killbill.billing.payment.core.sm.payments;


import javax.annotation.Nullable;

import org.killbill.automaton.Operation; import org.killbill.automaton.Operation;
import org.killbill.automaton.OperationResult; import org.killbill.automaton.OperationResult;
import org.killbill.automaton.State; import org.killbill.automaton.State;
Expand Down Expand Up @@ -52,10 +50,6 @@ protected PaymentEnteringStateCallback(final PaymentAutomatonDAOHelper daoHelper
public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final LeavingStateCallback leavingStateCallback) { public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final LeavingStateCallback leavingStateCallback) {
logger.debug("Entering state {} with result {}", newState.getName(), operationResult); logger.debug("Entering state {} with result {}", newState.getName(), operationResult);


if (paymentStateContext.isSkipOperationForUnknownTransaction()) {
return;
}

// If the transaction was not created -- for instance we had an exception in leavingState callback then we bail; if not, then update state: // If the transaction was not created -- for instance we had an exception in leavingState callback then we bail; if not, then update state:
if (paymentStateContext.getPaymentTransactionModelDao() != null && paymentStateContext.getPaymentTransactionModelDao().getId() != null) { if (paymentStateContext.getPaymentTransactionModelDao() != null && paymentStateContext.getPaymentTransactionModelDao().getId() != null) {
final PaymentTransactionInfoPlugin paymentInfoPlugin = paymentStateContext.getPaymentTransactionInfoPlugin(); final PaymentTransactionInfoPlugin paymentInfoPlugin = paymentStateContext.getPaymentTransactionInfoPlugin();
Expand Down
Expand Up @@ -69,10 +69,6 @@ protected PaymentOperation(final GlobalLocker locker,
@Override @Override
public OperationResult doOperationCallback() throws OperationException { public OperationResult doOperationCallback() throws OperationException {


if (paymentStateContext.isSkipOperationForUnknownTransaction()) {
return OperationResult.SUCCESS;
}

try { try {
this.plugin = daoHelper.getPaymentProviderPlugin(); this.plugin = daoHelper.getPaymentProviderPlugin();


Expand Down
Expand Up @@ -71,23 +71,23 @@ protected Payment doCallSpecificOperationCallback() throws PaymentApiException {
} }
final PaymentModelDao payment = new PaymentModelDao(clock.getUTCNow(), final PaymentModelDao payment = new PaymentModelDao(clock.getUTCNow(),
clock.getUTCNow(), clock.getUTCNow(),
paymentStateContext.account.getId(), paymentStateContext.getAccount().getId(),
paymentStateContext.paymentMethodId, paymentStateContext.getPaymentMethodId(),
paymentStateContext.paymentExternalKey); paymentStateContext.getPaymentExternalKey());


final PaymentTransactionModelDao transaction = new PaymentTransactionModelDao(clock.getUTCNow(), final PaymentTransactionModelDao transaction = new PaymentTransactionModelDao(clock.getUTCNow(),
clock.getUTCNow(), clock.getUTCNow(),
paymentStateContext.getAttemptId(), paymentStateContext.getAttemptId(),
paymentStateContext.paymentTransactionExternalKey, paymentStateContext.getPaymentTransactionExternalKey(),
paymentStateContext.paymentId, paymentStateContext.getPaymentId(),
paymentStateContext.transactionType, paymentStateContext.getTransactionType(),
clock.getUTCNow(), clock.getUTCNow(),
TransactionStatus.SUCCESS, TransactionStatus.SUCCESS,
paymentStateContext.amount, paymentStateContext.getAmount(),
paymentStateContext.currency, paymentStateContext.getCurrency(),
"", "",
""); "");
final PaymentModelDao paymentModelDao = paymentDao.insertPaymentWithFirstTransaction(payment, transaction, paymentStateContext.internalCallContext); final PaymentModelDao paymentModelDao = paymentDao.insertPaymentWithFirstTransaction(payment, transaction, paymentStateContext.getInternalCallContext());
final PaymentTransaction convertedTransaction = new DefaultPaymentTransaction(transaction.getId(), final PaymentTransaction convertedTransaction = new DefaultPaymentTransaction(transaction.getId(),
paymentStateContext.getAttemptId(), paymentStateContext.getAttemptId(),
transaction.getTransactionExternalKey(), transaction.getTransactionExternalKey(),
Expand Down
Expand Up @@ -134,8 +134,8 @@ public void testLeaveStateForConflictingPaymentTransactionExternalKeyAcrossAccou
paymentStateContext.getPaymentMethodId(), paymentStateContext.getPaymentMethodId(),
paymentStateContext.getAmount(), paymentStateContext.getAmount(),
paymentStateContext.getCurrency(), paymentStateContext.getCurrency(),
paymentStateContext.shouldLockAccountAndDispatch, paymentStateContext.shouldLockAccountAndDispatch(),
paymentStateContext.overridePluginOperationResult, paymentStateContext.getOverridePluginOperationResult(),
paymentStateContext.getProperties(), paymentStateContext.getProperties(),
internalCallContextForOtherAccount, internalCallContextForOtherAccount,
callContext); callContext);
Expand Down

0 comments on commit 4f8a23f

Please sign in to comment.