killbill-aplcache
Changes
.DS_Store 0(+0 -0)
account/pom.xml 2(+1 -1)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java 62(+59 -3)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java 4(+2 -2)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java 4(+2 -2)
catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java 11(+6 -5)
catalog/src/main/java/org/killbill/billing/catalog/dao/PlanPhaseKeysCollectionBinder.java 57(+0 -57)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg 8(+3 -5)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg 6(+2 -4)
catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg 9(+3 -6)
entitlement/pom.xml 2(+1 -1)
entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg 17(+8 -9)
invoice/pom.xml 2(+1 -1)
invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java 4(+3 -1)
invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg 16(+8 -8)
invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg 32(+16 -16)
invoice/src/test/java/org/killbill/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java 4(+2 -2)
invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java 225(+225 -0)
invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java 31(+31 -0)
payment/src/main/java/org/killbill/billing/payment/core/PaymentPluginServiceRegistration.java 7(+5 -2)
payment/src/main/java/org/killbill/billing/payment/core/sm/control/DefaultControlCompleted.java 11(+8 -3)
payment/src/main/java/org/killbill/billing/payment/dao/TransactionStatusCollectionBinder.java 57(+0 -57)
payment/src/test/java/org/killbill/billing/payment/core/janitor/TestCompletionTaskBase.java 91(+91 -0)
payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java 14(+11 -3)
profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillBillEmbeddedDBProvider.java 1(+1 -0)
profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java 18(+9 -9)
profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentPluginProperties.java 26(+21 -5)
README.md 2(+1 -1)
subscription/pom.xml 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java 16(+8 -8)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java 10(+5 -5)
subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg 24(+12 -12)
subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg 28(+14 -14)
subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg 10(+5 -5)
tenant/pom.xml 2(+1 -1)
usage/pom.xml 2(+1 -1)
util/pom.xml 11(+10 -1)
util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java 145(+0 -145)
util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java 25(+21 -4)
util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java 4(+2 -2)
util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg 8(+4 -4)
util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg 2(+0 -2)
util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg 9(+3 -6)
util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg 8(+3 -5)
util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg 2(+0 -2)
Details
.DS_Store 0(+0 -0)
diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/.DS_Store differ
account/pom.xml 2(+1 -1)
diff --git a/account/pom.xml b/account/pom.xml
index 8f1eaa0..5c2e8e8 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -79,7 +79,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java b/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
index 80856ce..5108df8 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
import java.util.UUID;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -30,17 +30,17 @@ import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface AccountEmailSqlDao extends EntitySqlDao<AccountEmailModelDao, AccountEmail> {
@SqlUpdate
@Audited(ChangeType.DELETE)
- public void markEmailAsDeleted(@BindBean final AccountEmailModelDao accountEmail,
- @BindBean final InternalCallContext context);
+ public void markEmailAsDeleted(@SmartBindBean final AccountEmailModelDao accountEmail,
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
public List<AccountEmailModelDao> getEmailByAccountId(@Bind("accountId") final UUID accountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java b/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
index 77bea77..1506e64 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
@@ -27,44 +27,44 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface AccountSqlDao extends EntitySqlDao<AccountModelDao, Account> {
@SqlQuery
public AccountModelDao getAccountByKey(@Bind("externalKey") final String key,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public UUID getIdFromKey(@Bind("externalKey") final String key,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Integer getBCD(@Bind("id") String accountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
- public void update(@BindBean final AccountModelDao account,
- @BindBean final InternalCallContext context);
+ public void update(@SmartBindBean final AccountModelDao account,
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
public Object updatePaymentMethod(@Bind("id") String accountId,
@Bind("paymentMethodId") String paymentMethodId,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
List<AccountModelDao> getAccountsByParentId(@Bind("parentAccountId") UUID parentAccountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public AccountModelDao luckySearch(@Bind("searchKey") final String searchKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg b/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
index fa5d62b..e54ad7d 100644
--- a/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
+++ b/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group AccountEmailSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "account_emails"
diff --git a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
index 937b12f..c46855d 100644
--- a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group AccountSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "accounts"
@@ -64,7 +64,7 @@ tableValues() ::= <<
/** The accounts table doesn't have an account_record_id column (it's the record_id) **/
accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
update() ::= <<
update accounts set
@@ -91,7 +91,7 @@ update accounts set
, updated_date = :updatedDate
, updated_by = :updatedBy
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -101,19 +101,19 @@ updatePaymentMethod() ::= <<
SET payment_method_id = :paymentMethodId
, updated_date = :updatedDate
, updated_by = :updatedBy
- WHERE id = :id <AND_CHECK_TENANT()>;
+ WHERE id = :id <AND_CHECK_TENANT("")>;
>>
getAccountByKey() ::= <<
- select <allTableFields()>
+ select <allTableFields("")>
from accounts
- where external_key = :externalKey <AND_CHECK_TENANT()>;
+ where external_key = :externalKey <AND_CHECK_TENANT("")>;
>>
getBCD() ::= <<
select billing_cycle_day_local
from accounts
- where id = :id <AND_CHECK_TENANT()>;
+ where id = :id <AND_CHECK_TENANT("")>;
>>
searchQuery(prefix) ::= <<
@@ -130,50 +130,50 @@ select
<allTableFields("t.")>
from <tableName()> t
join (
- select distinct <recordIdField()>
+ select distinct <recordIdField("")>
from (
(
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
- where <idField()> = :searchKey
- <andCheckSoftDeletionWithComma()>
- <AND_CHECK_TENANT()>
+ where <idField("")> = :searchKey
+ <andCheckSoftDeletionWithComma("")>
+ <AND_CHECK_TENANT("")>
limit 1
)
union all
(
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
where name = :searchKey
- <andCheckSoftDeletionWithComma()>
- <AND_CHECK_TENANT()>
+ <andCheckSoftDeletionWithComma("")>
+ <AND_CHECK_TENANT("")>
limit 1
)
union all
(
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
where email = :searchKey
- <andCheckSoftDeletionWithComma()>
- <AND_CHECK_TENANT()>
+ <andCheckSoftDeletionWithComma("")>
+ <AND_CHECK_TENANT("")>
limit 1
)
union all
(
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
where external_key = :searchKey
- <andCheckSoftDeletionWithComma()>
- <AND_CHECK_TENANT()>
+ <andCheckSoftDeletionWithComma("")>
+ <AND_CHECK_TENANT("")>
limit 1
)
union all
(
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
where company_name = :searchKey
- <andCheckSoftDeletionWithComma()>
- <AND_CHECK_TENANT()>
+ <andCheckSoftDeletionWithComma("")>
+ <AND_CHECK_TENANT("")>
limit 1
)
) search_with_idx
@@ -185,14 +185,14 @@ limit 1
getIdFromKey() ::= <<
SELECT id
FROM accounts
- WHERE external_key = :externalKey <AND_CHECK_TENANT()>;
+ WHERE external_key = :externalKey <AND_CHECK_TENANT("")>;
>>
getAccountsByParentId() ::= <<
- select <allTableFields()>
+ select <allTableFields("")>
from accounts
where parent_account_id = :parentAccountId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
;
>>
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 06e6817..2969715 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -435,7 +435,6 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
.isNotifiedForInvoices(false)
.externalKey(UUID.randomUUID().toString().substring(1, 8))
.currency(Currency.USD)
- .paymentMethodId(UUID.randomUUID())
.timeZone(DateTimeZone.UTC);
if (billingDay != null) {
builder.billingCycleDayLocal(billingDay);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
index f5b74e6..7879aad 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -39,6 +39,7 @@ import org.killbill.billing.control.plugin.api.PriorPaymentControlResult;
import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PaymentOptions;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionType;
@@ -108,6 +109,54 @@ public class TestPaymentWithControl extends TestIntegrationBase {
}
@Test(groups = "slow")
+ public void testAuthSuccessWithPaymentControlNullPaymentMethodId() throws Exception {
+ final AccountData accountData = getAccountData(1);
+ final Account account = accountUserApi.createAccount(accountData, callContext);
+
+ // Add non-default payment method
+ final PaymentMethodPlugin info = createPaymentMethodPlugin();
+ final UUID paymentMethodId = paymentApi.addPaymentMethod(account, UUID.randomUUID().toString(), BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, false, info, PLUGIN_PROPERTIES, callContext);
+
+ testPaymentControlWithControl.setAdjustedPaymentMethodId(paymentMethodId);
+
+ busHandler.pushExpectedEvents(NextEvent.PAYMENT);
+ final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, null, null, BigDecimal.ONE, account.getCurrency(), null, null,
+ properties, paymentOptions, callContext);
+ assertListenerStatus();
+
+ final Payment paymentWithAttempts = paymentApi.getPayment(payment.getId(), false, true, ImmutableList.<PluginProperty>of(), callContext);
+ Assert.assertEquals(paymentWithAttempts.getPaymentMethodId(), paymentMethodId);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().size(), 1);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getPaymentMethodId(), paymentMethodId);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getStateName(), "SUCCESS");
+ }
+
+ @Test(groups = "slow")
+ public void testAuthFailureWithPaymentControlNullPaymentMethodId() throws Exception {
+ final AccountData accountData = getAccountData(1);
+ final Account account = accountUserApi.createAccount(accountData, callContext);
+
+ // Add non-default payment method
+ final PaymentMethodPlugin info = createPaymentMethodPlugin();
+ final UUID paymentMethodId = paymentApi.addPaymentMethod(account, UUID.randomUUID().toString(), BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, false, info, PLUGIN_PROPERTIES, callContext);
+
+ testPaymentControlWithControl.setAdjustedPaymentMethodId(paymentMethodId);
+
+ paymentPlugin.makeNextPaymentFailWithError();
+
+ busHandler.pushExpectedEvents(NextEvent.PAYMENT_ERROR);
+ final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, null, null, BigDecimal.ONE, account.getCurrency(), null, null,
+ properties, paymentOptions, callContext);
+ assertListenerStatus();
+
+ final Payment paymentWithAttempts = paymentApi.getPayment(payment.getId(), false, true, ImmutableList.<PluginProperty>of(), callContext);
+ Assert.assertEquals(paymentWithAttempts.getPaymentMethodId(), paymentMethodId);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().size(), 1);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getPaymentMethodId(), paymentMethodId);
+ Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getStateName(), "ABORTED");
+ }
+
+ @Test(groups = "slow")
public void testAuthCaptureWithPaymentControl() throws Exception {
final AccountData accountData = getAccountData(1);
@@ -184,6 +233,8 @@ public class TestPaymentWithControl extends TestIntegrationBase {
private final Map<String, Integer> calls;
+ private UUID adjustedPaymentMethodId = null;
+
public TestPaymentControlPluginApi() {
calls = new HashMap<String, Integer>();
}
@@ -194,6 +245,11 @@ public class TestPaymentWithControl extends TestIntegrationBase {
public void reset() {
calls.clear();
+ adjustedPaymentMethodId = null;
+ }
+
+ public void setAdjustedPaymentMethodId(final UUID adjustedPaymentMethodId) {
+ this.adjustedPaymentMethodId = adjustedPaymentMethodId;
}
@Override
@@ -213,7 +269,7 @@ public class TestPaymentWithControl extends TestIntegrationBase {
}
@Override
public UUID getAdjustedPaymentMethodId() {
- return null;
+ return adjustedPaymentMethodId;
}
@Override
public Iterable<PluginProperty> getAdjustedPluginProperties() {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
index 19164aa..ea1c2d1 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
@@ -22,7 +22,7 @@ import java.util.List;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -30,7 +30,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface CatalogOverridePhaseDefinitionSqlDao extends Transactional<CatalogOverridePhaseDefinitionSqlDao>, CloseMe {
@SqlUpdate
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
index 8570039..47ac60c 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
@@ -19,7 +19,7 @@ package org.killbill.billing.catalog.dao;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -27,7 +27,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface CatalogOverridePlanDefinitionSqlDao extends Transactional<CatalogOverridePlanDefinitionSqlDao>, CloseMe {
@SqlUpdate
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
index 3993ddf..ae7d936 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -21,15 +21,16 @@ import java.util.Collection;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface CatalogOverridePlanPhaseSqlDao extends Transactional<CatalogOverridePlanPhaseSqlDao>, CloseMe {
@SqlUpdate
@@ -41,7 +42,7 @@ public interface CatalogOverridePlanPhaseSqlDao extends Transactional<CatalogOve
@SmartBindBean final InternalTenantContext context);
@SqlQuery
- public Long getTargetPlanDefinition(@PlanPhaseKeysCollectionBinder final Collection<String> concatPhaseNumAndPhaseDefRecordId,
+ public Long getTargetPlanDefinition(@BindIn("keys") final Collection<String> concatPhaseNumAndPhaseDefRecordId,
@Bind("targetCount") final Integer targetCount,
@SmartBindBean final InternalTenantContext context);
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
index e51ae47..7e987c9 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group CatalogOverridePhaseDefinitionSqlDao;
-
tableName() ::= "catalog_override_phase_definition"
@@ -39,7 +37,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -48,7 +46,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where record_id = :recordId
and tenant_record_id = :tenantRecordId
@@ -56,7 +54,7 @@ and tenant_record_id = :tenantRecordId
>>
getByAttributes() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where parent_phase_name = :parentPhaseName
and currency = :currency
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
index 3024bc0..b9ae158 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group CatalogOverridePlanDefinitionSqlDao;
-
tableName() ::= "catalog_override_plan_definition"
tableFields(prefix) ::= <<
@@ -34,7 +32,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -43,7 +41,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where record_id = :recordId
and tenant_record_id = :tenantRecordId
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
index be35a86..ba61278 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
@@ -1,6 +1,3 @@
-group CatalogOverridePlanPhaseSqlDao;
-
-
tableName() ::= "catalog_override_plan_phase"
@@ -36,7 +33,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -45,7 +42,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from
<tableName()>
where record_id = :recordId
@@ -62,7 +59,7 @@ from (select
from
<tableName()>
where
- concat_ws(',', phase_number, phase_def_record_id) in (<keys: {key | :key_<i0>}; separator="," >)
+ concat_ws(',', phase_number, phase_def_record_id) in (<keys>)
and tenant_record_id = :tenantRecordId
group by target_plan_def_record_id) tmp
where
entitlement/pom.xml 2(+1 -1)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 4373590..06b81a7 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -75,7 +75,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
index 95024c3..344a645 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
@@ -28,33 +28,33 @@ import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface BlockingStateSqlDao extends EntitySqlDao<BlockingStateModelDao, BlockingState> {
@SqlQuery
public abstract BlockingStateModelDao getBlockingStateForService(@Bind("blockableId") UUID blockableId,
@Bind("service") String serviceName,
@Bind("effectiveDate") Date effectiveDate,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public abstract List<BlockingStateModelDao> getBlockingState(@Bind("blockableId") UUID blockableId,
@Bind("effectiveDate") Date effectiveDate,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public abstract List<BlockingStateModelDao> getBlockingHistoryForService(@Bind("blockableId") UUID blockableId,
@Bind("service") String serviceName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
public void unactiveEvent(@Bind("id") String id,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
}
diff --git a/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg b/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
index feeee40..9d78819 100644
--- a/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
+++ b/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
@@ -1,5 +1,4 @@
-group BlockingStateSqlDao: EntitySqlDao;
-
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "blocking_states"
@@ -45,14 +44,14 @@ tableValues() ::= <<
getBlockingStateForService() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from
<tableName()>
where blockable_id = :blockableId
and service = :service
and effective_date \<= :effectiveDate
and is_active
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
-- We want the current state, hence the order desc and limit 1
order by effective_date desc, record_id desc
limit 1
@@ -71,7 +70,7 @@ getBlockingState() ::= <<
where blockable_id = :blockableId
and effective_date \<= :effectiveDate
and is_active
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
group by service
) tmp
on t.record_id = tmp.record_id
@@ -81,14 +80,14 @@ getBlockingState() ::= <<
getBlockingHistoryForService() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from
<tableName()>
where blockable_id = :blockableId
and service = :service
and is_active
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
@@ -97,6 +96,6 @@ update
<tableName()>
set is_active = false
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
invoice/pom.xml 2(+1 -1)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index defab3b..85a0773 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -80,7 +80,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java b/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
index c7af0ef..88a88c3 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/calculator/InvoiceCalculatorUtils.java
@@ -69,13 +69,10 @@ public abstract class InvoiceCalculatorUtils {
InvoiceItemType.RECURRING.equals(invoiceItem.getInvoiceItemType());
}
- public static BigDecimal computeInvoiceBalance(final Currency currency,
- @Nullable final Iterable<InvoiceItem> invoiceItems,
- @Nullable final Iterable<InvoicePayment> invoicePayments,
- boolean writtenOffOrMigrated) {
- if (writtenOffOrMigrated) {
- return BigDecimal.ZERO;
- }
+ public static BigDecimal computeRawInvoiceBalance(final Currency currency,
+ @Nullable final Iterable<InvoiceItem> invoiceItems,
+ @Nullable final Iterable<InvoicePayment> invoicePayments) {
+
final BigDecimal amountPaid = computeInvoiceAmountPaid(currency, invoicePayments)
.add(computeInvoiceAmountRefunded(currency, invoicePayments));
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
index 48de156..162c204 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
@@ -64,7 +64,7 @@ public class CBADao {
if (balance.compareTo(BigDecimal.ZERO) < 0) {
// Current balance is negative, we need to generate a credit (positive CBA amount)
return buildCBAItem(invoice, balance, context);
- } else if (balance.compareTo(BigDecimal.ZERO) > 0 && invoice.getStatus() == InvoiceStatus.COMMITTED) {
+ } else if (balance.compareTo(BigDecimal.ZERO) > 0 && invoice.getStatus() == InvoiceStatus.COMMITTED && !invoice.isWrittenOff()) {
// Current balance is positive and the invoice is COMMITTED, we need to use some of the existing if available (negative CBA amount)
// PERF: in some codepaths, the CBA maybe have already been computed
BigDecimal accountCBA = accountCBAOrNull;
@@ -86,7 +86,7 @@ public class CBADao {
private BigDecimal getInvoiceBalance(final InvoiceModelDao invoice) {
final InvoiceModelDao parentInvoice = invoice.getParentInvoice();
- if ((parentInvoice != null) && (InvoiceModelDaoHelper.getBalance(parentInvoice).compareTo(BigDecimal.ZERO) == 0)) {
+ if ((parentInvoice != null) && (InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(parentInvoice).compareTo(BigDecimal.ZERO) == 0)) {
final Iterable<InvoiceItemModelDao> items = Iterables.filter(parentInvoice.getInvoiceItems(), new Predicate<InvoiceItemModelDao>() {
@Override
public boolean apply(@Nullable final InvoiceItemModelDao input) {
@@ -105,7 +105,7 @@ public class CBADao {
}
- return InvoiceModelDaoHelper.getBalance(invoice);
+ return InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice);
}
// We let the code below rehydrate the invoice before we can add the CBA item
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 0afa55c..bd35813 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -439,7 +439,21 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
BigDecimal accountBalance = BigDecimal.ZERO;
final List<InvoiceModelDao> invoices = invoiceDaoHelper.getAllInvoicesByAccountFromTransaction(invoicesTags, entitySqlDaoWrapperFactory, context);
for (final InvoiceModelDao cur : invoices) {
- accountBalance = accountBalance.add((new DefaultInvoice(cur)).getBalance());
+
+ // Skip DRAFT invoices
+ if (cur.getStatus().equals(InvoiceStatus.DRAFT)) {
+ continue;
+ }
+
+ final boolean hasZeroParentBalance =
+ cur.getParentInvoice() != null &&
+ (cur.getParentInvoice().isWrittenOff() ||
+ cur.getParentInvoice().getStatus() == InvoiceStatus.DRAFT ||
+ InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(cur.getParentInvoice()).compareTo(BigDecimal.ZERO) == 0);
+
+
+ // invoices that are WRITTEN_OFF or paid children invoices are excluded from balance computation but the cba summation needs to be included
+ accountBalance = cur.isWrittenOff() || hasZeroParentBalance ? BigDecimal.ZERO : accountBalance.add(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(cur));
cba = cba.add(InvoiceModelDaoHelper.getCBAAmount(cur));
}
return accountBalance.subtract(cba);
@@ -865,7 +879,10 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
// Retrieve the invoice and make sure it belongs to the right account
final InvoiceModelDao invoice = transactional.getById(invoiceId.toString(), context);
- if (invoice == null || !invoice.getAccountId().equals(accountId)) {
+ if (invoice == null ||
+ !invoice.getAccountId().equals(accountId) ||
+ invoice.isMigrated() ||
+ invoice.getStatus() == InvoiceStatus.DRAFT) {
throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
}
@@ -884,7 +901,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
// Verify the final invoice balance is not negative
invoiceDaoHelper.populateChildren(invoice, invoicesTags, entitySqlDaoWrapperFactory, context);
- if (InvoiceModelDaoHelper.getBalance(invoice).compareTo(BigDecimal.ZERO) < 0) {
+ if (InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).compareTo(BigDecimal.ZERO) < 0) {
throw new InvoiceApiException(ErrorCode.INVOICE_WOULD_BE_NEGATIVE);
}
@@ -1089,9 +1106,10 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
private void notifyBusOfInvoiceCreation(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InvoiceModelDao invoice, final InternalCallContext context) {
try {
- final BigDecimal balance = InvoiceModelDaoHelper.getBalance(invoice);
+ // This is called for a new COMMITTED invoice (which cannot be writtenOff as it does not exist yet, so rawBalance == balance)
+ final BigDecimal rawBalance = InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice);
final DefaultInvoiceCreationEvent event = new DefaultInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
- balance, invoice.getCurrency(),
+ rawBalance, invoice.getCurrency(),
context.getAccountRecordId(), context.getTenantRecordId(),
context.getUserToken());
eventBus.postFromTransaction(event, entitySqlDaoWrapperFactory.getHandle().getConnection());
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
index cfd92a1..ecebd92 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
@@ -175,9 +175,10 @@ public class InvoiceDaoHelper {
@Override
public boolean apply(final InvoiceModelDao in) {
final InvoiceModelDao invoice = (in.getParentInvoice() == null) ? in : in.getParentInvoice();
- final BigDecimal balance = InvoiceModelDaoHelper.getBalance(invoice);
+ final BigDecimal balance = InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice);
log.debug("Computed balance={} for invoice={}", balance, in);
- return InvoiceStatus.COMMITTED.equals(in.getStatus()) && (balance.compareTo(BigDecimal.ZERO) >= 1) &&
+ return InvoiceStatus.COMMITTED.equals(in.getStatus()) &&
+ (balance.compareTo(BigDecimal.ZERO) >= 1 && !in.isWrittenOff()) &&
(upToDate == null || in.getTargetDate() == null || !in.getTargetDate().isAfter(upToDate));
}
});
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
index 8c7ded7..7a864d9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
@@ -27,38 +27,38 @@ import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface InvoiceItemSqlDao extends EntitySqlDao<InvoiceItemModelDao, InvoiceItem> {
@SqlQuery
List<InvoiceItemModelDao> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoiceItemModelDao> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoiceItemModelDao> getAdjustedOrRepairedInvoiceItemsByLinkedId(@Bind("linkedItemId") final String linkedItemId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
void updateAmount(@Bind("id") String invoiceItemId,
@Bind("amount")BigDecimal amount,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
List<InvoiceItemModelDao> getInvoiceItemsByParentInvoice(@Bind("parentInvoiceId") final String parentInvoiceId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- BigDecimal getAccountCBA(@BindBean final InternalTenantContext context);
+ BigDecimal getAccountCBA(@SmartBindBean final InternalTenantContext context);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDaoHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDaoHelper.java
index a240128..877e741 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDaoHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceModelDaoHelper.java
@@ -18,8 +18,6 @@ package org.killbill.billing.invoice.dao;
import java.math.BigDecimal;
-import javax.annotation.Nullable;
-
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.calculator.InvoiceCalculatorUtils;
@@ -33,22 +31,25 @@ public class InvoiceModelDaoHelper {
private InvoiceModelDaoHelper() {}
- public static BigDecimal getBalance(final InvoiceModelDao invoiceModelDao) {
- return InvoiceCalculatorUtils.computeInvoiceBalance(invoiceModelDao.getCurrency(),
- Iterables.transform(invoiceModelDao.getInvoiceItems(), new Function<InvoiceItemModelDao, InvoiceItem>() {
- @Override
- public InvoiceItem apply(final InvoiceItemModelDao input) {
- return InvoiceItemFactory.fromModelDao(input);
- }
- }),
- Iterables.transform(invoiceModelDao.getInvoicePayments(), new Function<InvoicePaymentModelDao, InvoicePayment>() {
- @Nullable
- @Override
- public InvoicePayment apply(final InvoicePaymentModelDao input) {
- return new DefaultInvoicePayment(input);
- }
- }),
- invoiceModelDao.isMigrated() || invoiceModelDao.isWrittenOff());
+ public static BigDecimal getRawBalanceForRegularInvoice(final InvoiceModelDao invoiceModelDao) {
+
+ if (invoiceModelDao.isMigrated()) {
+ return BigDecimal.ZERO;
+ }
+
+ return InvoiceCalculatorUtils.computeRawInvoiceBalance(invoiceModelDao.getCurrency(),
+ Iterables.transform(invoiceModelDao.getInvoiceItems(), new Function<InvoiceItemModelDao, InvoiceItem>() {
+ @Override
+ public InvoiceItem apply(final InvoiceItemModelDao input) {
+ return InvoiceItemFactory.fromModelDao(input);
+ }
+ }),
+ Iterables.transform(invoiceModelDao.getInvoicePayments(), new Function<InvoicePaymentModelDao, InvoicePayment>() {
+ @Override
+ public InvoicePayment apply(final InvoicePaymentModelDao input) {
+ return new DefaultInvoicePayment(input);
+ }
+ }));
}
public static BigDecimal getCBAAmount(final InvoiceModelDao invoiceModelDao) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
index 2973f53..dbaa0a9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -19,27 +19,26 @@ package org.killbill.billing.invoice.dao;
import java.util.Collection;
import java.util.List;
-import java.util.UUID;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.invoice.api.InvoiceParentChild;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface InvoiceParentChildrenSqlDao extends EntitySqlDao<InvoiceParentChildModelDao, InvoiceParentChild> {
@SqlQuery
List<InvoiceParentChildModelDao> getChildInvoicesByParentInvoiceId(@Bind("parentInvoiceId") final String parentInvoiceId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- List<InvoiceParentChildModelDao> getParentChildMappingsByChildInvoiceIds(@UUIDCollectionBinder final Collection<String> childInvoiceIds,
- @BindBean final InternalTenantContext context);
+ List<InvoiceParentChildModelDao> getParentChildMappingsByChildInvoiceIds(@BindIn("ids") final Collection<String> childInvoiceIds,
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
index d763bd1..994eb58 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -27,47 +27,47 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePaymentModelDao, InvoicePayment> {
@SqlQuery
public List<InvoicePaymentModelDao> getByPaymentId(@Bind("paymentId") final String paymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<InvoicePaymentModelDao> getAllPaymentsForInvoiceIncludedInit(@Bind("invoiceId") final String invoiceId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoicePaymentModelDao> getInvoicePayments(@Bind("paymentId") final String paymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
InvoicePaymentModelDao getPaymentForCookieId(@Bind("paymentCookieId") final String paymentCookieId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
BigDecimal getRemainingAmountPaid(@Bind("invoicePaymentId") final String invoicePaymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
UUID getAccountIdFromInvoicePaymentId(@Bind("invoicePaymentId") final String invoicePaymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoicePaymentModelDao> getChargeBacksByAccountId(@Bind("accountId") final String accountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<InvoicePaymentModelDao> getChargebacksByPaymentId(@Bind("paymentId") final String paymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
void updateAttempt(@Bind("recordId") Long recordId,
@@ -79,5 +79,5 @@ public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePaymentModelDa
@Bind("paymentCookieId") final String paymentCookieId,
@Bind("linkedInvoicePaymentId") final String linkedInvoicePaymentId,
@Bind("success") final boolean success,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
index 9ed8f28..6d405b0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
@@ -28,36 +28,36 @@ import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
@SqlQuery
List<InvoiceModelDao> getInvoicesBySubscription(@Bind("subscriptionId") final String subscriptionId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
UUID getInvoiceIdByPaymentId(@Bind("paymentId") final String paymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
void updateStatus(@Bind("id") String invoiceId,
@Bind("status") String status,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
InvoiceModelDao getParentDraftInvoice(@Bind("accountId") final String parentAccountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- List<InvoiceModelDao> getByIds(@UUIDCollectionBinder final Collection<String> invoiceIds,
- @BindBean final InternalTenantContext context);
+ List<InvoiceModelDao> getByIds(@BindIn("ids") final Collection<String> invoiceIds,
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index a300bf1..d8fc889 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -861,7 +861,7 @@ public class InvoiceDispatcher {
if (parentInvoiceModelDao == null) {
throw new InvoiceApiException(ErrorCode.INVOICE_MISSING_PARENT_INVOICE, childInvoiceModelDao.getId());
- } else if (InvoiceModelDaoHelper.getBalance(parentInvoiceModelDao).compareTo(BigDecimal.ZERO) == 0) {
+ } else if (InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(parentInvoiceModelDao).compareTo(BigDecimal.ZERO) == 0) {
// ignore item adjustments for paid invoices.
return;
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
index c041450..0541c07 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
@@ -251,12 +251,17 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
@Override
public BigDecimal getBalance() {
- return getStatus().equals(InvoiceStatus.DRAFT) || hasZeroParentBalance() ?
- BigDecimal.ZERO :
- InvoiceCalculatorUtils.computeInvoiceBalance(currency, invoiceItems, payments, isWrittenOff() || isMigrationInvoice());
+ if (isWrittenOff() ||
+ isMigrationInvoice() ||
+ getStatus() == InvoiceStatus.DRAFT ||
+ hasZeroParentBalance()) {
+ return BigDecimal.ZERO;
+ } else {
+ return InvoiceCalculatorUtils.computeRawInvoiceBalance(currency, invoiceItems, payments);
+ }
}
- private boolean hasZeroParentBalance() {
+ public boolean hasZeroParentBalance() {
return (parentInvoice != null) && (parentInvoice.getBalance().compareTo(BigDecimal.ZERO) == 0);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
index c79db5c..26f5714 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
@@ -144,7 +144,9 @@ public class ContiguousIntervalUsageInArrear {
numberOfPeriod++;
nextBillCycleDate = bid.getFutureBillingDateFor(numberOfPeriod);
}
- if (closedInterval && endDate.isAfter(transitionTimes.get(transitionTimes.size() - 1))) {
+ if (closedInterval &&
+ transitionTimes.size() > 0 &&
+ endDate.isAfter(transitionTimes.get(transitionTimes.size() - 1))) {
transitionTimes.add(endDate);
}
isBuilt.set(true);
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index c99d95c..c7596b4 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceItemSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_items"
@@ -46,27 +46,27 @@ tableValues() ::= <<
getInvoiceItemsByInvoice() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE invoice_id = :invoiceId
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
;
>>
getInvoiceItemsBySubscription() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE subscription_id = :subscriptionId
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
;
>>
getAdjustedOrRepairedInvoiceItemsByLinkedId() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE linked_item_id = :linkedItemId
AND type IN ('ITEM_ADJ', 'REPAIR_ADJ')
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
;
>>
@@ -74,7 +74,7 @@ updateAmount() ::= <<
UPDATE <tableName()>
SET amount = :amount
WHERE id = :id
- <AND_CHECK_TENANT()>;
+ <AND_CHECK_TENANT("")>;
>>
getInvoiceItemsByParentInvoice() ::= <<
@@ -83,7 +83,7 @@ getInvoiceItemsByParentInvoice() ::= <<
INNER JOIN invoice_parent_children invRel ON invRel.child_invoice_id = items.invoice_id
WHERE invRel.parent_invoice_id = :parentInvoiceId
<AND_CHECK_TENANT("items.")>
- <defaultOrderBy()>
+ <defaultOrderBy("")>
;
>>
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
index 2a96b7a..93cd6e9 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceParentChildrenSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_parent_children"
@@ -29,17 +29,17 @@ allTableValues() ::= <<
>>
getChildInvoicesByParentInvoiceId() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE parent_invoice_id = :parentInvoiceId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
>>
getParentChildMappingsByChildInvoiceIds(ids) ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
- WHERE child_invoice_id in (<ids: {id | :id_<i0>}; separator="," >)
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ WHERE child_invoice_id in (<ids>)
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
>>
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 7fb6bb6..140ff05 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoicePayment: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoice_payments"
@@ -45,41 +45,41 @@ AND payment_id IS NOT NULL
>>
getByPaymentId() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE payment_id = :paymentId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
;
>>
getPaymentForCookieId() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE payment_cookie_id = :paymentCookieId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
LIMIT 1
;
>>
getAllPaymentsForInvoiceIncludedInit() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE invoice_id = :invoiceId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
;
>>
getInvoicePayments() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE payment_id = :paymentId
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
;
>>
@@ -88,7 +88,7 @@ getRemainingAmountPaid() ::= <<
FROM <tableName()>
WHERE (id = :invoicePaymentId OR linked_invoice_payment_id = :invoicePaymentId)
AND success
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
;
>>
@@ -114,12 +114,12 @@ getChargeBacksByAccountId() ::= <<
>>
getChargebacksByPaymentId() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE type = 'CHARGED_BACK'
AND linked_invoice_payment_id IN (SELECT id FROM invoice_payments WHERE payment_id = :paymentId)
AND success
- <AND_CHECK_TENANT()>
+ <AND_CHECK_TENANT("")>
;
>>
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 812767f..ab962d9 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "invoices"
@@ -59,23 +59,23 @@ updateStatus() ::= <<
UPDATE <tableName()>
SET status = :status
WHERE id = :id
- <AND_CHECK_TENANT()>;
+ <AND_CHECK_TENANT("")>;
>>
getParentDraftInvoice() ::= <<
- SELECT <allTableFields()>
+ SELECT <allTableFields("")>
FROM <tableName()>
WHERE account_id = :accountId
AND status = 'DRAFT'
- <AND_CHECK_TENANT()>
- <defaultOrderBy()>
+ <AND_CHECK_TENANT("")>
+ <defaultOrderBy("")>
>>
getByIds(ids) ::= <<
select
<allTableFields("t.")>
from <tableName()> t
-where <idField("t.")> in (<ids: {id | :id_<i0>}; separator="," >)
+where <idField("t.")> in (<ids>)
<AND_CHECK_TENANT("t.")>
;
>>
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index f5849cd..4447c42 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -81,7 +81,7 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceTestSuiteWithEmbedded
Assert.assertEquals(invoice.getInvoiceItems().size(), 1);
Assert.assertEquals(invoice.getInvoiceItems().get(0).getAmount().compareTo(MIGRATION_INVOICE_AMOUNT), 0);
Assert.assertEquals(invoice.getInvoiceItems().get(0).getType(), InvoiceItemType.RECURRING);
- Assert.assertEquals(InvoiceModelDaoHelper.getBalance(invoice).compareTo(BigDecimal.ZERO), 0);
+ Assert.assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).compareTo(BigDecimal.ZERO), 0);
Assert.assertEquals(invoice.getCurrency(), MIGRATION_INVOICE_CURRENCY);
Assert.assertTrue(invoice.isMigrated());
@@ -108,7 +108,7 @@ public class TestDefaultInvoiceMigrationApi extends InvoiceTestSuiteWithEmbedded
public void testBalance() throws InvoiceApiException {
final InvoiceModelDao migrationInvoice = invoiceDao.getById(migrationInvoiceId, internalCallContext);
final InvoiceModelDao regularInvoice = invoiceDao.getById(regularInvoiceId, internalCallContext);
- final BigDecimal balanceOfAllInvoices = InvoiceModelDaoHelper.getBalance(migrationInvoice).add(InvoiceModelDaoHelper.getBalance(regularInvoice));
+ final BigDecimal balanceOfAllInvoices = InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(migrationInvoice).add(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(regularInvoice));
final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, callContext);
Assert.assertEquals(accountBalance.compareTo(balanceOfAllInvoices), 0);
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 f83ab5f..daabe13 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
@@ -364,6 +364,10 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
Assert.assertEquals(creditInvoice.getStatus(), InvoiceStatus.DRAFT);
Assert.assertEquals(creditInvoiceItem.getInvoiceId(), creditInvoice.getId());
+ // Verify DRAFT invoice is not taken into consideration when computing accountBalance
+ final BigDecimal accountBalance2 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ Assert.assertEquals(accountBalance2, accountBalance);
+
// move invoice from DRAFT to COMMITTED
invoiceUserApi.commitInvoice(creditInvoice.getId(), callContext);
creditInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java
new file mode 100644
index 0000000..6a8795f
--- /dev/null
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.invoice.api.user;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.invoice.InvoiceTestSuiteWithEmbeddedDB;
+import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.invoice.api.InvoiceItem;
+import org.killbill.billing.invoice.api.InvoiceStatus;
+import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
+import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
+import org.killbill.billing.util.tag.ControlTagType;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestInvoiceFlagBehaviors extends InvoiceTestSuiteWithEmbeddedDB {
+
+ private UUID accountId;
+
+ @Override
+ @BeforeMethod(groups = "slow")
+ public void beforeMethod() throws Exception {
+ super.beforeMethod();
+ final Account account = invoiceUtil.createAccount(callContext);
+ accountId = account.getId();
+ }
+
+ @Test(groups = "slow", description = "Verify invoice/account balance with a WRITTEN_OFF invoice. Verify account credit is not used against such invoice")
+ public void testWrittenOffInvoiceBeforeAccountCredit() throws Exception {
+
+ // Create new invoice with one charge and expect account credit to be used
+ final List<InvoiceItem> items = invoiceUserApi.insertExternalCharges(accountId, null, ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, BigDecimal.TEN, accountCurrency)), true, callContext);
+ assertEquals(items.size(), 1);
+
+ // Check both invoice and account balance is 10.00
+ final UUID invoiceId = items.get(0).getInvoiceId();
+
+ final Invoice invoice0 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice0.getBalance().compareTo(BigDecimal.TEN), 0);
+ final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance0.compareTo(BigDecimal.TEN), 0);
+
+ final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA0.compareTo(BigDecimal.ZERO), 0);
+
+ // Tag invoice with WRITTEN_OFF and expect balance to now show as Zero
+ tagUserApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext);
+
+ // Check both invoice and account balance is NOW 0
+ final Invoice invoice1 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice1.getBalance().compareTo(BigDecimal.ZERO), 0);
+
+ final BigDecimal accountBalance1 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance1.compareTo(BigDecimal.ZERO), 0);
+
+ final BigDecimal accountCBA1 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA1.compareTo(BigDecimal.ZERO), 0);
+
+ // Add credit on the account
+ invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+
+ final Invoice invoice2 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice2.getBalance().compareTo(BigDecimal.ZERO), 0);
+ assertEquals(invoice2.getInvoiceItems().size(), 1);
+
+ final BigDecimal accountBalance2 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance2.compareTo(new BigDecimal("-10.00")), 0);
+
+ final BigDecimal accountCBA2 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA2.compareTo(BigDecimal.TEN), 0);
+
+
+ }
+
+ @Test(groups = "slow", description = "Verify invoice/account balance with a WRITTEN_OFF invoice. Verify behavior when WRITTEN_OFF tag is added after credit was added to invoice" )
+ public void testWrittenOffInvoiceWithAccountCredit() throws Exception {
+
+ // Add credit on the account
+ invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+
+ final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0);
+
+ final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA0.compareTo(BigDecimal.TEN), 0);
+
+ // Create new invoice with one charge and expect account credit to be used
+ final List<InvoiceItem> items = invoiceUserApi.insertExternalCharges(accountId, null, ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, new BigDecimal("13.5"), accountCurrency)), true, callContext);
+ assertEquals(items.size(), 1);
+
+ final BigDecimal accountBalance1 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance1.compareTo(new BigDecimal("3.5")), 0);
+
+ final BigDecimal accountCBA1 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA1.compareTo(BigDecimal.ZERO), 0);
+
+ // Tag invoice with WRITTEN_OFF and expect balance to now show as Zero
+ tagUserApi.addTag(items.get(0).getInvoiceId(), ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext);
+
+ final BigDecimal accountBalance2 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance2.compareTo(BigDecimal.ZERO), 0);
+
+ final BigDecimal accountCBA2 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA2.compareTo(BigDecimal.ZERO), 0);
+ }
+
+ @Test(groups = "slow", description = "Verify invoice/account balance with a WRITTEN_OFF invoice. Verify account credit is not added to a previously WRITTEN_OFF invoice." )
+ public void testWrittenOffInvoiceWithAccountCredit2() throws Exception {
+
+ // Add credit on the account
+ invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+
+ final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0);
+
+ final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA0.compareTo(BigDecimal.TEN), 0);
+
+ // Create new invoice with one charge and expect account credit to be used
+ final List<InvoiceItem> items = invoiceUserApi.insertExternalCharges(accountId, null, ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, new BigDecimal("4.0"), accountCurrency)), true, callContext);
+ assertEquals(items.size(), 1);
+
+ // Tag invoice with WRITTEN_OFF
+ final UUID invoiceId = items.get(0).getInvoiceId();
+ tagUserApi.addTag(invoiceId, ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext);
+
+ // Add another charge on the **same invoice** => Because it is WRITTEN_OFF, we expect the CBA logic to not apply any credit
+ final List<InvoiceItem> items2 = invoiceUserApi.insertExternalCharges(accountId, null, ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), invoiceId, accountId, null, null, null, new BigDecimal("10.0"), accountCurrency)), true, callContext);
+ assertEquals(items2.size(), 1);
+
+ final BigDecimal accountBalance2 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance2.compareTo(new BigDecimal("-6.00")), 0);
+
+ final BigDecimal accountCBA2 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA2.compareTo(new BigDecimal("6.00")), 0);
+ }
+
+
+ @Test(groups = "slow", description = "Verify invoice/account balance with migrated invoice. Verify account credit is not consumed and that invoice/account balance does not take into account migrated invoice.")
+ public void testMigratedInvoiceWithAccountCredit() throws Exception {
+
+ // Add credit on the account
+ invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+
+ final UUID invoiceId = invoiceUserApi.createMigrationInvoice(accountId, null, ImmutableList.<InvoiceItem>of(new FixedPriceInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, "foo", "bar", null, null, BigDecimal.ONE, accountCurrency)), callContext);
+
+ final Invoice invoice1 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice1.getBalance().compareTo(BigDecimal.ZERO), 0);
+
+ // Verify credit is **not applied** against migration invoice
+ final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0);
+
+ final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA0.compareTo(BigDecimal.TEN), 0);
+
+ }
+
+ @Test(groups = "slow", description = "Verify invoice/account balance with DRAFT invoice. Verify that invoice/account balance are ZERO in DRAFT mode but becomes visible after it hasa been COMMITTED." )
+ public void testDraftInvoiceWithAccountCredit() throws Exception {
+
+ // Add credit on the account
+ invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+
+ // Create new invoice with one charge and expect account credit to be used
+ final List<InvoiceItem> items = invoiceUserApi.insertExternalCharges(accountId, null, ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, new BigDecimal("4.0"), accountCurrency)), false, callContext);
+ assertEquals(items.size(), 1);
+
+ final UUID invoiceId = items.get(0).getInvoiceId();
+
+ final Invoice invoice1 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice1.getStatus(), InvoiceStatus.DRAFT);
+
+ // Verify CBA was *NOT* applied against DRAFT invoice
+ assertEquals(invoice1.getInvoiceItems().size(), 1);
+ // And balance is ZERO because DRAFT mode
+ assertEquals(invoice1.getBalance().compareTo(BigDecimal.ZERO), 0);
+
+ // Verify credit is not applied against migration invoice
+ final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0);
+
+ final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA0.compareTo(BigDecimal.TEN), 0);
+
+ invoiceUserApi.commitInvoice(invoiceId, callContext);
+
+ final Invoice invoice2 = invoiceUserApi.getInvoice(invoiceId, callContext);
+ assertEquals(invoice2.getStatus(), InvoiceStatus.COMMITTED);
+
+ // Verify this time credit was applied against COMMITTED invoice
+ assertEquals(invoice2.getBalance().compareTo(BigDecimal.ZERO), 0);
+
+ final BigDecimal accountBalance1 = invoiceUserApi.getAccountBalance(accountId, callContext);
+ assertEquals(accountBalance1.compareTo(new BigDecimal("-6.0")), 0);
+
+ final BigDecimal accountCBA1 = invoiceUserApi.getAccountCBA(accountId, callContext);
+ assertEquals(accountCBA1.compareTo(new BigDecimal("6.0")), 0);
+ }
+
+}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
index 8ddb1f2..0e1ea27 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
@@ -68,7 +68,7 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
}
try {
eventBus.post(new DefaultInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
- InvoiceModelDaoHelper.getBalance(invoice), invoice.getCurrency(),
+ InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice), invoice.getCurrency(),
context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()));
} catch (final PersistentBus.EventBusException ex) {
throw new RuntimeException(ex);
@@ -260,7 +260,7 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
for (final InvoiceModelDao invoice : getAll(context)) {
if (accountId.equals(invoice.getAccountId())) {
- balance = balance.add(InvoiceModelDaoHelper.getBalance(invoice));
+ balance = balance.add(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice));
}
}
@@ -272,7 +272,7 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice,
final List<InvoiceModelDao> unpaidInvoices = new ArrayList<InvoiceModelDao>();
for (final InvoiceModelDao invoice : getAll(context)) {
- if (accountId.equals(invoice.getAccountId()) && (InvoiceModelDaoHelper.getBalance(invoice).compareTo(BigDecimal.ZERO) > 0) && !invoice.isMigrated()) {
+ if (accountId.equals(invoice.getAccountId()) && (InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).compareTo(BigDecimal.ZERO) > 0) && !invoice.isMigrated()) {
unpaidInvoices.add(invoice);
}
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index 1cb8bbf..9d7199a 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -127,7 +127,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
assertTrue(thisInvoice.getInvoiceDate().compareTo(invoiceDate) == 0);
assertEquals(thisInvoice.getCurrency(), Currency.USD);
assertEquals(thisInvoice.getInvoiceItems().size(), 0);
- assertTrue(InvoiceModelDaoHelper.getBalance(thisInvoice).compareTo(BigDecimal.ZERO) == 0);
+ assertTrue(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(thisInvoice).compareTo(BigDecimal.ZERO) == 0);
}
@Test(groups = "slow")
@@ -147,7 +147,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
final InvoiceModelDao savedInvoice = invoiceDao.getById(invoiceId, context);
assertNotNull(savedInvoice);
- assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice).compareTo(new BigDecimal("21.00")), 0);
+ assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(savedInvoice).compareTo(new BigDecimal("21.00")), 0);
assertEquals(savedInvoice.getInvoiceItems().size(), 1);
final BigDecimal paymentAmount = new BigDecimal("11.00");
@@ -159,7 +159,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
final InvoiceModelDao retrievedInvoice = invoiceDao.getById(invoiceId, context);
assertNotNull(retrievedInvoice);
assertEquals(retrievedInvoice.getInvoiceItems().size(), 1);
- assertEquals(InvoiceModelDaoHelper.getBalance(retrievedInvoice).compareTo(new BigDecimal("10.00")), 0);
+ assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(retrievedInvoice).compareTo(new BigDecimal("10.00")), 0);
}
@Test(groups = "slow")
@@ -668,16 +668,16 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
endDate, amount, amount, Currency.USD);
invoiceUtil.createInvoiceItem(item2, context);
- BigDecimal balancePriorRefund = invoiceDao.getAccountBalance(accountId, context);
- assertEquals(balancePriorRefund.compareTo(new BigDecimal("20.00")), 0);
+ BigDecimal accountBalance = invoiceDao.getAccountBalance(accountId, context);
+ assertEquals(accountBalance.compareTo(new BigDecimal("20.00")), 0);
// Pay the whole thing
final UUID paymentId = UUID.randomUUID();
final BigDecimal payment1 = amount;
final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice.getId(), new DateTime(), payment1, Currency.USD, Currency.USD, null, true);
invoiceUtil.createPayment(payment, context);
- balancePriorRefund = invoiceDao.getAccountBalance(accountId, context);
- assertEquals(balancePriorRefund.compareTo(new BigDecimal("0.00")), 0);
+ accountBalance = invoiceDao.getAccountBalance(accountId, context);
+ assertEquals(accountBalance.compareTo(new BigDecimal("0.00")), 0);
// Repair the item (And add CBA item that should be generated)
final InvoiceItem repairItem = new RepairAdjInvoiceItem(invoice.getId(), accountId, startDate, endDate, amount.negate(), Currency.USD, item2.getId());
@@ -691,13 +691,13 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
itemAdjustment.put(item2.getId(), null);
invoiceDao.createRefund(paymentId, refundAmount, true, itemAdjustment, UUID.randomUUID().toString(), context);
- balancePriorRefund = invoiceDao.getAccountBalance(accountId, context);
+ accountBalance = invoiceDao.getAccountBalance(accountId, context);
final boolean partialRefund = refundAmount.compareTo(amount) < 0;
final BigDecimal cba = invoiceDao.getAccountCBA(accountId, context);
final InvoiceModelDao savedInvoice = invoiceDao.getById(invoice.getId(), context);
- final BigDecimal expectedCba = balancePriorRefund.compareTo(BigDecimal.ZERO) < 0 ? balancePriorRefund.negate() : BigDecimal.ZERO;
+ final BigDecimal expectedCba = accountBalance.compareTo(BigDecimal.ZERO) < 0 ? accountBalance.negate() : BigDecimal.ZERO;
assertEquals(cba.compareTo(expectedCba), 0);
// Let's re-calculate them from invoice
@@ -706,12 +706,12 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
if (partialRefund) {
// IB = 20 (rec) - 20 (repair) + 20 (cba) - (20 -7) = 7; AB = IB - CBA = 7 - 20 = -13
- assertEquals(balancePriorRefund.compareTo(new BigDecimal("-13.0")), 0);
+ assertEquals(accountBalance.compareTo(new BigDecimal("-13.0")), 0);
assertEquals(savedInvoice.getInvoiceItems().size(), 4);
assertEquals(balanceAfterRefund.compareTo(new BigDecimal("-13.0")), 0);
assertEquals(cbaAfterRefund.compareTo(expectedCba), 0);
} else {
- assertEquals(balancePriorRefund.compareTo(new BigDecimal("0.0")), 0);
+ assertEquals(accountBalance.compareTo(new BigDecimal("0.0")), 0);
assertEquals(savedInvoice.getInvoiceItems().size(), 4);
assertEquals(balanceAfterRefund.compareTo(BigDecimal.ZERO), 0);
assertEquals(cbaAfterRefund.compareTo(expectedCba), 0);
@@ -983,7 +983,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
assertEquals(invoices.size(), 1);
final InvoiceModelDao invoice = invoices.get(0);
- assertTrue(InvoiceModelDaoHelper.getBalance(invoice).compareTo(BigDecimal.ZERO) == 0);
+ assertTrue(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).compareTo(BigDecimal.ZERO) == 0);
final List<InvoiceItemModelDao> invoiceItems = invoice.getInvoiceItems();
assertEquals(invoiceItems.size(), 2);
boolean foundCredit = false;
@@ -1058,7 +1058,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
assertEquals(invoices.size(), 1);
final InvoiceModelDao invoice = invoices.get(0);
- assertTrue(InvoiceModelDaoHelper.getBalance(invoice).compareTo(expectedBalance) == 0);
+ assertTrue(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).compareTo(expectedBalance) == 0);
final List<InvoiceItemModelDao> invoiceItems = invoice.getInvoiceItems();
assertEquals(invoiceItems.size(), expectCBA ? 3 : 2);
boolean foundCredit = false;
@@ -1236,10 +1236,10 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
invoiceUtil.createInvoice(invoice2, context);
final InvoiceModelDao savedInvoice1 = invoiceDao.getById(invoice1.getId(), context);
- assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice1), KillBillMoney.of(TEN, savedInvoice1.getCurrency()));
+ assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(savedInvoice1), KillBillMoney.of(TEN, savedInvoice1.getCurrency()));
final InvoiceModelDao savedInvoice2 = invoiceDao.getById(invoice2.getId(), context);
- assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice2), KillBillMoney.of(FIVE, savedInvoice2.getCurrency()));
+ assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(savedInvoice2), KillBillMoney.of(FIVE, savedInvoice2.getCurrency()));
}
@Test(groups = "slow")
@@ -1388,7 +1388,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
assertNotNull(savedInvoice);
assertEquals(savedInvoice.getInvoiceItems().size(), 2);
- assertEquals(InvoiceModelDaoHelper.getBalance(savedInvoice).compareTo(cheapAmount), 0);
+ assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(savedInvoice).compareTo(cheapAmount), 0);
}
@Test(groups = "slow")
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
index dc90d85..e1df2df 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
@@ -316,7 +316,7 @@ public class TestInvoiceHelper {
public void verifyInvoice(final UUID invoiceId, final double balance, final double cbaAmount, final InternalTenantContext context) throws InvoiceApiException {
final InvoiceModelDao invoice = invoiceDao.getById(invoiceId, context);
- Assert.assertEquals(InvoiceModelDaoHelper.getBalance(invoice).doubleValue(), balance);
+ Assert.assertEquals(InvoiceModelDaoHelper.getRawBalanceForRegularInvoice(invoice).doubleValue(), balance);
Assert.assertEquals(InvoiceModelDaoHelper.getCBAAmount(invoice).doubleValue(), cbaAmount);
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
index 5614cc0..96e06b7 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
@@ -322,4 +322,35 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
Assert.assertEquals(rolledUpUsage.get(1).getRolledUpUnits().get(1).getAmount(), new Long(21L));
}
+
+
+ @Test(groups = "fast", description="See https://github.com/killbill/killbill/issues/706")
+ public void testWithRawUsageStartDateAfterEndDate() throws CatalogApiException {
+
+ final LocalDate startDate = new LocalDate(2014, 10, 16);
+ final LocalDate endDate = startDate;
+ final LocalDate targetDate = endDate;
+
+ final LocalDate rawUsageStartDate = new LocalDate(2015, 10, 16);
+
+ final List<RawUsage> rawUsages = new ArrayList<RawUsage>();
+ rawUsages.add(new DefaultRawUsage(subscriptionId, startDate, "unit", 130L));
+
+ final DefaultTieredBlock block = createDefaultTieredBlock("unit", 100, 10, BigDecimal.ONE);
+ final DefaultTier tier = createDefaultTierWithBlocks(block);
+ final DefaultUsage usage = createConsumableInArrearUsage(usageName, BillingPeriod.MONTHLY, TierBlockPolicy.ALL_TIERS, tier);
+
+
+ final BillingEvent event1 = createMockBillingEvent(startDate.toDateTimeAtStartOfDay(DateTimeZone.UTC),BillingPeriod.MONTHLY, Collections.<Usage>emptyList());
+ final BillingEvent event2 = createMockBillingEvent(new LocalDate(2014, 10, 16).toDateTimeAtStartOfDay(DateTimeZone.UTC), BillingPeriod.MONTHLY, Collections.<Usage>emptyList());
+
+
+ final ContiguousIntervalUsageInArrear intervalConsumableInArrear = new ContiguousIntervalUsageInArrear(usage, accountId, invoiceId, rawUsages, targetDate, rawUsageStartDate, internalCallContext);
+ intervalConsumableInArrear.addBillingEvent(event1);
+ intervalConsumableInArrear.addBillingEvent(event2);
+
+ final ContiguousIntervalUsageInArrear res = intervalConsumableInArrear.build(true);
+ assertEquals(res.getTransitionTimes().size(), 0);
+ }
+
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
index f8150da..17763cf 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentAttemptJson.java
@@ -1,5 +1,6 @@
/*
- * Copyright 2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -85,13 +86,14 @@ public class PaymentAttemptJson extends JsonBase {
public PaymentAttemptJson(final PaymentAttempt paymentAttempt, final String paymentExternalKey, @Nullable final List<AuditLog> attemptsLogs) {
this(paymentAttempt.getAccountId().toString(),
- paymentAttempt.getPaymentMethodId().toString(),
+ // Could be null if aborted in the priorCall
+ paymentAttempt.getPaymentMethodId() != null ? paymentAttempt.getPaymentMethodId().toString() : null,
paymentExternalKey,
paymentAttempt.getTransactionId() != null ? paymentAttempt.getTransactionId().toString() : null,
paymentAttempt.getTransactionExternalKey(),
paymentAttempt.getTransactionType().toString(),
paymentAttempt.getEffectiveDate(),
- paymentAttempt.getStateName() != null ? paymentAttempt.getStateName() : null,
+ paymentAttempt.getStateName(),
paymentAttempt.getAmount(),
paymentAttempt.getCurrency() != null ? paymentAttempt.getCurrency().toString() : null,
paymentAttempt.getPluginName(),
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
index f65431f..8afb59e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/SubscriptionJson.java
@@ -98,7 +98,7 @@ public class SubscriptionJson extends JsonBase {
@JsonCreator
public EventSubscriptionJson(@JsonProperty("eventId") final String eventId,
@JsonProperty("billingPeriod") final String billingPeriod,
- @JsonProperty("effectiveDt") final LocalDate effectiveDate,
+ @JsonProperty("effectiveDate") final LocalDate effectiveDate,
@JsonProperty("plan") final String plan,
@JsonProperty("product") final String product,
@JsonProperty("priceList") final String priceList,
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 add62fe..c5c98e8 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
@@ -422,7 +422,9 @@ public class PaymentResource extends ComboPaymentResource {
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginPropertiesFromBody = extractPluginProperties(json.getProperties());
+ final Iterable<PluginProperty> pluginPropertiesFromQuery = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
@@ -500,8 +502,11 @@ public class PaymentResource extends ComboPaymentResource {
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginPropertiesFromBody = extractPluginProperties(json.getProperties());
+ final Iterable<PluginProperty> pluginPropertiesFromQuery = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
+
final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
@@ -573,8 +578,11 @@ public class PaymentResource extends ComboPaymentResource {
final String comment,
final UriInfo uriInfo,
final HttpServletRequest request) throws PaymentApiException, AccountApiException {
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginPropertiesFromBody = extractPluginProperties(json != null ? json.getProperties() : null);
+ final Iterable<PluginProperty> pluginPropertiesFromQuery = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
+
final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
@@ -649,8 +657,11 @@ public class PaymentResource extends ComboPaymentResource {
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginPropertiesFromBody = extractPluginProperties(json.getProperties());
+ final Iterable<PluginProperty> pluginPropertiesFromQuery = extractPluginProperties(pluginPropertiesString);
+ final Iterable<PluginProperty> pluginProperties = Iterables.concat(pluginPropertiesFromQuery, pluginPropertiesFromBody);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
+
final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
index 409c770..29893e5 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
@@ -18,6 +18,7 @@
package org.killbill.billing.payment.core.janitor;
import java.io.IOException;
+import java.util.Iterator;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
@@ -86,16 +87,25 @@ abstract class CompletionTaskBase<T> implements Runnable {
log.info("Janitor was requested to stop");
return;
}
- final Iterable<T> items = getItemsForIteration();
- for (final T item : items) {
- if (isStopped) {
- log.info("Janitor was requested to stop");
- return;
+
+ final Iterator<T> iterator = getItemsForIteration().iterator();
+ try {
+ while (iterator.hasNext()) {
+ final T item = iterator.next();
+ if (isStopped) {
+ log.info("Janitor was requested to stop");
+ return;
+ }
+ try {
+ doIteration(item);
+ } catch (final Exception e) {
+ log.warn(e.getMessage());
+ }
}
- try {
- doIteration(item);
- } catch (final IllegalStateException e) {
- log.warn(e.getMessage());
+ } finally {
+ // In case the loop stops early, make sure to close the underlying DB connection
+ while (iterator.hasNext()) {
+ iterator.next();
}
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentPluginServiceRegistration.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentPluginServiceRegistration.java
index 016be05..f64e772 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentPluginServiceRegistration.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentPluginServiceRegistration.java
@@ -20,6 +20,7 @@ package org.killbill.billing.payment.core;
import java.util.Set;
import java.util.UUID;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.killbill.billing.ErrorCode;
@@ -45,9 +46,11 @@ public class PaymentPluginServiceRegistration {
return pluginRegistry.getAllServices();
}
- public PaymentMethodModelDao getPaymentMethodById(final UUID paymentMethodId, final boolean includedDeleted, final InternalTenantContext context) throws PaymentApiException {
+ public PaymentMethodModelDao getPaymentMethodById(@Nullable final UUID paymentMethodId, final boolean includedDeleted, final InternalTenantContext context) throws PaymentApiException {
final PaymentMethodModelDao paymentMethodModel;
- if (includedDeleted) {
+ if (paymentMethodId == null) {
+ paymentMethodModel = null;
+ } else if (includedDeleted) {
paymentMethodModel = paymentDao.getPaymentMethodIncludedDeleted(paymentMethodId, context);
} else {
paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId, context);
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/DefaultControlCompleted.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/DefaultControlCompleted.java
index 0d3f97f..4f67980 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/DefaultControlCompleted.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/DefaultControlCompleted.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -62,7 +62,12 @@ public class DefaultControlCompleted implements EnteringStateCallback {
null;
// At this stage we can update the paymentAttempt state AND serialize the plugin properties. Control plugins will have had the opportunity to erase sensitive data if required.
- retryablePaymentAutomatonRunner.getPaymentDao().updatePaymentAttemptWithProperties(attempt.getId(), transactionId, state.getName(), getSerializedProperties(), paymentStateContext.getInternalCallContext());
+ retryablePaymentAutomatonRunner.getPaymentDao().updatePaymentAttemptWithProperties(attempt.getId(),
+ paymentStateContext.getPaymentMethodId(),
+ transactionId,
+ state.getName(),
+ getSerializedProperties(),
+ paymentStateContext.getInternalCallContext());
if (retriedState.getName().equals(state.getName()) && !isUnknownTransaction()) {
retryServiceScheduler.scheduleRetry(ObjectType.PAYMENT_ATTEMPT, attempt.getId(), attempt.getId(), attempt.getTenantRecordId(),
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
index 22baff9..f06040a 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
@@ -126,14 +126,14 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
}
@Override
- public void updatePaymentAttemptWithProperties(final UUID paymentAttemptId, final UUID transactionId, final String state, final byte[] pluginProperties, final InternalCallContext context) {
+ public void updatePaymentAttemptWithProperties(final UUID paymentAttemptId, final UUID paymentMethodId, final UUID transactionId, final String state, final byte[] pluginProperties, final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final String transactionIdStr = transactionId != null ? transactionId.toString() : null;
final PaymentAttemptSqlDao transactional = entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class);
- transactional.updateAttemptWithProperties(paymentAttemptId.toString(), transactionIdStr, state, pluginProperties, contextWithUpdatedDate(context));
+ transactional.updateAttemptWithProperties(paymentAttemptId.toString(), paymentMethodId == null ? null : paymentMethodId.toString(), transactionIdStr, state, pluginProperties, contextWithUpdatedDate(context));
return null;
}
});
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
index d9aef5d..5ef0bb6 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -26,14 +28,14 @@ import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface PaymentAttemptSqlDao extends EntitySqlDao<PaymentAttemptModelDao, Entity> {
@SqlUpdate
@@ -41,23 +43,24 @@ public interface PaymentAttemptSqlDao extends EntitySqlDao<PaymentAttemptModelDa
void updateAttempt(@Bind("id") final String attemptId,
@Bind("transactionId") final String transactionId,
@Bind("stateName") final String stateName,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
void updateAttemptWithProperties(@Bind("id") final String attemptId,
+ @Bind("paymentMethodId") final String paymentMethodId,
@Bind("transactionId") final String transactionId,
@Bind("stateName") final String stateName,
@Bind("pluginProperties") final byte[] pluginProperties,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
List<PaymentAttemptModelDao> getByTransactionExternalKey(@Bind("transactionExternalKey") final String transactionExternalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
List<PaymentAttemptModelDao> getByPaymentExternalKey(@Bind("paymentExternalKey") final String paymentExternalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
Long getCountByStateNameAcrossTenants(@Bind("stateName") final String stateName,
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
index b7180e8..a2be2ae 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
@@ -41,7 +41,7 @@ public interface PaymentDao extends EntityDao<PaymentModelDao, Payment, PaymentA
public void updatePaymentAttempt(UUID paymentAttemptId, UUID transactionId, String state, InternalCallContext context);
- public void updatePaymentAttemptWithProperties(UUID paymentAttemptId, UUID transactionId, String state, final byte[] pluginProperties, InternalCallContext context);
+ public void updatePaymentAttemptWithProperties(UUID paymentAttemptId, UUID paymentMethodId, UUID transactionId, String state, final byte[] pluginProperties, InternalCallContext context);
public Pagination<PaymentAttemptModelDao> getPaymentAttemptsByStateAcrossTenants(String stateName, DateTime createdBeforeDate, final Long offset, final Long limit);
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
index da14f3e..5512781 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
@@ -22,7 +22,7 @@ import java.util.Iterator;
import java.util.List;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -33,37 +33,37 @@ import org.killbill.billing.payment.api.PaymentMethod;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao, PaymentMethod> {
@SqlUpdate
@Audited(ChangeType.UPDATE)
void markPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
void unmarkPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
- PaymentMethodModelDao getByExternalKey(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+ PaymentMethodModelDao getByExternalKey(@Bind("externalKey") String paymentMethodExternalKey, @SmartBindBean InternalTenantContext context);
@SqlQuery
- PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+ PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(@Bind("externalKey") String paymentMethodExternalKey, @SmartBindBean InternalTenantContext context);
@SqlQuery
PaymentMethodModelDao getPaymentMethodIncludedDelete(@Bind("id") final String paymentMethodId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- List<PaymentMethodModelDao> getForAccount(@BindBean final InternalTenantContext context);
+ List<PaymentMethodModelDao> getForAccount(@SmartBindBean final InternalTenantContext context);
@SqlQuery
- List<PaymentMethodModelDao> getForAccountIncludedDelete(@BindBean final InternalTenantContext context);
+ List<PaymentMethodModelDao> getForAccountIncludedDelete(@SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
@@ -71,10 +71,10 @@ public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao,
@Bind("offset") final Long offset,
@Bind("rowCount") final Long rowCount,
@Define("ordering") final String ordering,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
index ee8ad0f..e932660 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
- * Groupon licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -27,56 +28,57 @@ import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.killbill.commons.jdbi.statement.SmartFetchSize;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, Payment> {
@SqlUpdate
@Audited(ChangeType.UPDATE)
void updatePaymentForNewTransaction(@Bind("id") final String paymentId,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
Object updatePaymentStateName(@Bind("id") final String paymentId,
@Bind("stateName") final String stateName,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
Object updateLastSuccessPaymentStateName(@Bind("id") final String paymentId,
@Bind("stateName") final String stateName,
@Bind("lastSuccessStateName") final String lastSuccessStateName,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
public PaymentModelDao getPaymentByExternalKey(@Bind("externalKey") final String externalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public List<PaymentModelDao> getPaymentsByStatesAcrossTenants(@StateCollectionBinder final Collection<String> states,
+ public List<PaymentModelDao> getPaymentsByStatesAcrossTenants(@BindIn("states") final Collection<String> states,
@Bind("createdBeforeDate") final Date createdBeforeDate,
@Bind("createdAfterDate") final Date createdAfterDate,
@Bind("limit") final int limit);
@SqlQuery
@SmartFetchSize(shouldStream = true)
- public Iterator<PaymentModelDao> searchByState(@PaymentStateCollectionBinder final Collection<String> paymentStates,
+ public Iterator<PaymentModelDao> searchByState(@BindIn("states") final Collection<String> paymentStates,
@Bind("offset") final Long offset,
@Bind("rowCount") final Long rowCount,
@Define("ordering") final String ordering,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public Long getSearchByStateCount(@PaymentStateCollectionBinder final Collection<String> paymentStates,
- @BindBean final InternalTenantContext context);
+ public Long getSearchByStateCount(@BindIn("states") final Collection<String> paymentStates,
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
@@ -84,9 +86,9 @@ public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, Payment> {
@Bind("offset") final Long offset,
@Bind("rowCount") final Long rowCount,
@Define("ordering") final String ordering,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
index ba8b739..b6666b7 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -30,14 +30,15 @@ import org.killbill.billing.payment.api.PaymentTransaction;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelDao, PaymentTransaction> {
@SqlUpdate
@@ -49,19 +50,19 @@ public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelD
@Bind("transactionStatus") final String transactionStatus,
@Bind("gatewayErrorCode") final String gatewayErrorCode,
@Bind("gatewayErrorMsg") final String gatewayErrorMsg,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
List<PaymentTransactionModelDao> getPaymentTransactionsByExternalKey(@Bind("transactionExternalKey") final String transactionExternalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- Long getCountByTransactionStatusPriorDateAcrossTenants(@TransactionStatusCollectionBinder final Collection<String> statuses,
+ Long getCountByTransactionStatusPriorDateAcrossTenants(@BindIn("statuses") final Collection<String> statuses,
@Bind("createdBeforeDate") final Date createdBeforeDate,
@Bind("createdAfterDate") final Date createdAfterDate);
@SqlQuery
- Iterator<PaymentTransactionModelDao> getByTransactionStatusPriorDateAcrossTenants(@TransactionStatusCollectionBinder final Collection<String> statuses,
+ Iterator<PaymentTransactionModelDao> getByTransactionStatusPriorDateAcrossTenants(@BindIn("statuses") final Collection<String> statuses,
@Bind("createdBeforeDate") final Date createdBeforeDate,
@Bind("createdAfterDate") final Date createdAfterDate,
@Bind("offset") final Long offset,
@@ -70,7 +71,7 @@ public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelD
@SqlQuery
public List<PaymentTransactionModelDao> getByPaymentId(@Bind("paymentId") final UUID paymentId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
index d8699fe..39dad12 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group PaymentAttemptSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "payment_attempts"
@@ -49,7 +49,7 @@ from <tableName()>
where transaction_external_key = :transactionExternalKey
<andCheckSoftDeletionWithComma("")>
<AND_CHECK_TENANT("")>
-<defaultOrderBy()>
+<defaultOrderBy("")>
;
>>
@@ -59,8 +59,8 @@ select
from <tableName()>
where payment_external_key = :paymentExternalKey
<andCheckSoftDeletionWithComma("")>
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
@@ -72,7 +72,7 @@ from <tableName()>
where state_name = :stateName
and created_date \< :createdBeforeDate
<andCheckSoftDeletionWithComma("")>
-order by <recordIdField()> <ordering>
+order by <recordIdField("")> <ordering>
limit :rowCount offset :offset
;
>>
@@ -95,19 +95,20 @@ set state_name = :stateName
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
updateAttemptWithProperties() ::= <<
update <tableName()>
set state_name = :stateName
+, payment_method_id = :paymentMethodId
, transaction_id = :transactionId
, plugin_properties = :pluginProperties
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
index 67c65f1..a26b7dd 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
@@ -1,6 +1,4 @@
-group PaymentMethodSqlDao: EntitySqlDao;
-
-
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "payment_methods"
@@ -36,7 +34,7 @@ set is_active = false
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -46,51 +44,51 @@ set is_active = true
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getByExternalKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where external_key = :externalKey
-<andCheckSoftDeletionWithComma()>
-<AND_CHECK_TENANT()>
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
;
>>
getPaymentMethodByExternalKeyIncludedDeleted() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where external_key = :externalKey
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getPaymentMethodIncludedDelete(accountId) ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getForAccount() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from <tableName()>
-where <accountRecordIdField()> = :accountRecordId
-<andCheckSoftDeletionWithComma()>
-<AND_CHECK_TENANT()>
+where <accountRecordIdField("")> = :accountRecordId
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
;
>>
getForAccountIncludedDelete() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from <tableName()>
-where <accountRecordIdField()> = :accountRecordId
-<AND_CHECK_TENANT()>
+where <accountRecordIdField("")> = :accountRecordId
+<AND_CHECK_TENANT("")>
;
>>
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
index b15a04b..395dfae 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group PaymentSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "payments"
@@ -41,7 +41,7 @@ update <tableName()>
set updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -51,7 +51,7 @@ set state_name = :stateName
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -62,7 +62,7 @@ set state_name = :stateName
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -71,7 +71,7 @@ select
<allTableFields("")>
from <tableName()>
where external_key = :externalKey
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -87,12 +87,12 @@ select
<allTableFields("t.")>
from <tableName()> t
join (
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
- where state_name in (<states: {state | :state_<i0>}; separator="," >)
- <AND_CHECK_TENANT()>
- <andCheckSoftDeletionWithComma()>
- order by <recordIdField()> <ordering>
+ where state_name in (<states>)
+ <AND_CHECK_TENANT("")>
+ <andCheckSoftDeletionWithComma("")>
+ order by <recordIdField("")> <ordering>
limit :rowCount offset :offset
) optimization on <recordIdField("optimization.")> = <recordIdField("t.")>
order by <recordIdField("t.")> <ordering>
@@ -103,7 +103,7 @@ getSearchByStateCount(states) ::= <<
select
count(1) as count
from <tableName()> t
-where t.state_name in (<states: {state | :state_<i0>}; separator="," >)
+where t.state_name in (<states>)
<andCheckSoftDeletionWithComma("t.")>
<AND_CHECK_TENANT("t.")>
;
@@ -138,7 +138,7 @@ from <tableName()> t
where
created_date >= :createdAfterDate
and created_date \< :createdBeforeDate
-and state_name in (<states: {state | :state_<i0>}; separator="," >)
+and state_name in (<states>)
limit :limit
;
>>
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
index 1f19f0b..cbdc740 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TransactionSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "payment_transactions"
@@ -51,8 +51,8 @@ select
<allTableFields("")>
from <tableName()>
where transaction_external_key = :transactionExternalKey
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
@@ -68,29 +68,29 @@ set transaction_status = :transactionStatus
, updated_by = :updatedBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getByPaymentId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where payment_id = :paymentId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
/* Does not include AND_CHECK_TENANT() since this is a global operation */
getByTransactionStatusPriorDateAcrossTenants(statuses, ordering) ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where
created_date >= :createdAfterDate
and created_date \< :createdBeforeDate
-and transaction_status in (<statuses: {status | :status_<i0>}; separator="," >)
-order by <recordIdField()> <ordering>
+and transaction_status in (<statuses>)
+order by <recordIdField("")> <ordering>
limit :rowCount offset :offset
;
>>
@@ -102,7 +102,7 @@ from <tableName()>
where
created_date >= :createdAfterDate
and created_date \< :createdBeforeDate
-and transaction_status in (<statuses: {status | :status_<i0>}; separator="," >)
+and transaction_status in (<statuses>)
;
>>
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/janitor/TestCompletionTaskBase.java b/payment/src/test/java/org/killbill/billing/payment/core/janitor/TestCompletionTaskBase.java
new file mode 100644
index 0000000..c32ea7f
--- /dev/null
+++ b/payment/src/test/java/org/killbill/billing/payment/core/janitor/TestCompletionTaskBase.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.payment.core.janitor;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.payment.PaymentTestSuiteWithEmbeddedDB;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.core.sm.PaymentControlStateMachineHelper;
+import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
+import org.killbill.billing.payment.core.sm.PluginControlPaymentAutomatonRunner;
+import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
+import org.killbill.billing.payment.dao.PaymentDao;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.definition.PaymentConfig;
+import org.killbill.clock.Clock;
+import org.killbill.commons.locker.GlobalLocker;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestCompletionTaskBase extends PaymentTestSuiteWithEmbeddedDB {
+
+ @Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/757")
+ public void testHandleRuntimeExceptions() throws PaymentApiException {
+ final List<PaymentAttemptModelDao> paymentAttemptModelDaos = ImmutableList.<PaymentAttemptModelDao>of(new PaymentAttemptModelDao(),
+ new PaymentAttemptModelDao());
+ final Iterator<PaymentAttemptModelDao> paymentAttemptModelDaoIterator = paymentAttemptModelDaos.iterator();
+ final Iterable<PaymentAttemptModelDao> itemsForIteration = new Iterable<PaymentAttemptModelDao>() {
+ @Override
+ public Iterator<PaymentAttemptModelDao> iterator() {
+ return paymentAttemptModelDaoIterator;
+ }
+ };
+ Assert.assertTrue(paymentAttemptModelDaoIterator.hasNext());
+
+ final Runnable incompletePaymentAttemptTaskWithException = new IncompletePaymentAttemptTaskWithException(itemsForIteration,
+ internalCallContextFactory,
+ paymentConfig,
+ paymentDao,
+ clock,
+ paymentSMHelper,
+ paymentControlStateMachineHelper,
+ accountApi,
+ pluginControlPaymentAutomatonRunner,
+ locker);
+
+ incompletePaymentAttemptTaskWithException.run();
+
+ // Make sure we cycled through all entries
+ Assert.assertFalse(paymentAttemptModelDaoIterator.hasNext());
+ }
+
+ private final class IncompletePaymentAttemptTaskWithException extends IncompletePaymentAttemptTask {
+
+ private final Iterable<PaymentAttemptModelDao> itemsForIteration;
+
+ public IncompletePaymentAttemptTaskWithException(final Iterable<PaymentAttemptModelDao> itemsForIteration, final InternalCallContextFactory internalCallContextFactory, final PaymentConfig paymentConfig, final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper, final PaymentControlStateMachineHelper retrySMHelper, final AccountInternalApi accountInternalApi, final PluginControlPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final GlobalLocker locker) {
+ super(internalCallContextFactory, paymentConfig, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, accountInternalApi, pluginControlledPaymentAutomatonRunner, locker);
+ this.itemsForIteration = itemsForIteration;
+ }
+
+ @Override
+ public Iterable<PaymentAttemptModelDao> getItemsForIteration() {
+ return itemsForIteration;
+ }
+
+ @Override
+ public void doIteration(final PaymentAttemptModelDao attempt) {
+ throw new NullPointerException("NPE for tests");
+ }
+ }
+}
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
index f167975..b932f15 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.time.DateTime;
@@ -100,15 +101,18 @@ public class MockPaymentDao extends MockEntityDaoBase<PaymentModelDao, Payment,
@Override
public void updatePaymentAttempt(final UUID paymentAttemptId, final UUID transactionId, final String state, final InternalCallContext context) {
- updatePaymentAttemptWithProperties(paymentAttemptId, transactionId, state, null, context);
+ updatePaymentAttemptWithProperties(paymentAttemptId, null, transactionId, state, null, context);
}
@Override
- public void updatePaymentAttemptWithProperties(final UUID paymentAttemptId, final UUID transactionId, final String state, final byte[] pluginProperties, final InternalCallContext context) {
+ public void updatePaymentAttemptWithProperties(final UUID paymentAttemptId, @Nullable final UUID paymentMethodId, final UUID transactionId, final String state, final byte[] pluginProperties, final InternalCallContext context) {
boolean success = false;
synchronized (this) {
for (PaymentAttemptModelDao cur : attempts.values()) {
if (cur.getId().equals(paymentAttemptId)) {
+ if (paymentMethodId != null) {
+ cur.setPaymentMethodId(paymentMethodId);
+ }
cur.setStateName(state);
cur.setTransactionId(transactionId);
if (pluginProperties != null) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
index 113c147..8e0f0fe 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
@@ -564,7 +564,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
properties.add(new PluginProperty("prop2", "value2", false));
final byte [] serializedProperties = PluginPropertySerializer.serialize(properties);
- paymentDao.updatePaymentAttemptWithProperties(rehydratedAttempt.getId(), transactionId, newStateName, serializedProperties, internalCallContext);
+ paymentDao.updatePaymentAttemptWithProperties(rehydratedAttempt.getId(), rehydratedAttempt.getPaymentMethodId(), transactionId, newStateName, serializedProperties, internalCallContext);
final PaymentAttemptModelDao attempt2 = paymentDao.getPaymentAttempt(rehydratedAttempt.getId(), internalCallContext);
assertEquals(attempt2.getStateName(), newStateName);
assertEquals(attempt2.getTransactionId(), transactionId);
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
index 0210596..cf7454d 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
@@ -33,7 +33,9 @@ import org.killbill.billing.payment.core.PaymentPluginServiceRegistration;
import org.killbill.billing.payment.core.PaymentProcessor;
import org.killbill.billing.payment.core.janitor.IncompletePaymentTransactionTask;
import org.killbill.billing.payment.core.janitor.Janitor;
+import org.killbill.billing.payment.core.sm.PaymentControlStateMachineHelper;
import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
+import org.killbill.billing.payment.core.sm.PluginControlPaymentAutomatonRunner;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.glue.PaymentModule;
import org.killbill.billing.payment.glue.TestPaymentModuleWithEmbeddedDB;
@@ -103,6 +105,10 @@ public abstract class PaymentTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
protected IncompletePaymentTransactionTask incompletePaymentTransactionTask;
@Inject
protected GlobalLocker locker;
+ @Inject
+ protected PluginControlPaymentAutomatonRunner pluginControlPaymentAutomatonRunner;
+ @Inject
+ protected PaymentControlStateMachineHelper paymentControlStateMachineHelper;
@Override
protected KillbillConfigSource getConfigSource() {
diff --git a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
index 3719daf..f451943 100644
--- a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
+++ b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -17,6 +17,8 @@
package org.killbill.billing.payment.provider;
+import java.util.UUID;
+
import org.joda.time.DateTime;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.retry.DefaultFailureCallResult;
@@ -33,6 +35,7 @@ public class MockPaymentControlProviderPlugin implements PaymentControlPluginApi
public static final String PLUGIN_NAME = "MOCK_RETRY_PLUGIN";
+ private UUID adjustedPaymentMethodId;
private boolean isAborted;
private DateTime nextRetryDate;
private Exception exception;
@@ -41,6 +44,11 @@ public class MockPaymentControlProviderPlugin implements PaymentControlPluginApi
private boolean onSuccessCallExecuted;
private boolean onFailureCallExecuted;
+ public MockPaymentControlProviderPlugin setAdjustedPaymentMethodId(final UUID adjustedPaymentMethodId) {
+ this.adjustedPaymentMethodId = adjustedPaymentMethodId;
+ return this;
+ }
+
public MockPaymentControlProviderPlugin setAborted(final boolean isAborted) {
this.isAborted = isAborted;
return this;
@@ -69,7 +77,7 @@ public class MockPaymentControlProviderPlugin implements PaymentControlPluginApi
} else if (exception instanceof RuntimeException) {
throw (RuntimeException) exception;
}
- return new DefaultPriorPaymentControlResult(isAborted);
+ return new DefaultPriorPaymentControlResult(isAborted, adjustedPaymentMethodId, null, null, null);
}
@Override
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillBillEmbeddedDBProvider.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillBillEmbeddedDBProvider.java
index b460401..a803057 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillBillEmbeddedDBProvider.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillBillEmbeddedDBProvider.java
@@ -34,6 +34,7 @@ public class KillBillEmbeddedDBProvider extends EmbeddedDBProvider {
final Collection<String> ddlFiles = new LinkedList<String>();
for (final String module : new String[]{"account",
"beatrix",
+ "catalog",
"entitlement",
"invoice",
"payment",
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index ff6de44..d05cc24 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -66,8 +66,6 @@ import org.killbill.billing.subscription.glue.DefaultSubscriptionModule;
import org.killbill.billing.tenant.glue.DefaultTenantModule;
import org.killbill.billing.usage.glue.UsageModule;
import org.killbill.billing.util.config.definition.NotificationConfig;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
import org.killbill.billing.util.email.EmailModule;
import org.killbill.billing.util.email.templates.TemplateModule;
import org.killbill.billing.util.glue.AuditModule;
@@ -79,6 +77,7 @@ import org.killbill.billing.util.glue.ConfigModule;
import org.killbill.billing.util.glue.CustomFieldModule;
import org.killbill.billing.util.glue.ExportModule;
import org.killbill.billing.util.glue.GlobalLockerModule;
+import org.killbill.billing.util.glue.IDBISetup;
import org.killbill.billing.util.glue.KillBillShiroAopModule;
import org.killbill.billing.util.glue.KillbillApiAopModule;
import org.killbill.billing.util.glue.NodesModule;
@@ -86,11 +85,9 @@ import org.killbill.billing.util.glue.NonEntityDaoModule;
import org.killbill.billing.util.glue.RecordIdModule;
import org.killbill.billing.util.glue.SecurityModule;
import org.killbill.billing.util.glue.TagStoreModule;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
import org.killbill.clock.Clock;
import org.killbill.clock.ClockMock;
import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.ResultSetMapperFactory;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
@@ -124,11 +121,14 @@ public class KillbillServerModule extends KillbillPlatformModule {
super.configureDao();
final Multibinder<ResultSetMapperFactory> resultSetMapperFactorySetBinder = Multibinder.newSetBinder(binder(), ResultSetMapperFactory.class);
- resultSetMapperFactorySetBinder.addBinding().toInstance(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+ for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+ resultSetMapperFactorySetBinder.addBinding().toInstance(resultSetMapperFactory);
+ }
final Multibinder<ResultSetMapper> resultSetMapperSetBinder = Multibinder.newSetBinder(binder(), ResultSetMapper.class);
- resultSetMapperSetBinder.addBinding().to(AuditLogModelDaoMapper.class).asEagerSingleton();
- resultSetMapperSetBinder.addBinding().to(RecordIdIdMappingsMapper.class).asEagerSingleton();
+ for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+ resultSetMapperSetBinder.addBinding().toInstance(resultSetMapper);
+ }
}
@Override
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
index 25517ab..319573b 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
@@ -29,6 +29,7 @@ import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.client.KillBillClient;
+import org.killbill.billing.client.KillBillClientException;
import org.killbill.billing.client.KillBillHttpClient;
import org.killbill.billing.client.RequestOptions;
import org.killbill.billing.client.model.Account;
@@ -119,11 +120,16 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
protected Account createAccountWithExternalPaymentMethod() throws Exception {
final Account input = createAccount();
+ createPaymentMethod(input, true);
+
+ return killBillClient.getAccount(input.getExternalKey(), requestOptions);
+ }
+
+ protected PaymentMethod createPaymentMethod(final Account input, final boolean isDefault) throws KillBillClientException {
final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
final PaymentMethod paymentMethodJson = new PaymentMethod(null, UUIDs.randomUUID().toString(), input.getAccountId(),
- true, ExternalPaymentProviderPlugin.PLUGIN_NAME, info);
- killBillClient.createPaymentMethod(paymentMethodJson, requestOptions);
- return killBillClient.getAccount(input.getExternalKey(), requestOptions);
+ isDefault, ExternalPaymentProviderPlugin.PLUGIN_NAME, info);
+ return killBillClient.createPaymentMethod(paymentMethodJson, requestOptions);
}
protected Account createAccount() throws Exception {
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 13b0fa4..69c17a0 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
@@ -19,6 +19,7 @@ package org.killbill.billing.jaxrs;
import java.math.BigDecimal;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -617,6 +618,29 @@ public class TestPayment extends TestJaxrsBase {
}
@Test(groups = "slow")
+ public void testComboAuthorizationControlWithNullPaymentMethodId() throws Exception {
+ final Account accountJson = createAccount();
+
+ // Non-default payment method
+ final PaymentMethod paymentMethod = createPaymentMethod(accountJson, false);
+ mockPaymentControlProviderPlugin.setAdjustedPaymentMethodId(paymentMethod.getPaymentMethodId());
+
+ accountJson.setAccountId(null);
+ final String paymentExternalKey = UUID.randomUUID().toString();
+
+ final PaymentTransaction authTransactionJson = new PaymentTransaction();
+ authTransactionJson.setPaymentExternalKey(paymentExternalKey);
+ authTransactionJson.setAmount(BigDecimal.TEN);
+ authTransactionJson.setTransactionType("AUTHORIZE");
+ final ComboPaymentTransaction comboPaymentTransaction = new ComboPaymentTransaction(accountJson, null, authTransactionJson, ImmutableList.<PluginProperty>of(), ImmutableList.<PluginProperty>of());
+
+ final Payment payment = killBillClient.createPayment(comboPaymentTransaction, ImmutableList.<String>of(MockPaymentControlProviderPlugin.PLUGIN_NAME), ImmutableMap.<String, String>of(), requestOptions);
+ verifyComboPayment(payment, paymentExternalKey, BigDecimal.TEN, BigDecimal.ZERO, BigDecimal.ZERO, 1, 1);
+
+ assertEquals(killBillClient.getPayment(payment.getPaymentId(), false, true, ImmutableMap.<String, String>of(), AuditLevel.NONE, requestOptions).getPaymentAttempts().size(), 1);
+ }
+
+ @Test(groups = "slow")
public void testComboAuthorizationControlPluginException() throws Exception {
final Account accountJson = getAccount();
accountJson.setAccountId(null);
@@ -799,7 +823,7 @@ public class TestPayment extends TestJaxrsBase {
assertEquals(payment.getRefundedAmount().compareTo(refundedAmount), 0);
assertEquals(payment.getTransactions().size(), nbTransactions);
- final Payments Payments = killBillClient.getPayments();
+ final Payments Payments = killBillClient.getPayments(requestOptions);
assertEquals(Payments.size(), paymentNb);
assertEquals(Payments.get(paymentNb - 1), payment);
}
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentPluginProperties.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentPluginProperties.java
index f31858f..3d87984 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentPluginProperties.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentPluginProperties.java
@@ -103,7 +103,7 @@ public class TestPaymentPluginProperties extends TestJaxrsBase {
for (org.killbill.billing.payment.api.PluginProperty input : properties) {
boolean found = false;
for (org.killbill.billing.payment.api.PluginProperty expect : expectedProperties) {
- if (expect.getKey().equals(input.getKey()) && expect.getValue().equals(expect.getValue())) {
+ if (expect.getKey().equals(input.getKey()) && expect.getValue().equals(input.getValue())) {
found = true;
break;
}
@@ -111,10 +111,10 @@ public class TestPaymentPluginProperties extends TestJaxrsBase {
Assert.assertTrue(found);
}
- for (org.killbill.billing.payment.api.PluginProperty expect : properties) {
+ for (org.killbill.billing.payment.api.PluginProperty expect : expectedProperties) {
boolean found = false;
- for (org.killbill.billing.payment.api.PluginProperty input : expectedProperties) {
- if (expect.getKey().equals(input.getKey()) && expect.getValue().equals(expect.getValue())) {
+ for (org.killbill.billing.payment.api.PluginProperty input : properties) {
+ if (expect.getKey().equals(input.getKey()) && expect.getValue().equals(input.getValue())) {
found = true;
break;
}
@@ -227,9 +227,25 @@ public class TestPaymentPluginProperties extends TestJaxrsBase {
params.putAll(KillBillHttpClient.CONTROL_PLUGIN_NAME, ImmutableList.<String>of(PluginPropertiesVerificator.PLUGIN_NAME));
final RequestOptions requestOptionsWithParams = basicRequestOptions.extend()
- .withQueryParams(params).build();
+ .withQueryParams(params).build();
killBillClient.completePayment(completeTransactionByPaymentId, queryProperties, requestOptionsWithParams);
+
+ //Capture the payment
+ final PaymentTransaction captureTransaction = new PaymentTransaction();
+ captureTransaction.setPaymentId(initialPayment.getPaymentId());
+ captureTransaction.setProperties(bodyProperties);
+ captureTransaction.setAmount(BigDecimal.TEN);
+ captureTransaction.setCurrency(account.getCurrency());
+ killBillClient.captureAuthorization(captureTransaction, ImmutableList.<String>of(PluginPropertiesVerificator.PLUGIN_NAME), queryProperties, requestOptions);
+
+ //Refund the payment
+ final PaymentTransaction refundTransaction = new PaymentTransaction();
+ refundTransaction.setPaymentId(initialPayment.getPaymentId());
+ refundTransaction.setProperties(bodyProperties);
+ refundTransaction.setAmount(BigDecimal.TEN);
+ refundTransaction.setCurrency(account.getCurrency());
+ killBillClient.refundPayment(refundTransaction, ImmutableList.<String>of(PluginPropertiesVerificator.PLUGIN_NAME), queryProperties, requestOptions);
}
private Payment createVerifyTransaction(final Account account,
README.md 2(+1 -1)
diff --git a/README.md b/README.md
index c810485..3ffcee9 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
Kill Bill is the Open-Source Billing & Payment Platform.
-Among features:
+## Among features
* Subscription engine, with plans management (trial, upgrade, downgrade, etc.), support of add-ons, bundles with multiple subscriptions
* Invoicing engine, supporting different billing alignments, recurring and one-time charges, international tax, metered billing
subscription/pom.xml 2(+1 -1)
diff --git a/subscription/pom.xml b/subscription/pom.xml
index e915aae..25811b5 100644
--- a/subscription/pom.xml
+++ b/subscription/pom.xml
@@ -75,7 +75,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
index 585e013..bc8f9f2 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
@@ -20,7 +20,7 @@ import java.util.Date;
import java.util.List;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -31,33 +31,33 @@ import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleMode
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface BundleSqlDao extends EntitySqlDao<SubscriptionBundleModelDao, SubscriptionBaseBundle> {
@SqlUpdate
@Audited(ChangeType.UPDATE)
public void updateBundleExternalKey(@Bind("id") String id,
@Bind("externalKey") String externalKey,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
public void updateBundleLastSysTime(@Bind("id") String id,
@Bind("lastSysUpdateDate") Date lastSysUpdate,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
public List<SubscriptionBundleModelDao> getBundlesFromAccountAndKey(@Bind("accountId") String accountId,
@Bind("externalKey") String externalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<SubscriptionBundleModelDao> getBundleFromAccount(@Bind("accountId") String accountId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<SubscriptionBundleModelDao> getBundlesForKey(@Bind("externalKey") String externalKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
index c47d482..0e195db 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
@@ -26,34 +26,34 @@ import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface SubscriptionEventSqlDao extends EntitySqlDao<SubscriptionEventModelDao, SubscriptionBaseEvent> {
@SqlUpdate
@Audited(ChangeType.UPDATE)
public void unactiveEvent(@Bind("id") String id,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
public List<SubscriptionEventModelDao> getFutureActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId,
@Bind("now") Date now,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<SubscriptionEventModelDao> getFutureOrPresentActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId,
@Bind("now") Date now,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<SubscriptionEventModelDao> getActiveEventsForSubscription(@Bind("subscriptionId") String subscriptionId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public List<SubscriptionEventModelDao> getFutureActiveEventsForAccount(@Bind("now") Date now, @BindBean final InternalTenantContext context);
+ public List<SubscriptionEventModelDao> getFutureActiveEventsForAccount(@Bind("now") Date now, @SmartBindBean final InternalTenantContext context);
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
index b47b5ba..c0c2495 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
@@ -20,7 +20,7 @@ import java.util.Date;
import java.util.List;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -31,18 +31,18 @@ import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface SubscriptionSqlDao extends EntitySqlDao<SubscriptionModelDao, SubscriptionBase> {
@SqlQuery
public List<SubscriptionModelDao> getSubscriptionsFromBundleId(@Bind("bundleId") String bundleId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
public void updateChargedThroughDate(@Bind("id") String id, @Bind("chargedThroughDate") Date chargedThroughDate,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
}
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
index 4495409..9a5337c 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group BundleSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "bundles"
@@ -32,7 +32,7 @@ last_sys_update_date = :lastSysUpdateDate
, updated_by = :createdBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
@@ -43,38 +43,38 @@ external_key = :externalKey
, updated_by = :createdBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getBundlesForKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from bundles
where
external_key = :externalKey
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getBundlesFromAccountAndKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from bundles
where
external_key = :externalKey
and account_id = :accountId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getBundleFromAccount() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from bundles
where
account_id = :accountId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
index cfb3ec4..94d407f 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group EventSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "subscription_events"
@@ -53,59 +53,59 @@ is_active = false
, updated_date = :updatedDate
where
id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
getFutureActiveEventForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
, record_id as total_ordering
from <tableName()>
where
subscription_id = :subscriptionId
and is_active = true
and effective_date > :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getFutureOrPresentActiveEventForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
, record_id as total_ordering
from <tableName()>
where
subscription_id = :subscriptionId
and is_active = true
and effective_date >= :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getActiveEventsForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
, record_id as total_ordering
from <tableName()>
where
subscription_id = :subscriptionId
and is_active = true
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getFutureActiveEventsForAccount() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
, record_id as total_ordering
from <tableName()>
where
account_record_id = :accountRecordId
and is_active = true
and effective_date > :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
index 47ae310..3f9388d 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group SubscriptionSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "subscriptions"
@@ -31,11 +31,11 @@ tableValues() ::= <<
getSubscriptionsFromBundleId() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from <tableName()>
where bundle_id = :bundleId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
@@ -46,6 +46,6 @@ charged_through_date = :chargedThroughDate
, updated_by = :createdBy
, updated_date = :updatedDate
where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
;
>>
tenant/pom.xml 2(+1 -1)
diff --git a/tenant/pom.xml b/tenant/pom.xml
index 644a027..103d84f 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -74,7 +74,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
index 1925151..281d07c 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
@@ -21,11 +21,11 @@ import java.util.List;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TenantBroadcastSqlDao extends EntitySqlDao<TenantBroadcastModelDao, Entity> {
@SqlQuery
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
index c0cac34..fe99bea 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
@@ -24,32 +24,32 @@ import org.killbill.billing.tenant.api.TenantKV;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TenantKVSqlDao extends EntitySqlDao<TenantKVModelDao, TenantKV> {
@SqlQuery
public List<TenantKVModelDao> getTenantValueForKey(@Bind("tenantKey") final String key,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public List<TenantKVModelDao> searchTenantKeyValues(@Bind("tenantKeyPrefix") final String tenantKeyPrefix,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.DELETE)
public void markTenantKeyAsDeleted(@Bind("id")final String id,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
public Object updateTenantValueKey(@Bind("id") final String id,
@Bind("tenantValue") final String tenantValue,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
}
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
index cf97271..ab4ded9 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
@@ -24,9 +24,9 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.killbill.billing.tenant.api.Tenant;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TenantSqlDao extends EntitySqlDao<TenantModelDao, Tenant> {
@SqlQuery
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
index b0e5bc3..b843665 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantBroadcastSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "tenant_broadcasts"
@@ -26,7 +26,7 @@ tableValues() ::= <<
/* No account_record_id field */
accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
getLatestEntries() ::= <<
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
index 9495969..19cfb11 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantKVSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "tenant_kvs"
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
index 56c8986..25cfc6f 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantDaoSql: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "tenants"
@@ -23,7 +23,7 @@ tableValues() ::= <<
/* No account_record_id field */
accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
/* No tenant_record_id field */
tenantRecordIdFieldWithComma(prefix) ::= ""
@@ -33,8 +33,8 @@ CHECK_TENANT(prefix) ::= "1 = 1"
/* Override default create call to include secrets */
create() ::= <<
insert into <tableName()> (
- <idField()>
-, <tableFields()>
+ <idField("")>
+, <tableFields("")>
, api_secret
, api_salt
)
usage/pom.xml 2(+1 -1)
diff --git a/usage/pom.xml b/usage/pom.xml
index 25c9467..8cc8fdf 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -70,7 +70,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
index 89fc3a2..e947fa5 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
@@ -27,17 +27,17 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.callcontext.InternalTenantContextBinder;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlBatch;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface RolledUpUsageSqlDao extends EntitySqlDao<RolledUpUsageModelDao, Entity> {
@SqlBatch
- void create(@BindBean Iterable<RolledUpUsageModelDao> usages,
+ void create(@SmartBindBean Iterable<RolledUpUsageModelDao> usages,
@InternalTenantContextBinder final InternalCallContext context);
@SqlQuery
diff --git a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
index b1d739c..44db9b9 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
+++ b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group RolledUpUsageSqlDao : EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "rolled_up_usage"
@@ -29,45 +29,45 @@ select
from <tableName()>
where subscription_id = :subscriptionId
and tracking_id = :trackingId
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
limit 1
;
>>
getUsageForSubscription() ::= <<
select
- <allTableFields()>
+ <allTableFields("")>
from <tableName()>
where subscription_id = :subscriptionId
and record_date >= :startDate
and record_date \< :endDate
and unit_type = :unitType
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getAllUsageForSubscription() ::= <<
select
- <allTableFields()>
+ <allTableFields("")>
from <tableName()>
where subscription_id = :subscriptionId
and record_date >= :startDate
and record_date \< :endDate
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
getRawUsageForAccount() ::= <<
select
- <allTableFields()>
+ <allTableFields("")>
from <tableName()>
where account_record_id = :accountRecordId
and record_date >= :startDate
and record_date \< :endDate
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
util/pom.xml 11(+10 -1)
diff --git a/util/pom.xml b/util/pom.xml
index 6f3e019..6a5ed2c 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -74,6 +74,11 @@
<artifactId>guice-multibindings</artifactId>
</dependency>
<dependency>
+ <groupId>com.ning</groupId>
+ <artifactId>compress-lzf</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>com.samskivert</groupId>
<artifactId>jmustache</artifactId>
</dependency>
@@ -130,7 +135,7 @@
</dependency>
<dependency>
<groupId>org.antlr</groupId>
- <artifactId>stringtemplate</artifactId>
+ <artifactId>ST4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@@ -191,6 +196,10 @@
</dependency>
<dependency>
<groupId>org.kill-bill.billing</groupId>
+ <artifactId>killbill-platform-lifecycle</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing</groupId>
<artifactId>killbill-platform-osgi</artifactId>
</dependency>
<dependency>
diff --git a/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java b/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
index 9efa110..fb6e7a5 100644
--- a/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
@@ -19,17 +19,17 @@ package org.killbill.billing.util.broadcast.dao;
import java.util.List;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface BroadcastSqlDao {
@SqlUpdate
- public void create(@BindBean final BroadcastModelDao broadcastModelDao);
+ public void create(@SmartBindBean final BroadcastModelDao broadcastModelDao);
@SqlQuery
public List<BroadcastModelDao> getLatestEntries(@Bind("recordId") final Long recordId);
diff --git a/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java b/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
index 6d7f32a..8ceda0e 100644
--- a/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
+++ b/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
@@ -39,8 +39,6 @@ public class DefaultBroadcastDao implements BroadcastDao {
public DefaultBroadcastDao(final IDBI dbi, final Clock clock) {
this.dbi = dbi;
this.clock = clock;
- ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(BroadcastModelDao.class));
-
}
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
index 53e589e..f75fd4b 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
import java.util.UUID;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -31,18 +31,18 @@ import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.customfield.CustomField;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface CustomFieldSqlDao extends EntitySqlDao<CustomFieldModelDao, CustomField> {
@SqlUpdate
@Audited(ChangeType.DELETE)
void markTagAsDeleted(@Bind("id") String customFieldId,
- @BindBean InternalCallContext context);
+ @SmartBindBean InternalCallContext context);
@SqlQuery
List<CustomFieldModelDao> getCustomFieldsForObject(@Bind("objectId") UUID objectId,
@Bind("objectType") ObjectType objectType,
- @BindBean InternalTenantContext internalTenantContext);
+ @SmartBindBean InternalTenantContext internalTenantContext);
}
diff --git a/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
index 7ca13e0..e9cf5b8 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
@@ -21,8 +21,9 @@ package org.killbill.billing.util.dao;
import java.util.Iterator;
import java.util.List;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
@@ -34,7 +35,6 @@ import org.killbill.billing.util.audit.dao.AuditLogModelDao;
import org.killbill.billing.util.cache.Cachable;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CachableKey;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
/**
* Note 1: cache invalidation has to happen for audit logs (which is tricky in the multi-nodes scenario).
@@ -45,33 +45,33 @@ import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
* <p/>
* Note 2: in the queries below, tableName always refers to the TableName enum, not the actual table name (TableName.getTableName()).
*/
-@EntitySqlDaoStringTemplate("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg")
+@KillBillSqlDaoStringTemplate("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg")
// Note: @RegisterMapper annotation won't work here as we build the SqlObject via EntitySqlDao (annotations won't be inherited for JDBI)
public interface AuditSqlDao {
@SqlUpdate
- public void insertAuditFromTransaction(@BindBean final EntityAudit audit,
- @BindBean final InternalCallContext context);
+ public void insertAuditFromTransaction(@SmartBindBean final EntityAudit audit,
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
- public Iterator<AuditLogModelDao> getAuditLogsForAccountRecordId(@BindBean final InternalTenantContext context);
+ public Iterator<AuditLogModelDao> getAuditLogsForAccountRecordId(@SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
public Iterator<AuditLogModelDao> getAuditLogsForTableNameAndAccountRecordId(@Bind("tableName") final String tableName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
@Cachable(CacheType.AUDIT_LOG)
public List<AuditLogModelDao> getAuditLogsForTargetRecordId(@CachableKey(1) @Bind("tableName") final String tableName,
@CachableKey(2) @Bind("targetRecordId") final long targetRecordId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
@Cachable(CacheType.AUDIT_LOG_VIA_HISTORY)
public List<AuditLogModelDao> getAuditLogsViaHistoryForTargetRecordId(@CachableKey(1) @Bind("tableName") final String historyTableName, /* Uppercased - used to find entries in audit_log table */
@CachableKey(2) @Define("historyTableName") final String actualHistoryTableName, /* Actual table name, used in the inner join query */
@CachableKey(3) @Bind("targetRecordId") final long targetRecordId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java b/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
index e5afcf6..42d7ceb 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
@@ -53,7 +53,7 @@ public @interface EntityHistoryBinder {
@Override
public void bind(final SQLStatement<?> q, final EntityHistoryBinder bind, final EntityHistoryModelDao<M, E> history) {
try {
- // Emulate @BindBean
+ // Emulate @SmartBindBean
final M arg = history.getEntity();
final BeanInfo infos = Introspector.getBeanInfo(arg.getClass());
final PropertyDescriptor[] props = infos.getPropertyDescriptors();
diff --git a/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
index 5f6d2d1..e1f7cee 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
@@ -24,7 +24,7 @@ import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.dao.EntityModelDao;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.GetGeneratedKeys;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -33,9 +33,9 @@ public interface HistorySqlDao<M extends EntityModelDao<E>, E extends Entity> {
@SqlQuery
public List<EntityHistoryModelDao<M, E>> getHistoryForTargetRecordId(@Bind("targetRecordId") final long targetRecordId,
- @BindBean InternalCallContext context);
+ @SmartBindBean InternalCallContext context);
@SqlUpdate
@GetGeneratedKeys
public Long addHistoryFromTransaction(@EntityHistoryBinder EntityHistoryModelDao<M, E> history,
- @BindBean InternalCallContext context);
+ @SmartBindBean InternalCallContext context);
}
diff --git a/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
index 798b334..650f052 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
@@ -21,15 +21,15 @@ package org.killbill.billing.util.dao;
import java.util.UUID;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe {
@SqlQuery
@@ -62,19 +62,19 @@ public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe
@SqlQuery
public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappings(@Define("tableName") String tableName,
@Define("historyTableName") String historyTableName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappingsForAccountsTable(@Define("tableName") String tableName,
@Define("historyTableName") String historyTableName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappingsForTablesWithoutAccountRecordId(@Define("tableName") String tableName,
@Define("historyTableName") String historyTableName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Iterable<RecordIdIdMappings> getRecordIdIdMappings(@Define("tableName") String tableName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
index ede762c..a4ddb91 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
@@ -32,40 +32,41 @@ import org.killbill.billing.util.dao.AuditSqlDao;
import org.killbill.billing.util.dao.HistorySqlDao;
import org.killbill.billing.util.entity.Entity;
import org.killbill.commons.jdbi.statement.SmartFetchSize;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> extends AuditSqlDao, HistorySqlDao<M, E>, Transactional<EntitySqlDao<M, E>>, CloseMe {
@SqlUpdate
@Audited(ChangeType.INSERT)
- public Object create(@BindBean final M entity,
- @BindBean final InternalCallContext context) throws EntityPersistenceException;
+ public Object create(@SmartBindBean final M entity,
+ @SmartBindBean final InternalCallContext context) throws EntityPersistenceException;
@SqlQuery
public M getById(@Bind("id") final String id,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public M getByRecordId(@Bind("recordId") final Long recordId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public List<M> getByAccountRecordId(@BindBean final InternalTenantContext context);
+ public List<M> getByAccountRecordId(@SmartBindBean final InternalTenantContext context);
@SqlQuery
- public List<M> getByAccountRecordIdIncludedDeleted(@BindBean final InternalTenantContext context);
+ public List<M> getByAccountRecordIdIncludedDeleted(@SmartBindBean final InternalTenantContext context);
@SqlQuery
@Cachable(CacheType.RECORD_ID)
public Long getRecordId(@CachableKey(1) @Bind("id") final String id,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
@@ -74,16 +75,16 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
@Bind("offset") final Long offset,
@Bind("rowCount") final Long rowCount,
@Define("ordering") final String ordering,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
public Long getSearchCount(@Bind("searchKey") final String searchKey,
@Bind("likeSearchKey") final String likeSearchKey,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
- public Iterator<M> getAll(@BindBean final InternalTenantContext context);
+ public Iterator<M> getAll(@SmartBindBean final InternalTenantContext context);
@SqlQuery
@SmartFetchSize(shouldStream = true)
@@ -91,11 +92,11 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
@Bind("rowCount") final Long rowCount,
@Define("orderBy") final String orderBy,
@Define("ordering") final String ordering,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public Long getCount(@BindBean final InternalTenantContext context);
+ public Long getCount(@SmartBindBean final InternalTenantContext context);
@SqlUpdate
- public void test(@BindBean final InternalTenantContext context);
+ public void test(@SmartBindBean final InternalTenantContext context);
}
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index 654d0da..f6ba247 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -32,6 +32,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nullable;
@@ -51,7 +52,6 @@ import org.killbill.billing.util.dao.EntityHistoryModelDao;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.dao.TableName;
import org.killbill.billing.util.entity.Entity;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
import org.killbill.clock.Clock;
import org.killbill.commons.profiling.Profiling;
import org.killbill.commons.profiling.Profiling.WithProfilingCallback;
@@ -62,6 +62,7 @@ import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.exceptions.DBIException;
import org.skife.jdbi.v2.exceptions.StatementException;
import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.unstable.BindIn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -84,6 +85,8 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
private final Logger logger = LoggerFactory.getLogger(EntitySqlDaoWrapperInvocationHandler.class);
+ private final Map<String, Annotation[][]> parameterAnnotationsByMethod = new ConcurrentHashMap<String, Annotation[][]>();
+
private final Class<S> sqlDaoClass;
private final S sqlDao;
private final Handle handle;
@@ -227,7 +230,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
if (cache != null && objectType != null) {
// Find all arguments marked with @CachableKey
final Map<Integer, Object> keyPieces = new LinkedHashMap<Integer, Object>();
- final Annotation[][] annotations = method.getParameterAnnotations();
+ final Annotation[][] annotations = getAnnotations(method);
for (int i = 0; i < annotations.length; i++) {
for (int j = 0; j < annotations[i].length; j++) {
final Annotation annotation = annotations[i][j];
@@ -408,7 +411,8 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
}
private List<String> retrieveEntityIdsFromArguments(final Method method, final Object[] args) {
- final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ final Annotation[][] parameterAnnotations = getAnnotations(method);
+
int i = -1;
for (final Object arg : args) {
i++;
@@ -430,7 +434,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
for (final Annotation annotation : parameterAnnotations[i]) {
if (arg instanceof String && Bind.class.equals(annotation.annotationType()) && ("id").equals(((Bind) annotation).value())) {
return ImmutableList.<String>of((String) arg);
- } else if (arg instanceof Collection && UUIDCollectionBinder.class.equals(annotation.annotationType())) {
+ } else if (arg instanceof Collection && BindIn.class.equals(annotation.annotationType()) && ("ids").equals(((BindIn) annotation).value())) {
return ImmutableList.<String>copyOf((Collection) arg);
}
}
@@ -438,6 +442,19 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
return ImmutableList.<String>of();
}
+ private Annotation[][] getAnnotations(final Method method) {
+ // Expensive to compute
+ final String methodString = method.toString();
+
+ // Method.getParameterAnnotations() generates lots of garbage objects
+ Annotation[][] parameterAnnotations = parameterAnnotationsByMethod.get(methodString);
+ if (parameterAnnotations == null) {
+ parameterAnnotations = method.getParameterAnnotations();
+ parameterAnnotationsByMethod.put(methodString, parameterAnnotations);
+ }
+ return parameterAnnotations;
+ }
+
private Builder<String> extractEntityIdsFromBatchArgument(final Iterable arg) {
final Iterator iterator = arg.iterator();
final Builder<String> entityIds = new Builder<String>();
diff --git a/util/src/main/java/org/killbill/billing/util/export/dao/DatabaseExportDao.java b/util/src/main/java/org/killbill/billing/util/export/dao/DatabaseExportDao.java
index 1f37627..0f99263 100644
--- a/util/src/main/java/org/killbill/billing/util/export/dao/DatabaseExportDao.java
+++ b/util/src/main/java/org/killbill/billing/util/export/dao/DatabaseExportDao.java
@@ -16,6 +16,7 @@
package org.killbill.billing.util.export.dao;
+import java.sql.Blob;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -160,6 +161,17 @@ public class DatabaseExportDao {
try {
while (iterator.hasNext()) {
final Map<String, Object> row = iterator.next();
+
+ for (final String k : row.keySet()) {
+ final Object value = row.get(k);
+ // For h2, transform a JdbcBlob into a byte[]
+ // See also LowerToCamelBeanMapper
+ if (value instanceof Blob) {
+ final Blob blob = (Blob) value;
+ row.put(k, blob.getBytes(0, (int) blob.length()));
+ }
+ }
+
out.write(row);
}
} finally {
diff --git a/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
new file mode 100644
index 0000000..0e78d66
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.glue;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.killbill.billing.lifecycle.ServiceFinder;
+import org.killbill.billing.util.broadcast.dao.BroadcastModelDao;
+import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
+import org.killbill.billing.util.dao.EntityHistoryModelDaoMapperFactory;
+import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.entity.Entity;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.billing.util.nodes.dao.NodeInfoModelDao;
+import org.killbill.billing.util.security.shiro.dao.RolesPermissionsModelDao;
+import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
+import org.killbill.billing.util.security.shiro.dao.UserModelDao;
+import org.killbill.billing.util.security.shiro.dao.UserRolesModelDao;
+import org.killbill.billing.util.validation.dao.DatabaseSchemaSqlDao;
+import org.killbill.bus.dao.BusEventModelDao;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.killbill.notificationq.dao.NotificationEventModelDao;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+public class IDBISetup {
+
+ public static List<? extends ResultSetMapperFactory> mapperFactoriesToRegister() {
+ final Builder<ResultSetMapperFactory> builder = ImmutableList.<ResultSetMapperFactory>builder();
+ builder.add(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(BroadcastModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(NodeInfoModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(UserModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(UserRolesModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(RolesPermissionsModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(BusEventModelDao.class));
+ builder.add(new LowerToCamelBeanMapperFactory(NotificationEventModelDao.class));
+
+ final ServiceFinder<EntitySqlDao> serviceFinder = new ServiceFinder<EntitySqlDao>(IDBISetup.class.getClassLoader(), EntitySqlDao.class.getName());
+ for (final Class<? extends EntitySqlDao> sqlObjectType : serviceFinder.getServices()) {
+ // Find the model class associated with this sqlObjectType (which is a SqlDao class) to register its mapper
+ // If a custom mapper is defined via @RegisterMapper, don't register our generic one
+ if (sqlObjectType.getGenericInterfaces() != null &&
+ sqlObjectType.getAnnotation(RegisterMapper.class) == null) {
+ for (int i = 0; i < sqlObjectType.getGenericInterfaces().length; i++) {
+ if (sqlObjectType.getGenericInterfaces()[i] instanceof ParameterizedType) {
+ final ParameterizedType type = (ParameterizedType) sqlObjectType.getGenericInterfaces()[i];
+ for (int j = 0; j < type.getActualTypeArguments().length; j++) {
+ final Type modelType = type.getActualTypeArguments()[j];
+ if (modelType instanceof Class) {
+ final Class modelClazz = (Class) modelType;
+ if (Entity.class.isAssignableFrom(modelClazz)) {
+ builder.add(new LowerToCamelBeanMapperFactory(modelClazz));
+ builder.add(new EntityHistoryModelDaoMapperFactory(modelClazz, sqlObjectType));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return builder.build();
+ }
+
+ public static List<? extends ResultSetMapper> mappersToRegister() {
+ return ImmutableList.<ResultSetMapper>builder()
+ .add(new AuditLogModelDaoMapper())
+ .add(new RecordIdIdMappingsMapper())
+ .add(new DatabaseSchemaSqlDao.ColumnInfoMapper())
+ .build();
+ }
+}
diff --git a/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java b/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
index 8d1c264..2c951ba 100644
--- a/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
+++ b/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
@@ -39,8 +39,6 @@ public class DefaultNodeInfoDao implements NodeInfoDao {
public DefaultNodeInfoDao(final IDBI dbi, final Clock clock) {
this.dbi = dbi;
this.clock = clock;
- ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(NodeInfoModelDao.class));
-
}
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java b/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
index ceedde4..e2be7f8 100644
--- a/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
@@ -20,17 +20,17 @@ package org.killbill.billing.util.nodes.dao;
import java.util.Date;
import java.util.List;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface NodeInfoSqlDao {
@SqlUpdate
- public void create(@BindBean final NodeInfoModelDao nodeInfo);
+ public void create(@SmartBindBean final NodeInfoModelDao nodeInfo);
@SqlUpdate
public void updateNodeInfo(@Bind("nodeName") final String nodeName, @Bind("nodeInfo") final String nodeInfo, @Bind("updatedDate") final Date updatedDate);
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
index 7dc71e7..013f859 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
@@ -54,9 +54,6 @@ public class DefaultUserDao implements UserDao {
this.dbi = dbi;
this.clock = clock;
this.securityConfig = securityConfig;
- ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(UserModelDao.class));
- ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(UserRolesModelDao.class));
- ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(RolesPermissionsModelDao.class));
}
@Override
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
index f277430..409f2a3 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
@@ -18,14 +18,14 @@
package org.killbill.billing.util.security.shiro.dao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface JDBCSessionSqlDao extends Transactional<JDBCSessionSqlDao> {
@SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
index 029b268..dccee99 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
@@ -19,14 +19,14 @@ package org.killbill.billing.util.security.shiro.dao;
import java.util.List;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface RolesPermissionsSqlDao extends Transactional<RolesPermissionsSqlDao> {
@SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
index 8c25d9b..e413146 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
@@ -20,14 +20,14 @@ package org.killbill.billing.util.security.shiro.dao;
import java.util.Date;
import java.util.List;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface UserRolesSqlDao extends Transactional<UserRolesSqlDao> {
@SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
index 6c7cd31..d9c659e 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
@@ -19,14 +19,14 @@ package org.killbill.billing.util.security.shiro.dao;
import java.util.Date;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface UsersSqlDao extends Transactional<UsersSqlDao> {
@SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
index 076ef0d..929fa42 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
@@ -1,7 +1,9 @@
/*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -19,36 +21,36 @@ package org.killbill.billing.util.tag.dao;
import java.util.Collection;
import java.util.List;
-import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
-import org.skife.jdbi.v2.sqlobject.SqlQuery;
-import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-
-import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
import org.killbill.billing.util.tag.TagDefinition;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.unstable.BindIn;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinitionModelDao, TagDefinition> {
@SqlQuery
public TagDefinitionModelDao getByName(@Bind("name") final String definitionName,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlUpdate
@Audited(ChangeType.DELETE)
public void markTagDefinitionAsDeleted(@Bind("id") final String definitionId,
- @BindBean final InternalCallContext context);
+ @SmartBindBean final InternalCallContext context);
@SqlQuery
public int tagDefinitionUsageCount(@Bind("id") final String definitionId,
- @BindBean final InternalTenantContext context);
+ @SmartBindBean final InternalTenantContext context);
@SqlQuery
- public List<TagDefinitionModelDao> getByIds(@UUIDCollectionBinder final Collection<String> definitionIds,
- @BindBean final InternalTenantContext context);
+ public List<TagDefinitionModelDao> getByIds(@BindIn("ids") final Collection<String> definitionIds,
+ @SmartBindBean final InternalTenantContext context);
}
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
index d1f0b67..257d5c3 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
import java.util.UUID;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -30,24 +30,24 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.billing.util.tag.Tag;
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
public interface TagSqlDao extends EntitySqlDao<TagModelDao, Tag> {
@SqlUpdate
@Audited(ChangeType.DELETE)
void markTagAsDeleted(@Bind("id") String tagId,
- @BindBean InternalCallContext context);
+ @SmartBindBean InternalCallContext context);
@SqlQuery
List<TagModelDao> getTagsForObject(@Bind("objectId") UUID objectId,
@Bind("objectType") ObjectType objectType,
- @BindBean InternalTenantContext internalTenantContext);
+ @SmartBindBean InternalTenantContext internalTenantContext);
@SqlQuery
List<TagModelDao> getTagsForObjectIncludedDeleted(@Bind("objectId") UUID objectId,
@Bind("objectType") ObjectType objectType,
- @BindBean InternalTenantContext internalTenantContext);
+ @SmartBindBean InternalTenantContext internalTenantContext);
}
diff --git a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
index 78e6d0f..aedee08 100644
--- a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -24,16 +24,14 @@ import java.util.List;
import javax.annotation.Nullable;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.killbill.billing.util.validation.DefaultColumnInfo;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
-import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
-@EntitySqlDaoStringTemplate
-@RegisterMapper(DatabaseSchemaSqlDao.ColumnInfoMapper.class)
+@KillBillSqlDaoStringTemplate
public interface DatabaseSchemaSqlDao {
@SqlQuery
diff --git a/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
index 49fa45a..a26bac2 100644
--- a/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group BroadcastSqlDao;
-
tableName() ::= "service_broadcasts"
@@ -29,9 +27,13 @@ allTableValues() ::= <<
, <tableValues()>
>>
+defaultOrderBy(prefix) ::= <<
+order by <prefix>record_id ASC
+>>
+
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
diff --git a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
index af3948a..ca8defa 100644
--- a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group CustomFieldSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
andCheckSoftDeletionWithComma(prefix) ::= "and <prefix>is_active"
@@ -41,14 +41,14 @@ where <idField("")> = :id
getCustomFieldsForObject() ::= <<
select
-<allTableFields()>
+<allTableFields("")>
from <tableName()>
where
object_id = :objectId
and object_type = :objectType
and is_active
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
;
>>
diff --git a/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
index b7e4d4b..6b6972f 100644
--- a/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
@@ -1,5 +1,3 @@
-group NonEntitySqlDao;
-
getRecordIdFromObject(tableName) ::= <<
select
record_id
diff --git a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
index 2d96592..26faf51 100644
--- a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
@@ -1,6 +1,3 @@
-group EntitySqlDao;
-
-
/****************** To override in each EntitySqlDao template file *****************************/
tableName() ::= ""
@@ -152,10 +149,10 @@ select
<allTableFields("t.")>
from <tableName()> t
join (
- select <recordIdField()>
+ select <recordIdField("")>
from <tableName()>
- where <CHECK_TENANT()>
- <andCheckSoftDeletionWithComma()>
+ where <CHECK_TENANT("")>
+ <andCheckSoftDeletionWithComma("")>
order by <orderBy> <ordering>
limit :rowCount offset :offset
) optimization on <recordIdField("optimization.")> = <recordIdField("t.")>
@@ -292,10 +289,10 @@ where (<searchQuery("t.")>)
create() ::= <<
insert into <tableName()> (
- <idField()>
-, <tableFields()>
-<accountRecordIdFieldWithComma()>
-<tenantRecordIdFieldWithComma()>
+ <idField("")>
+, <tableFields("")>
+<accountRecordIdFieldWithComma("")>
+<tenantRecordIdFieldWithComma("")>
)
values (
<idValue()>
@@ -338,7 +335,7 @@ auditTableValues() ::= <<
getHistoryForTargetRecordId() ::= <<
select
- <idField()>
+ <idField("")>
, <historyTableFields("t.")>
<accountRecordIdFieldWithComma("t.")>
<tenantRecordIdFieldWithComma("t.")>
@@ -351,10 +348,10 @@ order by <recordIdField("t.")> ASC
addHistoryFromTransaction() ::= <<
insert into <historyTableName()> (
- <idField()>
-, <historyTableFields()>
-<accountRecordIdFieldWithComma()>
-<tenantRecordIdFieldWithComma()>
+ <idField("")>
+, <historyTableFields("")>
+<accountRecordIdFieldWithComma("")>
+<tenantRecordIdFieldWithComma("")>
)
values (
<idValue()>
@@ -368,7 +365,7 @@ values (
insertAuditFromTransaction() ::= <<
insert into <auditTableName()> (
-<auditTableFields()>
+<auditTableFields("")>
)
values (
<auditTableValues()>
diff --git a/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
index 312c45d..87463e6 100644
--- a/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group NodeInfoSqlDao;
-
tableName() ::= "node_infos"
tableFields(prefix) ::= <<
@@ -31,7 +29,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -40,7 +38,7 @@ values (
>>
getByNodeName() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where node_name = :nodeName
and is_active
@@ -48,7 +46,7 @@ and is_active
>>
getAll() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where is_active
order by node_name asc
@@ -68,4 +66,4 @@ delete
from <tableName()>
where node_name = :nodeName
;
->>
\ No newline at end of file
+>>
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
index b002312..e6091e5 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group JDBCSessionSqlDao;
-
read() ::= <<
select
record_id
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
index 5da1774..febc7ee 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
@@ -1,6 +1,3 @@
-group RolesPermissionsSqlDao;
-
-
tableName() ::= "roles_permissions"
tableFields(prefix) ::= <<
@@ -37,7 +34,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -46,7 +43,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where record_id = :recordId
and is_active
@@ -55,7 +52,7 @@ and is_active
getByRoleName() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where role_name = :roleName
and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
index 0c9fe1c..3d4d327 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group UserRolesSqlDao;
-
tableName() ::= "user_roles"
tableFields(prefix) ::= <<
@@ -36,7 +34,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -45,7 +43,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where record_id = :recordId
and is_active
@@ -53,7 +51,7 @@ and is_active
>>
getByUsername() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where username = :username
and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
index 07bd4d5..94a6882 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group UsersSqlDao;
-
tableName() ::= "users"
tableFields(prefix) ::= <<
@@ -38,7 +36,7 @@ allTableValues() ::= <<
create() ::= <<
insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
)
values (
<tableValues()>
@@ -47,7 +45,7 @@ values (
>>
getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where record_id = :recordId
and is_active
@@ -55,7 +53,7 @@ and is_active
>>
getByUsername() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
from <tableName()>
where username = :username
and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
index a1efb99..cc1f546 100644
--- a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TagDefinitionDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "tag_definitions"
@@ -63,7 +63,7 @@ select
<allTableFields("t.")>
from <tableName()> t
where t.is_active
-and <idField("t.")> in (<ids: {id | :id_<i0>}; separator="," >)
+and <idField("t.")> in (<ids>)
<AND_CHECK_TENANT("t.")>
;
>>
diff --git a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
index 177ec5b..6f4d604 100644
--- a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TagDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "tags"
diff --git a/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
index e14db44..075fa67 100644
--- a/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group DatabaseSchemaSqlDao;
-
getSchemaInfo(schemaName) ::= <<
SELECT TABLE_NAME, COLUMN_NAME, IS_NULLABLE, DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE
diff --git a/util/src/test/java/org/killbill/billing/DBTestingHelper.java b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
index 7023039..7046879 100644
--- a/util/src/test/java/org/killbill/billing/DBTestingHelper.java
+++ b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -24,14 +24,13 @@ import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicBoolean;
import org.killbill.billing.platform.test.PlatformDBTestingHelper;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.glue.IDBISetup;
import org.killbill.billing.util.io.IOUtils;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
import com.google.common.base.MoreObjects;
@@ -58,9 +57,13 @@ public class DBTestingHelper extends PlatformDBTestingHelper {
final DBI dbi = (DBI) super.getDBI();
// Register KB specific mappers
if (initialized.compareAndSet(false, true)) {
- dbi.registerMapper(new AuditLogModelDaoMapper());
- dbi.registerMapper(new RecordIdIdMappingsMapper());
- dbi.registerMapper(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+ for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+ dbi.registerMapper(resultSetMapperFactory);
+ }
+
+ for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+ dbi.registerMapper(resultSetMapper);
+ }
}
return dbi;
}
diff --git a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
index a93add6..588d765 100644
--- a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
+++ b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
@@ -16,123 +16,61 @@
package org.killbill.billing.util.dao;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.util.regex.Pattern;
-import org.antlr.stringtemplate.StringTemplateGroup;
import org.killbill.billing.util.UtilTestSuiteNoDB;
+import org.stringtemplate.v4.STGroup;
+import org.stringtemplate.v4.STGroupFile;
import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import com.google.common.collect.ImmutableMap;
-
public class TestStringTemplateInheritance extends UtilTestSuiteNoDB {
- InputStream entityStream;
- InputStream kombuchaStream;
-
- @Override
- @BeforeMethod(groups = "fast")
- public void beforeMethod() throws Exception {
- super.beforeMethod();
- entityStream = this.getClass().getResourceAsStream("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg");
- kombuchaStream = this.getClass().getResourceAsStream("/org/killbill/billing/util/dao/Kombucha.sql.stg");
- }
-
- @Override
- @AfterMethod(groups = "fast")
- public void afterMethod() throws Exception {
- super.afterMethod();
- if (entityStream != null) {
- entityStream.close();
- }
- if (kombuchaStream != null) {
- kombuchaStream.close();
- }
- }
-
@Test(groups = "fast")
public void testCheckQueries() throws Exception {
- // From http://www.antlr.org/wiki/display/ST/ST+condensed+--+Templates+and+groups#STcondensed--Templatesandgroups-Withsupergroupfile:
- // there is no mechanism for automatically loading a mentioned super-group file
- new StringTemplateGroup(new InputStreamReader(entityStream));
-
- final StringTemplateGroup kombucha = new StringTemplateGroup(new InputStreamReader(kombuchaStream));
+ final STGroup kombucha = new STGroupFile(this.getClass().getResource("/org/killbill/billing/util/dao/Kombucha.sql.stg"), "UTF-8", '<', '>');
// Verify non inherited template
- Assert.assertEquals(kombucha.getInstanceOf("isIsTimeForKombucha").toString(), "select hour(current_timestamp(0)) = 17 as is_time;");
+ Assert.assertEquals(kombucha.getInstanceOf("isIsTimeForKombucha").render(), "select hour(current_timestamp(0)) = 17 as is_time;");
// Verify inherited templates
- assertPattern(kombucha.getInstanceOf("getById").toString(), "select\r?\n" +
- " t.record_id\r?\n" +
- ", t.id\r?\n" +
- ", t.tea\r?\n" +
- ", t.mushroom\r?\n" +
- ", t.sugar\r?\n" +
- ", t.account_record_id\r?\n" +
- ", t.tenant_record_id\r?\n" +
- "from kombucha t\r?\n" +
- "where t.id = :id\r?\n" +
- "and t.tenant_record_id = :tenantRecordId\r?\n" +
- ";");
- assertPattern(kombucha.getInstanceOf("getByRecordId").toString(), "select\r?\n" +
- " t.record_id\r?\n" +
- ", t.id\r?\n" +
- ", t.tea\r?\n" +
- ", t.mushroom\r?\n" +
- ", t.sugar\r?\n" +
- ", t.account_record_id\r?\n" +
- ", t.tenant_record_id\r?\n" +
- "from kombucha t\r?\n" +
- "where t.record_id = :recordId\r?\n" +
- "and t.tenant_record_id = :tenantRecordId\r?\n" +
- ";");
- assertPattern(kombucha.getInstanceOf("getRecordId").toString(), "select\r?\n" +
+ assertPattern(kombucha.getInstanceOf("getById").render(), "select\r?\n" +
+ " t.record_id\r?\n" +
+ ", t.id\r?\n" +
+ ", t.tea\r?\n" +
+ ", t.mushroom\r?\n" +
+ ", t.sugar\r?\n" +
+ ", t.account_record_id\r?\n" +
+ ", t.tenant_record_id\r?\n" +
+ "from kombucha t\r?\n" +
+ "where t.id = :id\r?\n" +
+ "and t.tenant_record_id = :tenantRecordId\r?\n" +
+ ";");
+ assertPattern(kombucha.getInstanceOf("getByRecordId").render(), "select\r?\n" +
" t.record_id\r?\n" +
+ ", t.id\r?\n" +
+ ", t.tea\r?\n" +
+ ", t.mushroom\r?\n" +
+ ", t.sugar\r?\n" +
+ ", t.account_record_id\r?\n" +
+ ", t.tenant_record_id\r?\n" +
"from kombucha t\r?\n" +
- "where t.id = :id\r?\n" +
+ "where t.record_id = :recordId\r?\n" +
"and t.tenant_record_id = :tenantRecordId\r?\n" +
";");
- assertPattern(kombucha.getInstanceOf("getHistoryRecordId").toString(), "select\r?\n" +
- " max\\(t.record_id\\)\r?\n" +
- "from kombucha_history t\r?\n" +
- "where t.target_record_id = :targetRecordId\r?\n" +
- "and t.tenant_record_id = :tenantRecordId\r?\n" +
- ";");
- assertPattern(kombucha.getInstanceOf("getAll").toString(), "select\r?\n" +
- " t.record_id\r?\n" +
- ", t.id\r?\n" +
- ", t.tea\r?\n" +
- ", t.mushroom\r?\n" +
- ", t.sugar\r?\n" +
- ", t.account_record_id\r?\n" +
- ", t.tenant_record_id\r?\n" +
- "from kombucha t\r?\n" +
- "where t.tenant_record_id = :tenantRecordId\r?\n" +
- "order by t.record_id ASC\r?\n" +
- ";");
- assertPattern(kombucha.getInstanceOf("get", ImmutableMap.<String, String>of("orderBy", "record_id", "offset", "3", "rowCount", "12", "ordering", "ASC")).toString(), "select\r?\n" +
- " t.record_id\r?\n" +
- ", t.id\r?\n" +
- ", t.tea\r?\n" +
- ", t.mushroom\r?\n" +
- ", t.sugar\r?\n" +
- ", t.account_record_id\r?\n" +
- ", t.tenant_record_id\r?\n" +
- "from kombucha t\r?\n" +
- "join \\(\r?\n" +
- " select record_id\r?\n" +
- " from kombucha\r?\n" +
- " where tenant_record_id = :tenantRecordId\r?\n" +
- " order by record_id ASC\r?\n" +
- " limit :rowCount offset :offset\r?\n" +
- "\\) optimization on optimization.record_id = t.record_id\r?\n" +
- "order by t.record_id ASC\r?\n" +
- ";");
- assertPattern(kombucha.getInstanceOf("test").toString(), "select\r?\n" +
+ assertPattern(kombucha.getInstanceOf("getRecordId").render(), "select\r?\n" +
+ " t.record_id\r?\n" +
+ "from kombucha t\r?\n" +
+ "where t.id = :id\r?\n" +
+ "and t.tenant_record_id = :tenantRecordId\r?\n" +
+ ";");
+ assertPattern(kombucha.getInstanceOf("getHistoryRecordId").render(), "select\r?\n" +
+ " max\\(t.record_id\\)\r?\n" +
+ "from kombucha_history t\r?\n" +
+ "where t.target_record_id = :targetRecordId\r?\n" +
+ "and t.tenant_record_id = :tenantRecordId\r?\n" +
+ ";");
+ assertPattern(kombucha.getInstanceOf("getAll").render(), "select\r?\n" +
" t.record_id\r?\n" +
", t.id\r?\n" +
", t.tea\r?\n" +
@@ -142,57 +80,92 @@ public class TestStringTemplateInheritance extends UtilTestSuiteNoDB {
", t.tenant_record_id\r?\n" +
"from kombucha t\r?\n" +
"where t.tenant_record_id = :tenantRecordId\r?\n" +
- "limit 1\r?\n" +
+ "order by t.record_id ASC\r?\n" +
";");
- assertPattern(kombucha.getInstanceOf("addHistoryFromTransaction").toString(), "insert into kombucha_history \\(\r?\n" +
- " id\r?\n" +
- ", target_record_id\r?\n" +
- ", change_type\r?\n" +
- ", tea\r?\n" +
- ", mushroom\r?\n" +
- ", sugar\r?\n" +
- ", account_record_id\r?\n" +
- ", tenant_record_id\r?\n" +
- "\\)\r?\n" +
- "values \\(\r?\n" +
- " :id\r?\n" +
- ", :targetRecordId\r?\n" +
- ", :changeType\r?\n" +
- ", :tea\r?\n" +
- ", :mushroom\r?\n" +
- ", :sugar\r?\n" +
- ", :accountRecordId\r?\n" +
- ", :tenantRecordId\r?\n" +
- "\\)\r?\n" +
- ";");
+ assertPattern(kombucha.getInstanceOf("get")
+ .add("orderBy", "record_id")
+ .add("offset", "3")
+ .add("rowCount", "12")
+ .add("ordering", "ASC")
+ .render(), "select\r?\n" +
+ " t.record_id\r?\n" +
+ ", t.id\r?\n" +
+ ", t.tea\r?\n" +
+ ", t.mushroom\r?\n" +
+ ", t.sugar\r?\n" +
+ ", t.account_record_id\r?\n" +
+ ", t.tenant_record_id\r?\n" +
+ "from kombucha t\r?\n" +
+ "join \\(\r?\n" +
+ " select record_id\r?\n" +
+ " from kombucha\r?\n" +
+ " where tenant_record_id = :tenantRecordId\r?\n" +
+ " order by record_id ASC\r?\n" +
+ " limit :rowCount offset :offset\r?\n" +
+ "\\) optimization on optimization.record_id = t.record_id\r?\n" +
+ "order by t.record_id ASC\r?\n" +
+ ";");
+ assertPattern(kombucha.getInstanceOf("test").render(), "select\r?\n" +
+ " t.record_id\r?\n" +
+ ", t.id\r?\n" +
+ ", t.tea\r?\n" +
+ ", t.mushroom\r?\n" +
+ ", t.sugar\r?\n" +
+ ", t.account_record_id\r?\n" +
+ ", t.tenant_record_id\r?\n" +
+ "from kombucha t\r?\n" +
+ "where t.tenant_record_id = :tenantRecordId\r?\n" +
+ "limit 1\r?\n" +
+ ";");
+ assertPattern(kombucha.getInstanceOf("addHistoryFromTransaction").render(), "insert into kombucha_history \\(\r?\n" +
+ " id\r?\n" +
+ ", target_record_id\r?\n" +
+ ", change_type\r?\n" +
+ ", tea\r?\n" +
+ ", mushroom\r?\n" +
+ ", sugar\r?\n" +
+ ", account_record_id\r?\n" +
+ ", tenant_record_id\r?\n" +
+ "\\)\r?\n" +
+ "values \\(\r?\n" +
+ " :id\r?\n" +
+ ", :targetRecordId\r?\n" +
+ ", :changeType\r?\n" +
+ ", :tea\r?\n" +
+ ", :mushroom\r?\n" +
+ ", :sugar\r?\n" +
+ ", :accountRecordId\r?\n" +
+ ", :tenantRecordId\r?\n" +
+ "\\)\r?\n" +
+ ";");
- assertPattern(kombucha.getInstanceOf("insertAuditFromTransaction").toString(), "insert into audit_log \\(\r?\n" +
- "id\r?\n" +
- ", table_name\r?\n" +
- ", target_record_id\r?\n" +
- ", change_type\r?\n" +
- ", created_by\r?\n" +
- ", reason_code\r?\n" +
- ", comments\r?\n" +
- ", user_token\r?\n" +
- ", created_date\r?\n" +
- ", account_record_id\r?\n" +
- ", tenant_record_id\r?\n" +
- "\\)\r?\n" +
- "values \\(\r?\n" +
- " :id\r?\n" +
- ", :tableName\r?\n" +
- ", :targetRecordId\r?\n" +
- ", :changeType\r?\n" +
- ", :createdBy\r?\n" +
- ", :reasonCode\r?\n" +
- ", :comments\r?\n" +
- ", :userToken\r?\n" +
- ", :createdDate\r?\n" +
- ", :accountRecordId\r?\n" +
- ", :tenantRecordId\r?\n" +
- "\\)\r?\n" +
- ";");
+ assertPattern(kombucha.getInstanceOf("insertAuditFromTransaction").render(), "insert into audit_log \\(\r?\n" +
+ "id\r?\n" +
+ ", table_name\r?\n" +
+ ", target_record_id\r?\n" +
+ ", change_type\r?\n" +
+ ", created_by\r?\n" +
+ ", reason_code\r?\n" +
+ ", comments\r?\n" +
+ ", user_token\r?\n" +
+ ", created_date\r?\n" +
+ ", account_record_id\r?\n" +
+ ", tenant_record_id\r?\n" +
+ "\\)\r?\n" +
+ "values \\(\r?\n" +
+ " :id\r?\n" +
+ ", :tableName\r?\n" +
+ ", :targetRecordId\r?\n" +
+ ", :changeType\r?\n" +
+ ", :createdBy\r?\n" +
+ ", :reasonCode\r?\n" +
+ ", :comments\r?\n" +
+ ", :userToken\r?\n" +
+ ", :createdDate\r?\n" +
+ ", :accountRecordId\r?\n" +
+ ", :tenantRecordId\r?\n" +
+ "\\)\r?\n" +
+ ";");
}
private void assertPattern(final String actual, final String expected) {
diff --git a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
index 02c6361..d2dc3a1 100644
--- a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
+++ b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
@@ -24,7 +24,7 @@ import org.killbill.billing.util.UtilTestSuiteWithEmbeddedDB;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.dao.EntityModelDao;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
public class TestStringTemplateInheritanceWithJdbi extends UtilTestSuiteWithEmbeddedDB {
@@ -32,7 +32,7 @@ public class TestStringTemplateInheritanceWithJdbi extends UtilTestSuiteWithEmbe
private static interface KombuchaModelDao extends EntityModelDao<Kombucha> {}
- @EntitySqlDaoStringTemplate("/org/killbill/billing/util/dao/Kombucha.sql.stg")
+ @KillBillSqlDaoStringTemplate("/org/killbill/billing/util/dao/Kombucha.sql.stg")
private static interface KombuchaSqlDao extends EntitySqlDao<KombuchaModelDao, Kombucha> {
@SqlQuery
diff --git a/util/src/test/java/org/killbill/billing/util/export/dao/TestDatabaseExportDao.java b/util/src/test/java/org/killbill/billing/util/export/dao/TestDatabaseExportDao.java
index e9b497f..01fe087 100644
--- a/util/src/test/java/org/killbill/billing/util/export/dao/TestDatabaseExportDao.java
+++ b/util/src/test/java/org/killbill/billing/util/export/dao/TestDatabaseExportDao.java
@@ -1,7 +1,9 @@
/*
- * Copyright 2010-2012 Ning, Inc.
+ * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -30,6 +32,8 @@ import org.killbill.billing.util.UtilTestSuiteWithEmbeddedDB;
import org.killbill.billing.util.api.DatabaseExportOutputStream;
import org.killbill.billing.util.validation.dao.DatabaseSchemaDao;
+import com.ning.compress.lzf.LZFEncoder;
+
public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
@@ -48,6 +52,7 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
final Date updatedDate = new Date(382910622000L);
final String updatedBy = UUID.randomUUID().toString().substring(0, 4);
+ final byte[] properties = LZFEncoder.encode(new byte[] { 'c', 'a', 'f', 'e' });
final String tableNameA = "test_database_export_dao_a";
final String tableNameB = "test_database_export_dao_b";
dbi.withHandle(new HandleCallback<Void>() {
@@ -56,6 +61,7 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
handle.execute("drop table if exists " + tableNameA);
handle.execute("create table " + tableNameA + "(record_id serial unique," +
"a_column char default 'a'," +
+ "blob_column mediumblob," +
"account_record_id bigint /*! unsigned */ not null," +
"tenant_record_id bigint /*! unsigned */ not null default 0," +
"primary key(record_id));");
@@ -65,8 +71,8 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
"account_record_id bigint /*! unsigned */ not null," +
"tenant_record_id bigint /*! unsigned */ not null default 0," +
"primary key(record_id));");
- handle.execute("insert into " + tableNameA + " (account_record_id, tenant_record_id) values (?, ?)",
- internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
+ handle.execute("insert into " + tableNameA + " (blob_column, account_record_id, tenant_record_id) values (?, ?, ?)",
+ properties, internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
handle.execute("insert into " + tableNameB + " (account_record_id, tenant_record_id) values (?, ?)",
internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
@@ -83,8 +89,8 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
Assert.assertEquals(newDump, "-- accounts record_id|id|external_key|email|name|first_name_length|currency|billing_cycle_day_local|payment_method_id|time_zone|locale|address1|address2|company_name|city|state_or_province|country|postal_code|phone|migrated|is_notified_for_invoices|created_date|created_by|updated_date|updated_by|tenant_record_id\n" +
String.format("%s|%s||%s|%s|%s||||||||||||||false|%s|%s|%s|%s|%s|%s", internalCallContext.getAccountRecordId(), accountId, accountEmail, accountName, firstNameLength,
isNotifiedForInvoices, "1970-05-24T18:33:02.000+0000", createdBy, "1982-02-18T20:03:42.000+0000", updatedBy, internalCallContext.getTenantRecordId()) + "\n" +
- "-- " + tableNameA + " record_id|a_column|account_record_id|tenant_record_id\n" +
- "1|a|" + internalCallContext.getAccountRecordId() + "|" + internalCallContext.getTenantRecordId() + "\n" +
+ "-- " + tableNameA + " record_id|a_column|blob_column|account_record_id|tenant_record_id\n" +
+ "1|a|WlYAAARjYWZl|" + internalCallContext.getAccountRecordId() + "|" + internalCallContext.getTenantRecordId() + "\n" +
"-- " + tableNameB + " record_id|b_column|account_record_id|tenant_record_id\n" +
"1|b|" + internalCallContext.getAccountRecordId() + "|" + internalCallContext.getTenantRecordId() + "\n");
diff --git a/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg b/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
index cbb4410..52dbbc8 100644
--- a/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
+++ b/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
@@ -1,4 +1,4 @@
-group Kombucha: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "kombucha"