killbill-memoizeit

Issue#335 - tests

5/2/2018 10:49:34 PM

Details

diff --git a/account/src/test/java/org/killbill/billing/account/dao/MockAccountDao.java b/account/src/test/java/org/killbill/billing/account/dao/MockAccountDao.java
index 077ca8d..69e8199 100644
--- a/account/src/test/java/org/killbill/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/org/killbill/billing/account/dao/MockAccountDao.java
@@ -193,4 +193,9 @@ public class MockAccountDao extends MockEntityDaoBase<AccountModelDao, Account, 
     public List<AuditLogWithHistory> getAuditLogsWithHistoryForId(final UUID accountId, final AuditLevel auditLevel, final InternalTenantContext context) throws AccountApiException {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public List<AuditLogWithHistory> getEmailAuditLogsWithHistoryForId(final UUID accountEmailId, final AuditLevel auditLevel, final InternalTenantContext context) throws AccountApiException {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorWithDB.java b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorWithDB.java
index 3912a51..e444b0a 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorWithDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorWithDB.java
@@ -27,8 +27,12 @@ import org.killbill.billing.payment.api.PaymentMethod;
 import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.dao.PaymentMethodModelDao;
 import org.killbill.billing.payment.dao.PaymentMethodSqlDao;
+import org.killbill.billing.payment.dao.PaymentModelDao;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.dao.EntityHistoryModelDao;
+import org.killbill.billing.util.dao.TableName;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -69,35 +73,34 @@ public class TestPaymentMethodProcessorWithDB extends PaymentTestSuiteWithEmbedd
         final UUID paymentMethodId = paymentMethodProcessor.createOrGetExternalPaymentMethod("pmExternalKey", account, PLUGIN_PROPERTIES, callContext, internalCallContext);
         final PaymentMethodModelDao paymentMethodModelDao = paymentDao.getPaymentMethod(paymentMethodId, internalCallContext);
 
-        final List<EntityHistoryModelDao<PaymentMethodModelDao, PaymentMethod>> history1 = getPaymentMethodHistory(paymentMethodModelDao.getRecordId());
-        Assert.assertEquals(history1.size(), 1);
-        Assert.assertEquals(history1.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertEquals(history1.get(0).getEntity().getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
-        Assert.assertEquals(history1.get(0).getEntity().getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
-        Assert.assertEquals(history1.get(0).getEntity().getExternalKey(), paymentMethodModelDao.getExternalKey());
-        Assert.assertTrue(history1.get(0).getEntity().isActive());
+        List<AuditLogWithHistory> auditLogsWithHistory = paymentDao.getPaymentMethodAuditLogsWithHistoryForId(paymentMethodModelDao.getId(), AuditLevel.FULL, internalCallContext);
+        Assert.assertEquals(auditLogsWithHistory.size(), 1);
+
+        PaymentMethodModelDao history1 = (PaymentMethodModelDao) auditLogsWithHistory.get(0).getEntity();
+        Assert.assertEquals(auditLogsWithHistory.get(0).getChangeType(), ChangeType.INSERT);
+        Assert.assertEquals(history1.getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
+        Assert.assertEquals(history1.getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
+        Assert.assertEquals(history1.getExternalKey(), paymentMethodModelDao.getExternalKey());
+        Assert.assertTrue(history1.isActive());
 
         paymentMethodProcessor.deletedPaymentMethod(account, paymentMethodId, true, true, ImmutableList.<PluginProperty>of(), callContext, internalCallContext);
 
-        final List<EntityHistoryModelDao<PaymentMethodModelDao, PaymentMethod>> history2 = getPaymentMethodHistory(paymentMethodModelDao.getRecordId());
-        Assert.assertEquals(history2.size(), 2);
-        Assert.assertEquals(history2.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertEquals(history2.get(0).getEntity().getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
-        Assert.assertEquals(history2.get(0).getEntity().getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
-        Assert.assertEquals(history2.get(0).getEntity().getExternalKey(), paymentMethodModelDao.getExternalKey());
-        Assert.assertTrue(history2.get(0).getEntity().isActive());
+        auditLogsWithHistory = paymentDao.getPaymentMethodAuditLogsWithHistoryForId(paymentMethodModelDao.getId(), AuditLevel.FULL, internalCallContext);
+        Assert.assertEquals(auditLogsWithHistory.size(), 2);
+
+        history1 = (PaymentMethodModelDao) auditLogsWithHistory.get(0).getEntity();
+        PaymentMethodModelDao history2 = (PaymentMethodModelDao) auditLogsWithHistory.get(1).getEntity();
+        Assert.assertEquals(auditLogsWithHistory.get(0).getChangeType(), ChangeType.INSERT);
+        Assert.assertEquals(history1.getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
+        Assert.assertEquals(history1.getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
+        Assert.assertEquals(history1.getExternalKey(), paymentMethodModelDao.getExternalKey());
+        Assert.assertTrue(history1.isActive());
         // Note: it looks like we don't consider this as a DELETE, probably because we can un-delete such payment methods?
-        Assert.assertEquals(history2.get(1).getChangeType(), ChangeType.UPDATE);
-        Assert.assertEquals(history2.get(1).getEntity().getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
-        Assert.assertEquals(history2.get(1).getEntity().getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
-        Assert.assertEquals(history2.get(1).getEntity().getExternalKey(), paymentMethodModelDao.getExternalKey());
+        Assert.assertEquals(auditLogsWithHistory.get(1).getChangeType(), ChangeType.UPDATE);
+        Assert.assertEquals(history2.getAccountRecordId(), paymentMethodModelDao.getAccountRecordId());
+        Assert.assertEquals(history2.getTenantRecordId(), paymentMethodModelDao.getTenantRecordId());
+        Assert.assertEquals(history2.getExternalKey(), paymentMethodModelDao.getExternalKey());
         // Note: upon deletion, the recorded state is the same as before the delete
-        Assert.assertTrue(history2.get(1).getEntity().isActive());
-    }
-
-    private List<EntityHistoryModelDao<PaymentMethodModelDao, PaymentMethod>> getPaymentMethodHistory(final Long paymentMethodRecordId) {
-        // See https://github.com/killbill/killbill/issues/335
-        final PaymentMethodSqlDao paymentMethodSqlDao = dbi.onDemand(PaymentMethodSqlDao.class);
-        return paymentMethodSqlDao.getHistoryForTargetRecordId(paymentMethodRecordId, internalCallContext);
+        Assert.assertTrue(history2.isActive());
     }
 }
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 1db8422..5380fee 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
@@ -39,6 +39,8 @@ import org.killbill.billing.payment.api.Payment;
 import org.killbill.billing.payment.api.PaymentApiException;
 import org.killbill.billing.payment.api.TransactionStatus;
 import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.entity.DefaultPagination;
 import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
@@ -426,6 +428,26 @@ public class MockPaymentDao extends MockEntityDaoBase<PaymentModelDao, Payment, 
     }
 
     @Override
+    public List<AuditLogWithHistory> getPaymentAuditLogsWithHistoryForId(final UUID paymentId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AuditLogWithHistory> getPaymentMethodAuditLogsWithHistoryForId(final UUID paymentMethodId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AuditLogWithHistory> getPaymentAttemptAuditLogsWithHistoryForId(final UUID paymentAttemptId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AuditLogWithHistory> getPaymentTransactionAuditLogsWithHistoryForId(final UUID paymentTransactionId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId, final InternalTenantContext context) {
         return getPaymentMethod(paymentMethodId, context);
     }
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 c587c69..37332e3 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
@@ -26,6 +26,7 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.dao.AccountModelDao;
 import org.killbill.billing.api.FlakyRetryAnalyzer;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.payment.PaymentTestSuiteWithEmbeddedDB;
@@ -34,6 +35,8 @@ import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.api.TransactionStatus;
 import org.killbill.billing.payment.api.TransactionType;
 import org.killbill.billing.payment.dao.PluginPropertySerializer.PluginPropertySerializerException;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.dao.EntityHistoryModelDao;
 import org.killbill.billing.util.entity.Pagination;
@@ -119,16 +122,18 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment.getPaymentMethodId(), paymentModelDao.getPaymentMethodId());
         assertNull(savedPayment.getStateName());
 
-        final List<EntityHistoryModelDao<PaymentModelDao, Payment>> history1 = getPaymentHistory(savedPayment.getRecordId());
-        Assert.assertEquals(history1.size(), 1);
-        Assert.assertEquals(history1.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertEquals(history1.get(0).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history1.get(0).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history1.get(0).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertEquals(history1.get(0).getEntity().getStateName(), savedPayment.getStateName());
-        Assert.assertEquals(history1.get(0).getEntity().getLastSuccessStateName(), savedPayment.getLastSuccessStateName());
-        Assert.assertNull(history1.get(0).getEntity().getStateName());
-        Assert.assertNull(history1.get(0).getEntity().getLastSuccessStateName());
+        List<AuditLogWithHistory> auditLogsWithHistory = paymentDao.getPaymentAuditLogsWithHistoryForId(savedPayment.getId(), AuditLevel.FULL, internalCallContext);
+        Assert.assertEquals(auditLogsWithHistory.size(), 1);
+
+        PaymentModelDao history1 = (PaymentModelDao) auditLogsWithHistory.get(0).getEntity();
+        Assert.assertEquals(auditLogsWithHistory.get(0).getChangeType(), ChangeType.INSERT);
+        Assert.assertEquals(history1.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history1.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history1.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertEquals(history1.getStateName(), savedPayment.getStateName());
+        Assert.assertEquals(history1.getLastSuccessStateName(), savedPayment.getLastSuccessStateName());
+        Assert.assertNull(history1.getStateName());
+        Assert.assertNull(history1.getLastSuccessStateName());
 
         final PaymentModelDao savedPayment2 = paymentDao.getPayment(savedPayment.getId(), internalCallContext);
         assertEquals(savedPayment2.getId(), paymentModelDao.getId());
@@ -175,19 +180,22 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedTransactionModelDao2.getAmount().compareTo(BigDecimal.TEN), 0);
         assertEquals(savedTransactionModelDao2.getCurrency(), Currency.AED);
 
-        final List<EntityHistoryModelDao<PaymentModelDao, Payment>> history2 = getPaymentHistory(savedPayment.getRecordId());
-        Assert.assertEquals(history2.size(), 2);
-        Assert.assertEquals(history2.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertEquals(history2.get(0).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history2.get(0).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history2.get(0).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertEquals(history2.get(1).getChangeType(), ChangeType.UPDATE);
-        Assert.assertEquals(history2.get(1).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history2.get(1).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history2.get(1).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertTrue(history2.get(1).getEntity().getUpdatedDate().compareTo(history2.get(0).getEntity().getUpdatedDate()) >= 0);
-        Assert.assertNull(history2.get(1).getEntity().getStateName());
-        Assert.assertNull(history2.get(1).getEntity().getLastSuccessStateName());
+        auditLogsWithHistory = paymentDao.getPaymentAuditLogsWithHistoryForId(savedPayment.getId(), AuditLevel.FULL, internalCallContext);
+        Assert.assertEquals(auditLogsWithHistory.size(), 2);
+
+        history1 = (PaymentModelDao) auditLogsWithHistory.get(0).getEntity();
+        PaymentModelDao history2 = (PaymentModelDao) auditLogsWithHistory.get(1).getEntity();
+        Assert.assertEquals(auditLogsWithHistory.get(0).getChangeType(), ChangeType.INSERT);
+        Assert.assertEquals(history1.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history1.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history1.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertEquals(auditLogsWithHistory.get(1).getChangeType(), ChangeType.UPDATE);
+        Assert.assertEquals(history2.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history2.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history2.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertTrue(history2.getUpdatedDate().compareTo(history2.getUpdatedDate()) >= 0);
+        Assert.assertNull(history2.getStateName());
+        Assert.assertNull(history2.getLastSuccessStateName());
 
         final List<PaymentTransactionModelDao> transactions = paymentDao.getTransactionsForPayment(savedPayment.getId(), internalCallContext);
         assertEquals(transactions.size(), 2);
@@ -203,24 +211,28 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(savedPayment4.getStateName(), "AUTH_ABORTED");
         assertEquals(savedPayment4.getLastSuccessStateName(), "AUTH_SUCCESS");
 
-        final List<EntityHistoryModelDao<PaymentModelDao, Payment>> history3 = getPaymentHistory(savedPayment.getRecordId());
-        Assert.assertEquals(history3.size(), 3);
-        Assert.assertEquals(history3.get(0).getChangeType(), ChangeType.INSERT);
-        Assert.assertEquals(history3.get(0).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history3.get(0).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history3.get(0).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertEquals(history3.get(1).getChangeType(), ChangeType.UPDATE);
-        Assert.assertEquals(history3.get(1).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history3.get(1).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history3.get(1).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertTrue(history3.get(1).getEntity().getUpdatedDate().compareTo(history3.get(0).getEntity().getUpdatedDate()) >= 0);
-        Assert.assertEquals(history3.get(2).getChangeType(), ChangeType.UPDATE);
-        Assert.assertEquals(history3.get(2).getEntity().getAccountRecordId(), savedPayment.getAccountRecordId());
-        Assert.assertEquals(history3.get(2).getEntity().getTenantRecordId(), savedPayment.getTenantRecordId());
-        Assert.assertEquals(history3.get(2).getEntity().getExternalKey(), savedPayment.getExternalKey());
-        Assert.assertTrue(history3.get(2).getEntity().getUpdatedDate().compareTo(history3.get(2).getEntity().getUpdatedDate()) >= 0);
-        Assert.assertEquals(history3.get(2).getEntity().getStateName(), savedPayment4.getStateName());
-        Assert.assertEquals(history3.get(2).getEntity().getLastSuccessStateName(), savedPayment4.getLastSuccessStateName());
+        auditLogsWithHistory = paymentDao.getPaymentAuditLogsWithHistoryForId(savedPayment.getId(), AuditLevel.FULL, internalCallContext);
+        Assert.assertEquals(auditLogsWithHistory.size(), 3);
+
+        history1 = (PaymentModelDao) auditLogsWithHistory.get(0).getEntity();
+        history2 = (PaymentModelDao) auditLogsWithHistory.get(1).getEntity();
+        final PaymentModelDao history3 = (PaymentModelDao) auditLogsWithHistory.get(2).getEntity();
+        Assert.assertEquals(auditLogsWithHistory.get(0).getChangeType(), ChangeType.INSERT);
+        Assert.assertEquals(history1.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history1.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history1.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertEquals(auditLogsWithHistory.get(1).getChangeType(), ChangeType.UPDATE);
+        Assert.assertEquals(history2.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history2.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history2.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertTrue(auditLogsWithHistory.get(1).getEntity().getUpdatedDate().compareTo(auditLogsWithHistory.get(0).getEntity().getUpdatedDate()) >= 0);
+        Assert.assertEquals(auditLogsWithHistory.get(2).getChangeType(), ChangeType.UPDATE);
+        Assert.assertEquals(history3.getAccountRecordId(), savedPayment.getAccountRecordId());
+        Assert.assertEquals(history3.getTenantRecordId(), savedPayment.getTenantRecordId());
+        Assert.assertEquals(history3.getExternalKey(), savedPayment.getExternalKey());
+        Assert.assertTrue(history3.getUpdatedDate().compareTo(history3.getUpdatedDate()) >= 0);
+        Assert.assertEquals(history3.getStateName(), savedPayment4.getStateName());
+        Assert.assertEquals(history3.getLastSuccessStateName(), savedPayment4.getLastSuccessStateName());
 
         final PaymentTransactionModelDao savedTransactionModelDao4 = paymentDao.getPaymentTransaction(savedTransactionModelDao2.getId(), internalCallContext);
         assertEquals(savedTransactionModelDao4.getTransactionExternalKey(), transactionExternalKey2);
@@ -597,11 +609,5 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
             }
         }));
     }
-
-    private List<EntityHistoryModelDao<PaymentModelDao, Payment>> getPaymentHistory(final Long paymentRecordId) {
-        // See https://github.com/killbill/killbill/issues/335
-        final PaymentSqlDao paymentSqlDao = dbi.onDemand(PaymentSqlDao.class);
-        return paymentSqlDao.getHistoryForTargetRecordId(paymentRecordId, internalCallContext);
-    }
 }
 
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
index 1f2e03a..79c93f7 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
@@ -47,6 +47,7 @@ import org.killbill.billing.payment.api.TransactionType;
 import org.killbill.billing.payment.bus.PaymentBusEventHandler;
 import org.killbill.billing.payment.core.janitor.Janitor;
 import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
+import org.killbill.billing.payment.dao.PaymentModelDao;
 import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
 import org.killbill.billing.payment.glue.DefaultPaymentService;
 import org.killbill.billing.payment.invoice.InvoicePaymentControlPluginApi;
@@ -55,6 +56,8 @@ import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
 import org.killbill.billing.payment.provider.DefaultNoOpPaymentInfoPlugin;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.platform.api.KillbillConfigSource;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.entity.dao.DBRouterUntyped;
 import org.killbill.billing.util.entity.dao.DBRouterUntyped.THREAD_STATE;
@@ -331,7 +334,7 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
                                                            "foo", "bar", internalCallContext);
         testListener.assertListenerStatus();
 
-        final List<PaymentTransactionModelDao> paymentTransactionHistoryBeforeJanitor = getPaymentTransactionHistory(transactionExternalKey);
+        final List<AuditLogWithHistory> paymentTransactionHistoryBeforeJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
         Assert.assertEquals(paymentTransactionHistoryBeforeJanitor.size(), 3);
 
         // Move clock for notification to be processed
@@ -341,9 +344,11 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
         testListener.assertListenerStatus();
 
         // Proves the Janitor ran (and updated the transaction)
-        final List<PaymentTransactionModelDao> paymentTransactionHistoryAfterJanitor = getPaymentTransactionHistory(transactionExternalKey);
+        final List<AuditLogWithHistory> paymentTransactionHistoryAfterJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
         Assert.assertEquals(paymentTransactionHistoryAfterJanitor.size(), 4);
-        Assert.assertEquals(paymentTransactionHistoryAfterJanitor.get(3).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+
+        PaymentTransactionModelDao history3 = (PaymentTransactionModelDao) paymentTransactionHistoryAfterJanitor.get(3).getEntity();
+        Assert.assertEquals(history3.getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
 
         final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
         // Janitor should have moved us to PAYMENT_FAILURE
@@ -381,11 +386,11 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
         // NO because we will keep retrying as we can't fix it...
         //assertNotificationsCompleted(internalCallContext, 5);
 
-        final List<PaymentTransactionModelDao> paymentTransactionHistoryBeforeJanitor = getPaymentTransactionHistory(transactionExternalKey);
+        final List<AuditLogWithHistory> paymentTransactionHistoryBeforeJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
         Assert.assertEquals(paymentTransactionHistoryBeforeJanitor.size(), 3);
 
         // Nothing new happened
-        final List<PaymentTransactionModelDao> paymentTransactionHistoryAfterJanitor = getPaymentTransactionHistory(transactionExternalKey);
+        final List<AuditLogWithHistory> paymentTransactionHistoryAfterJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
         Assert.assertEquals(paymentTransactionHistoryAfterJanitor.size(), 3);
     }
 
@@ -521,35 +526,6 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
         return result;
     }
 
-    // I wish we had a simplest way to query our history rows..
-    private List<PaymentTransactionModelDao> getPaymentTransactionHistory(final String transactionExternalKey) {
-        return dbi.withHandle(new HandleCallback<List<PaymentTransactionModelDao>>() {
-            @Override
-            public List<PaymentTransactionModelDao> withHandle(final Handle handle) throws Exception {
-                final List<Map<String, Object>> queryResult = handle.select("select * from payment_transaction_history where transaction_external_key = ? order by record_id asc",
-                                                                            transactionExternalKey);
-                final List<PaymentTransactionModelDao> result = new ArrayList<PaymentTransactionModelDao>(queryResult.size());
-                for (final Map<String, Object> row : queryResult) {
-                    final PaymentTransactionModelDao transactionModelDao = new PaymentTransactionModelDao(UUID.fromString((String) row.get("id")),
-                                                                                                          null,
-                                                                                                          (String) row.get("transaction_external_key"),
-                                                                                                          null,
-                                                                                                          null,
-                                                                                                          UUID.fromString((String) row.get("payment_id")),
-                                                                                                          TransactionType.valueOf((String) row.get("transaction_type")),
-                                                                                                          null,
-                                                                                                          TransactionStatus.valueOf((String) row.get("transaction_status")),
-                                                                                                          (BigDecimal) row.get("amount"),
-                                                                                                          Currency.valueOf((String) row.get("currency")),
-                                                                                                          (String) row.get("gateway_error_code"),
-                                                                                                          String.valueOf(row.get("gateway_error_msg")));
-                    result.add(transactionModelDao);
-                }
-                return result;
-            }
-        });
-    }
-
     private void assertNotificationsCompleted(final InternalCallContext internalCallContext, final long timeoutSec) {
         try {
             await().atMost(timeoutSec, SECONDS).until(new Callable<Boolean>() {
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
index 66ff2e5..e2c93f8 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
@@ -20,6 +20,7 @@ package org.killbill.billing.jaxrs;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
@@ -28,6 +29,7 @@ import javax.annotation.Nullable;
 
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.dao.AccountModelDao;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.model.Account;
 import org.killbill.billing.client.model.Accounts;
@@ -42,6 +44,7 @@ import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.audit.ChangeType;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -53,6 +56,7 @@ import com.google.inject.Inject;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -551,4 +555,37 @@ public class TestAccount extends TestJaxrsBase {
         assertEquals(auditLogsJson.get(3).getObjectId(), accountCustomFields.get(2).getCustomFieldId());
     }
 
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testGetAccountAuditLogsWithHistory() throws Exception {
+        final Account accountJson = createAccount();
+        assertNotNull(accountJson);
+
+        // Update Account
+        final Account newInput = new Account(accountJson.getAccountId(),
+                                             "zozo", 4, accountJson.getExternalKey(), "rr@google.com", 18,
+                                             "USD", null, false, null, null, "UTC",
+                                             "bl1", "bh2", "", "", "ca", "San Francisco", "usa", "en", "415-255-2991",
+                                             "notes", false, false, null, null);
+
+        final Account updatedAccount = killBillClient.updateAccount(newInput, requestOptions);
+
+
+        final List<AuditLog> auditLogWithHistories = killBillClient.getAccountAuditLogsWithHistory(accountJson.getAccountId());
+        assertEquals(auditLogWithHistories.size(), 2);
+        assertEquals(auditLogWithHistories.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(auditLogWithHistories.get(0).getObjectType(), ObjectType.ACCOUNT);
+        assertEquals(auditLogWithHistories.get(0).getObjectId(), accountJson.getAccountId());
+
+        final LinkedHashMap history1 = (LinkedHashMap) auditLogWithHistories.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("externalKey"), accountJson.getExternalKey());
+        assertEquals(history1.get("name"), accountJson.getName());
+
+        final LinkedHashMap history2 = (LinkedHashMap) auditLogWithHistories.get(1).getHistory();
+        assertNotNull(history2);
+        assertEquals(history2.get("externalKey"), accountJson.getExternalKey());
+        assertNotEquals(history2.get("name"), accountJson.getName());
+        assertEquals(history2.get("name"), "zozo");
+    }
+
 }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountEmail.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountEmail.java
index f0ef8d6..29b6613 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountEmail.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccountEmail.java
@@ -18,14 +18,21 @@
 
 package org.killbill.billing.jaxrs;
 
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.UUID;
 
+import org.killbill.billing.ObjectType;
 import org.killbill.billing.client.model.Account;
 import org.killbill.billing.client.model.AccountEmail;
+import org.killbill.billing.client.model.AuditLog;
+import org.killbill.billing.util.audit.ChangeType;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 public class TestAccountEmail extends TestJaxrsBase {
 
     @Test(groups = "slow", description = "Can create and delete account emails")
@@ -75,4 +82,30 @@ public class TestAccountEmail extends TestJaxrsBase {
         killBillClient.addEmailToAccount(accountEmailJson2, createdBy, reason, comment);
         Assert.assertEquals(killBillClient.getEmailsForAccount(accountId), fourthEmails);
     }
+
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testGetAccountEmailAuditLogsWithHistory() throws Exception {
+        final Account accountJson = createAccount();
+        assertNotNull(accountJson);
+
+        final String email1 = UUID.randomUUID().toString();
+        final AccountEmail accountEmailJson1 = new AccountEmail(accountJson.getAccountId(), email1);
+
+        // Add an email
+        killBillClient.addEmailToAccount(accountEmailJson1, requestOptions);
+
+        // get all audit for the account
+        final List<AuditLog> auditLogsJson = killBillClient.getAccountAuditLogs(accountJson.getAccountId());
+        Assert.assertEquals(auditLogsJson.size(), 2);
+
+        final List<AuditLog> emailAuditLogWithHistories = killBillClient.getAccountEmailAuditLogsWithHistory(accountJson.getAccountId(), auditLogsJson.get(0).getObjectId());
+        assertEquals(emailAuditLogWithHistories.size(), 1);
+        assertEquals(emailAuditLogWithHistories.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(emailAuditLogWithHistories.get(0).getObjectType(), ObjectType.ACCOUNT_EMAIL);
+        assertEquals(emailAuditLogWithHistories.get(0).getObjectId(), auditLogsJson.get(0).getObjectId());
+
+        final LinkedHashMap history1 = (LinkedHashMap) emailAuditLogWithHistories.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("email"), email1);
+    }
 }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
index c66ff3b..a0fadbb 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCustomField.java
@@ -18,6 +18,8 @@
 
 package org.killbill.billing.jaxrs;
 
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -25,14 +27,19 @@ import javax.annotation.Nullable;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.model.Account;
+import org.killbill.billing.client.model.AuditLog;
 import org.killbill.billing.client.model.CustomField;
 import org.killbill.billing.client.model.CustomFields;
 import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.ChangeType;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 public class TestCustomField extends TestJaxrsBase {
 
 
@@ -105,6 +112,39 @@ public class TestCustomField extends TestJaxrsBase {
         Assert.assertEquals(allBundleCustomFieldsForAccount.size(), 5);
     }
 
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testCustomFieldTagAuditLogsWithHistory() throws Exception {
+        final Account accountJson = createAccount();
+        assertNotNull(accountJson);
+
+        final CustomField customField = new CustomField();
+        customField.setName("custom");
+        customField.setValue(UUID.randomUUID().toString().substring(0, 5));
+        killBillClient.createAccountCustomField(accountJson.getAccountId(), customField, requestOptions);
+
+        // get all audit for the account
+        final List<AuditLog> auditLogsJson = killBillClient.getAccountAuditLogs(accountJson.getAccountId());
+        Assert.assertEquals(auditLogsJson.size(), 2);
+        UUID objectId = null;
+        for (AuditLog auditLog : auditLogsJson) {
+            if (auditLog.getObjectType().equals(ObjectType.CUSTOM_FIELD)) {
+                objectId = auditLog.getObjectId();
+                break;
+            }
+        }
+        assertNotNull(objectId);
+        final List<AuditLog> customFieldAuditLogWithHistory = killBillClient.getCustomFieldsAuditLogsWithHistory(accountJson.getAccountId(), objectId);
+        assertEquals(customFieldAuditLogWithHistory.size(), 1);
+        assertEquals(customFieldAuditLogWithHistory.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(customFieldAuditLogWithHistory.get(0).getObjectType(), ObjectType.CUSTOM_FIELD);
+        assertEquals(customFieldAuditLogWithHistory.get(0).getObjectId(), objectId);
+
+        final LinkedHashMap history1 = (LinkedHashMap) customFieldAuditLogWithHistory.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("fieldName"), "custom");
+
+    }
+
     private void doSearchCustomField(final String searchKey, @Nullable final CustomField expectedCustomField) throws KillBillClientException {
         final CustomFields customFields = killBillClient.searchCustomFields(searchKey, requestOptions);
         if (expectedCustomField == null) {
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 2b3f8a7..aca468c 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
@@ -21,6 +21,8 @@ import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
@@ -31,6 +33,7 @@ import org.killbill.billing.ObjectType;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.RequestOptions;
 import org.killbill.billing.client.model.Account;
+import org.killbill.billing.client.model.AuditLog;
 import org.killbill.billing.client.model.ComboPaymentTransaction;
 import org.killbill.billing.client.model.InvoicePayments;
 import org.killbill.billing.client.model.Payment;
@@ -51,6 +54,7 @@ import org.killbill.billing.payment.plugin.api.PaymentPluginStatus;
 import org.killbill.billing.payment.provider.MockPaymentControlProviderPlugin;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.ChangeType;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
@@ -64,6 +68,7 @@ import com.google.inject.Inject;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
@@ -758,6 +763,48 @@ public class TestPayment extends TestJaxrsBase {
         Assert.assertEquals(paymentTransactionTag.get(0).getTagDefinitionName(), tagDefinitionName);
     }
 
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testPaymentAuditLogsWithHistory() throws Exception {
+        final Account account = createAccountWithDefaultPaymentMethod();
+        final String externalPaymentKey = UUID.randomUUID().toString();
+        final UUID paymentId = testCreateRetrievePayment(account, null, externalPaymentKey, 1);
+
+        final Payment payment = killBillClient.getPaymentByExternalKey(externalPaymentKey);
+        assertEquals(payment.getPaymentId(), paymentId);
+
+        final List<AuditLog> paymentAuditLogWithHistory = killBillClient.getPaymentAuditLogsWithHistory(account.getAccountId(), paymentId);
+        assertEquals(paymentAuditLogWithHistory.size(), 8);
+        assertEquals(paymentAuditLogWithHistory.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(paymentAuditLogWithHistory.get(0).getObjectType(), ObjectType.PAYMENT);
+        assertEquals(paymentAuditLogWithHistory.get(0).getObjectId(), paymentId);
+
+        final LinkedHashMap history1 = (LinkedHashMap) paymentAuditLogWithHistory.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("stateName"), null );
+        final LinkedHashMap history2 = (LinkedHashMap) paymentAuditLogWithHistory.get(1).getHistory();
+        assertNotNull(history2);
+        assertEquals(history2.get("stateName"), "AUTH_SUCCESS" );
+        final LinkedHashMap history3 = (LinkedHashMap) paymentAuditLogWithHistory.get(2).getHistory();
+        assertNotNull(history3);
+        assertEquals(history3.get("stateName"), "AUTH_SUCCESS" );
+        final LinkedHashMap history4 = (LinkedHashMap) paymentAuditLogWithHistory.get(3).getHistory();
+        assertNotNull(history4);
+        assertEquals(history4.get("stateName"), "CAPTURE_SUCCESS" );
+        final LinkedHashMap history5 = (LinkedHashMap) paymentAuditLogWithHistory.get(4).getHistory();
+        assertNotNull(history5);
+        assertEquals(history5.get("stateName"), "CAPTURE_SUCCESS" );
+        final LinkedHashMap history6 = (LinkedHashMap) paymentAuditLogWithHistory.get(5).getHistory();
+        assertNotNull(history6);
+        assertEquals(history6.get("stateName"), "CAPTURE_SUCCESS" );
+        final LinkedHashMap history7 = (LinkedHashMap) paymentAuditLogWithHistory.get(6).getHistory();
+        assertNotNull(history7);
+        assertEquals(history7.get("stateName"), "CAPTURE_SUCCESS" );
+        final LinkedHashMap history8 = (LinkedHashMap) paymentAuditLogWithHistory.get(7).getHistory();
+        assertNotNull(history8);
+        assertEquals(history8.get("stateName"), "REFUND_SUCCESS" );
+
+    }
+
     private UUID testCreateRetrievePayment(final Account account, @Nullable final UUID paymentMethodId,
                                            final String paymentExternalKey, final int paymentNb) throws Exception {
         // Authorization
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
index e44da34..c2e6dc9 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
@@ -20,20 +20,26 @@ package org.killbill.billing.jaxrs;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.UUID;
 
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.client.model.Account;
+import org.killbill.billing.client.model.AuditLog;
 import org.killbill.billing.client.model.CustomField;
 import org.killbill.billing.client.model.CustomFields;
 import org.killbill.billing.client.model.PaymentMethod;
 import org.killbill.billing.client.model.PaymentMethods;
 import org.killbill.billing.client.model.PluginProperty;
 import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.ChangeType;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 public class TestPaymentMethod extends TestJaxrsBase {
 
     @Test(groups = "slow", description = "Create/retrieve by externalKey")
@@ -137,6 +143,24 @@ public class TestPaymentMethod extends TestJaxrsBase {
         Assert.assertEquals(deletedCustomFields.size(), 0);
     }
 
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testPaymentMethodAuditLogsWithHistory() throws Exception {
+        final Account account = createAccountWithDefaultPaymentMethod();
+        assertNotNull(account);
+        final UUID paymentMethodId = account.getPaymentMethodId();
+
+        final List<AuditLog> paymentMethodAuditLogWithHistory = killBillClient.getPaymentMethodAuditLogsWithHistory(account.getAccountId(), paymentMethodId);
+        assertEquals(paymentMethodAuditLogWithHistory.size(), 1);
+        assertEquals(paymentMethodAuditLogWithHistory.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(paymentMethodAuditLogWithHistory.get(0).getObjectType(), ObjectType.PAYMENT_METHOD);
+        assertEquals(paymentMethodAuditLogWithHistory.get(0).getObjectId(), paymentMethodId);
+
+        final LinkedHashMap history1 = (LinkedHashMap) paymentMethodAuditLogWithHistory.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("accountId"), account.getAccountId().toString());
+
+    }
+
     private void doSearch(final String searchKey, final PaymentMethod paymentMethodJson) throws Exception {
         final List<PaymentMethod> results1 = killBillClient.searchPaymentMethodsByKey(searchKey, true);
         Assert.assertEquals(results1.size(), 1);
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
index ae69442..a4142aa 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
@@ -18,6 +18,7 @@
 
 package org.killbill.billing.jaxrs;
 
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.UUID;
 
@@ -29,11 +30,13 @@ import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.model.Account;
+import org.killbill.billing.client.model.AuditLog;
 import org.killbill.billing.client.model.Subscription;
 import org.killbill.billing.client.model.Tag;
 import org.killbill.billing.client.model.TagDefinition;
 import org.killbill.billing.client.model.Tags;
 import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.tag.ControlTagType;
 import org.killbill.billing.util.tag.dao.SystemTags;
 import org.testng.Assert;
@@ -165,6 +168,40 @@ public class TestTag extends TestJaxrsBase {
         }
     }
 
+    @Test(groups = "slow", description = "retrieve account logs")
+    public void testGetTagAuditLogsWithHistory() throws Exception {
+        final Account accountJson = createAccount();
+        assertNotNull(accountJson);
+
+        final TagDefinition accountTagDefInput = new TagDefinition(null, false, "accounttagdef", "nothing special",  ImmutableList.<ObjectType>of(ObjectType.TRANSACTION));
+        final TagDefinition accountTagDef = killBillClient.createTagDefinition(accountTagDefInput, requestOptions);
+        killBillClient.createAccountTag(accountJson.getAccountId(), accountTagDef.getId(), requestOptions);
+
+        // get all audit for the account
+        final List<AuditLog> auditLogsJson = killBillClient.getAccountAuditLogs(accountJson.getAccountId());
+        Assert.assertEquals(auditLogsJson.size(), 2);
+        UUID objectId = null;
+        for (AuditLog auditLog : auditLogsJson) {
+            if (auditLog.getObjectType().equals(ObjectType.TAG)) {
+                objectId = auditLog.getObjectId();
+                break;
+            }
+        }
+        assertNotNull(objectId);
+        final List<AuditLog> tagAuditLogWithHistories = killBillClient.getTagAuditLogsWithHistory(accountJson.getAccountId(), objectId);
+        assertEquals(tagAuditLogWithHistories.size(), 1);
+        assertEquals(tagAuditLogWithHistories.get(0).getChangeType(), ChangeType.INSERT.toString());
+        assertEquals(tagAuditLogWithHistories.get(0).getObjectType(), ObjectType.TAG);
+        assertEquals(tagAuditLogWithHistories.get(0).getObjectId(), objectId);
+
+        final LinkedHashMap history1 = (LinkedHashMap) tagAuditLogWithHistories.get(0).getHistory();
+        assertNotNull(history1);
+        assertEquals(history1.get("tagDefinitionId"), accountTagDef.getId().toString());
+        assertEquals(history1.get("objectId"), accountJson.getAccountId().toString());
+        assertEquals(history1.get("objectType"), ObjectType.ACCOUNT.toString());
+
+    }
+
     @Test(groups = "slow", description = "Can paginate through all tags")
     public void testTagsPagination() throws Exception {
         final Account account = createAccount();
diff --git a/util/src/test/java/org/killbill/billing/mock/api/MockAccountUserApi.java b/util/src/test/java/org/killbill/billing/mock/api/MockAccountUserApi.java
index cbbf33a..038b180 100644
--- a/util/src/test/java/org/killbill/billing/mock/api/MockAccountUserApi.java
+++ b/util/src/test/java/org/killbill/billing/mock/api/MockAccountUserApi.java
@@ -191,7 +191,12 @@ public class MockAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public List<AuditLogWithHistory> getAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext) throws AccountApiException {
+    public List<AuditLogWithHistory> getAuditLogsWithHistoryForId(final UUID accountId, final AuditLevel auditLevel, final TenantContext tenantContext) throws AccountApiException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<AuditLogWithHistory> getEmailAuditLogsWithHistoryForId(final UUID accountId, final UUID accountEmailId, final AuditLevel auditLevel, final TenantContext tenantContext) throws AccountApiException {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
index ae80cd4..e3a782a 100644
--- a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
+++ b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
@@ -23,7 +23,9 @@ import java.util.UUID;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.api.AuditLevel;
 import org.killbill.billing.util.api.CustomFieldApiException;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.customfield.CustomField;
 import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
@@ -63,6 +65,11 @@ public class MockCustomFieldDao extends MockEntityDaoBase<CustomFieldModelDao, C
     }
 
     @Override
+    public List<AuditLogWithHistory> getCustomFieldAuditLogsWithHistoryForId(final UUID customFieldId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public Pagination<CustomFieldModelDao> searchCustomFields(final String searchKey, final Long offset, final Long limit, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
diff --git a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
index 636c76f..bfe0afe 100644
--- a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
+++ b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDao.java
@@ -26,7 +26,9 @@ import java.util.UUID;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.api.AuditLevel;
 import org.killbill.billing.util.api.TagApiException;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
 import org.killbill.billing.util.tag.Tag;
@@ -106,6 +108,11 @@ public class MockTagDao extends MockEntityDaoBase<TagModelDao, Tag, TagApiExcept
         return tagStore.get(getAccountId(internalTenantContext.getAccountRecordId()));
     }
 
+    @Override
+    public List<AuditLogWithHistory> getTagAuditLogsWithHistoryForId(final UUID tagId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
     public void clear() {
         tagStore.clear();
     }
diff --git a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDefinitionDao.java b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDefinitionDao.java
index 8ae3ab6..16c91db 100644
--- a/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDefinitionDao.java
+++ b/util/src/test/java/org/killbill/billing/util/tag/dao/MockTagDefinitionDao.java
@@ -25,7 +25,9 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.api.AuditLevel;
 import org.killbill.billing.util.api.TagDefinitionApiException;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
 import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
 import org.killbill.billing.util.tag.TagDefinition;
 
@@ -60,6 +62,11 @@ public class MockTagDefinitionDao extends MockEntityDaoBase<TagDefinitionModelDa
     }
 
     @Override
+    public List<AuditLogWithHistory> getTagDefinitionAuditLogsWithHistoryForId(final UUID tagDefinitionId, final AuditLevel auditLevel, final InternalTenantContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public List<TagDefinitionModelDao> getByIds(final Collection<UUID> definitionIds, final InternalTenantContext context) {
         return null;
     }