killbill-memoizeit
Changes
pom.xml 2(+1 -1)
Details
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 89473ac..956cb7b 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -256,6 +256,8 @@ public interface JaxrsResource {
public static final String FORM = "form";
public static final String NOTIFICATION = "notification";
+ public static final String CANCEL_SCHEDULED_PAYMENT_TRANSACTION = "cancelScheduledPaymentTransaction";
+
public static final String INVOICE_TEMPLATE = "template";
public static final String INVOICE_MP_TEMPLATE = "manualPayTemplate";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index 6b47e30..e0e13b8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -784,6 +784,45 @@ public class PaymentResource extends ComboPaymentResource {
return createPaymentResponse(uriInfo, result, transactionType, paymentTransactionJson.getTransactionExternalKey());
}
+ @TimedResource(name = "cancelScheduledPaymentTransaction")
+ @DELETE
+ @Path("/{paymentTransactionId:" + UUID_PATTERN + "}/" + CANCEL_SCHEDULED_PAYMENT_TRANSACTION)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Cancels a scheduled payment attempt retry")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentTransactionId supplied")})
+ public Response cancelScheduledPaymentTransactionById(@PathParam("paymentTransactionId") final String paymentTransactionId,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+ paymentApi.cancelScheduledPaymentTransaction(UUID.fromString(paymentTransactionId), callContext);
+ return Response.status(Status.OK).build();
+ }
+
+ @TimedResource(name = "cancelScheduledPaymentTransaction")
+ @DELETE
+ @Path("/" + CANCEL_SCHEDULED_PAYMENT_TRANSACTION)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Cancels a scheduled payment attempt retry")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentTransactionExternalKey supplied")})
+ public Response cancelScheduledPaymentTransactionByExternalKey(@QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String paymentTransactionExternalKey,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+ paymentApi.cancelScheduledPaymentTransaction(paymentTransactionExternalKey, callContext);
+ return Response.status(Status.OK).build();
+ }
+
+
+
+
@TimedResource
@GET
@Path("/{paymentId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index 394320d..d73faad 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -582,6 +582,18 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
@Override
+ public void cancelScheduledPaymentTransaction(final String paymentTransactionExternalKey, final CallContext callContext) throws PaymentApiException {
+ checkNotNullParameter(paymentTransactionExternalKey, "paymentTransactionExternalKey");
+ paymentProcessor.cancelScheduledPaymentTransaction(null, paymentTransactionExternalKey, callContext);
+ }
+
+ @Override
+ public void cancelScheduledPaymentTransaction(final UUID paymentTransactionId, final CallContext callContext) throws PaymentApiException {
+ checkNotNullParameter(paymentTransactionId, "paymentTransactionId");
+ paymentProcessor.cancelScheduledPaymentTransaction(paymentTransactionId, null, callContext);
+ }
+
+ @Override
public Payment notifyPendingTransactionOfStateChanged(final Account account, final UUID paymentTransactionId, final boolean isSuccess, final CallContext callContext) throws PaymentApiException {
checkNotNullParameter(account, "account");
checkNotNullParameter(paymentTransactionId, "paymentTransactionId");
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index c57de1c..e8981f9 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -353,6 +353,43 @@ public class PaymentProcessor extends ProcessorBase {
);
}
+ public void cancelScheduledPaymentTransaction(@Nullable final UUID paymentTransactionId, @Nullable final String paymentTransactionExternalKey, final CallContext callContext) throws PaymentApiException {
+
+ final InternalCallContext internalCallContextWithoutAccountRecordId = internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(callContext);
+ final String effectivePaymentTransactionExternalKey;
+ if (paymentTransactionExternalKey == null) {
+ final PaymentTransactionModelDao transaction = paymentDao.getPaymentTransaction(paymentTransactionId, internalCallContextWithoutAccountRecordId);
+ effectivePaymentTransactionExternalKey = transaction.getTransactionExternalKey();
+ } else {
+ effectivePaymentTransactionExternalKey = paymentTransactionExternalKey;
+ }
+
+ final List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttemptByTransactionExternalKey(effectivePaymentTransactionExternalKey, internalCallContextWithoutAccountRecordId);
+ if (attempts.isEmpty()) {
+ return;
+ }
+
+ final PaymentAttemptModelDao lastPaymentAttempt = attempts.get(attempts.size() - 1);
+ final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(lastPaymentAttempt.getAccountId(), callContext);
+
+ try {
+ final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, DefaultRetryService.QUEUE_NAME);
+ final List<NotificationEventWithMetadata<NotificationEvent>> notificationEventWithMetadatas =
+ retryQueue.getFutureNotificationForSearchKeys(internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
+
+ for (final NotificationEventWithMetadata<NotificationEvent> notificationEvent : notificationEventWithMetadatas) {
+ if (((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId().equals(lastPaymentAttempt.getId())) {
+ retryQueue.removeNotification(notificationEvent.getRecordId());
+ break;
+ }
+ }
+ } catch (final NoSuchNotificationQueue noSuchNotificationQueue) {
+ log.error("ERROR Loading Notification Queue - " + noSuchNotificationQueue.getMessage());
+ throw new IllegalStateException(noSuchNotificationQueue);
+ }
+ }
+
+
private Payment performOperation(final boolean isApiPayment,
@Nullable final UUID attemptId,
final TransactionType transactionType,
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 03d6a18..5927275 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.124-SNAPSHOT</version>
+ <version>0.125-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.17.3-SNAPSHOT</version>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
index 9c418c8..0baeb5e 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
@@ -172,8 +172,16 @@ public class TestPayment extends TestJaxrsBase {
Assert.assertEquals(invoicePayments.get(0).getTargetInvoiceId(), failedInvoiceId);
Assert.assertNotNull(invoicePayments.get(0).getPaymentAttempts());
+ Assert.assertEquals(invoicePayments.get(0).getPaymentAttempts().size(), 2);
Assert.assertEquals(invoicePayments.get(0).getPaymentAttempts().get(0).getStateName(), "RETRIED");
Assert.assertEquals(invoicePayments.get(0).getPaymentAttempts().get(1).getStateName(), "SCHEDULED");
+
+
+ // Remove the future notification and check SCHEDULED does not appear any longer
+ killBillClient.cancelScheduledPaymentTransaction(null, invoicePayments.get(0).getPaymentAttempts().get(1).getTransactionExternalKey(), inputOptions);
+ invoicePayments = killBillClient.getInvoicePayment(failedInvoiceId, inputOptions);
+ Assert.assertEquals(invoicePayments.get(0).getPaymentAttempts().size(), 1);
+ Assert.assertEquals(invoicePayments.get(0).getPaymentAttempts().get(0).getStateName(), "RETRIED");
}
@Test(groups = "slow")