killbill-memoizeit

Details

diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
index cb7dfcb..047f073 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
@@ -151,6 +151,11 @@ public class InvoiceApiHelper {
 
         final Map<UUID, BigDecimal> output = dao.computeItemAdjustments(invoiceToBeAdjusted.getId().toString(), input, context);
 
+        // Nothing to adjust
+        if (output.get(invoiceItemId) == null) {
+            return null;
+        }
+
         // If we pass that stage, it means the validation succeeded so we just need to extract resulting amount and negate the result.
         final BigDecimal amountToAdjust = output.get(invoiceItemId).negate();
         // Finally, create the adjustment
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index c19bb7c..4079b53 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -419,7 +419,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                                                                          effectiveDate,
                                                                                          description,
                                                                                          internalCallContextFactory.createInternalCallContext(accountId, context));
-                invoice.addInvoiceItem(adjustmentItem);
+                if (adjustmentItem != null) {
+                    invoice.addInvoiceItem(adjustmentItem);
+                }
 
                 return ImmutableList.<Invoice>of(invoice);
             }
@@ -432,9 +434,9 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                                                                                         return InvoiceItemType.ITEM_ADJ.equals(invoiceItem.getInvoiceItemType());
                                                                                                     }
                                                                                                 });
-        Preconditions.checkState(adjustmentInvoiceItems.size() == 1, "Should have created a single adjustment item: " + adjustmentInvoiceItems);
+        Preconditions.checkState(adjustmentInvoiceItems.size() <= 1, "Should have created a single adjustment item: " + adjustmentInvoiceItems);
 
-        return adjustmentInvoiceItems.iterator().next();
+        return adjustmentInvoiceItems.iterator().hasNext() ? adjustmentInvoiceItems.iterator().next() : null;
     }
 
     @Override
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index 98fc4b3..7daf146 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -262,6 +262,9 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         // Verify the adjusted account balance
         final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
+
+        // Verify idempotency
+        Assert.assertNull(invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(), null, callContext));
     }
 
     @Test(groups = "slow")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index cd70288..ac5a0fe 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -474,7 +474,11 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     callContext);
         }
 
-        return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId(), request);
+        if (adjustmentItem == null) {
+            return Response.status(Status.NOT_FOUND).build();
+        } else {
+            return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId(), request);
+        }
     }
 
     @TimedResource