killbill-aplcache
Changes
invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java 4(+2 -2)
overdue/pom.xml 11(+11 -0)
Details
diff --git a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
index 50bf592..c7127d4 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/overdue/OverdueStateSet.java
@@ -18,10 +18,14 @@ package com.ning.billing.catalog.api.overdue;
import org.joda.time.DateTime;
+import com.ning.billing.catalog.api.CatalogApiException;
+
public interface OverdueStateSet<T extends Overdueable> {
public abstract OverdueState<T> findClearState();
+ public abstract OverdueState<T> findState(String stateName) throws CatalogApiException;
+
public abstract OverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now);
public abstract DateTime dateOfNextCheck(BillingState<T> billingState, DateTime now);
diff --git a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
index fb2d2a6..9a81737 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
@@ -18,10 +18,6 @@ package com.ning.billing.catalog.api;
import java.util.Date;
-import org.joda.time.DateTime;
-
-import com.ning.billing.catalog.api.overdue.BillingStateBundle;
-import com.ning.billing.catalog.api.overdue.OverdueState;
import com.ning.billing.catalog.api.overdue.OverdueStateSet;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 9ef5338..36794e3 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -107,6 +107,10 @@ public enum ErrorCode {
* Billing Alignment
*/
CAT_INVALID_BILLING_ALIGNMENT(2060, "Invalid billing alignment '%s'"),
+ /*
+ * Overdue
+ */
+ CAT_NO_SUCH_OVEDUE_STATE(2070, "No such overdue state '%s'"),
/*
*
diff --git a/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
index c506dfd..24aee7d 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/overdue/OverdueStatesBundle.java
@@ -18,7 +18,10 @@ package com.ning.billing.catalog.overdue;
import javax.xml.bind.annotation.XmlElement;
+import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.overdue.OverdueState;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.util.config.ValidationErrors;
@@ -44,6 +47,14 @@ public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBund
}
return errors;
}
+
+ @Override
+ public OverdueState<SubscriptionBundle> findState(String stateName) throws CatalogApiException {
+ for(DefaultOverdueState<SubscriptionBundle> state: bundleOverdueStates) {
+ if(state.getName().equals(stateName) ) { return state; }
+ }
+ throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_OVEDUE_STATE, stateName);
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index f82eaef..60c36de 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -110,7 +110,7 @@ public class TestDefaultInvoiceMigrationApi {
private final Clock clock = new ClockMock();
- @BeforeClass(alwaysRun = true)
+ @BeforeClass(groups={"slow"})
public void setup() throws Exception
{
log.info("Starting set up");
@@ -133,7 +133,7 @@ public class TestDefaultInvoiceMigrationApi {
regularInvoiceId = generateRegularInvoice();
}
- @AfterClass(alwaysRun = true)
+ @AfterClass(groups={"slow"})
public void tearDown() {
try {
((DefaultBusService) busService).stopBus();
overdue/pom.xml 11(+11 -0)
diff --git a/overdue/pom.xml b/overdue/pom.xml
index 759b56a..0f5a57d 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -78,6 +78,17 @@
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-mxj</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-mxj-db-files</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
<plugins>
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index 97fab0b..cec80ad 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -19,28 +19,44 @@ package com.ning.billing.overdue.api;
import org.apache.commons.lang.NotImplementedException;
import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.StaticCatalog;
import com.ning.billing.catalog.api.overdue.BillingState;
import com.ning.billing.catalog.api.overdue.OverdueError;
import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.OverdueStateSet;
import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.overdue.OverdueService;
import com.ning.billing.overdue.OverdueUserApi;
-import com.ning.billing.overdue.dao.OverdueDao;
+import com.ning.billing.util.overdue.dao.OverdueAccessDao;
public class DefaultOverdueUserApi implements OverdueUserApi{
- private OverdueDao dao;
private OverdueService service;
+ private CatalogService catalogService;
+ private OverdueAccessDao accessDao;
@Inject
- public DefaultOverdueUserApi(OverdueDao dao, OverdueService service) {
- this.dao = dao;
+ public DefaultOverdueUserApi(OverdueService service, CatalogService catalogService, OverdueAccessDao accessDao) {
this.service = service;
+ this.catalogService = catalogService;
+ this.accessDao = accessDao;
}
+ @SuppressWarnings("unchecked")
@Override
- public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable) {
- return dao.getOverdueStateFor(overdueable);
+ public <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueError {
+ try {
+ String stateName = accessDao.getOverdueStateNameFor(overdueable);
+ StaticCatalog catalog = catalogService.getCurrentCatalog();
+ OverdueStateSet<SubscriptionBundle> states = catalog.currentBundleOverdueStateSet();
+ return (OverdueState<T>) states.findState(stateName);
+ } catch (CatalogApiException e) {
+ throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED,overdueable.getId(), overdueable.getClass().getSimpleName());
+ }
}
@Override
diff --git a/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java
index 610aab0..75286de 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueDao.java
@@ -18,11 +18,10 @@ package com.ning.billing.overdue.dao;
import com.ning.billing.catalog.api.overdue.OverdueState;
import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.util.clock.Clock;
public interface OverdueDao {
- <T extends Overdueable> OverdueState<T> getOverdueStateFor(T overdueable);
-
- <T extends Overdueable> void setOverdueStateForBundle(T overdueable, OverdueState<T> newOverdueState);
+ <T extends Overdueable> void setOverdueStateForBundle(T overdueable, OverdueState<T> newOverdueState, Clock clock);
}
\ No newline at end of file
diff --git a/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueSqlDao.java b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueSqlDao.java
new file mode 100644
index 0000000..dac4050
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/dao/OverdueSqlDao.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.dao;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.entity.BinderBase;
+
+@ExternalizedSqlViaStringTemplate3()
+public interface OverdueSqlDao extends OverdueDao {
+
+ @Override
+ @SqlUpdate
+ public abstract <T extends Overdueable> void setOverdueStateForBundle(
+ @Bind(binder = OverdueableBinder.class) T overdueable,
+ @Bind(binder = OverdueStateBinder.class) OverdueState<T> overdueState,
+ @Bind(binder = CurrentTimeBinder.class) Clock clock) ;
+
+ public static class OverdueableBinder extends BinderBase implements Binder<Bind, Overdueable> {
+ @Override
+ public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Overdueable overdueable) {
+ stmt.bind("id", overdueable.getId().toString());
+ }
+ }
+ public static class OverdueStateBinder<T extends Overdueable> extends BinderBase implements Binder<Bind, OverdueState<T>> {
+ @Override
+ public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, OverdueState<T> overdueState) {
+ stmt.bind("state", overdueState.getName());
+ }
+ }
+
+ public static class CurrentTimeBinder extends BinderBase implements Binder<Bind, Clock> {
+ @Override
+ public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Clock clock) {
+ stmt.bind("created_date", clock.getUTCNow());
+ }
+
+ }
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/glue/OverdueModule.java b/overdue/src/main/java/com/ning/billing/overdue/glue/OverdueModule.java
new file mode 100644
index 0000000..5797b1b
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/glue/OverdueModule.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.glue;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.ning.billing.overdue.dao.OverdueDao;
+import com.ning.billing.overdue.dao.OverdueSqlDao;
+
+public class OverdueModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(OverdueDao.class).toProvider(OverdueDaoProvider.class);
+ }
+
+ public static class OverdueDaoProvider implements Provider<OverdueDao>{
+
+ private IDBI dbi;
+
+
+ @Inject
+ public OverdueDaoProvider(IDBI dbi){
+ this.dbi = dbi;
+ }
+
+
+ @Override
+ public OverdueDao get() {
+ return dbi.onDemand(OverdueSqlDao.class);
+ }
+ }
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index f2258bd..1b7feeb 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -21,27 +21,27 @@ import com.ning.billing.catalog.api.overdue.OverdueError;
import com.ning.billing.catalog.api.overdue.OverdueState;
import com.ning.billing.catalog.api.overdue.OverdueStateSet;
import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.overdue.OverdueUserApi;
import com.ning.billing.overdue.applicator.OverdueStateApplicator;
import com.ning.billing.overdue.calculator.BillingStateCalculator;
-import com.ning.billing.overdue.dao.OverdueDao;
import com.ning.billing.util.clock.Clock;
public class OverdueWrapper<T extends Overdueable> {
private final T overdueable;
- private final OverdueDao dao;
+ private final OverdueUserApi api;
private final Clock clock;
private final OverdueStateSet<T> overdueStateSet;
private final BillingStateCalculator<T> billingStateCalcuator;
private final OverdueStateApplicator<T> overdueStateApplicator;
- public OverdueWrapper(T overdueable, OverdueDao dao,
+ public OverdueWrapper(T overdueable, OverdueUserApi api,
OverdueStateSet<T> overdueStateSet,
Clock clock,
BillingStateCalculator<T> billingStateCalcuator,
OverdueStateApplicator<T> overdueStateApplicator) {
this.overdueable = overdueable;
this.overdueStateSet = overdueStateSet;
- this.dao = dao;
+ this.api = api;
this.clock = clock;
this.billingStateCalcuator = billingStateCalcuator;
this.overdueStateApplicator = overdueStateApplicator;
@@ -49,7 +49,7 @@ public class OverdueWrapper<T extends Overdueable> {
public OverdueState<T> refresh() throws OverdueError {
BillingState<T> billingState = billingStateCalcuator.calculateBillingState(overdueable);
- OverdueState<T> previousOverdueStateName = dao.getOverdueStateFor(overdueable);
+ OverdueState<T> previousOverdueStateName = api.getOverdueStateFor(overdueable);
OverdueState<T> nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
if(!previousOverdueStateName.equals(nextOverdueState.getName())) {
overdueStateApplicator.apply(overdueable, nextOverdueState, nextOverdueState, overdueStateSet.dateOfNextCheck(billingState, clock.getUTCNow()));
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
index 594c606..76b3dd0 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -23,9 +23,9 @@ import com.ning.billing.catalog.api.CatalogService;
import com.ning.billing.catalog.api.overdue.OverdueError;
import com.ning.billing.catalog.api.overdue.Overdueable;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.overdue.OverdueUserApi;
import com.ning.billing.overdue.applicator.OverdueStateApplicatorBundle;
import com.ning.billing.overdue.calculator.BillingStateCalculatorBundle;
-import com.ning.billing.overdue.dao.OverdueDao;
import com.ning.billing.util.clock.Clock;
public class OverdueWrapperFactory {
@@ -33,15 +33,15 @@ public class OverdueWrapperFactory {
private final CatalogService catalogService;
private final BillingStateCalculatorBundle billingStateCalcuatorBundle;
private final OverdueStateApplicatorBundle overdueStateApplicatorBundle;
- private final OverdueDao dao;
+ private final OverdueUserApi api;
private final Clock clock;
@Inject
- public OverdueWrapperFactory(OverdueDao dao, CatalogService catalogService, Clock clock, BillingStateCalculatorBundle billingStateCalcuatorBundle, OverdueStateApplicatorBundle overdueStateApplicatorBundle) {
+ public OverdueWrapperFactory(OverdueUserApi api, CatalogService catalogService, Clock clock, BillingStateCalculatorBundle billingStateCalcuatorBundle, OverdueStateApplicatorBundle overdueStateApplicatorBundle) {
this.billingStateCalcuatorBundle = billingStateCalcuatorBundle;
this.overdueStateApplicatorBundle = overdueStateApplicatorBundle;
this.catalogService = catalogService;
- this.dao = dao;
+ this.api = api;
this.clock = clock;
}
@@ -50,7 +50,7 @@ public class OverdueWrapperFactory {
public <T extends Overdueable> OverdueWrapper<T> createOverdueWrapperFor(T overdueable) throws OverdueError {
try {
if(overdueable instanceof SubscriptionBundle) {
- return (OverdueWrapper<T>)new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle)overdueable, dao, catalogService.getCurrentCatalog().currentBundleOverdueStateSet(),
+ return (OverdueWrapper<T>)new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle)overdueable, api, catalogService.getCurrentCatalog().currentBundleOverdueStateSet(),
clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle );
} else {
throw new OverdueError(ErrorCode.OVERDUE_OVERDUEABLE_NOT_SUPPORTED, overdueable.getClass());
diff --git a/overdue/src/main/resources/com/ning/billing/overdue/dao/OverdueSqlDao.sql.stg b/overdue/src/main/resources/com/ning/billing/overdue/dao/OverdueSqlDao.sql.stg
new file mode 100644
index 0000000..229a6a7
--- /dev/null
+++ b/overdue/src/main/resources/com/ning/billing/overdue/dao/OverdueSqlDao.sql.stg
@@ -0,0 +1,13 @@
+group OverdueSqlDao;
+
+setOverdueStateForBundle() ::= <<
+ insert into overdue_states (
+ id
+ , state
+ , created_date
+ ) values (
+ :id
+ , :state
+ , NOW()
+ );
+>>
\ No newline at end of file
diff --git a/overdue/src/test/java/com/ning/billing/overdue/dao/MockModule.java b/overdue/src/test/java/com/ning/billing/overdue/dao/MockModule.java
new file mode 100644
index 0000000..30adc91
--- /dev/null
+++ b/overdue/src/test/java/com/ning/billing/overdue/dao/MockModule.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.dao;
+
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.catalog.glue.CatalogModule;
+import com.ning.billing.dbi.DBIProvider;
+import com.ning.billing.dbi.DbiConfig;
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
+
+
+public class MockModule extends AbstractModule {
+ public static final String PLUGIN_NAME = "Booboo";
+
+ @Override
+ protected void configure() {
+ bind(Clock.class).to(ClockMock.class).asEagerSingleton();
+ bind(ClockMock.class).asEagerSingleton();
+ bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+
+ final MysqlTestingHelper helper = new MysqlTestingHelper();
+ bind(MysqlTestingHelper.class).toInstance(helper);
+ if (helper.isUsingLocalInstance()) {
+ bind(IDBI.class).toProvider(DBIProvider.class).asEagerSingleton();
+ final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
+ bind(DbiConfig.class).toInstance(config);
+ } else {
+ final IDBI dbi = helper.getDBI();
+ bind(IDBI.class).toInstance(dbi);
+ }
+
+ install(new CatalogModule());
+ }
+
+
+}
diff --git a/overdue/src/test/java/com/ning/billing/overdue/dao/TestOverdueDao.java b/overdue/src/test/java/com/ning/billing/overdue/dao/TestOverdueDao.java
new file mode 100644
index 0000000..b49a670
--- /dev/null
+++ b/overdue/src/test/java/com/ning/billing/overdue/dao/TestOverdueDao.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.dao;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.Duration;
+import com.ning.billing.catalog.api.TimeUnit;
+import com.ning.billing.catalog.api.overdue.OverdueState;
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.overdue.glue.OverdueModule;
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.glue.OverdueAccessModule;
+import com.ning.billing.util.overdue.dao.OverdueAccessDao;
+
+@Guice(modules = {MockModule.class, OverdueModule.class, OverdueAccessModule.class})
+public class TestOverdueDao {
+ private Logger log = LoggerFactory.getLogger(TestOverdueDao.class);
+
+ @Inject
+ private MysqlTestingHelper helper;
+
+ @Inject
+ private OverdueDao dao;
+
+ @Inject
+ private OverdueAccessDao accessDao;
+
+ @BeforeClass(groups={"slow"})
+ public void setup() throws IOException {
+ log.info("Starting set up");
+
+ final String utilDdl = IOUtils.toString(TestOverdueDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+
+ helper.startMysql();
+ helper.initDb(utilDdl);
+
+ }
+
+
+ @Test(groups={"slow"}, enabled=true)
+ public void testDao() {
+ ClockMock clock = new ClockMock();
+ SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+ UUID bundleId = UUID.randomUUID();
+ ((ZombieControl)bundle).addResult("getId", bundleId);
+
+ String overdueStateName = "WayPassedItMan";
+ @SuppressWarnings("unchecked")
+ OverdueState<SubscriptionBundle> state = BrainDeadProxyFactory.createBrainDeadProxyFor(OverdueState.class);
+ ((ZombieControl)state).addResult("getName", overdueStateName);
+
+ dao.setOverdueStateForBundle(bundle, state, clock);
+ clock.setDeltaFromReality(1000 * 3600 * 24);
+
+ String overdueStateName2 = "NoReallyThisCantGoOn";
+ ((ZombieControl)state).addResult("getName", overdueStateName2);
+ dao.setOverdueStateForBundle(bundle, state, clock);
+
+ Assert.assertEquals(accessDao.getOverdueStateNameFor(bundle), overdueStateName2);
+
+ }
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/OverdueAccessModule.java b/util/src/main/java/com/ning/billing/util/glue/OverdueAccessModule.java
new file mode 100644
index 0000000..8f4f634
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/OverdueAccessModule.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.glue;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.ning.billing.util.overdue.dao.OverdueAccessDao;
+import com.ning.billing.util.overdue.dao.OverdueAccessSqlDao;
+
+public class OverdueAccessModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(OverdueAccessDao.class).toProvider(OverdueAccessDaoProvider.class);
+ }
+
+ public static class OverdueAccessDaoProvider implements Provider<OverdueAccessDao>{
+
+ private IDBI dbi;
+
+
+ @Inject
+ public OverdueAccessDaoProvider(IDBI dbi){
+ this.dbi = dbi;
+ }
+
+
+ @Override
+ public OverdueAccessDao get() {
+ return dbi.onDemand(OverdueAccessSqlDao.class);
+ }
+ }
+
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.java b/util/src/main/java/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.java
new file mode 100644
index 0000000..b6e0426
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.overdue.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
+import com.ning.billing.util.overdue.OverdueAccessApi;
+
+@ExternalizedSqlViaStringTemplate3()
+public interface OverdueAccessSqlDao extends Transactional<OverdueAccessSqlDao>, CloseMe, Transmogrifier, OverdueAccessDao {
+
+ @Override
+ @SqlQuery
+ @Mapper(OverdueStateSqlMapper.class)
+ public abstract String getOverdueStateNameFor(@Bind(binder = OverdueableBinder.class)Overdueable overdueable) ;
+
+ public static class OverdueStateSqlMapper extends MapperBase implements ResultSetMapper<String> {
+
+ @Override
+ public String map(int index, ResultSet r, StatementContext ctx)
+ throws SQLException {
+ return r.getString("state") == null ? OverdueAccessApi.CLEAR_STATE_NAME : r.getString("state");
+ }
+ }
+
+ public static class OverdueableBinder extends BinderBase implements Binder<Bind, Overdueable> {
+ @Override
+ public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Overdueable overdueable) {
+ stmt.bind("id", overdueable.getId().toString());
+ }
+ }
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java b/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java
new file mode 100644
index 0000000..5b7e6be
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/overdue/DefaultOverdueAcessApi.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.overdue;
+
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.overdue.Overdueable;
+import com.ning.billing.util.overdue.dao.OverdueAccessDao;
+
+public class DefaultOverdueAcessApi implements OverdueAccessApi {
+ private OverdueAccessDao dao;
+
+ @Inject
+ public DefaultOverdueAcessApi(OverdueAccessDao dao) {
+ this.dao = dao;
+ }
+
+ @Override
+ public String getOverdueStateNameFor(Overdueable overdueable) {
+ return dao.getOverdueStateNameFor(overdueable);
+ }
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java b/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java
new file mode 100644
index 0000000..4ca82d8
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/overdue/OverdueAccessApi.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.overdue;
+
+import com.ning.billing.catalog.api.overdue.Overdueable;
+
+public interface OverdueAccessApi {
+ public static final String CLEAR_STATE_NAME = "__KILLBILL__CLEAR__OVERDUE_STATE__";
+
+ public String getOverdueStateNameFor(Overdueable overdueable);
+
+
+}
diff --git a/util/src/main/resources/com/ning/billing/util/ddl.sql b/util/src/main/resources/com/ning/billing/util/ddl.sql
index 17442c1..2bce344 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -117,3 +117,12 @@ CREATE TABLE audit_log (
comments varchar(255) DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
+
+DROP TABLE IF EXISTS overdue_states;
+CREATE TABLE overdue_states (
+ id char(36) NOT NULL,
+ state varchar(50) NOT NULL,
+ created_date datetime NOT NULL
+) ENGINE=innodb;
+CREATE INDEX overdue_states_by_id ON overdue_states (id);
+
diff --git a/util/src/main/resources/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.sql.stg
new file mode 100644
index 0000000..606a4d0
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/overdue/dao/OverdueAccessSqlDao.sql.stg
@@ -0,0 +1,13 @@
+group OverdueAccessSqlDao;
+
+getOverdueStateNameFor() ::= <<
+ select
+ id
+ , state
+ , created_date
+ from overdue_states
+ where id = :id
+ order by created_date desc
+ limit 1
+ ;
+>>
\ No newline at end of file