Details
diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index c4078b4..bb6961c 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -93,7 +93,7 @@ public class AnalyticsListener {
@Subscribe
public void handleAccountCreation(final AccountCreationEvent event) {
- bacDao.accountCreated(event.getData(), createCallContext(event));
+ bacDao.accountUpdated(event.getId(), createCallContext(event));
}
@Subscribe
@@ -125,21 +125,21 @@ public class AnalyticsListener {
@Subscribe
public void handlePaymentInfo(final PaymentInfoEvent paymentInfo) {
bipDao.invoicePaymentPosted(paymentInfo.getAccountId(),
- paymentInfo.getPaymentId(),
- paymentInfo.getExtFirstPaymentRefId(),
- paymentInfo.getExtSecondPaymentRefId(),
- paymentInfo.getStatus().toString(),
- createCallContext(paymentInfo));
+ paymentInfo.getPaymentId(),
+ paymentInfo.getExtFirstPaymentRefId(),
+ paymentInfo.getExtSecondPaymentRefId(),
+ paymentInfo.getStatus().toString(),
+ createCallContext(paymentInfo));
}
@Subscribe
public void handlePaymentError(final PaymentErrorEvent paymentError) {
bipDao.invoicePaymentPosted(paymentError.getAccountId(),
- paymentError.getPaymentId(),
- null,
- null,
- paymentError.getMessage(),
- createCallContext(paymentError));
+ paymentError.getPaymentId(),
+ null,
+ null,
+ paymentError.getMessage(),
+ createCallContext(paymentError));
}
@Subscribe
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
index fb4fd15..b134a9e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
@@ -23,12 +23,13 @@ import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.account.api.AccountData;
import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
import com.ning.billing.analytics.model.BusinessAccount;
import com.ning.billing.catalog.api.Currency;
@@ -62,21 +63,6 @@ public class BusinessAccountDao {
this.paymentApi = paymentApi;
}
- public void accountCreated(final AccountData data, final InternalCallContext context) {
- final Account account;
- try {
- account = accountApi.getAccountByKey(data.getExternalKey(), context);
- accountUpdated(account.getId(), context);
- } catch (AccountApiException e) {
- log.warn("Error encountered creating BusinessAccount", e);
- }
- }
-
- /**
- * Notification handler for Invoice creations
- *
- * @param accountId account id associated with the created invoice
- */
public void accountUpdated(final UUID accountId, final InternalCallContext context) {
final Account account;
try {
@@ -86,24 +72,27 @@ public class BusinessAccountDao {
return;
}
- updateAccountInTransaction(account, sqlDao, context);
+ final BusinessAccount bac = createBusinessAccountFromAccount(account, context);
+ sqlDao.inTransaction(new Transaction<Void, BusinessAccountSqlDao>() {
+ @Override
+ public Void inTransaction(final BusinessAccountSqlDao transactional, final TransactionStatus status) throws Exception {
+ updateAccountInTransaction(bac, transactional, context);
+ return null;
+ }
+ });
}
- public void updateAccountInTransaction(final Account account, final BusinessAccountSqlDao transactional, final InternalCallContext context) {
- BusinessAccount bac = transactional.getAccount(account.getId().toString(), context);
- if (bac == null) {
- bac = new BusinessAccount(account.getId());
- updateBusinessAccountFromAccount(account, bac, context);
- log.info("ACCOUNT CREATION " + bac);
- transactional.createAccount(bac, context);
- } else {
- updateBusinessAccountFromAccount(account, bac, context);
- log.info("ACCOUNT UPDATE " + bac);
- transactional.saveAccount(bac, context);
- }
+ // Called also from BusinessInvoiceDao and BusinessInvoicePaymentDao.
+ // Note: computing the BusinessAccount object is fairly expensive, hence should be done outside of the transaction
+ public void updateAccountInTransaction(final BusinessAccount bac, final BusinessAccountSqlDao transactional, final InternalCallContext context) {
+ log.info("ACCOUNT UPDATE " + bac);
+ transactional.deleteAccount(bac.getAccountId().toString(), context);
+ transactional.createAccount(bac, context);
}
- private void updateBusinessAccountFromAccount(final Account account, final BusinessAccount bac, final InternalTenantContext context) {
+ public BusinessAccount createBusinessAccountFromAccount(final Account account, final InternalTenantContext context) {
+ final BusinessAccount bac = new BusinessAccount(account.getId());
+
bac.setName(account.getName());
bac.setKey(account.getExternalKey());
final Currency currency = account.getCurrency();
@@ -164,5 +153,7 @@ public class BusinessAccountDao {
} catch (PaymentApiException ex) {
log.error(String.format("Failed to handle account update for account %s", account.getId()), ex);
}
+
+ return bac;
}
}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
index cad45b5..6d59d8c 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
@@ -35,6 +35,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
import com.ning.billing.analytics.dao.BusinessInvoiceItemSqlDao;
import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
+import com.ning.billing.analytics.model.BusinessAccount;
import com.ning.billing.analytics.model.BusinessInvoice;
import com.ning.billing.analytics.model.BusinessInvoiceItem;
import com.ning.billing.catalog.api.CatalogApiException;
@@ -109,6 +110,9 @@ public class BusinessInvoiceDao {
businessInvoices.put(businessInvoice, businessInvoiceItems);
}
+ // Update the account record
+ final BusinessAccount bac = businessAccountDao.createBusinessAccountFromAccount(account, context);
+
// Delete and recreate invoice and invoice items in the transaction
sqlDao.inTransaction(new Transaction<Void, BusinessInvoiceSqlDao>() {
@Override
@@ -117,7 +121,7 @@ public class BusinessInvoiceDao {
// Update balance, last invoice date and total invoice balance in BAC
final BusinessAccountSqlDao accountSqlDao = transactional.become(BusinessAccountSqlDao.class);
- businessAccountDao.updateAccountInTransaction(account, accountSqlDao, context);
+ businessAccountDao.updateAccountInTransaction(bac, accountSqlDao, context);
return null;
}
});
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
index 17be9a6..9d3b7b2 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
@@ -31,6 +31,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
import com.ning.billing.analytics.dao.BusinessInvoicePaymentSqlDao;
import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
+import com.ning.billing.analytics.model.BusinessAccount;
import com.ning.billing.analytics.model.BusinessInvoicePayment;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
@@ -158,6 +159,9 @@ public class BusinessInvoicePaymentDao {
invoicePaymentType,
linkedInvoicePaymentId);
+ // Update the account record
+ final BusinessAccount bac = accountDao.createBusinessAccountFromAccount(account, context);
+
// Make sure to limit the scope of the transaction to avoid InnoDB deadlocks
invoicePaymentSqlDao.inTransaction(new Transaction<Void, BusinessInvoicePaymentSqlDao>() {
@Override
@@ -176,7 +180,7 @@ public class BusinessInvoicePaymentDao {
// Update bac to get the latest account balance, total invoice balance, etc.
final BusinessAccountSqlDao accountSqlDao = transactional.become(BusinessAccountSqlDao.class);
- accountDao.updateAccountInTransaction(account, accountSqlDao, context);
+ accountDao.updateAccountInTransaction(bac, accountSqlDao, context);
log.info("Added payment {}", businessInvoicePayment);
return null;
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
index f081a7a..f223626 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
@@ -55,5 +55,9 @@ public interface BusinessAccountSqlDao extends Transactional<BusinessAccountSqlD
@InternalTenantContextBinder final InternalCallContext context);
@SqlUpdate
+ int deleteAccount(@Bind("account_id") final String accountId,
+ @InternalTenantContextBinder final InternalCallContext context);
+
+ @SqlUpdate
void test(@InternalTenantContextBinder final InternalTenantContext context);
}
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
index 3fab53f..07e1b96 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountSqlDao.sql.stg
@@ -114,6 +114,10 @@ saveAccount() ::= <<
;
>>
+deleteAccount(account_id) ::= <<
+delete from bac where account_id = :account_id <AND_CHECK_TENANT()>;
+>>
+
test() ::= <<
select 1 from bac where <CHECK_TENANT()>;
>>