killbill-aplcache
Changes
bin/gen_updater.rb 70(+70 -0)
NEWS 5(+4 -1)
profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties 325(+129 -196)
Details
bin/gen_updater.rb 70(+70 -0)
diff --git a/bin/gen_updater.rb b/bin/gen_updater.rb
new file mode 100644
index 0000000..14f75c9
--- /dev/null
+++ b/bin/gen_updater.rb
@@ -0,0 +1,70 @@
+require 'json'
+require 'open-uri'
+
+def get_as_json(url)
+ raw = URI.parse(url).read
+ JSON.parse(raw)
+end
+
+current_stable_train = nil
+current_dev_train = nil
+
+current_stable_version = nil
+current_dev_version = nil
+
+metadata = get_as_json("https://api.github.com/repos/killbill/killbill/tags")
+releases = []
+metadata.each do |entry|
+ parsed = entry['name'].scan(/killbill-([0-9]+\.([0-9]+)\.[0-9]+)/).last
+ version = parsed.first
+
+ train = parsed.last.to_i
+ if train % 2 == 1
+ current_dev_train = train if current_dev_train.to_i < train
+ current_dev_version = version if current_dev_version.nil? || (current_dev_version < version)
+ else
+ current_stable_train = train if current_stable_train.to_i < train
+ current_stable_version = version if current_stable_version.nil? || (current_stable_version < version)
+ end
+
+ releases << {
+ :train => train,
+ :version => version
+ }
+end
+
+doc =<<EOF
+## Top level keys
+# general.notice = This notice should rarely, if ever, be used as everyone will see it
+
+EOF
+
+current_train = nil
+latest_from_train = nil
+releases.each do |release|
+ if release[:train] != current_train || current_train == nil
+ current_train = release[:train]
+ latest_from_train = release[:version]
+ doc << "### 0.#{current_train}.x series ###\n\n"
+ end
+
+ doc << "\# #{release[:version]}\n"
+
+ if release[:version] == latest_from_train
+ doc << "#{release[:version]}.updates =\n"
+ else
+ doc << "#{release[:version]}.updates = #{latest_from_train}\n"
+ end
+
+ if release[:version] == current_dev_version || release[:version] == current_stable_version
+ doc << "#{release[:version]}.notices = This is the latest #{release[:train] % 2 == 1 ? 'dev' : 'GA'} release.\n"
+ elsif release[:train] != current_dev_train
+ doc << "#{release[:version]}.notices = We recommend upgrading to #{current_stable_version}, our latest GA release.\n"
+ else
+ doc << "#{release[:version]}.notices = We recommend upgrading to #{current_dev_version}, our latest dev release.\n"
+ end
+
+ doc << "#{release[:version]}.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-#{release[:version]}\n\n"
+end
+
+puts doc.chomp!
\ No newline at end of file
NEWS 5(+4 -1)
diff --git a/NEWS b/NEWS
index bb13ca8..842a436 100644
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,7 @@
See https://github.com/killbill/killbill/releases/tag/killbill-0.16.1
0.16.0
- TBD (point to 0.16 release page)
+ See https://github.com/killbill/killbill/releases/tag/killbill-0.16.0
0.15.10
See https://github.com/killbill/killbill/releases/tag/killbill-0.15.10
@@ -50,6 +50,9 @@
0.15.0
See https://github.com/killbill/killbill/issues?q=milestone%3ARelease-0.15.0+is%3Aclosed
+0.14.1
+ Fix usage bug (see 8511f41cdf78bd1cb9d0c335ffa8d40ca53aeccd)
+
0.14.0
http://killbill.io/blog/kill-bill-0-14-0-released/
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 7885616..4df2541 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
@@ -367,10 +367,17 @@ public class PaymentProcessor extends ProcessorBase {
String currentStateName = null;
if (paymentStateContext.getPaymentId() != null) {
PaymentModelDao paymentModelDao = daoHelper.getPayment();
+
+ // Sanity: verify the payment belongs to the right account (in case it was looked-up by payment or transaction external key)
+ if (!paymentModelDao.getAccountRecordId().equals(internalCallContext.getAccountRecordId())) {
+ // TODO 0.17.x New ErrorCode (it's not necessarily the transaction external key that matches)
+ throw new PaymentApiException(ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS, paymentStateContext.getPaymentTransactionExternalKey());
+ }
+
if (paymentStateContext.getTransactionId() != null || paymentStateContext.getPaymentTransactionExternalKey() != null) {
// If a transaction id or key is passed, we are maybe completing an existing transaction (unless a new key was provided)
final List<PaymentTransactionModelDao> paymentTransactionsForCurrentPayment = daoHelper.getPaymentDao().getTransactionsForPayment(paymentStateContext.getPaymentId(), paymentStateContext.getInternalCallContext());
- PaymentTransactionModelDao transactionToComplete = findTransactionToCompleteAndRunSanityChecks(paymentModelDao, paymentTransactionsForCurrentPayment, paymentStateContext);
+ PaymentTransactionModelDao transactionToComplete = findTransactionToCompleteAndRunSanityChecks(paymentModelDao, paymentTransactionsForCurrentPayment, paymentStateContext, internalCallContext);
if (transactionToComplete != null) {
// For completion calls, always invoke the Janitor first to get the latest state. The state machine will then
@@ -415,7 +422,8 @@ public class PaymentProcessor extends ProcessorBase {
private PaymentTransactionModelDao findTransactionToCompleteAndRunSanityChecks(final PaymentModelDao paymentModelDao,
final Iterable<PaymentTransactionModelDao> paymentTransactionsForCurrentPayment,
- final PaymentStateContext paymentStateContext) throws PaymentApiException {
+ final PaymentStateContext paymentStateContext,
+ final InternalCallContext internalCallContext) throws PaymentApiException {
final Collection<PaymentTransactionModelDao> completionCandidates = new LinkedList<PaymentTransactionModelDao>();
for (final PaymentTransactionModelDao paymentTransactionModelDao : paymentTransactionsForCurrentPayment) {
// Check if we already have a transaction for that id or key
@@ -434,7 +442,20 @@ public class PaymentProcessor extends ProcessorBase {
// Sanity: if we already have a transaction for that id or key, the transaction type must match
if (paymentTransactionModelDao.getTransactionType() != paymentStateContext.getTransactionType()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_INVALID_OPERATION, paymentStateContext.getTransactionType(), paymentModelDao.getStateName());
+ throw new PaymentApiException(ErrorCode.PAYMENT_INVALID_PARAMETER, "transactionType", String.format("%s doesn't match existing transaction type %s", paymentStateContext.getTransactionType(), paymentTransactionModelDao.getTransactionType()));
+ }
+
+ // Sanity: verify we don't already have a successful transaction for that key (chargeback reversals are a bit special, it's the only transaction type we can revert)
+ if (paymentTransactionModelDao.getTransactionExternalKey().equals(paymentStateContext.getPaymentTransactionExternalKey()) &&
+ paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.SUCCESS &&
+ paymentTransactionModelDao.getTransactionType() != TransactionType.CHARGEBACK) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS, paymentStateContext.getPaymentTransactionExternalKey());
+ }
+
+ // Sanity: don't share keys across accounts
+ if (paymentTransactionModelDao.getTransactionExternalKey().equals(paymentStateContext.getPaymentTransactionExternalKey()) &&
+ !paymentTransactionModelDao.getAccountRecordId().equals(internalCallContext.getAccountRecordId())) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS, paymentStateContext.getPaymentTransactionExternalKey());
}
// UNKNOWN transactions are potential candidates, we'll invoke the Janitor first though
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
index d7a03e2..012d7c0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
@@ -18,6 +18,7 @@
package org.killbill.billing.payment.core.sm;
import java.math.BigDecimal;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -42,6 +43,7 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.payment.api.TransactionType;
import org.killbill.billing.payment.core.PaymentExecutors;
import org.killbill.billing.payment.core.sm.payments.AuthorizeCompleted;
@@ -67,6 +69,7 @@ import org.killbill.billing.payment.core.sm.payments.VoidInitiated;
import org.killbill.billing.payment.core.sm.payments.VoidOperation;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.dao.PaymentModelDao;
+import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
import org.killbill.billing.payment.dispatcher.PluginDispatcher;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.util.callcontext.CallContext;
@@ -126,7 +129,7 @@ public class PaymentAutomatonRunner {
final CallContext callContext,
final InternalCallContext internalCallContext) throws PaymentApiException {
// Retrieve the payment id from the payment external key if needed
- final UUID effectivePaymentId = paymentId != null ? paymentId : retrievePaymentId(paymentExternalKey, internalCallContext);
+ final UUID effectivePaymentId = paymentId != null ? paymentId : retrievePaymentId(paymentExternalKey, paymentTransactionExternalKey, internalCallContext);
return new PaymentStateContext(isApiPayment,
effectivePaymentId,
@@ -245,12 +248,40 @@ public class PaymentAutomatonRunner {
}
}
- private UUID retrievePaymentId(@Nullable final String paymentExternalKey, final InternalCallContext internalCallContext) {
- if (paymentExternalKey == null) {
+ // TODO Could we cache these to avoid extra queries in PaymentAutomatonDAOHelper?
+ private UUID retrievePaymentId(@Nullable final String paymentExternalKey, @Nullable final String paymentTransactionExternalKey, final InternalCallContext internalCallContext) throws PaymentApiException {
+ if (paymentExternalKey != null) {
+ final PaymentModelDao payment = paymentDao.getPaymentByExternalKey(paymentExternalKey, internalCallContext);
+ if (payment != null) {
+ return payment.getId();
+ }
+ }
+
+ if (paymentTransactionExternalKey == null) {
return null;
}
- final PaymentModelDao payment = paymentDao.getPaymentByExternalKey(paymentExternalKey, internalCallContext);
- return payment == null ? null : payment.getId();
+ final List<PaymentTransactionModelDao> paymentTransactionModelDaos = paymentDao.getPaymentTransactionsByExternalKey(paymentTransactionExternalKey, internalCallContext);
+ for (final PaymentTransactionModelDao paymentTransactionModelDao : paymentTransactionModelDaos) {
+ if (paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.SUCCESS ||
+ paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.PENDING ||
+ paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.UNKNOWN) {
+ return paymentTransactionModelDao.getPaymentId();
+ }
+ }
+
+ UUID paymentIdCandidate = null;
+ for (final PaymentTransactionModelDao paymentTransactionModelDao : paymentTransactionModelDaos) {
+ if (paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.PAYMENT_FAILURE ||
+ paymentTransactionModelDao.getTransactionStatus() == TransactionStatus.PLUGIN_FAILURE) {
+ if (paymentIdCandidate == null) {
+ paymentIdCandidate = paymentTransactionModelDao.getPaymentId();
+ } else if (!paymentIdCandidate.equals(paymentTransactionModelDao.getPaymentId())) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, "Multiple failed payments sharing the same transaction external key - this should never happen");
+ }
+ }
+ }
+
+ return paymentIdCandidate;
}
}
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index 8db97ce..d455610 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -1715,7 +1715,6 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testSanityAcrossTransactionTypes() throws PaymentApiException {
-
final BigDecimal requestedAmount = BigDecimal.TEN;
final String paymentExternalKey = "ahhhhhhhh";
final String transactionExternalKey = "okkkkkkk";
@@ -1730,21 +1729,18 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
Assert.assertEquals(pendingPayment.getTransactions().get(0).getExternalKey(), transactionExternalKey);
Assert.assertEquals(pendingPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PENDING);
-
try {
createPayment(TransactionType.PURCHASE, null, paymentExternalKey, transactionExternalKey, requestedAmount, PaymentPluginStatus.PENDING);
Assert.fail("PURCHASE transaction with same key should have failed");
} catch (final PaymentApiException expected) {
- Assert.assertEquals(expected.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
+ Assert.assertEquals(expected.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
}
}
@Test(groups = "slow")
public void testSuccessfulInitialTransactionToSameTransaction() throws Exception {
-
final BigDecimal requestedAmount = BigDecimal.TEN;
for (final TransactionType transactionType : ImmutableList.<TransactionType>of(TransactionType.AUTHORIZE, TransactionType.PURCHASE, TransactionType.CREDIT)) {
-
final String paymentExternalKey = UUID.randomUUID().toString();
final String keyA = UUID.randomUUID().toString();
@@ -1760,6 +1756,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
createPayment(transactionType, processedPayment.getId(), paymentExternalKey, keyB, requestedAmount, PaymentPluginStatus.PROCESSED);
Assert.fail("Retrying initial successful transaction (AUTHORIZE, PURCHASE, CREDIT) with same different key should fail");
} catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
}
// Attempt to create another {AUTH, PURCHASE, CREDIT} with same key => key constraint should make the request fail
@@ -1767,17 +1764,15 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
createPayment(transactionType, processedPayment.getId(), paymentExternalKey, keyA, requestedAmount, PaymentPluginStatus.PROCESSED);
Assert.fail("Retrying initial successful transaction (AUTHORIZE, PURCHASE, CREDIT) with same transaction key should fail");
} catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
}
}
}
-
@Test(groups = "slow")
public void testPendingInitialTransactionToSameTransaction() throws Exception {
-
final BigDecimal requestedAmount = BigDecimal.TEN;
for (final TransactionType transactionType : ImmutableList.<TransactionType>of(TransactionType.AUTHORIZE, TransactionType.PURCHASE, TransactionType.CREDIT)) {
-
final String paymentExternalKey = UUID.randomUUID().toString();
final String keyA = UUID.randomUUID().toString();
@@ -1793,6 +1788,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
createPayment(transactionType, pendingPayment.getId(), paymentExternalKey, keyB, requestedAmount, PaymentPluginStatus.PROCESSED);
Assert.fail("Retrying initial successful transaction (AUTHORIZE, PURCHASE, CREDIT) with same different key should fail");
} catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
}
// Attempt to create another {AUTH, PURCHASE, CREDIT} with same key => That should work because we are completing the payment
@@ -1803,13 +1799,10 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
}
}
-
@Test(groups = "slow")
public void testFailedInitialTransactionToSameTransactionWithSameKey() throws Exception {
-
final BigDecimal requestedAmount = BigDecimal.TEN;
for (final TransactionType transactionType : ImmutableList.<TransactionType>of(TransactionType.AUTHORIZE, TransactionType.PURCHASE, TransactionType.CREDIT)) {
-
final String paymentExternalKey = UUID.randomUUID().toString();
final String keyA = UUID.randomUUID().toString();
@@ -1826,13 +1819,10 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
}
}
-
@Test(groups = "slow")
public void testFailedInitialTransactionToSameTransactionWithDifferentKey() throws Exception {
-
final BigDecimal requestedAmount = BigDecimal.TEN;
for (final TransactionType transactionType : ImmutableList.<TransactionType>of(TransactionType.AUTHORIZE, TransactionType.PURCHASE, TransactionType.CREDIT)) {
-
final String paymentExternalKey = UUID.randomUUID().toString();
final String keyA = UUID.randomUUID().toString();
@@ -1851,7 +1841,292 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
}
}
+ @Test(groups = "slow")
+ public void testKeysSanityOnPending() throws Exception {
+ final String authKey = UUID.randomUUID().toString();
+ final Payment pendingAuthorization = createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PENDING);
+ assertNotNull(pendingAuthorization);
+ Assert.assertEquals(pendingAuthorization.getTransactions().size(), 1);
+ Assert.assertEquals(pendingAuthorization.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PENDING);
+
+ try {
+ // Capture with the same transaction external key should fail
+ createPayment(TransactionType.CAPTURE, pendingAuthorization.getId(), null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+ }
+
+ final Account account1 = testHelper.createTestAccount("bobo2@gmail.com", true);
+ try {
+ // Different auth with the same payment external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), null, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same payment external key but different transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Auth with the same payment external key but different transaction external key should not go through
+ createPayment(TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PENDING);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
+ }
+
+ // Auth with the same payment and transaction external keys should go through (completion)
+ final Payment pendingAuthorization2 = createPayment(TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), authKey, BigDecimal.TEN, PaymentPluginStatus.PENDING);
+ assertNotNull(pendingAuthorization2);
+ Assert.assertEquals(pendingAuthorization2.getTransactions().size(), 1);
+ Assert.assertEquals(pendingAuthorization2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PENDING);
+
+ // Auth with the same transaction external key should go through (completion)
+ final Payment authorization = createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ assertNotNull(authorization);
+ Assert.assertEquals(authorization.getTransactions().size(), 1);
+ Assert.assertEquals(authorization.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+
+ try {
+ // Different auth with the same payment external key on a different account should still fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), null, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same payment external key but different transaction external key on a different account should still fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, pendingAuthorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key on a different account should still fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ // Capture with a different transaction external key should go through
+ final String captureKey = UUID.randomUUID().toString();
+ final Payment pendingCapture = createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey, BigDecimal.ONE, PaymentPluginStatus.PENDING);
+ Assert.assertEquals(pendingCapture.getTransactions().size(), 2);
+ Assert.assertEquals(pendingCapture.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(pendingCapture.getTransactions().get(1).getTransactionStatus(), TransactionStatus.PENDING);
+
+ try {
+ // Different auth with the same transaction external key should fail
+ createPayment(TransactionType.AUTHORIZE, null, null, captureKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, captureKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ // Second capture with the same transaction external key should go through (completion)
+ final Payment capturedPayment = createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey, BigDecimal.ONE, PaymentPluginStatus.PROCESSED);
+ Assert.assertEquals(capturedPayment.getTransactions().size(), 2);
+ Assert.assertEquals(capturedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+
+ // Second capture with a different transaction external key should go through
+ final String captureKey2 = UUID.randomUUID().toString();
+ final Payment capturedPayment2 = createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey2, BigDecimal.ONE, PaymentPluginStatus.PROCESSED);
+ Assert.assertEquals(capturedPayment2.getTransactions().size(), 3);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(2).getTransactionStatus(), TransactionStatus.SUCCESS);
+ }
+
+ @Test(groups = "slow")
+ public void testKeysSanityOnSuccess() throws Exception {
+ final String authKey = UUID.randomUUID().toString();
+ final Payment authorization = createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ assertNotNull(authorization);
+ Assert.assertEquals(authorization.getTransactions().size(), 1);
+ Assert.assertEquals(authorization.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+
+ try {
+ // Capture with the same transaction external key should fail
+ createPayment(TransactionType.CAPTURE, authorization.getId(), null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+ }
+
+ try {
+ // Different auth with the same payment external key should fail
+ createPayment(TransactionType.AUTHORIZE, null, authorization.getExternalKey(), null, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
+ }
+
+ try {
+ // Different auth with the same payment external key but different transaction external key should fail
+ createPayment(TransactionType.AUTHORIZE, null, authorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_OPERATION.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key should fail
+ createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ final Account account1 = testHelper.createTestAccount("bobo2@gmail.com", true);
+ try {
+ // Different auth with the same payment external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, authorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same payment external key but different transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, authorization.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ // Capture with a different transaction external key should go through
+ final String captureKey = UUID.randomUUID().toString();
+ final Payment capturedPayment = createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey, BigDecimal.ONE, PaymentPluginStatus.PROCESSED);
+ Assert.assertEquals(capturedPayment.getTransactions().size(), 2);
+ Assert.assertEquals(capturedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+
+ try {
+ // Second capture with the same transaction external key should fail
+ createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey, BigDecimal.ONE, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key should fail
+ createPayment(TransactionType.AUTHORIZE, null, null, captureKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+ }
+
+ try {
+ // Different auth with the same transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, captureKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ // Second capture with a different transaction external key should go through
+ final String captureKey2 = UUID.randomUUID().toString();
+ final Payment capturedPayment2 = createPayment(TransactionType.CAPTURE, authorization.getId(), null, captureKey2, BigDecimal.ONE, PaymentPluginStatus.PROCESSED);
+ Assert.assertEquals(capturedPayment2.getTransactions().size(), 3);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+ Assert.assertEquals(capturedPayment2.getTransactions().get(2).getTransactionStatus(), TransactionStatus.SUCCESS);
+ }
+
+ @Test(groups = "slow")
+ public void testKeysSanityOnFailure() throws Exception {
+ final String authKey = UUID.randomUUID().toString();
+ final Payment failedAuthorization1 = createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.ERROR);
+ assertNotNull(failedAuthorization1);
+ Assert.assertEquals(failedAuthorization1.getTransactions().size(), 1);
+ Assert.assertEquals(failedAuthorization1.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+
+ final Account account1 = testHelper.createTestAccount("bobo2@gmail.com", true);
+ try {
+ // Different auth with the same payment external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, failedAuthorization1.getExternalKey(), null, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+ try {
+ // Different auth with the same transaction external key on a different account should fail
+ createPayment(account1, TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.PROCESSED);
+ Assert.fail();
+ } catch (final PaymentApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_ACTIVE_TRANSACTION_KEY_EXISTS.getCode());
+ }
+
+ // Different auth with the same payment external key should go through
+ final Payment failedAuthorization2 = createPayment(TransactionType.AUTHORIZE, null, failedAuthorization1.getExternalKey(), null, BigDecimal.TEN, PaymentPluginStatus.ERROR);
+ assertNotNull(failedAuthorization2);
+ Assert.assertEquals(failedAuthorization2.getTransactions().size(), 2);
+ Assert.assertEquals(failedAuthorization2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertEquals(failedAuthorization2.getTransactions().get(0).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertNotEquals(failedAuthorization2.getTransactions().get(1).getExternalKey(), authKey);
+
+ // Different auth with the same transaction external key should go through
+ final Payment failedAuthorization3 = createPayment(TransactionType.AUTHORIZE, null, null, authKey, BigDecimal.TEN, PaymentPluginStatus.ERROR);
+ assertNotNull(failedAuthorization3);
+ Assert.assertEquals(failedAuthorization3.getTransactions().size(), 3);
+ Assert.assertEquals(failedAuthorization3.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertEquals(failedAuthorization3.getTransactions().get(0).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization3.getTransactions().get(1).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertNotEquals(failedAuthorization3.getTransactions().get(1).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization3.getTransactions().get(2).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertEquals(failedAuthorization3.getTransactions().get(2).getExternalKey(), authKey);
+
+ // Different auth with the same payment external key but different transaction external key should go through
+ final Payment failedAuthorization4 = createPayment(TransactionType.AUTHORIZE, null, failedAuthorization1.getExternalKey(), UUID.randomUUID().toString(), BigDecimal.TEN, PaymentPluginStatus.ERROR);
+ assertNotNull(failedAuthorization4);
+ Assert.assertEquals(failedAuthorization4.getTransactions().size(), 4);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(0).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(1).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertNotEquals(failedAuthorization4.getTransactions().get(1).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(2).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(2).getExternalKey(), authKey);
+ Assert.assertEquals(failedAuthorization4.getTransactions().get(3).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+ Assert.assertNotEquals(failedAuthorization4.getTransactions().get(3).getExternalKey(), authKey);
+ }
private void verifyRefund(final Payment refund, final String paymentExternalKey, final String paymentTransactionExternalKey, final String refundTransactionExternalKey, final BigDecimal requestedAmount, final BigDecimal refundAmount, final TransactionStatus transactionStatus) {
Assert.assertEquals(refund.getExternalKey(), paymentExternalKey);
@@ -1945,6 +2220,16 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
@Nullable final String paymentTransactionExternalKey,
@Nullable final BigDecimal amount,
final PaymentPluginStatus paymentPluginStatus) throws PaymentApiException {
+ return createPayment(account, transactionType, paymentId, paymentExternalKey, paymentTransactionExternalKey, amount, paymentPluginStatus);
+ }
+
+ private Payment createPayment(final Account account,
+ final TransactionType transactionType,
+ @Nullable final UUID paymentId,
+ @Nullable final String paymentExternalKey,
+ @Nullable final String paymentTransactionExternalKey,
+ @Nullable final BigDecimal amount,
+ final PaymentPluginStatus paymentPluginStatus) throws PaymentApiException {
final Iterable<PluginProperty> pluginProperties = ImmutableList.<PluginProperty>of(new PluginProperty(MockPaymentProviderPlugin.PLUGIN_PROPERTY_PAYMENT_PLUGIN_STATUS_OVERRIDE, paymentPluginStatus.toString(), false));
switch (transactionType) {
case AUTHORIZE:
diff --git a/profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties b/profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties
index 8444c7d..182a482 100644
--- a/profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties
+++ b/profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties
@@ -1,231 +1,164 @@
## Top level keys
# general.notice = This notice should rarely, if ever, be used as everyone will see it
+### 0.17.x series ###
+
+# 0.17.0
+0.17.0.updates =
+0.17.0.notices = This is the latest dev release.
+0.17.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.17.0
+
+### 0.16.x series ###
+
+# 0.16.6
+0.16.6.updates =
+0.16.6.notices = This is the latest GA release.
+0.16.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.6
+
+# 0.16.5
+0.16.5.updates = 0.16.6
+0.16.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.5
+
+# 0.16.4
+0.16.4.updates = 0.16.6
+0.16.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.4
+
+# 0.16.3
+0.16.3.updates = 0.16.6
+0.16.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.3
+
+# 0.16.2
+0.16.2.updates = 0.16.6
+0.16.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.2
+
+# 0.16.1
+0.16.1.updates = 0.16.6
+0.16.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.1
+
+# 0.16.0
+0.16.0.updates = 0.16.6
+0.16.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.0
+
+### 0.15.x series ###
+
+# 0.15.10
+0.15.10.updates =
+0.15.10.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.10.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.10
+
+# 0.15.9
+0.15.9.updates = 0.15.10
+0.15.9.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.9.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.9
+
+# 0.15.8
+0.15.8.updates = 0.15.10
+0.15.8.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.8.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.8
+
+# 0.15.7
+0.15.7.updates = 0.15.10
+0.15.7.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.7.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.7
+
+# 0.15.6
+0.15.6.updates = 0.15.10
+0.15.6.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.6
+
+# 0.15.5
+0.15.5.updates = 0.15.10
+0.15.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.5
+
+# 0.15.4
+0.15.4.updates = 0.15.10
+0.15.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.4
+
+# 0.15.3
+0.15.3.updates = 0.15.10
+0.15.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.3
+
+# 0.15.2
+0.15.2.updates = 0.15.10
+0.15.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.2
+
+# 0.15.1
+0.15.1.updates = 0.15.10
+0.15.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.1
+
+# 0.15.0
+0.15.0.updates = 0.15.10
+0.15.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.0
+
### 0.14.x series ###
+# 0.14.1
+0.14.1.updates =
+0.14.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.14.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.14.1
+
# 0.14.0
-0.14.0.updates =
-0.14.0.notices = This is the latest GA release.
-0.14.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.14.0.updates = 0.14.1
+0.14.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.14.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.14.0
### 0.13.x series ###
-## 0.13.7 -- latest unstable release
+# 0.13.7
0.13.7.updates =
-0.13.7.notices = This is the latest dev release.
+0.13.7.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.7.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.7
-## 0.13.6
+# 0.13.6
0.13.6.updates = 0.13.7
-0.13.6.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.6.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.6
-## 0.13.5
+# 0.13.5
0.13.5.updates = 0.13.7
-0.13.5.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.5
-## 0.13.4
+# 0.13.4
0.13.4.updates = 0.13.7
-0.13.4.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.4
-## 0.13.3
+# 0.13.3
0.13.3.updates = 0.13.7
-0.13.3.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.3
-## 0.13.2
+# 0.13.2
0.13.2.updates = 0.13.7
-0.13.2.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.2
-## 0.13.1
+# 0.13.1
0.13.1.updates = 0.13.7
-0.13.1.notices = We recommend upgrading to 0.13.7, our latest dev release.
-0.13.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.13.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.13.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.1
### 0.12.x series ###
-## 0.12.1
+# 0.12.1
0.12.1.updates =
-0.12.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.12.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.12.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.12.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.12.1
# 0.12.0
0.12.0.updates = 0.12.1
-0.12.0.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.12.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-### 0.11.x series ###
-
-## 0.11.13
-0.11.13.updates =
-0.11.13.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.13.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.12
-0.11.12.updates = 0.11.13
-0.11.12.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.12.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.11
-0.11.11.updates = 0.11.13
-0.11.11.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.11.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.10
-0.11.10.updates = 0.11.13
-0.11.10.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.10.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.9
-0.11.9.updates = 0.11.13
-0.11.9.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.9.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.8
-0.11.8.updates = 0.11.13
-0.11.8.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.8.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.7
-0.11.7.updates = 0.11.13
-0.11.7.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.7.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.6
-0.11.6.updates = 0.11.13
-0.11.6.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.6.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.5
-0.11.5.updates = 0.11.13
-0.11.5.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.5.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.4
-0.11.4.updates = 0.11.13
-0.11.4.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.4.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.3
-0.11.3.updates = 0.11.13
-0.11.3.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.3.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.2
-0.11.2.updates = 0.11.13
-0.11.2.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.2.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.1
-0.11.1.updates = 0.11.13
-0.11.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-### 0.10.x series ###
-
-## 0.10.2
-0.10.2.updates =
-0.10.2.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.10.2.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.10.1
-0.10.1.updates = 0.10.2
-0.10.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.10.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.10.0
-0.10.0.updates = 0.10.2
-0.10.0.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.10.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-### 0.9.x series ###
-
-## 0.9.2
-0.9.2.updates =
-0.9.2.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.9.2.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.9.1
-0.9.1.updates = 0.9.2
-0.9.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.9.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.9.0
-0.9.0.updates = 0.9.2
-0.9.0.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.9.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-### 0.8.x series ###
-
-## 0.8.13
-0.8.13.updates =
-0.8.13.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.13.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.12
-0.8.12.updates = 0.8.13
-0.8.12.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.12.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.11
-0.8.11.updates = 0.8.13
-0.8.11.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.11.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.10
-0.8.10.updates = 0.8.13
-0.8.10.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.10.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.9
-0.8.9.updates = 0.8.13
-0.8.9.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.9.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.8
-0.8.8.updates = 0.8.13
-0.8.8.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.8.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.7
-0.8.7.updates = 0.8.13
-0.8.7.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.7.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.6
-0.8.6.updates = 0.8.13
-0.8.6.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.6.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.5
-0.8.5.updates = 0.8.13
-0.8.5.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.5.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.4
-0.8.4.updates = 0.8.13
-0.8.4.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.4.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.3
-0.8.3.updates = 0.8.13
-0.8.3.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.3.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.2
-0.8.2.updates = 0.8.13
-0.8.2.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.2.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.1
-0.8.1.updates = 0.8.13
-0.8.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.8.0
-0.8.0.updates = 0.8.13
-0.8.0.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.8.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.12.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.12.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.12.0
diff --git a/profiles/killpay/src/main/resources/update-checker/killbill-server-update-list.properties b/profiles/killpay/src/main/resources/update-checker/killbill-server-update-list.properties
index f585321..182a482 100644
--- a/profiles/killpay/src/main/resources/update-checker/killbill-server-update-list.properties
+++ b/profiles/killpay/src/main/resources/update-checker/killbill-server-update-list.properties
@@ -1,105 +1,164 @@
## Top level keys
# general.notice = This notice should rarely, if ever, be used as everyone will see it
+### 0.17.x series ###
+
+# 0.17.0
+0.17.0.updates =
+0.17.0.notices = This is the latest dev release.
+0.17.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.17.0
+
+### 0.16.x series ###
+
+# 0.16.6
+0.16.6.updates =
+0.16.6.notices = This is the latest GA release.
+0.16.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.6
+
+# 0.16.5
+0.16.5.updates = 0.16.6
+0.16.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.5
+
+# 0.16.4
+0.16.4.updates = 0.16.6
+0.16.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.4
+
+# 0.16.3
+0.16.3.updates = 0.16.6
+0.16.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.3
+
+# 0.16.2
+0.16.2.updates = 0.16.6
+0.16.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.2
+
+# 0.16.1
+0.16.1.updates = 0.16.6
+0.16.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.1
+
+# 0.16.0
+0.16.0.updates = 0.16.6
+0.16.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.16.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.16.0
+
+### 0.15.x series ###
+
+# 0.15.10
+0.15.10.updates =
+0.15.10.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.10.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.10
+
+# 0.15.9
+0.15.9.updates = 0.15.10
+0.15.9.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.9.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.9
+
+# 0.15.8
+0.15.8.updates = 0.15.10
+0.15.8.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.8.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.8
+
+# 0.15.7
+0.15.7.updates = 0.15.10
+0.15.7.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.7.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.7
+
+# 0.15.6
+0.15.6.updates = 0.15.10
+0.15.6.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.6
+
+# 0.15.5
+0.15.5.updates = 0.15.10
+0.15.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.5
+
+# 0.15.4
+0.15.4.updates = 0.15.10
+0.15.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.4
+
+# 0.15.3
+0.15.3.updates = 0.15.10
+0.15.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.3
+
+# 0.15.2
+0.15.2.updates = 0.15.10
+0.15.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.2
+
+# 0.15.1
+0.15.1.updates = 0.15.10
+0.15.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.1
+
+# 0.15.0
+0.15.0.updates = 0.15.10
+0.15.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.15.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.15.0
+
### 0.14.x series ###
+# 0.14.1
+0.14.1.updates =
+0.14.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.14.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.14.1
+
# 0.14.0
-0.14.0.updates =
-0.14.0.notices = This is the latest GA release.
-0.14.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.14.0.updates = 0.14.1
+0.14.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.14.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.14.0
### 0.13.x series ###
-## 0.13.7 -- latest unstable release
+# 0.13.7
0.13.7.updates =
-0.13.7.notices = This is the latest dev release.
+0.13.7.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.7.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.7
-## 0.13.6
+# 0.13.6
0.13.6.updates = 0.13.7
-0.13.6.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.6.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.6.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.6
-## 0.13.5
+# 0.13.5
0.13.5.updates = 0.13.7
-0.13.5.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.5.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.5.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.5
-## 0.13.4
+# 0.13.4
0.13.4.updates = 0.13.7
-0.13.4.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.4.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.4.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.4
-## 0.13.3
+# 0.13.3
0.13.3.updates = 0.13.7
-0.13.3.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.3.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.3.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.3
-## 0.13.2
+# 0.13.2
0.13.2.updates = 0.13.7
-0.13.2.notices = We recommend upgrading to 0.13.7, our latest dev release.
+0.13.2.notices = We recommend upgrading to 0.16.6, our latest GA release.
0.13.2.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.2
-## 0.13.1
+# 0.13.1
0.13.1.updates = 0.13.7
-0.13.1.notices = We recommend upgrading to 0.13.7, our latest dev release.
-0.13.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.13.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.13.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.13.1
### 0.12.x series ###
-## 0.12.1
+# 0.12.1
0.12.1.updates =
-0.12.1.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.12.1.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.12.1.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.12.1.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.12.1
# 0.12.0
0.12.0.updates = 0.12.1
-0.12.0.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.12.0.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-### 0.11.x series ###
-
-## 0.11.13
-0.11.13.updates =
-0.11.13.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.13.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.12
-0.11.12.updates = 0.11.13
-0.11.12.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.12.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.11
-0.11.11.updates = 0.11.13
-0.11.11.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.11.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.10
-0.11.10.updates = 0.11.13
-0.11.10.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.10.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.9
-0.11.9.updates = 0.11.13
-0.11.9.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.9.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.8
-0.11.8.updates = 0.11.13
-0.11.8.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.8.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.7
-0.11.7.updates = 0.11.13
-0.11.7.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.7.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.6
-0.11.6.updates = 0.11.13
-0.11.6.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.6.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
-
-## 0.11.5
-0.11.5.updates = 0.11.13
-0.11.5.notices = We recommend upgrading to 0.14.0, our latest GA release.
-0.11.5.release-notes = https://github.com/killbill/killbill/blob/master/NEWS
+0.12.0.notices = We recommend upgrading to 0.16.6, our latest GA release.
+0.12.0.release-notes = https://github.com/killbill/killbill/releases/tag/killbill-0.12.0
diff --git a/util/src/main/java/org/killbill/billing/util/config/definition/JaxrsConfig.java b/util/src/main/java/org/killbill/billing/util/config/definition/JaxrsConfig.java
index a55cd88..95fe22d 100644
--- a/util/src/main/java/org/killbill/billing/util/config/definition/JaxrsConfig.java
+++ b/util/src/main/java/org/killbill/billing/util/config/definition/JaxrsConfig.java
@@ -35,7 +35,7 @@ public interface JaxrsConfig extends KillbillConfig {
TimeSpan getJaxrsTimeout();
@Config("org.killbill.jaxrs.location.full.url")
- @Default("false")
+ @Default("true")
@Description("Type of return for the jaxrs response location URL")
boolean isJaxrsLocationFullUrl();