killbill-memoizeit
Changes
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java 23(+23 -0)
entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java 19(+18 -1)
entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java 5(+3 -2)
entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java 12(+10 -2)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java 6(+4 -2)
entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg 1(+1 -0)
entitlement/src/main/resources/org/killbill/billing/entitlement/migration/V20190221163050__blocking_state_history_tables.sql 25(+25 -0)
payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorWithDB.java 3(+1 -2)
pom.xml 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 18(+18 -0)
Details
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
index 562aa85..d820c71 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
@@ -39,6 +39,9 @@ import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.entity.Pagination;
public interface SubscriptionBaseInternalApi {
@@ -99,4 +102,10 @@ public interface SubscriptionBaseInternalApi {
public UUID getBundleIdFromSubscriptionId(UUID entitlementId, InternalTenantContext context) throws SubscriptionBaseApiException;
public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context) throws SubscriptionBaseApiException;
+
+ public List<AuditLogWithHistory> getSubscriptionBundleAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext);
+
+ public List<AuditLogWithHistory> getSubscriptionAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext);
+
+ public List<AuditLogWithHistory> getSubscriptionEventAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext);
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
index 69b5a51..71ffea4 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -57,6 +57,8 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
@@ -454,6 +456,27 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
}
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionBundleAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return subscriptionBaseInternalApi.getSubscriptionBundleAuditLogsWithHistoryForId(uuid, auditLevel, tenantContext);
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return subscriptionBaseInternalApi.getSubscriptionAuditLogsWithHistoryForId(uuid, auditLevel, tenantContext);
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionEventAuditLogsWithHistoryForId(final UUID uuid, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return subscriptionBaseInternalApi.getSubscriptionEventAuditLogsWithHistoryForId(uuid, auditLevel, tenantContext);
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getBlockingStateAuditLogsWithHistoryForId(final UUID blockingId, final AuditLevel auditLevel, final TenantContext context) {
+ return blockingStateDao.getBlockingStateAuditLogsWithHistoryForId(blockingId, auditLevel, internalCallContextFactory.createInternalTenantContext(blockingId, ObjectType.BLOCKING_STATES, context));
+ }
+
+
private List<SubscriptionBundle> getSubscriptionBundlesForAccount(final UUID accountId, final TenantContext tenantContext) throws SubscriptionApiException {
final InternalTenantContext internalTenantContextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateDao.java
index 5ef0c47..4f5a940 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateDao.java
@@ -29,6 +29,8 @@ import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.EntitlementApiException;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.entity.dao.EntityDao;
import com.google.common.base.Optional;
@@ -81,4 +83,13 @@ public interface BlockingStateDao extends EntityDao<BlockingStateModelDao, Block
*/
public void unactiveBlockingState(UUID blockableId, final InternalCallContext context);
+ /**
+ *
+ * @param blockableId id of the blockable object
+ * @param auditLevel audit level
+ * @param context call context
+ * @return the list of audit with history for this blockableId
+ */
+ List<AuditLogWithHistory> getBlockingStateAuditLogsWithHistoryForId(UUID blockableId, AuditLevel auditLevel, InternalTenantContext context);
+
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateModelDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateModelDao.java
index 8c10dfc..62f0483 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateModelDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateModelDao.java
@@ -158,7 +158,7 @@ public class BlockingStateModelDao extends EntityModelDaoBase implements EntityM
@Override
public TableName getHistoryTableName() {
- return null;
+ return TableName.BLOCKING_STATES;
}
@Override
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
index f6d2cd5..fc68b21 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
@@ -47,11 +47,15 @@ import org.killbill.billing.entitlement.block.BlockingChecker.BlockingAggregator
import org.killbill.billing.entitlement.block.StatelessBlockingChecker;
import org.killbill.billing.entitlement.engine.core.BlockingTransitionNotificationKey;
import org.killbill.billing.platform.api.KillbillService.KILLBILL_SERVICES;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheController;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.dao.TableName;
import org.killbill.billing.util.entity.dao.EntityDaoBase;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
@@ -114,16 +118,18 @@ public class DefaultBlockingStateDao extends EntityDaoBase<BlockingStateModelDao
private final PersistentBus eventBus;
private final CacheController<String, UUID> objectIdCacheController;
private final NonEntityDao nonEntityDao;
+ private final AuditDao auditDao;
private final StatelessBlockingChecker statelessBlockingChecker = new StatelessBlockingChecker();
public DefaultBlockingStateDao(final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
- final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
+ final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final AuditDao auditDao, final InternalCallContextFactory internalCallContextFactory) {
super(nonEntityDao, cacheControllerDispatcher, new EntitySqlDaoTransactionalJdbiWrapper(dbi, roDbi, clock, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory), BlockingStateSqlDao.class);
this.clock = clock;
this.notificationQueueService = notificationQueueService;
this.eventBus = eventBus;
this.objectIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID);
+ this.auditDao = auditDao;
this.nonEntityDao = nonEntityDao;
}
@@ -387,6 +393,17 @@ public class DefaultBlockingStateDao extends EntityDaoBase<BlockingStateModelDao
});
}
+ @Override
+ public List<AuditLogWithHistory> getBlockingStateAuditLogsWithHistoryForId(final UUID blockableId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<AuditLogWithHistory>>() {
+ @Override
+ public List<AuditLogWithHistory> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) {
+ final BlockingStateSqlDao transactional = entitySqlDaoWrapperFactory.become(BlockingStateSqlDao.class);
+ return auditDao.getAuditLogsWithHistoryForId(transactional, TableName.BLOCKING_STATES, blockableId, auditLevel, context);
+ }
+ });
+ }
+
private List<BlockingState> filterBlockingStates(final Collection<BlockingState> models, final UUID objectId, final BlockingStateType blockingStateType) {
return ImmutableList.<BlockingState>copyOf(Collections2.<BlockingState>filter(models,
new Predicate<BlockingState>() {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
index 9e9ba63..37b833a 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
@@ -35,6 +35,7 @@ import org.killbill.billing.entitlement.engine.core.EventsStreamBuilder;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.dao.NonEntityDao;
@@ -49,8 +50,8 @@ public class OptimizedProxyBlockingStateDao extends ProxyBlockingStateDao {
public OptimizedProxyBlockingStateDao(final EventsStreamBuilder eventsStreamBuilder, final SubscriptionBaseInternalApi subscriptionBaseInternalApi,
final IDBI dbi, final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
- final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
- super(eventsStreamBuilder, subscriptionBaseInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+ final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final AuditDao auditDao, final InternalCallContextFactory internalCallContextFactory) {
+ super(eventsStreamBuilder, subscriptionBaseInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, auditDao, internalCallContextFactory);
}
/**
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
index 40ff779..fe57dfa 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
@@ -45,6 +45,9 @@ import org.killbill.billing.platform.api.KillbillService.KILLBILL_SERVICES;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.customfield.ShouldntHappenException;
@@ -176,11 +179,11 @@ public class ProxyBlockingStateDao implements BlockingStateDao {
@Inject
public ProxyBlockingStateDao(final EventsStreamBuilder eventsStreamBuilder, final SubscriptionBaseInternalApi subscriptionBaseInternalApi,
final IDBI dbi, @Named(MAIN_RO_IDBI_NAMED) final IDBI roDbi, final Clock clock, final NotificationQueueService notificationQueueService, final PersistentBus eventBus,
- final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final InternalCallContextFactory internalCallContextFactory) {
+ final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao, final AuditDao auditDao, final InternalCallContextFactory internalCallContextFactory) {
this.eventsStreamBuilder = eventsStreamBuilder;
this.subscriptionInternalApi = subscriptionBaseInternalApi;
this.clock = clock;
- this.delegate = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+ this.delegate = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, auditDao, internalCallContextFactory);
}
@Override
@@ -244,6 +247,11 @@ public class ProxyBlockingStateDao implements BlockingStateDao {
delegate.unactiveBlockingState(blockableId, context);
}
+ @Override
+ public List<AuditLogWithHistory> getBlockingStateAuditLogsWithHistoryForId(final UUID blockableId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return delegate.getBlockingStateAuditLogsWithHistoryForId(blockableId, auditLevel, context);
+ }
+
// Add blocking states for add-ons, which would be impacted by a future cancellation or change of their base plan
// See DefaultEntitlement#computeAddOnBlockingStates
private List<BlockingState> addBlockingStatesNotOnDisk(final List<BlockingState> blockingStatesOnDisk,
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
index 9f72b61..a663141 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
@@ -59,6 +59,7 @@ import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
+import org.killbill.billing.util.audit.dao.AuditDao;
import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -100,6 +101,7 @@ public class EventsStreamBuilder {
final PersistentBus eventBus,
final CacheControllerDispatcher cacheControllerDispatcher,
final NonEntityDao nonEntityDao,
+ final AuditDao auditDao,
final InternalCallContextFactory internalCallContextFactory) {
this.accountInternalApi = accountInternalApi;
this.subscriptionInternalApi = subscriptionInternalApi;
@@ -107,8 +109,8 @@ public class EventsStreamBuilder {
this.checker = checker;
this.clock = clock;
this.internalCallContextFactory = internalCallContextFactory;
- this.defaultBlockingStateDao = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
- this.blockingStateDao = new OptimizedProxyBlockingStateDao(this, subscriptionInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, internalCallContextFactory);
+ this.defaultBlockingStateDao = new DefaultBlockingStateDao(dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, auditDao, internalCallContextFactory);
+ this.blockingStateDao = new OptimizedProxyBlockingStateDao(this, subscriptionInternalApi, dbi, roDbi, clock, notificationQueueService, eventBus, cacheControllerDispatcher, nonEntityDao, auditDao, internalCallContextFactory);
}
public EventsStream refresh(final EventsStream eventsStream, final TenantContext tenantContext) throws EntitlementApiException {
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 f5227a1..baf6b96 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,6 +1,7 @@
import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
tableName() ::= "blocking_states"
+historyTableName() ::= "blocking_state_history"
andCheckSoftDeletionWithComma(prefix) ::= "and <prefix>is_active"
diff --git a/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql b/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
index c085a6b..5e9dd05 100644
--- a/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
+++ b/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
@@ -24,3 +24,29 @@ CREATE TABLE blocking_states (
CREATE INDEX blocking_states_id ON blocking_states(blockable_id);
CREATE INDEX blocking_states_id_real ON blocking_states(id);
CREATE INDEX blocking_states_tenant_account_record_id ON blocking_states(tenant_record_id, account_record_id);
+
+DROP TABLE IF EXISTS blocking_state_history;
+CREATE TABLE blocking_state_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ blockable_id varchar(36) NOT NULL,
+ type varchar(20) NOT NULL,
+ state varchar(50) NOT NULL,
+ service varchar(20) NOT NULL,
+ block_change bool NOT NULL,
+ block_entitlement bool NOT NULL,
+ block_billing bool NOT NULL,
+ effective_date datetime NOT NULL,
+ is_active boolean default true,
+ change_type varchar(6) NOT NULL,
+ created_date datetime NOT NULL,
+ created_by varchar(50) NOT NULL,
+ updated_date datetime DEFAULT NULL,
+ updated_by varchar(50) DEFAULT NULL,
+ account_record_id bigint /*! unsigned */ not null,
+ tenant_record_id bigint /*! unsigned */ not null default 0,
+ PRIMARY KEY(record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE INDEX blocking_state_history_target_record_id ON blocking_state_history(target_record_id);
+CREATE INDEX blocking_state_history_tenant_record_id ON blocking_state_history(tenant_record_id);
\ No newline at end of file
diff --git a/entitlement/src/main/resources/org/killbill/billing/entitlement/migration/V20190221163050__blocking_state_history_tables.sql b/entitlement/src/main/resources/org/killbill/billing/entitlement/migration/V20190221163050__blocking_state_history_tables.sql
new file mode 100644
index 0000000..e9156fe
--- /dev/null
+++ b/entitlement/src/main/resources/org/killbill/billing/entitlement/migration/V20190221163050__blocking_state_history_tables.sql
@@ -0,0 +1,25 @@
+DROP TABLE IF EXISTS blocking_state_history;
+CREATE TABLE blocking_state_history (
+ record_id serial unique,
+ id varchar(36) NOT NULL,
+ target_record_id bigint /*! unsigned */ not null,
+ blockable_id varchar(36) NOT NULL,
+ type varchar(20) NOT NULL,
+ state varchar(50) NOT NULL,
+ service varchar(20) NOT NULL,
+ block_change bool NOT NULL,
+ block_entitlement bool NOT NULL,
+ block_billing bool NOT NULL,
+ effective_date datetime NOT NULL,
+ is_active boolean default true,
+ change_type varchar(6) NOT NULL,
+ created_date datetime NOT NULL,
+ created_by varchar(50) NOT NULL,
+ updated_date datetime DEFAULT NULL,
+ updated_by varchar(50) DEFAULT NULL,
+ account_record_id bigint /*! unsigned */ not null,
+ tenant_record_id bigint /*! unsigned */ not null default 0,
+ PRIMARY KEY(record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE INDEX blocking_state_history_target_record_id ON blocking_state_history(target_record_id);
+CREATE INDEX blocking_state_history_tenant_record_id ON blocking_state_history(tenant_record_id);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/MockBlockingStateDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/MockBlockingStateDao.java
index 21c5c72..c3ec944 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/MockBlockingStateDao.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/MockBlockingStateDao.java
@@ -33,6 +33,8 @@ import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.EntitlementApiException;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.entity.dao.MockEntityDaoBase;
import com.google.common.base.MoreObjects;
@@ -105,6 +107,11 @@ public class MockBlockingStateDao extends MockEntityDaoBase<BlockingStateModelDa
throw new UnsupportedOperationException();
}
+ @Override
+ public List<AuditLogWithHistory> getBlockingStateAuditLogsWithHistoryForId(final UUID blockableId, final AuditLevel auditLevel, final InternalTenantContext context) {
+ return null;
+ }
+
public synchronized void clear() {
blockingStates.clear();
blockingStatesPerAccountRecordId.clear();
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
index 610f4b1..3e6fe4a 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
@@ -28,6 +28,9 @@ import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.junction.DefaultBlockingState;
+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.Test;
@@ -100,4 +103,41 @@ public class TestBlockingDao extends EntitlementTestSuiteWithEmbeddedDB {
Assert.assertEquals(history2.get(0).getStateName(), overdueStateName);
Assert.assertEquals(history2.get(1).getStateName(), overdueStateName2);
}
+
+ @Test(groups = "slow")
+ public void testWithAuditAndHistory() throws Exception {
+
+ final UUID uuid = createAccount(getAccountData(1)).getId();
+ final String overdueStateName = "StateBlock";
+ final String service = "auditAndHistory";
+
+ testListener.pushExpectedEvent(NextEvent.BLOCK);
+ final BlockingState blockingState = new DefaultBlockingState(uuid, BlockingStateType.ACCOUNT, overdueStateName, service, false, true, false, clock.getUTCNow());
+ blockingStateDao.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableMap.<BlockingState, Optional<UUID>>of(blockingState, Optional.<UUID>absent()), internalCallContext);
+ assertListenerStatus();
+
+
+ final List<AuditLogWithHistory> h1 = blockingStateDao.getBlockingStateAuditLogsWithHistoryForId(blockingState.getId(), AuditLevel.FULL, internalCallContext);
+ Assert.assertEquals(h1.size(), 1);
+
+ final AuditLogWithHistory firstHistoryRow = h1.get(0);
+ Assert.assertEquals(firstHistoryRow.getChangeType(), ChangeType.INSERT);
+ final BlockingStateModelDao firstBlockingState = (BlockingStateModelDao) firstHistoryRow.getEntity();
+ Assert.assertFalse(firstBlockingState.getBlockChange());
+ Assert.assertTrue(firstBlockingState.getBlockEntitlement());
+ Assert.assertFalse(firstBlockingState.getBlockBilling());
+ Assert.assertTrue(firstBlockingState.isActive());
+
+ blockingStateDao.unactiveBlockingState(blockingState.getId(), internalCallContext);
+ final List<AuditLogWithHistory> h2 = blockingStateDao.getBlockingStateAuditLogsWithHistoryForId(blockingState.getId(), AuditLevel.FULL, internalCallContext);
+ Assert.assertEquals(h2.size(), 2);
+ final AuditLogWithHistory secondHistoryRow = h2.get(1);
+
+ Assert.assertEquals(secondHistoryRow.getChangeType(), ChangeType.DELETE);
+ final BlockingStateModelDao secondBlockingState = (BlockingStateModelDao) secondHistoryRow.getEntity();
+ Assert.assertFalse(secondBlockingState.getBlockChange());
+ Assert.assertTrue(secondBlockingState.getBlockEntitlement());
+ Assert.assertFalse(secondBlockingState.getBlockBilling());
+ Assert.assertFalse(secondBlockingState.isActive());
+ }
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 8e6df2e..c7d08bf 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -1132,6 +1132,20 @@ public class AccountResource extends JaxRsResourceBase {
}
@TimedResource
+ @GET
+ @Path("/{blockingId:" + UUID_PATTERN + "}/" + BLOCK + "/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve blocking state audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Blocking state not found")})
+ public Response getBlockingStateAuditLogsWithHistory(@PathParam("blockingId") final UUID blockingId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = subscriptionApi.getBlockingStateAuditLogsWithHistoryForId(blockingId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+
+ @TimedResource
@POST
@Path("/{accountId:" + UUID_PATTERN + "}/" + BLOCK)
@Consumes(APPLICATION_JSON)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index 8c2ea77..ff0eb59 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -55,6 +55,7 @@ import org.killbill.billing.entitlement.api.EntitlementApiException;
import org.killbill.billing.entitlement.api.SubscriptionApi;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.entitlement.api.SubscriptionBundle;
+import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.BlockingStateJson;
import org.killbill.billing.jaxrs.json.BundleJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
@@ -64,6 +65,7 @@ import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -71,6 +73,7 @@ import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.audit.AccountAuditLogs;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.customfield.CustomField;
@@ -165,6 +168,19 @@ public class BundleResource extends JaxRsResourceBase {
@TimedResource
@GET
+ @Path("/{bundleId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve bundle audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Subscription bundle not found")})
+ public Response getBundleAuditLogsWithHistory(@PathParam("bundleId") final UUID bundleId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = subscriptionApi.getSubscriptionBundleAuditLogsWithHistoryForId(bundleId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+ @TimedResource
+ @GET
@Path("/" + PAGINATION)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "List bundles", response = BundleJson.class, responseContainer = "List")
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 8451e15..44e32ec 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -173,6 +173,8 @@ public interface JaxrsResource {
String SUBSCRIPTIONS = "subscriptions";
String SUBSCRIPTIONS_PATH = PREFIX + "/" + SUBSCRIPTIONS;
+ String EVENTS = "events";
+
String ENTITLEMENTS = "entitlements";
String ENTITLEMENTS_PATH = PREFIX + "/" + ENTITLEMENTS;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index 48f0cf3..f17729f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -75,6 +75,7 @@ import org.killbill.billing.events.NullInvoiceInternalEvent;
import org.killbill.billing.events.PaymentErrorInternalEvent;
import org.killbill.billing.events.PaymentInfoInternalEvent;
import org.killbill.billing.events.PaymentPluginErrorInternalEvent;
+import org.killbill.billing.jaxrs.json.AuditLogJson;
import org.killbill.billing.jaxrs.json.BlockingStateJson;
import org.killbill.billing.jaxrs.json.BulkSubscriptionsBundleJson;
import org.killbill.billing.jaxrs.json.BundleJson;
@@ -87,6 +88,7 @@ import org.killbill.billing.jaxrs.util.KillbillEventHandler;
import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -94,6 +96,7 @@ import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.audit.AccountAuditLogs;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.userrequest.CompletionUserRequestBase;
@@ -166,10 +169,36 @@ public class SubscriptionResource extends JaxRsResourceBase {
}
@TimedResource
+ @GET
+ @Path("/{subscriptionId:" + UUID_PATTERN + "}/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve subscription audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Subscription not found")})
+ public Response getSubscriptionAuditLogsWithHistory(@PathParam("subscriptionId") final UUID subscriptionId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = subscriptionApi.getSubscriptionAuditLogsWithHistoryForId(subscriptionId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+ @TimedResource
+ @GET
+ @Path("/{eventId:" + UUID_PATTERN + "}/" + EVENTS + "/" + AUDIT_LOG_WITH_HISTORY)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve subscription event audit logs with history by id", response = AuditLogJson.class, responseContainer = "List")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Subscription event not found")})
+ public Response getSubscriptionEventAuditLogsWithHistory(@PathParam("eventId") final UUID eventId,
+ @javax.ws.rs.core.Context final HttpServletRequest request) {
+ final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
+ final List<AuditLogWithHistory> auditLogWithHistory = subscriptionApi.getSubscriptionEventAuditLogsWithHistoryForId(eventId, AuditLevel.FULL, tenantContext);
+ return Response.status(Status.OK).entity(getAuditLogsWithHistory(auditLogWithHistory)).build();
+ }
+
+
+ @TimedResource
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
-
@ApiOperation(value = "Create an subscription", response = SubscriptionJson.class)
@ApiResponses(value = {@ApiResponse(code = 201, message = "Subscription created successfully")})
public Response createSubscription(final SubscriptionJson subscription,
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 73144b1..6a686fb 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
@@ -99,7 +99,6 @@ public class TestPaymentMethodProcessorWithDB extends PaymentTestSuiteWithEmbedd
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.isActive());
+ Assert.assertFalse(history2.isActive());
}
}
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 501ec3b..99c9c99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.143.8</version>
+ <version>0.143.9-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.20.7-SNAPSHOT</version>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index 2680ba5..4b52cb8 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
+import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
@@ -68,6 +69,8 @@ import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleMode
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.bcd.BCDEvent;
import org.killbill.billing.subscription.events.bcd.BCDEventData;
+import org.killbill.billing.util.api.AuditLevel;
+import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.cache.AccountIdFromBundleIdCacheLoader;
import org.killbill.billing.util.cache.BundleIdFromSubscriptionIdCacheLoader;
import org.killbill.billing.util.cache.Cachable.CacheType;
@@ -477,6 +480,21 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
return accountId;
}
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionBundleAuditLogsWithHistoryForId(final UUID bundleId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getSubscriptionBundleAuditLogsWithHistoryForId(bundleId, auditLevel, internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, tenantContext));
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionAuditLogsWithHistoryForId(final UUID subscriptionId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getSubscriptionAuditLogsWithHistoryForId(subscriptionId, auditLevel, internalCallContextFactory.createInternalTenantContext(subscriptionId, ObjectType.SUBSCRIPTION, tenantContext));
+ }
+
+ @Override
+ public List<AuditLogWithHistory> getSubscriptionEventAuditLogsWithHistoryForId(final UUID eventId, final AuditLevel auditLevel, final TenantContext tenantContext) {
+ return dao.getSubscriptionEventAuditLogsWithHistoryForId(eventId, auditLevel, internalCallContextFactory.createInternalTenantContext(eventId, ObjectType.SUBSCRIPTION_EVENT, tenantContext));
+ }
+
private CacheLoaderArgument createAccountIdFromBundleIdCacheLoaderArgument(final InternalTenantContext internalTenantContext) {
final AccountIdFromBundleIdCacheLoader.LoaderCallback loaderCallback = new AccountIdFromBundleIdCacheLoader.LoaderCallback() {
public UUID loadAccountId(final UUID bundleId, final InternalTenantContext internalTenantContext) {
diff --git a/util/src/main/java/org/killbill/billing/util/dao/TableName.java b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
index f32c9a2..f4158c9 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/TableName.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
@@ -30,7 +30,8 @@ public enum TableName {
ACCOUNT_EMAIL("account_emails", ObjectType.ACCOUNT_EMAIL, ACCOUNT_EMAIL_HISTORY),
BUNDLE_HISTORY("bundle_history"),
BUNDLES("bundles", ObjectType.BUNDLE, BUNDLE_HISTORY),
- BLOCKING_STATES("blocking_states", ObjectType.BLOCKING_STATES),
+ BLOCKING_STATE_HISTORY("blocking_state_history"),
+ BLOCKING_STATES("blocking_states", ObjectType.BLOCKING_STATES, BLOCKING_STATE_HISTORY),
CUSTOM_FIELD_HISTORY("custom_field_history"),
CUSTOM_FIELD("custom_fields", ObjectType.CUSTOM_FIELD, CUSTOM_FIELD_HISTORY),
INVOICE_ITEMS("invoice_items", ObjectType.INVOICE_ITEM),
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 6bb5bd6..d9aa68f 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
@@ -73,6 +73,10 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
@SmartBindBean final InternalTenantContext context);
@SqlQuery
+ List<M> getByIdsIncludedDeleted(@BindIn("ids") final Collection<String> ids,
+ @SmartBindBean final InternalTenantContext context);
+
+ @SqlQuery
public List<M> getByAccountRecordId(@SmartBindBean final InternalTenantContext context);
@SqlQuery
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 b4b8a0e..34238f6 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
@@ -225,14 +225,6 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
// Get the current state before deletion for the history tables
final Map<Long, M> deletedAndUpdatedEntities = new HashMap<Long, M>();
- if (changeType == ChangeType.DELETE) {
- final List<M> entitiesToBeDeleted = sqlDao.getByIds(entityIds, contextMaybeWithoutAccountRecordId);
- printSQLWarnings();
- for (final M entityToBeDeleted : entitiesToBeDeleted) {
- deletedAndUpdatedEntities.put(entityToBeDeleted.getRecordId(), entityToBeDeleted);
- }
- }
-
// Real jdbc call
final Object obj = prof.executeWithProfiling(ProfilingFeatureType.DAO_DETAILS, getProfilingId("raw", method), new WithProfilingCallback<Object, Throwable>() {
@Override
@@ -248,17 +240,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
InternalCallContext context = null;
// Retrieve record_id(s) for audit and history tables
final List<Long> entityRecordIds = new LinkedList<Long>();
- if (changeType == ChangeType.DELETE) {
- for (final Long entityRecordId : deletedAndUpdatedEntities.keySet()) {
- final M entity = deletedAndUpdatedEntities.get(entityRecordId);
- entityRecordIds.add(entityRecordId);
- if (tableName == null) {
- tableName = entity.getTableName();
- } else {
- Preconditions.checkState(tableName == entity.getTableName(), "Entities with different TableName: %s", deletedAndUpdatedEntities);
- }
- }
- } else if (changeType == ChangeType.INSERT) {
+ if (changeType == ChangeType.INSERT) {
Preconditions.checkNotNull(tableName, "Insert query should have an EntityModelDao as argument: %s", args);
if (isBatchQuery) {
@@ -275,8 +257,8 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
context = internalCallContextFactory.createInternalCallContext(accountModelDao, entityRecordIds.get(0), contextMaybeWithoutAccountRecordId);
}
} else {
- // For updates, easiest is to go back to the database
- final List<M> retrievedEntities = sqlDao.getByIds(entityIds, contextMaybeWithoutAccountRecordId);
+ // Rehydrate entry with latest state
+ final List<M> retrievedEntities = sqlDao.getByIdsIncludedDeleted(entityIds, contextMaybeWithoutAccountRecordId);
printSQLWarnings();
for (final M entity : retrievedEntities) {
deletedAndUpdatedEntities.put(entity.getRecordId(), entity);
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 c1c256f..0a9d423 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
@@ -200,6 +200,16 @@ where <idField("t.")> in (<ids>)
;
>>
+getByIdsIncludedDeleted(ids) ::= <<
+select
+<allTableFields("t.")>
+from <tableName()> t
+where <idField("t.")> in (<ids>)
+<AND_CHECK_TENANT("t.")>
+<defaultOrderBy("t.")>
+;
+>>
+
/** Note: account_record_id can be NULL **/
getByAccountRecordId(accountRecordId) ::= <<
select