killbill-uncached

util: make DefaultAuditDao support history tables Whenever

8/11/2012 2:50:24 PM

Details

diff --git a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
index d1f8a9e..73f82ec 100644
--- a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
+++ b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.util.audit.dao;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
@@ -40,6 +41,15 @@ public class DefaultAuditDao implements AuditDao {
 
     @Override
     public List<AuditLog> getAuditLogsForId(final TableName tableName, final UUID objectId) {
+        if (tableName.hasHistoryTable()) {
+            return doGetAuditLogsViaHistoryForId(tableName, objectId);
+        } else {
+            return doGetAuditLogsForId(tableName, objectId);
+        }
+    }
+
+    private List<AuditLog> doGetAuditLogsForId(final TableName tableName, final UUID objectId) {
+        // Look at the table and gather all record_id for that objectId
         final Long recordId = auditSqlDao.getRecordIdForTable(tableName.getTableName().toLowerCase(), objectId.toString());
         if (recordId == null) {
             return ImmutableList.<AuditLog>of();
@@ -47,4 +57,21 @@ public class DefaultAuditDao implements AuditDao {
             return auditSqlDao.getAuditLogsForRecordId(tableName, recordId);
         }
     }
+
+    private List<AuditLog> doGetAuditLogsViaHistoryForId(final TableName tableName, final UUID objectId) {
+        final List<AuditLog> auditLogs = new ArrayList<AuditLog>();
+
+        // Look at the history table and gather all the history_record_id for that objectId
+        final List<Long> recordIds = auditSqlDao.getHistoryRecordIdsForTable(tableName.getHistoryTableName().getTableName().toLowerCase(),
+                                                                             objectId.toString());
+        if (recordIds == null) {
+            return auditLogs;
+        } else {
+            for (final Long recordId : recordIds) {
+                auditLogs.addAll(auditSqlDao.getAuditLogsForRecordId(tableName.getHistoryTableName(), recordId));
+            }
+
+            return auditLogs;
+        }
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
index 58a08c6..341b448 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
@@ -54,6 +54,10 @@ public interface AuditSqlDao {
                                     @Bind("id") final String id);
 
     @SqlQuery
+    public List<Long> getHistoryRecordIdsForTable(@Define("tableName") final String tableName,
+                                                  @Bind("id") final String id);
+
+    @SqlQuery
     public Long getHistoryRecordId(@Bind("recordId") final Long recordId);
 
 }
diff --git a/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
index b83b952..129ab4d 100644
--- a/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/dao/AuditSqlDao.sql.stg
@@ -29,3 +29,9 @@ getRecordIdForTable(tableName) ::= <<
   WHERE id = :id
   LIMIT 1
 >>
+
+getHistoryRecordIdsForTable(tableName) ::= <<
+  SELECT history_record_id record_id
+  FROM <tableName>
+  WHERE object_id = :id
+>>
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
index ed39506..1763625 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
@@ -18,6 +18,7 @@ package com.ning.billing.util.audit.dao;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.Handle;
@@ -30,6 +31,8 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContext;
@@ -41,6 +44,7 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.dao.TableName;
 import com.ning.billing.util.glue.AuditModule;
 import com.ning.billing.util.tag.MockTagStoreModuleSql;
+import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
@@ -50,6 +54,8 @@ import com.google.inject.Inject;
 @Guice(modules = {MockTagStoreModuleSql.class, AuditModule.class})
 public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
 
+    private final UUID objectTagged = UUID.randomUUID();
+
     @Inject
     private TagDefinitionDao tagDefinitionDao;
 
@@ -82,11 +88,8 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
     }
 
     @Test(groups = "slow")
-    public void testRetrieveAudits() throws Exception {
-        final TagDefinition defYo = tagDefinitionDao.create("yo", "defintion yo", context);
-
-        // Create a tag
-        tagDao.insertTag(UUID.randomUUID(), ObjectType.ACCOUNT, defYo.getId(), context);
+    public void testRetrieveAuditsDirectly() throws Exception {
+        addTag();
 
         // Verify we get an audit entry for the tag_history table
         final Handle handle = dbi.open();
@@ -94,6 +97,32 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         handle.close();
 
         final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG_HISTORY, UUID.fromString(tagHistoryString));
+        verifyAuditLogsForTag(auditLogs);
+    }
+
+    @Test(groups = "slow")
+    public void testRetrieveAuditsViaHistory() throws Exception {
+        addTag();
+
+        final List<AuditLog> auditLogs = auditDao.getAuditLogsForId(TableName.TAG, objectTagged);
+        verifyAuditLogsForTag(auditLogs);
+    }
+
+    private void addTag() throws TagDefinitionApiException, TagApiException {
+        // Create a tag definition
+        final TagDefinition tagDefinition = tagDefinitionDao.create(UUID.randomUUID().toString().substring(0, 5),
+                                                                    UUID.randomUUID().toString().substring(0, 5),
+                                                                    context);
+        Assert.assertEquals(tagDefinitionDao.getById(tagDefinition.getId()), tagDefinition);
+
+        // Create a tag
+        tagDao.insertTag(objectTagged, ObjectType.ACCOUNT, tagDefinition.getId(), context);
+        final Map<String, Tag> tags = tagDao.loadEntities(objectTagged, ObjectType.ACCOUNT);
+        Assert.assertEquals(tags.size(), 1);
+        Assert.assertEquals(tags.values().iterator().next().getTagDefinitionId(), tagDefinition.getId());
+    }
+
+    private void verifyAuditLogsForTag(final List<AuditLog> auditLogs) {
         Assert.assertEquals(auditLogs.size(), 1);
         Assert.assertEquals(auditLogs.get(0).getUserToken(), context.getUserToken().toString());
         Assert.assertEquals(auditLogs.get(0).getChangeType(), ChangeType.INSERT);
diff --git a/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleSql.java b/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleSql.java
index 56bb2f7..aafb006 100644
--- a/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleSql.java
+++ b/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleSql.java
@@ -16,10 +16,7 @@
 
 package com.ning.billing.util.tag;
 
-
-import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.tweak.HandleCallback;
 
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.dbi.MysqlTestingHelper;
@@ -29,25 +26,14 @@ import com.ning.billing.util.bus.InMemoryBus;
 import com.ning.billing.util.glue.TagStoreModule;
 
 public class MockTagStoreModuleSql extends TagStoreModule {
-    private MysqlTestingHelper helper;
 
     @Override
     protected void configure() {
-        helper = KillbillTestSuiteWithEmbeddedDB.getMysqlTestingHelper();
+        final MysqlTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getMysqlTestingHelper();
         bind(IDBI.class).toInstance(helper.getDBI());
         bind(MysqlTestingHelper.class).toInstance(helper);
         install(new MockClockModule());
         bind(Bus.class).toInstance(new InMemoryBus());
         super.configure();
     }
-
-    public void execute(final String ddl) {
-        helper.getDBI().withHandle(new HandleCallback<Void>() {
-            @Override
-            public Void withHandle(final Handle handle) throws Exception {
-                handle.execute(ddl);
-                return null;
-            }
-        });
-    }
 }