killbill-memoizeit

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index ad064e6..962c160 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -30,14 +30,12 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.Response.StatusType;
 import javax.ws.rs.core.StreamingOutput;
 import javax.ws.rs.core.UriInfo;
 
@@ -94,12 +92,14 @@ import org.slf4j.LoggerFactory;
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Strings;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 
 public abstract class JaxRsResourceBase implements JaxrsResource {
 
@@ -535,8 +535,10 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         Preconditions.checkArgument(actual == expected, errorMessage);
     }
 
-    protected Response createPaymentResponse(UriInfo uriInfo, Payment payment, TransactionType transactionType, @Nullable String transactionExternalKey) {
+    protected Response createPaymentResponse(final UriInfo uriInfo, final Payment payment, final TransactionType transactionType, @Nullable final String transactionExternalKey) {
         final PaymentTransaction createdTransaction = findCreatedTransaction(payment, transactionType, transactionExternalKey);
+        Preconditions.checkNotNull(createdTransaction, "No transaction of type '%s' found", transactionType);
+
         switch (createdTransaction.getTransactionStatus()) {
             case PENDING:
             case SUCCESS:
@@ -553,14 +555,25 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         return Response.serverError().build();
     }
 
-    private PaymentTransaction findCreatedTransaction(Payment payment, TransactionType transactionType, @Nullable String transactionExternalKey) {
-        for(PaymentTransaction transaction : payment.getTransactions()) {
-            if (transaction.getTransactionType() == transactionType
-                && Objects.equals(transaction.getExternalKey(), transactionExternalKey)) {
-                return transaction;
+    private PaymentTransaction findCreatedTransaction(final Payment payment, final TransactionType transactionType, @Nullable final String transactionExternalKey) {
+        // Make sure we start looking from the latest transaction created
+        final List<PaymentTransaction> reversedTransactions = Lists.reverse(payment.getTransactions());
+        final Iterable<PaymentTransaction> matchingTransactions = Iterables.filter(reversedTransactions, new Predicate<PaymentTransaction>() {
+            @Override
+            public boolean apply(final PaymentTransaction input) {
+                return input.getTransactionType() == transactionType;
+            }
+        });
+
+        if (transactionExternalKey != null) {
+            for (final PaymentTransaction transaction : matchingTransactions) {
+                if (Objects.equal(transaction.getExternalKey(), transactionExternalKey)) {
+                    return transaction;
+                }
             }
         }
-        // If nothing is found, return last transaction
-        return Iterables.getLast(payment.getTransactions());
+
+        // If nothing is found, return the latest transaction of given type
+        return Iterables.getFirst(matchingTransactions, null);
     }
 }