killbill-uncached
Changes
beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java 140(+140 -0)
bin/clean-and-install 22(+22 -0)
entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java 19(+19 -0)
entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java 8(+4 -4)
entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java 114(+76 -38)
entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java 112(+75 -37)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java 208(+103 -105)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java 8(+4 -4)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java 185(+109 -76)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java 12(+6 -6)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java 2(+1 -1)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java 10(+5 -5)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java 36(+22 -14)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java 14(+7 -7)
Details
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
index 8dc3312..2745c33 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
@@ -65,4 +65,5 @@ public interface SubscriptionEvent extends BusEvent {
Integer getRemainingEventsForUserOperation();
Long getTotalOrdering();
+
}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
new file mode 100644
index 0000000..2dfe2ee
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -0,0 +1,140 @@
+/*
+ * 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.beatrix.integration.overdue;
+//
+//import static org.testng.Assert.assertNotNull;
+//
+//import java.io.ByteArrayInputStream;
+//import java.io.InputStream;
+//
+//import org.joda.time.DateTime;
+//import org.joda.time.Interval;
+//
+//import com.google.inject.Inject;
+//import com.ning.billing.account.api.Account;
+//import com.ning.billing.beatrix.integration.TestIntegrationBase;
+//import com.ning.billing.catalog.api.BillingPeriod;
+//import com.ning.billing.catalog.api.Duration;
+//import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+//import com.ning.billing.catalog.api.PriceListSet;
+//import com.ning.billing.catalog.api.ProductCategory;
+//import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+//import com.ning.billing.entitlement.api.user.SubscriptionData;
+//import com.ning.billing.junction.api.BlockingApi;
+//import com.ning.billing.overdue.config.OverdueConfig;
+//import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
+//import com.ning.billing.util.clock.ClockMock;
+//import com.ning.billing.util.config.XMLLoader;
+//
+//public class TestOverdueIntegration extends TestIntegrationBase {
+// private final String configXml =
+// "<overdueConfig>" +
+// " <bundleOverdueStates>" +
+// " <state name=\"OD1\">" +
+// " <condition>" +
+// " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+// " <unit>MONTHS</unit><number>1</number>" +
+// " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+// " </condition>" +
+// " <externalMessage>Reached OD1</externalMessage>" +
+// " <blockChanges>true</blockChanges>" +
+// " <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+// " </state>" +
+// " <state name=\"OD2\">" +
+// " <condition>" +
+// " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+// " <unit>MONTHS</unit><number>2</number>" +
+// " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+// " </condition>" +
+// " <externalMessage>Reached OD1</externalMessage>" +
+// " <blockChanges>true</blockChanges>" +
+// " <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+// " </state>" +
+// " </bundleOverdueStates>" +
+// "</overdueConfig>";
+// private OverdueConfig config;
+//
+// @Inject
+// private ClockMock clock;
+//
+// @Inject
+// private MockPaymentProviderPlugin paymentPlugin;
+//
+// @Inject
+// private BlockingApi blockingApi;
+//
+// private Account account;
+// private SubscriptionBundle bundle;
+// private String productName;
+// private BillingPeriod term;
+// private String planSetName;
+//
+// long twoWeeks = new Interval(clock.getUTCNow(), clock.getUTCNow().plusWeeks(2)).toDurationMillis();
+// long fourWeeks = new Interval(clock.getUTCNow(), clock.getUTCNow().plusWeeks(4)).toDurationMillis();
+//
+// //@BeforeMethod
+// public void setup() throws Exception {
+// InputStream is = new ByteArrayInputStream(configXml.getBytes());
+// config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
+// Account account = accountUserApi.createAccount(getAccountData(25), null, null, context);
+// assertNotNull(account);
+//
+// bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+//
+// productName = "Shotgun";
+// term = BillingPeriod.MONTHLY;
+// planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+//
+// // create account
+// // set mock payments to fail
+// // reset clock
+// // configure basic OD state rules for 2 states OD1 1-2month, OD2 2-3 month
+// }
+//
+// //@AfterMethod
+// public void cleanup(){
+// // Clear databases
+// }
+//
+// public void testBasicOverdueState() throws Exception {
+// DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+// clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
+//
+//
+// // set next invoice to fail and create network
+// paymentPlugin.makeNextInvoiceFail();
+// SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+// new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+// assertNotNull(baseSubscription);
+//
+//
+// // advance time 2weeks
+// clock.addDeltaFromReality(twoWeeks);
+//
+// // should still be in clear state
+// blockingApi.getBlockingStateFor(bundle);
+//
+// // set next invoice to fail and advance time 1 month
+// clock.addDeltaFromReality(fourWeeks);
+//
+// // should now be in OD1 state
+// // set next invoice to fail and advance time 1 month
+// // should now be in OD2 state
+//
+//
+// }
+//}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index f7db5d1..5f442c6 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountData;
-import com.ning.billing.beatrix.integration.TestBusHandler.NextEvent;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.PhaseType;
@@ -49,24 +49,28 @@ import com.ning.billing.invoice.api.Invoice;
public class TestIntegration extends TestIntegrationBase {
@Test(groups = "slow", enabled = true)
public void testBasePlanCompleteWithBillingDayInPast() throws Exception {
+ log.info("Starting testBasePlanCompleteWithBillingDayInPast");
DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
testBasePlanComplete(startDate, 31, false);
}
@Test(groups = "slow", enabled = true)
public void testBasePlanCompleteWithBillingDayPresent() throws Exception {
+ log.info("Starting testBasePlanCompleteWithBillingDayPresent");
DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
testBasePlanComplete(startDate, 1, false);
}
@Test(groups = "slow", enabled = true)
public void testBasePlanCompleteWithBillingDayAlignedWithTrial() throws Exception {
+ log.info("Starting testBasePlanCompleteWithBillingDayAlignedWithTrial");
DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
testBasePlanComplete(startDate, 2, false);
}
@Test(groups = "slow", enabled = true)
public void testBasePlanCompleteWithBillingDayInFuture() throws Exception {
+ log.info("Starting testBasePlanCompleteWithBillingDayInFuture");
DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
testBasePlanComplete(startDate, 3, true);
}
@@ -91,9 +95,12 @@ public class TestIntegration extends TestIntegrationBase {
}
}
- @Test(groups = "slow", enabled = true)
+ // STEPH set to disabled until test written properly and fixed
+ @Test(groups = "slow", enabled = false)
public void testRepairChangeBPWithAddonIncluded() throws Exception {
+ log.info("Starting testRepairChangeBPWithAddonIncluded");
+
DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
@@ -142,10 +149,13 @@ public class TestIntegration extends TestIntegrationBase {
busHandler.pushExpectedEvent(NextEvent.PAYMENT);
clock.addDeltaFromReality(it.toDurationMillis());
assertTrue(busHandler.isCompleted(DELAY));
+
+ assertListenerStatus();
}
@Test(groups = {"slow"})
public void testRepairForInvoicing() throws AccountApiException, EntitlementUserApiException {
+
log.info("Starting testRepairForInvoicing");
Account account = accountUserApi.createAccount(getAccountData(1), null, null, context);
@@ -178,6 +188,8 @@ public class TestIntegration extends TestIntegrationBase {
@Test(groups = "slow", enabled = false)
public void testWithRecreatePlan() throws Exception {
+ log.info("Starting testWithRecreatePlan");
+
DateTime initialDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
int billingDay = 2;
@@ -244,7 +256,7 @@ public class TestIntegration extends TestIntegrationBase {
subscription.recreate(new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), endDate, context);
assertTrue(busHandler.isCompleted(DELAY));
-
+ assertListenerStatus();
}
private void testBasePlanComplete(DateTime initialCreationDate, int billingDay,
@@ -440,12 +452,18 @@ public class TestIntegration extends TestIntegrationBase {
// The invoice system is still working to verify there is nothing to do
Thread.sleep(DELAY);
+
+ assertListenerStatus();
+
log.info("TEST PASSED !");
}
@Test(groups = "slow")
public void testForMultipleRecurringPhases() throws AccountApiException, EntitlementUserApiException, InterruptedException {
+
+ log.info("Starting testForMultipleRecurringPhases");
+
DateTime initialCreationDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
clock.setDeltaFromReality(initialCreationDate.getMillis() - clock.getUTCNow().getMillis());
@@ -505,5 +523,7 @@ public class TestIntegration extends TestIntegrationBase {
invoices = invoiceUserApi.getInvoicesByAccount(accountId);
assertNotNull(invoices);
assertEquals(invoices.size(),14);
+
+ assertListenerStatus();
}
}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index a70bce9..579f47c 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -36,6 +36,7 @@ import org.skife.jdbi.v2.TransactionCallback;
import org.skife.jdbi.v2.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
@@ -45,7 +46,10 @@ import com.google.inject.Inject;
import com.ning.billing.account.api.AccountData;
import com.ning.billing.account.api.AccountService;
import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.api.TestApiListener;
+import com.ning.billing.api.TestListenerStatus;
import com.ning.billing.beatrix.lifecycle.Lifecycle;
+import com.ning.billing.catalog.DefaultCatalogService;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.entitlement.api.EntitlementService;
@@ -54,6 +58,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.entitlement.engine.core.Engine;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoiceService;
@@ -67,7 +72,7 @@ import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.ClockMock;
-public class TestIntegrationBase implements TestFailure {
+public class TestIntegrationBase implements TestListenerStatus {
protected static final int NUMBER_OF_DECIMALS = InvoicingConfiguration.getNumberOfDecimals();
protected static final int ROUNDING_METHOD = InvoicingConfiguration.getRoundingMode();
@@ -80,7 +85,7 @@ public class TestIntegrationBase implements TestFailure {
protected static final Logger log = LoggerFactory.getLogger(TestIntegration.class);
protected static long AT_LEAST_ONE_MONTH_MS = 31L * 24L * 3600L * 1000L;
- protected static final long DELAY = 5000;
+ protected static final long DELAY = 10000;
@Inject
protected IDBI dbi;
@@ -119,28 +124,29 @@ public class TestIntegrationBase implements TestFailure {
@Inject
protected AccountUserApi accountUserApi;
- protected TestBusHandler busHandler;
+ protected TestApiListener busHandler;
- private boolean currentTestStatusSuccess;
- private String currentTestFailedMsg;
+ private boolean isListenerFailed;
+ private String listenerFailedMsg;
@Override
public void failed(String msg) {
- currentTestStatusSuccess = false;
- currentTestFailedMsg = msg;
+ isListenerFailed = true;
+ listenerFailedMsg = msg;
}
@Override
- public void reset() {
- currentTestStatusSuccess = true;
- currentTestFailedMsg = null;
+ public void resetTestListenerStatus() {
+ isListenerFailed = false;
+ listenerFailedMsg = null;
}
- protected void assertFailureFromBusHandler() {
- if (!currentTestStatusSuccess) {
- log.error(currentTestFailedMsg);
- fail();
+
+ protected void assertListenerStatus() {
+ if (isListenerFailed) {
+ log.error(listenerFailedMsg);
+ Assert.fail(listenerFailedMsg);
}
}
@@ -163,73 +169,50 @@ public class TestIntegrationBase implements TestFailure {
helper.initDb(junctionDb);
}
+
@BeforeClass(groups = "slow")
public void setup() throws Exception{
setupMySQL();
- cleanupData();
-
context = new DefaultCallContextFactory(clock).createCallContext("Integration Test", CallOrigin.TEST, UserType.TEST);
-
- /**
- * Initialize lifecyle for subset of services
- */
- busHandler = new TestBusHandler(this);
- lifecycle.fireStartupSequencePriorEventRegistration();
- busService.getBus().register(busHandler);
- lifecycle.fireStartupSequencePostEventRegistration();
+ busHandler = new TestApiListener(this);
+
}
@AfterClass(groups = "slow")
public void tearDown() throws Exception {
- lifecycle.fireShutdownSequencePriorEventUnRegistration();
- busService.getBus().unregister(busHandler);
- lifecycle.fireShutdownSequencePostEventUnRegistration();
helper.stopMysql();
}
@BeforeMethod(groups = "slow")
- public void setupTest() {
+ public void setupTest() throws Exception {
log.warn("\n");
log.warn("RESET TEST FRAMEWORK\n\n");
- cleanupData();
- busHandler.reset();
+
+ // Pre test cleanup
+ helper.cleanupAllTables();
+
clock.resetDeltaFromReality();
- reset();
+ resetTestListenerStatus();
+
+ // Start services
+ lifecycle.fireStartupSequencePriorEventRegistration();
+ busService.getBus().register(busHandler);
+ lifecycle.fireStartupSequencePostEventRegistration();
}
@AfterMethod(groups = "slow")
- public void cleanupTest() {
+ public void cleanupTest() throws Exception {
+ lifecycle.fireShutdownSequencePriorEventUnRegistration();
+ busService.getBus().unregister(busHandler);
+ lifecycle.fireShutdownSequencePostEventUnRegistration();
+
log.warn("DONE WITH TEST\n");
}
- protected void cleanupData() {
- dbi.inTransaction(new TransactionCallback<Void>() {
- @Override
- public Void inTransaction(Handle h, TransactionStatus status)
- throws Exception {
- h.execute("truncate table accounts");
- h.execute("truncate table entitlement_events");
- h.execute("truncate table subscriptions");
- h.execute("truncate table bundles");
- h.execute("truncate table notifications");
- h.execute("truncate table claimed_notifications");
- h.execute("truncate table invoices");
- h.execute("truncate table fixed_invoice_items");
- h.execute("truncate table recurring_invoice_items");
- h.execute("truncate table tag_definitions");
- h.execute("truncate table tags");
- h.execute("truncate table custom_fields");
- h.execute("truncate table invoice_payments");
- h.execute("truncate table payment_attempts");
- h.execute("truncate table payments");
- return null;
- }
- });
- }
protected void verifyTestResult(UUID accountId, UUID subscriptionId,
DateTime startDate, DateTime endDate,
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
index 6490640..c733097 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.ning.billing.account.api.Account;
-import com.ning.billing.beatrix.integration.TestBusHandler.NextEvent;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -56,11 +56,13 @@ public class TestRepairIntegration extends TestIntegrationBase {
@Test(groups={"slow"}, enabled=true)
public void testRepairChangeBPWithAddonIncludedIntrial() throws Exception {
+ log.info("Starting testRepairChangeBPWithAddonIncludedIntrial");
testRepairChangeBPWithAddonIncluded(true);
}
@Test(groups={"slow"}, enabled=true)
public void testRepairChangeBPWithAddonIncludedOutOfTrial() throws Exception {
+ log.info("Starting testRepairChangeBPWithAddonIncludedOutOfTrial");
testRepairChangeBPWithAddonIncluded(false);
}
@@ -168,7 +170,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
- assertFailureFromBusHandler();
+ assertListenerStatus();
}
}
@@ -327,6 +329,4 @@ public class TestRepairIntegration extends TestIntegrationBase {
}
});
}
-
-
}
bin/clean-and-install 22(+22 -0)
diff --git a/bin/clean-and-install b/bin/clean-and-install
new file mode 100755
index 0000000..c6c3ac4
--- /dev/null
+++ b/bin/clean-and-install
@@ -0,0 +1,22 @@
+#! /usr/bin/env bash
+
+###################################################################################
+# #
+# 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. #
+# #
+###################################################################################
+
+bin/db-helper -a clean -d killbill;
+mvn -Dcom.ning.billing.dbi.test.useLocalDb=true clean install
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
index ea310f9..3cf74ec 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
@@ -348,5 +348,24 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
return false;
return true;
}
+
+ @Override
+ public String toString() {
+ return "DefaultSubscriptionEvent [transitionType=" + transitionType
+ + ", effectiveTransitionTime=" + effectiveTransitionTime
+ + ", totalOrdering=" + totalOrdering
+ + ", subscriptionId=" + subscriptionId + ", bundleId="
+ + bundleId + ", eventId=" + eventId
+ + ", requestedTransitionTime=" + requestedTransitionTime
+ + ", previousState=" + previousState + ", previousPriceList="
+ + previousPriceList + ", previousPlan=" + previousPlan
+ + ", previousPhase=" + previousPhase + ", nextState="
+ + nextState + ", nextPriceList=" + nextPriceList
+ + ", nextPlan=" + nextPlan + ", nextPhase=" + nextPhase
+ + ", remainingEventsForUserOperation="
+ + remainingEventsForUserOperation + ", userToken=" + userToken
+ + ", startDate=" + startDate + "]";
+
+ }
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
index 0353bb7..e1f6c28 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
@@ -27,15 +27,16 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementAccountMigration;
import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementBundleMigration;
@@ -50,14 +51,17 @@ public abstract class TestMigration extends TestApiBase {
public void testSingleBasePlan() {
try {
+
+ log.info("Starting testSingleBasePlan");
+
final DateTime startDate = clock.getUTCNow().minusMonths(2);
- DateTime beforeMigration = clock.getUTCNow();
+ DateTime beforeMigration = clock.getUTCNow();
EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlan(startDate);
DateTime afterMigration = clock.getUTCNow();
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
migrationApi.migrate(toBeMigrated, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
assertEquals(bundles.size(), 1);
@@ -73,6 +77,8 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-annual");
assertEquals(subscription.getChargedThroughDate(), startDate.plusYears(1));
+
+ assertListenerStatus();
} catch (EntitlementMigrationApiException e) {
Assert.fail("", e);
}
@@ -80,16 +86,17 @@ public abstract class TestMigration extends TestApiBase {
public void testPlanWithAddOn() {
try {
+ log.info("Starting testPlanWithAddOn");
DateTime beforeMigration = clock.getUTCNow();
final DateTime initalBPStart = clock.getUTCNow().minusMonths(3);
final DateTime initalAddonStart = clock.getUTCNow().minusMonths(1).plusDays(7);
EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanAndAddons(initalBPStart, initalAddonStart);
DateTime afterMigration = clock.getUTCNow();
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
migrationApi.migrate(toBeMigrated, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
assertEquals(bundles.size(), 1);
@@ -120,6 +127,7 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(aoSubscription.getCurrentPlan().getName(), "telescopic-scope-monthly");
assertEquals(aoSubscription.getChargedThroughDate(), initalAddonStart.plusMonths(1));
+ assertListenerStatus();
} catch (EntitlementMigrationApiException e) {
Assert.fail("", e);
}
@@ -128,15 +136,15 @@ public abstract class TestMigration extends TestApiBase {
public void testSingleBasePlanFutureCancelled() {
try {
-
+ log.info("Starting testSingleBasePlanFutureCancelled");
final DateTime startDate = clock.getUTCNow().minusMonths(1);
DateTime beforeMigration = clock.getUTCNow();
EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanFutreCancelled(startDate);
DateTime afterMigration = clock.getUTCNow();
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
migrationApi.migrate(toBeMigrated, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
assertEquals(bundles.size(), 1);
@@ -153,12 +161,13 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-annual");
assertEquals(subscription.getChargedThroughDate(), startDate.plusYears(1));
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_BILLING);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- // Duration oneYear = getDurationYear(1);
- // clock.setDeltaFromReality(oneYear, 0);
- clock.addYears(1);
- assertTrue(testListener.isApiCompleted(5000));
+
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusYears(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
assertNotNull(subscription.getEndDate());
@@ -168,6 +177,8 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getState(), SubscriptionState.CANCELLED);
assertNull(subscription.getCurrentPlan());
+ assertListenerStatus();
+
} catch (EntitlementMigrationApiException e) {
Assert.fail("", e);
}
@@ -176,12 +187,14 @@ public abstract class TestMigration extends TestApiBase {
public void testSingleBasePlanWithPendingPhase() {
try {
+
+ log.info("Starting testSingleBasePlanWithPendingPhase");
final DateTime trialDate = clock.getUTCNow().minusDays(10);
EntitlementAccountMigration toBeMigrated = createAccountFuturePendingPhase(trialDate);
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
migrationApi.migrate(toBeMigrated, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
assertEquals(bundles.size(), 1);
@@ -199,12 +212,12 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
assertEquals(subscription.getChargedThroughDate(), trialDate.plusDays(30));
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_BILLING);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- Duration thirtyDays = getDurationDay(30);
- // clock.setDeltaFromReality(thirtyDays, 0);
- clock.addDays(30);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
assertEquals(subscription.getStartDate(), trialDate);
assertEquals(subscription.getEndDate(), null);
@@ -214,6 +227,8 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
assertEquals(subscription.getCurrentPhase().getName(), "assault-rifle-monthly-evergreen");
+ assertListenerStatus();
+
} catch (EntitlementMigrationApiException e) {
Assert.fail("", e);
}
@@ -222,13 +237,14 @@ public abstract class TestMigration extends TestApiBase {
public void testSingleBasePlanWithPendingChange() {
try {
+ log.info("Starting testSingleBasePlanWithPendingChange");
DateTime beforeMigration = clock.getUTCNow();
EntitlementAccountMigration toBeMigrated = createAccountFuturePendingChange();
DateTime afterMigration = clock.getUTCNow();
- testListener.pushNextApiExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+ testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
migrationApi.migrate(toBeMigrated, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
assertEquals(bundles.size(), 1);
@@ -244,10 +260,11 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- Duration oneMonth = getDurationMonth(1);
- clock.setDeltaFromReality(oneMonth, 0);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
assertEquals(subscription.getEndDate(), null);
@@ -257,6 +274,8 @@ public abstract class TestMigration extends TestApiBase {
assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
assertEquals(subscription.getCurrentPlan().getName(), "shotgun-annual");
+ assertListenerStatus();
+
} catch (EntitlementMigrationApiException e) {
Assert.fail("", e);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
index 6ea53bc..0195d69 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
@@ -31,26 +31,26 @@ public class TestMigrationMemory extends TestMigration {
}
@Override
- @Test(enabled=false, groups="fast")
+ @Test(enabled=true, groups="fast")
public void testSingleBasePlan() {
super.testSingleBasePlan();
}
@Override
- @Test(enabled=false, groups="fast")
+ @Test(enabled=true, groups="fast")
public void testSingleBasePlanFutureCancelled() {
super.testSingleBasePlanFutureCancelled();
}
@Override
- @Test(enabled=false, groups="fast")
+ @Test(enabled=true, groups="fast")
public void testPlanWithAddOn() {
super.testPlanWithAddOn();
}
@Override
- @Test(enabled=false, groups="fast")
+ @Test(enabled=true, groups="fast")
public void testSingleBasePlanWithPendingPhase() {
super.testSingleBasePlanWithPendingPhase();
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index 62d905a..7d1389e 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
@@ -34,6 +34,7 @@ import org.joda.time.DateTimeZone;
import org.joda.time.Period;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
@@ -42,6 +43,9 @@ import org.testng.annotations.BeforeMethod;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.ning.billing.account.api.AccountData;
+import com.ning.billing.api.TestApiListener;
+import com.ning.billing.api.TestApiListener.NextEvent;
+import com.ning.billing.api.TestListenerStatus;
import com.ning.billing.catalog.DefaultCatalogService;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Catalog;
@@ -54,7 +58,6 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.catalog.api.TimeUnit;
import com.ning.billing.config.EntitlementConfig;
import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.billing.ChargeThruApi;
import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi;
import com.ning.billing.entitlement.api.timeline.EntitlementTimelineApi;
@@ -80,7 +83,8 @@ import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.glue.RealImplementation;
-public abstract class TestApiBase {
+public abstract class TestApiBase implements TestListenerStatus {
+
protected static final Logger log = LoggerFactory.getLogger(TestApiBase.class);
protected static final long DAY_IN_MS = (24 * 3600 * 1000);
@@ -100,12 +104,23 @@ public abstract class TestApiBase {
protected AccountData accountData;
protected Catalog catalog;
- protected ApiTestListener testListener;
+ protected TestApiListener testListener;
protected SubscriptionBundle bundle;
private MysqlTestingHelper helper;
protected CallContext context = new TestCallContext("Api Test");
+ private boolean isListenerFailed;
+ private String listenerFailedMsg;
+
+ //
+ // The date on which we make our test start; just to ensure that running tests at different dates does not
+ // produce different results. nothing specific about that date; we could change it to anything.
+ //
+ protected DateTime testStartDate = new DateTime(2012, 5, 7, 0, 3, 42, 0);
+
+
+
public static void loadSystemPropertiesFromClasspath(final String resource) {
final URL url = TestApiBase.class.getResource(resource);
assertNotNull(url);
@@ -131,6 +146,19 @@ public abstract class TestApiBase {
}
}
+
+ @Override
+ public void failed(final String msg) {
+ this.isListenerFailed = true;
+ this.listenerFailedMsg = msg;
+ }
+
+ @Override
+ public void resetTestListenerStatus() {
+ this.isListenerFailed = false;
+ this.listenerFailedMsg = null;
+ }
+
@BeforeClass(alwaysRun = true)
public void setup() throws Exception {
@@ -149,64 +177,97 @@ public abstract class TestApiBase {
dao = g.getInstance(EntitlementDao.class);
clock = (ClockMock) g.getInstance(Clock.class);
helper = (isSqlTest(dao)) ? g.getInstance(MysqlTestingHelper.class) : null;
+ init();
+ }
+
+ private void init() throws Exception {
+
+ setupDao();
((DefaultCatalogService) catalogService).loadCatalog();
((Engine) entitlementService).initialize();
- init(g);
- ((DefaultBusService) busService).startBus();
- }
- private static boolean isSqlTest(EntitlementDao theDao) {
- return (! (theDao instanceof MockEntitlementDaoMemory));
+ accountData = getAccountData();
+ assertNotNull(accountData);
+ catalog = catalogService.getFullCatalog();
+ assertNotNull(catalog);
+ testListener = new TestApiListener(this);
}
- private void setupMySQL() throws IOException {
+ private void setupDao() throws IOException {
if (helper != null) {
final String entitlementDdl = IOUtils.toString(TestApiBase.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
final String utilDdl = IOUtils.toString(TestApiBase.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
helper.startMysql();
- helper.cleanupAllTables();
helper.initDb(entitlementDdl);
helper.initDb(utilDdl);
}
}
- private void init(Injector g) throws Exception {
-
- setupMySQL();
- accountData = getAccountData();
- assertNotNull(accountData);
- catalog = catalogService.getFullCatalog();
- assertNotNull(catalog);
- testListener = new ApiTestListener(busService.getBus());
+ private static boolean isSqlTest(EntitlementDao theDao) {
+ return (! (theDao instanceof MockEntitlementDaoMemory));
}
-
+
@BeforeMethod(alwaysRun = true)
public void setupTest() throws Exception {
log.warn("RESET TEST FRAMEWORK\n\n");
+ // CLEANUP ALL DB TABLES OR IN MEMORY STRUCTURES
+ cleanupDao();
+
+ // RESET LIST OF EXPECTED EVENTS
if (testListener != null) {
testListener.reset();
+ resetTestListenerStatus();
}
-
+
+ // RESET CLOCK
clock.resetDeltaFromReality();
- ((MockEntitlementDao) dao).reset();
+ // START BUS AND REGISTER LISTENER
+ busService.getBus().start();
busService.getBus().register(testListener);
+
+ // START NOTIFICATION QUEUE FOR ENTITLEMENT
+ ((Engine)entitlementService).start();
+
+ // SETUP START DATE
+ clock.setDeltaFromReality(testStartDate.getMillis() - clock.getUTCNow().getMillis());
+
+ // CREATE NEW BUNDLE FOR TEST
UUID accountId = UUID.randomUUID();
bundle = entitlementApi.createBundleForAccount(accountId, "myDefaultBundle", context);
assertNotNull(bundle);
-
- ((Engine)entitlementService).start();
}
@AfterMethod(alwaysRun = true)
public void cleanupTest() throws Exception {
+
+ // UNREGISTER TEST LISTENER AND STOP BUS
busService.getBus().unregister(testListener);
+ busService.getBus().stop();
+
+ // STOP NOTIFICATION QUEUE
((Engine)entitlementService).stop();
+
log.warn("DONE WITH TEST\n");
}
+
+ protected void assertListenerStatus() {
+ if (isListenerFailed) {
+ log.error(listenerFailedMsg);
+ Assert.fail(listenerFailedMsg);
+ }
+ }
+
+ private void cleanupDao() {
+ if (helper != null) {
+ helper.cleanupAllTables();
+ } else {
+ ((MockEntitlementDao) dao).reset();
+ }
+ }
protected SubscriptionData createSubscription(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
throws EntitlementUserApiException {
@@ -219,13 +280,13 @@ public abstract class TestApiBase {
protected SubscriptionData createSubscriptionWithBundle(final UUID bundleId, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
throws EntitlementUserApiException {
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
-
+
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundleId,
new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSet, null),
requestedDate == null ? clock.getUTCNow() : requestedDate, context);
assertNotNull(subscription);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
return subscription;
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index e988805..fce7e8a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -34,6 +35,7 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
import com.ning.billing.ErrorCode;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
@@ -43,7 +45,6 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.timeline.BundleTimeline;
import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
@@ -67,6 +68,8 @@ public class TestRepairBP extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testFetchBundleRepair() throws Exception {
+ log.info("Starting testFetchBundleRepair");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -125,11 +128,14 @@ public class TestRepairBP extends TestApiBaseRepair {
assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), aoTerm);
}
}
+ assertListenerStatus();
}
@Test(groups={"slow"})
public void testBPRepairWithCancellationOnstart() throws Exception {
+ log.info("Starting testBPRepairWithCancellationOnstart");
+
String baseProduct = "Shotgun";
DateTime startDate = clock.getUTCNow();
@@ -137,8 +143,8 @@ public class TestRepairBP extends TestApiBaseRepair {
Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
// Stays in trial-- for instance
- Duration durationShift = getDurationDay(10);
- clock.setDeltaFromReality(durationShift, 0);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(10));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -190,9 +196,9 @@ public class TestRepairBP extends TestApiBaseRepair {
// SECOND RE-ISSUE CALL-- NON DRY RUN
dryRun = false;
- testListener.expectRepairCompletion();
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
- assertTrue(testListener.isRepairCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
subscriptionRepair = realRunBundleRepair.getSubscriptions();
assertEquals(subscriptionRepair.size(), 1);
@@ -211,10 +217,15 @@ public class TestRepairBP extends TestApiBaseRepair {
assertEquals(realRunBaseSubscription.getStartDate(), startDate);
assertEquals(realRunBaseSubscription.getState(), SubscriptionState.CANCELLED);
+
+ assertListenerStatus();
}
@Test(groups={"slow"})
public void testBPRepairReplaceCreateBeforeTrial() throws Exception {
+
+ log.info("Starting testBPRepairReplaceCreateBeforeTrial");
+
String baseProduct = "Shotgun";
String newBaseProduct = "Assault-Rifle";
@@ -229,10 +240,14 @@ public class TestRepairBP extends TestApiBaseRepair {
ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
+ assertListenerStatus();
}
@Test(groups={"slow"}, enabled=true)
public void testBPRepairReplaceCreateInTrial() throws Exception {
+
+ log.info("Starting testBPRepairReplaceCreateInTrial");
+
String baseProduct = "Shotgun";
String newBaseProduct = "Assault-Rifle";
@@ -248,9 +263,10 @@ public class TestRepairBP extends TestApiBaseRepair {
UUID baseSubscriptionId = testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(getDurationDay(32));
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
@@ -269,11 +285,16 @@ public class TestRepairBP extends TestApiBaseRepair {
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+
+ assertListenerStatus();
}
@Test(groups={"slow"})
public void testBPRepairReplaceCreateAfterTrial() throws Exception {
+
+ log.info("Starting testBPRepairReplaceCreateAfterTrial");
+
String baseProduct = "Shotgun";
String newBaseProduct = "Assault-Rifle";
@@ -288,25 +309,28 @@ public class TestRepairBP extends TestApiBaseRepair {
ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
testBPRepairCreate(false, startDate, clockShift, baseProduct, newBaseProduct, expected);
-
+ assertListenerStatus();
}
private UUID testBPRepairCreate(boolean inTrial, DateTime startDate, int clockShift,
String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents) throws Exception {
+ log.info("Starting testBPRepairCreate");
+
// CREATE BP
Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
// MOVE CLOCK
if (clockShift > 0) {
if (!inTrial) {
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
}
- Duration durationShift = getDurationDay(clockShift);
- clock.setDeltaFromReality(durationShift, 0);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
+ clock.addDeltaFromReality(it.toDurationMillis());
if (!inTrial) {
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
}
}
@@ -327,7 +351,7 @@ public class TestRepairBP extends TestApiBaseRepair {
// FIRST ISSUE DRY RUN
BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
- boolean dryRun = true;
+ boolean dryRun = true;
BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
assertEquals(subscriptionRepair.size(), 1);
@@ -362,8 +386,9 @@ public class TestRepairBP extends TestApiBaseRepair {
// SECOND RE-ISSUE CALL-- NON DRY RUN
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
-
+ assertTrue(testListener.isCompleted(5000));
subscriptionRepair = realRunBundleRepair.getSubscriptions();
assertEquals(subscriptionRepair.size(), 1);
cur = subscriptionRepair.get(0);
@@ -402,6 +427,8 @@ public class TestRepairBP extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testBPRepairAddChangeInTrial() throws Exception {
+ log.info("Starting testBPRepairAddChangeInTrial");
+
String baseProduct = "Shotgun";
String newBaseProduct = "Assault-Rifle";
@@ -420,9 +447,10 @@ public class TestRepairBP extends TestApiBaseRepair {
UUID baseSubscriptionId = testBPRepairAddChange(true, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
// CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(getDurationDay(32));
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
@@ -439,11 +467,15 @@ public class TestRepairBP extends TestApiBaseRepair {
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+
+ assertListenerStatus();
}
@Test(groups={"slow"})
public void testBPRepairAddChangeAfterTrial() throws Exception {
+ log.info("Starting testBPRepairAddChangeAfterTrial");
+
String baseProduct = "Shotgun";
String newBaseProduct = "Assault-Rifle";
@@ -459,24 +491,27 @@ public class TestRepairBP extends TestApiBaseRepair {
expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, newBaseProduct, PhaseType.EVERGREEN,
ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, changeDate));
testBPRepairAddChange(false, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
+
+ assertListenerStatus();
}
private UUID testBPRepairAddChange(boolean inTrial, DateTime startDate, int clockShift,
String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents, int expectedTransitions) throws Exception {
+
// CREATE BP
Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
// MOVE CLOCK
if (!inTrial) {
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
}
-
- Duration durationShift = getDurationDay(clockShift);
- clock.setDeltaFromReality(durationShift, 0);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
+ clock.addDeltaFromReality(it.toDurationMillis());
if (!inTrial) {
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
}
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
@@ -498,6 +533,7 @@ public class TestRepairBP extends TestApiBaseRepair {
boolean dryRun = true;
BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+
List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
assertEquals(subscriptionRepair.size(), 1);
SubscriptionTimeline cur = subscriptionRepair.get(0);
@@ -532,7 +568,9 @@ public class TestRepairBP extends TestApiBaseRepair {
// SECOND RE-ISSUE CALL-- NON DRY RUN
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
subscriptionRepair = realRunBundleRepair.getSubscriptions();
assertEquals(subscriptionRepair.size(), 1);
@@ -572,15 +610,19 @@ public class TestRepairBP extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairWithFurureCancelEvent() throws Exception {
+ log.info("Starting testRepairWithFurureCancelEvent");
+
DateTime startDate = clock.getUTCNow();
// CREATE BP
Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
// MOVE CLOCK -- OUT OF TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(getDurationDay(35), 0);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(35));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
@@ -616,7 +658,9 @@ public class TestRepairBP extends TestApiBaseRepair {
BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
boolean dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
repairApi.repairBundle(bRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
@@ -633,6 +677,8 @@ public class TestRepairBP extends TestApiBaseRepair {
PlanPhase currentPhase = baseSubscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+
+ assertListenerStatus();
}
@@ -640,12 +686,11 @@ public class TestRepairBP extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testENT_REPAIR_VIEW_CHANGED_newEvent() throws Exception {
+ log.info("Starting testENT_REPAIR_VIEW_CHANGED_newEvent");
+
TestWithException test = new TestWithException();
DateTime startDate = clock.getUTCNow();
- testListener.reset();
- clock.resetDeltaFromReality();
-
final Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
test.withException(new TestWithExceptionCallback() {
@@ -663,12 +708,13 @@ public class TestRepairBP extends TestApiBaseRepair {
BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
DateTime changeTime = clock.getUTCNow();
baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
- assertTrue(testListener.isApiCompleted(5000));
-
+ assertTrue(testListener.isCompleted(5000));
+
repairApi.repairBundle(bRepair, true, context);
+ assertListenerStatus();
}
}, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
}
@@ -676,12 +722,11 @@ public class TestRepairBP extends TestApiBaseRepair {
@Test(groups={"slow"}, enabled=false)
public void testENT_REPAIR_VIEW_CHANGED_ctd() throws Exception {
+ log.info("Starting testENT_REPAIR_VIEW_CHANGED_ctd");
+
TestWithException test = new TestWithException();
DateTime startDate = clock.getUTCNow();
- testListener.reset();
- clock.resetDeltaFromReality();
-
final Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
test.withException(new TestWithExceptionCallback() {
@@ -704,6 +749,8 @@ public class TestRepairBP extends TestApiBaseRepair {
entitlementApi.getSubscriptionFromId(baseSubscription.getId());
repairApi.repairBundle(bRepair, true, context);
+
+ assertListenerStatus();
}
}, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
index 57a78e6..ec75a30 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
@@ -24,11 +24,13 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
@@ -38,7 +40,6 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.timeline.BundleTimeline;
import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.DeletedEvent;
@@ -59,6 +60,8 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairChangeBPWithAddonIncluded() throws Exception {
+ log.info("Starting testRepairChangeBPWithAddonIncluded");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -67,15 +70,16 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
SubscriptionData aoSubscription2 = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -165,8 +169,11 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
- dryRun = false;
+ dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
+
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
@@ -210,6 +217,8 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairChangeBPWithAddonNonAvailable() throws Exception {
+ log.info("Starting testRepairChangeBPWithAddonNonAvailable");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -218,17 +227,18 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- someTimeLater = getDurationDay(32);
- clock.addDeltaFromReality(someTimeLater);
- assertTrue(testListener.isApiCompleted(7000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(7000));
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -295,8 +305,10 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
-
+ assertTrue(testListener.isCompleted(5000));
+
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -327,6 +339,8 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairCancelBP_EOT_WithAddons() throws Exception {
+ log.info("Starting testRepairCancelBP_EOT_WithAddons");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -335,17 +349,19 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- someTimeLater = getDurationDay(40);
- clock.addDeltaFromReality(someTimeLater);
- assertTrue(testListener.isApiCompleted(7000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(7000));
// SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
@@ -414,7 +430,9 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -443,11 +461,12 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
// MOVE CLOCK AFTER CANCEL DATE
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- someTimeLater = getDurationDay(32);
- clock.addDeltaFromReality(someTimeLater);
- assertTrue(testListener.isApiCompleted(7000));
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(7000));
newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
@@ -464,6 +483,9 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairCancelAO() throws Exception {
+
+ log.info("Starting testRepairCancelAO");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -472,13 +494,14 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -530,7 +553,10 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
+
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
assertEquals(aoRepair.getExistingEvents().size(), 2);
@@ -553,6 +579,9 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairRecreateAO() throws Exception {
+
+ log.info("Starting testRepairRecreateAO");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -561,13 +590,14 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -616,7 +646,9 @@ public class TestRepairWithAO extends TestApiBaseRepair {
// NOW COMMIT
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
assertEquals(aoRepair.getExistingEvents().size(), 2);
@@ -644,6 +676,8 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairChangeAOOK() throws Exception {
+ log.info("Starting testRepairChangeAOOK");
+
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -652,13 +686,14 @@ public class TestRepairWithAO extends TestApiBaseRepair {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -706,7 +741,9 @@ public class TestRepairWithAO extends TestApiBaseRepair {
// AND NOW COMMIT
dryRun = false;
+ testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+ assertTrue(testListener.isCompleted(5000));
aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
assertEquals(aoRepair.getExistingEvents().size(), 3);
@@ -734,10 +771,11 @@ public class TestRepairWithAO extends TestApiBaseRepair {
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- someTimeLater = getDurationDay(60);
- clock.addDeltaFromReality(someTimeLater);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(60));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
currentPhase = newAoSubscription.getCurrentPhase();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
index 285b17d..7421b48 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -31,6 +32,7 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
import com.ning.billing.ErrorCode;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
@@ -38,7 +40,6 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.timeline.BundleTimeline;
import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
@@ -61,27 +62,30 @@ public class TestRepairWithError extends TestApiBaseRepair {
return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleMemory());
}
-
- @BeforeMethod(groups={"fast"})
- public void beforeMethod() throws Exception {
+ @BeforeMethod(alwaysRun = true)
+ public void setupTest() throws Exception {
+ super.setupTest();
test = new TestWithException();
startDate = clock.getUTCNow();
baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
- testListener.reset();
- clock.resetDeltaFromReality();
}
@Test(groups={"fast"})
public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING() throws Exception {
+
+ log.info("Starting testENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException {
// MOVE AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- Duration durationShift = getDurationDay(40);
- clock.setDeltaFromReality(durationShift, 0);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ assertTrue(testListener.isCompleted(5000));
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -99,23 +103,26 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_INVALID_DELETE_SET() throws Exception {
+
+ log.info("Starting testENT_REPAIR_INVALID_DELETE_SET");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
- Duration durationShift = getDurationDay(3);
- clock.setDeltaFromReality(durationShift, 0);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
DateTime changeTime = clock.getUTCNow();
baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
// MOVE AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- durationShift = getDurationDay(40);
- clock.addDeltaFromReality(durationShift);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -133,6 +140,9 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_NON_EXISTENT_DELETE_EVENT() throws Exception {
+
+ log.info("Starting testENT_REPAIR_NON_EXISTENT_DELETE_EVENT");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException {
@@ -153,15 +163,18 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_SUB_RECREATE_NOT_EMPTY() throws Exception {
+
+ log.info("Starting testENT_REPAIR_SUB_RECREATE_NOT_EMPTY");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException {
// MOVE AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- Duration durationShift = getDurationDay(40);
- clock.setDeltaFromReality(durationShift, 0);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -181,15 +194,19 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_SUB_EMPTY() throws Exception {
+
+ log.info("Starting testENT_REPAIR_SUB_EMPTY");
+
test.withException(new TestWithExceptionCallback() {
+
@Override
public void doTest() throws EntitlementRepairException {
// MOVE AFTER TRIAL
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- Duration durationShift = getDurationDay(40);
- clock.setDeltaFromReality(durationShift, 0);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -209,19 +226,22 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_AO_CREATE_BEFORE_BP_START() throws Exception {
+
+ log.info("Starting testENT_REPAIR_AO_CREATE_BEFORE_BP_START");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
-
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -254,19 +274,22 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING() throws Exception {
+
+ log.info("Starting testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
// MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
- Duration someTimeLater = getDurationDay(3);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
-
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
// MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
- clock.addDeltaFromReality(someTimeLater);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
@@ -298,13 +321,17 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"})
public void testENT_REPAIR_BP_RECREATE_MISSING_AO() throws Exception {
+
+ log.info("Starting testENT_REPAIR_BP_RECREATE_MISSING_AO");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
//testListener.pushExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(getDurationDay(5), 0);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
//assertTrue(testListener.isCompleted(5000));
SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -337,14 +364,18 @@ public class TestRepairWithError extends TestApiBaseRepair {
//
@Test(groups={"fast"}, enabled=false)
public void testENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE() throws Exception {
+
+ log.info("Starting testENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
/*
//testListener.pushExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(getDurationDay(5), 0);
- //assertTrue(testListener.isCompleted(5000));
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -382,6 +413,9 @@ public class TestRepairWithError extends TestApiBaseRepair {
@Test(groups={"fast"}, enabled=false)
public void testENT_REPAIR_MISSING_AO_DELETE_EVENT() throws Exception {
+
+ log.info("Starting testENT_REPAIR_MISSING_AO_DELETE_EVENT");
+
test.withException(new TestWithExceptionCallback() {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
@@ -389,6 +423,10 @@ public class TestRepairWithError extends TestApiBaseRepair {
/*
// MOVE CLOCK -- JUST BEFORE END OF TRIAL
+ *
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(29));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
clock.setDeltaFromReality(getDurationDay(29), 0);
SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
index 2780fe5..d412e59 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
@@ -21,15 +21,15 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-import org.apache.commons.lang.NotImplementedException;
import org.joda.time.DateTime;
-import org.joda.time.Period;
+import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.CatalogApiException;
import com.ning.billing.catalog.api.Duration;
@@ -40,8 +40,6 @@ import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PlanSpecifier;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.catalog.api.TimeUnit;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
import com.ning.billing.entitlement.glue.MockEngineModuleSql;
@@ -57,6 +55,8 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testCreateCancelAddon() {
+ log.info("Starting testCreateCancelAddon");
+
try {
String baseProduct = "Shotgun";
BillingPeriod baseTerm = BillingPeriod.MONTHLY;
@@ -75,11 +75,12 @@ public class TestUserApiAddOn extends TestApiBase {
aoSubscription.cancel(now, false, context);
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ assertTrue(testListener.isCompleted(5000));
assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertListenerStatus();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@@ -87,6 +88,9 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testCancelBPWithAddon() {
+
+ log.info("Starting testCancelBPWithAddon");
+
try {
String baseProduct = "Shotgun";
@@ -103,13 +107,13 @@ public class TestUserApiAddOn extends TestApiBase {
SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
// MOVE CLOCK AFTER TRIAL + AO DISCOUNT
- Duration twoMonths = getDurationMonth(2);
- clock.setDeltaFromReality(twoMonths, DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(5000));
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(2));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD TO CANCEL IN FUTURE
DateTime now = clock.getUTCNow();
@@ -129,15 +133,19 @@ public class TestUserApiAddOn extends TestApiBase {
// MOVE AFTER CANCELLATION
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// REFETCH AO SUBSCRIPTION AND CHECK THIS IS CANCELLED
aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertListenerStatus();
+
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@@ -146,6 +154,9 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testChangeBPWithAddonNonIncluded() {
+
+ log.info("Starting testChangeBPWithAddonNonIncluded");
+
try {
String baseProduct = "Shotgun";
@@ -162,13 +173,13 @@ public class TestUserApiAddOn extends TestApiBase {
SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
// MOVE CLOCK AFTER TRIAL + AO DISCOUNT
- Duration twoMonths = getDurationMonth(2);
- clock.setDeltaFromReality(twoMonths, DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(5000));
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(2));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD TO CHANGE IN FUTURE
DateTime now = clock.getUTCNow();
@@ -183,15 +194,16 @@ public class TestUserApiAddOn extends TestApiBase {
String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, context);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
// REFETCH AO SUBSCRIPTION AND CHECK THIS CANCELLED
aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertListenerStatus();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@@ -199,6 +211,9 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testChangeBPWithAddonNonAvailable() {
+
+ log.info("Starting testChangeBPWithAddonNonAvailable");
+
try {
String baseProduct = "Shotgun";
@@ -215,13 +230,13 @@ public class TestUserApiAddOn extends TestApiBase {
SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
// MOVE CLOCK AFTER TRIAL + AO DISCOUNT
- Duration twoMonths = getDurationMonth(2);
- clock.setDeltaFromReality(twoMonths, DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(5000));
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(2));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD TO CANCEL IN FUTURE
DateTime now = clock.getUTCNow();
@@ -245,16 +260,18 @@ public class TestUserApiAddOn extends TestApiBase {
// MOVE AFTER CHANGE
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// REFETCH AO SUBSCRIPTION AND CHECK THIS CANCELLED
aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
assertEquals(aoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertListenerStatus();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
@@ -263,6 +280,9 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testAddonCreateWithBundleAlign() {
+
+ log.info("Starting testAddonCreateWithBundleAlign");
+
try {
String aoProduct = "Telescopic-Scope";
BillingPeriod aoTerm = BillingPeriod.MONTHLY;
@@ -278,6 +298,7 @@ public class TestUserApiAddOn extends TestApiBase {
testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
+ assertListenerStatus();
} catch (CatalogApiException e) {
Assert.fail(e.getMessage());
}
@@ -287,6 +308,8 @@ public class TestUserApiAddOn extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testAddonCreateWithSubscriptionAlign() {
+ log.info("Starting testAddonCreateWithSubscriptionAlign");
+
try {
String aoProduct = "Laser-Scope";
BillingPeriod aoTerm = BillingPeriod.MONTHLY;
@@ -302,13 +325,15 @@ public class TestUserApiAddOn extends TestApiBase {
testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
- } catch (CatalogApiException e) {
- Assert.fail(e.getMessage());
- }
+ assertListenerStatus();
+ } catch (CatalogApiException e) {
+ Assert.fail(e.getMessage());
+ }
}
private void testAddonCreateInternal(String aoProduct, BillingPeriod aoTerm, String aoPriceList, PlanAlignmentCreate expAlignement) {
+
try {
String baseProduct = "Shotgun";
@@ -319,9 +344,9 @@ public class TestUserApiAddOn extends TestApiBase {
SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
// MOVE CLOCK 14 DAYS LATER
- Duration someTimeLater = getDurationDay(13);
- clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
-
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(14));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
// CREATE ADDON
DateTime beforeAOCreation = clock.getUTCNow();
SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
@@ -338,73 +363,46 @@ public class TestUserApiAddOn extends TestApiBase {
assertNotNull(aoCurrentPhase);
assertEquals(aoCurrentPhase.getPhaseType(), PhaseType.DISCOUNT);
- assertDateWithin(aoSubscription.getStartDate(), beforeAOCreation, afterAOCreation);
- assertEquals(aoSubscription.getBundleStartDate(), baseSubscription.getBundleStartDate());
-
- // CHECK next AO PHASE EVENT IS INDEED A MONTH AFTER BP STARTED => BUNDLE ALIGNMENT
- SubscriptionEvent aoPendingTranstion = aoSubscription.getPendingTransition();
-
- if (expAlignement == PlanAlignmentCreate.START_OF_BUNDLE) {
- assertEquals(aoPendingTranstion.getEffectiveTransitionTime(), baseSubscription.getStartDate().plusMonths(1));
- } else {
- assertEquals(aoPendingTranstion.getEffectiveTransitionTime(), aoSubscription.getStartDate().plusMonths(1));
- }
-
- // ADD TWO PHASE EVENTS (BP + AO)
- testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
-
- // MOVE THROUGH TIME TO GO INTO EVERGREEN
-
- // Talk with Stephane about this fix. It seemed that the add on phase change was not appearing in the queue
- // hypothesis is that waiting a period that is exactly the duration of the phase might be an instant too short
- // depending how the comparison works
-
- //someTimeLater = aoCurrentPhase.getDuration();
- someTimeLater = new Duration() {
- @Override
- public TimeUnit getUnit() {
- return TimeUnit.DAYS;
- }
-
- @Override
- public int getNumber() {
- return 32;
- }
-
- @Override
- public DateTime addToDateTime(DateTime dateTime) {
- throw new NotImplementedException();
- }
- @Override
- public Period toJodaPeriod() {
- throw new UnsupportedOperationException();
- }
- };
-
- clock.addDeltaFromReality(someTimeLater);
- clock.addDeltaFromReality(getDurationDay(1));
- assertTrue(testListener.isApiCompleted(5000));
-
-
- // CHECK EVERYTHING AGAIN
- aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
-
- aoCurrentPlan = aoSubscription.getCurrentPlan();
- assertNotNull(aoCurrentPlan);
- assertEquals(aoCurrentPlan.getProduct().getName(),aoProduct);
- assertEquals(aoCurrentPlan.getProduct().getCategory(), ProductCategory.ADD_ON);
- assertEquals(aoCurrentPlan.getBillingPeriod(), aoTerm);
-
- aoCurrentPhase = aoSubscription.getCurrentPhase();
- assertNotNull(aoCurrentPhase);
- assertEquals(aoCurrentPhase.getPhaseType(), PhaseType.EVERGREEN);
-
-
- aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
- aoPendingTranstion = aoSubscription.getPendingTransition();
- assertNull(aoPendingTranstion);
+ assertDateWithin(aoSubscription.getStartDate(), beforeAOCreation, afterAOCreation);
+ assertEquals(aoSubscription.getBundleStartDate(), baseSubscription.getBundleStartDate());
+
+ // CHECK next AO PHASE EVENT IS INDEED A MONTH AFTER BP STARTED => BUNDLE ALIGNMENT
+ SubscriptionEvent aoPendingTranstion = aoSubscription.getPendingTransition();
+
+ if (expAlignement == PlanAlignmentCreate.START_OF_BUNDLE) {
+ assertEquals(aoPendingTranstion.getEffectiveTransitionTime(), baseSubscription.getStartDate().plusMonths(1));
+ } else {
+ assertEquals(aoPendingTranstion.getEffectiveTransitionTime(), aoSubscription.getStartDate().plusMonths(1));
+ }
+
+ // ADD TWO PHASE EVENTS (BP + AO)
+ testListener.reset();
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ // MOVE THROUGH TIME TO GO INTO EVERGREEN
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(33));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
+
+
+ // CHECK EVERYTHING AGAIN
+ aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+ aoCurrentPlan = aoSubscription.getCurrentPlan();
+ assertNotNull(aoCurrentPlan);
+ assertEquals(aoCurrentPlan.getProduct().getName(),aoProduct);
+ assertEquals(aoCurrentPlan.getProduct().getCategory(), ProductCategory.ADD_ON);
+ assertEquals(aoCurrentPlan.getBillingPeriod(), aoTerm);
+
+ aoCurrentPhase = aoSubscription.getCurrentPhase();
+ assertNotNull(aoCurrentPhase);
+ assertEquals(aoCurrentPhase.getPhaseType(), PhaseType.EVERGREEN);
+
+
+ aoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ aoPendingTranstion = aoSubscription.getPendingTransition();
+ assertNull(aoPendingTranstion);
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 09046f1..7fb06e0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -22,15 +22,16 @@ import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PriceListSet;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
import com.ning.billing.util.clock.DefaultClock;
@@ -55,20 +56,21 @@ public abstract class TestUserApiCancel extends TestApiBase {
assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
// ADVANCE TIME still in trial
- Duration moveALittleInTime = getDurationDay(3);
- clock.setDeltaFromReality(moveALittleInTime, 0);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
DateTime future = clock.getUTCNow();
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
// CANCEL in trial period to get IMM policy
subscription.cancel(clock.getUTCNow(), false, context);
currentPhase = subscription.getCurrentPhase();
- testListener.isApiCompleted(1000);
+ testListener.isCompleted(3000);
assertNull(currentPhase);
checkNextPhaseChange(subscription, 0, null);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -94,9 +96,11 @@ public abstract class TestUserApiCancel extends TestApiBase {
checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ assertTrue(testListener.isCompleted(5000));
trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.EVERGREEN);
@@ -106,21 +110,25 @@ public abstract class TestUserApiCancel extends TestApiBase {
billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
-
// CANCEL
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancel(clock.getUTCNow(), false, context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
+ testListener.reset();
// MOVE TO EOT + RECHECK
- clock.addDeltaFromReality(ctd);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
DateTime future = clock.getUTCNow();
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNull(currentPhase);
checkNextPhaseChange(subscription, 0, null);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -147,22 +155,25 @@ public abstract class TestUserApiCancel extends TestApiBase {
checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.EVERGREEN);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
// CANCEL
subscription.cancel(clock.getUTCNow(), false, context);
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNull(currentPhase);
checkNextPhaseChange(subscription, 0, null);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -191,9 +202,10 @@ public abstract class TestUserApiCancel extends TestApiBase {
checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
PlanPhase currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
@@ -203,27 +215,25 @@ public abstract class TestUserApiCancel extends TestApiBase {
billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
-
- // CANCEL
+ // CANCEL EOT
subscription.cancel(clock.getUTCNow(), false, context);
- assertFalse(testListener.isApiCompleted(2000));
subscription.uncancel(context);
-
+
// MOVE TO EOT + RECHECK
- clock.addDeltaFromReality(ctd);
- DateTime future = clock.getUTCNow();
- assertFalse(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.UNCANCEL);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
Plan currentPlan = subscription.getCurrentPlan();
assertEquals(currentPlan.getProduct().getName(), prod);
currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
}
-
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
index 7eccbdd..625002a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
@@ -33,25 +33,25 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCancelSubscriptionIMM() {
super.testCancelSubscriptionIMM();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCancelSubscriptionEOTWithChargeThroughDate() throws EntitlementBillingApiException {
super.testCancelSubscriptionEOTWithChargeThroughDate();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCancelSubscriptionEOTWithNoChargeThroughDate() {
super.testCancelSubscriptionEOTWithNoChargeThroughDate();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testUncancel() throws EntitlementBillingApiException {
super.testUncancel();
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index b5b98e4..b1d2c0b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -25,8 +25,10 @@ import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
@@ -34,7 +36,6 @@ import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
import com.ning.billing.entitlement.events.EntitlementEvent;
@@ -69,7 +70,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
String toProd, BillingPeriod toTerm, String toPlanSet) {
- log.info("Starting testChangePlanBundleAlignEOTWithNoChargeThroughDateReal");
+ log.info("Starting testChangePlanBundleAlignEOTWithNoChargeThroughDate");
try {
@@ -78,22 +79,26 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
// MOVE TO NEXT PHASE
PlanPhase currentPhase = subscription.getCurrentPhase();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(currentPhase.getDuration(), DAY_IN_MS);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
DateTime futureNow = clock.getUTCNow();
DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
- assertTrue(testListener.isApiCompleted(3000));
+ assertTrue(testListener.isCompleted(5000));
// CHANGE PLAN
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
// CHECK CHANGE PLAN
currentPhase = subscription.getCurrentPhase();
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.EVERGREEN);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -101,13 +106,14 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
protected void testChangePlanBundleAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
+ log.info("Starting testChangePlanBundleAlignEOTWithChargeThroughDate");
testChangePlanBundleAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", "Pistol", BillingPeriod.ANNUAL, "gunclubDiscount");
}
private void testChangePlanBundleAlignEOTWithChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
String toProd, BillingPeriod toTerm, String toPlanSet) throws EntitlementBillingApiException {
- log.info("Starting testChangeSubscriptionEOTWithChargeThroughDate");
+
try {
// CREATE
@@ -118,9 +124,10 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
PlanPhase currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
@@ -131,10 +138,11 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
// RE READ SUBSCRIPTION + CHANGE PLAN
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
testListener.reset();
// CHECK CHANGE PLAN
@@ -151,14 +159,16 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
// MOVE TO EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
currentPhase = subscription.getCurrentPhase();
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.DISCOUNT);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -179,37 +189,31 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
- Duration moveALittleInTime = getDurationDay(3);
- clock.setDeltaFromReality(moveALittleInTime, 0);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+ clock.addDeltaFromReality(it.toDurationMillis());
// CHANGE PLAN IMM
subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.TRIAL);
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
PlanPhase currentPhase = subscription.getCurrentPhase();
DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
// NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(currentPhase.getDuration());
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
+ clock.addDeltaFromReality(it.toDurationMillis());
DateTime futureNow = clock.getUTCNow();
- /*
- try {
- Thread.sleep(1000 * 3000);
- } catch (Exception e) {
-
- }
- */
-
assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
- assertTrue(testListener.isApiCompleted(3000));
+ assertTrue(testListener.isCompleted(5000));
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -217,14 +221,13 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
protected void testChangePlanChangePlanAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
+ log.info("Starting testChangePlanChangePlanAlignEOTWithChargeThroughDate");
tChangePlanChangePlanAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.ANNUAL, "rescue");
}
private void tChangePlanChangePlanAlignEOTWithChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
String toProd, BillingPeriod toTerm, String toPlanSet) throws EntitlementBillingApiException {
- log.info("Starting testChangePlanBundleAlignEOTWithChargeThroughDate");
-
try {
DateTime currentTime = clock.getUTCNow();
@@ -235,11 +238,12 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
currentTime = clock.getUTCNow();
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
currentTime = clock.getUTCNow();
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
// SET CTD
Duration ctd = getDurationMonth(1);
@@ -254,19 +258,22 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
// CHANGE PLAN
currentTime = clock.getUTCNow();
-
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow(), context);
checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.EVERGREEN);
// CHECK CHANGE DID NOT KICK IN YET
- assertFalse(testListener.isApiCompleted(2000));
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ assertFalse(testListener.isCompleted(3000));
+ testListener.reset();
// MOVE TO AFTER CTD
- clock.addDeltaFromReality(ctd);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
currentTime = clock.getUTCNow();
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
// CHECK CORRECT PRODUCT, PHASE, PLAN SET
String currentProduct = subscription.getCurrentPlan().getProduct().getName();
@@ -276,22 +283,27 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
-
// MOVE TIME ABOUT ONE MONTH BEFORE NEXT EXPECTED PHASE CHANGE
- clock.addDeltaFromReality(getDurationMonth(11));
-
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(11));
+ clock.addDeltaFromReality(it.toDurationMillis());
currentTime = clock.getUTCNow();
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
+ testListener.reset();
DateTime nextExpectedPhaseChange = DefaultClock.addDuration(newChargedThroughDate, currentPhase.getDuration());
checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
// MOVE TIME RIGHT AFTER NEXT EXPECTED PHASE CHANGE
- clock.addDeltaFromReality(getDurationMonth(1));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
currentTime = clock.getUTCNow();
- assertTrue(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -299,15 +311,18 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
protected void testMultipleChangeLastIMM() throws EntitlementBillingApiException {
+ log.info("Starting testMultipleChangeLastIMM");
try {
SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
PlanPhase trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ assertTrue(testListener.isCompleted(5000));
// SET CTD
List<Duration> durationList = new ArrayList<Duration>();
@@ -320,14 +335,16 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
// CHANGE EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
+ testListener.reset();
// CHANGE
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertTrue(testListener.isCompleted(5000));
Plan currentPlan = subscription.getCurrentPlan();
assertNotNull(currentPlan);
@@ -338,7 +355,8 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
-
+
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -346,15 +364,17 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
protected void testMultipleChangeLastEOT() throws EntitlementBillingApiException {
+ log.info("Starting testMultipleChangeLastEOT");
try {
SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
PlanPhase trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD
List<Duration> durationList = new ArrayList<Duration>();
@@ -366,15 +386,17 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
// CHANGE EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Shotgun", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
testListener.reset();
// CHANGE EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
testListener.reset();
// CHECK NO CHANGE OCCURED YET
@@ -389,9 +411,11 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
// ACTIVATE CHNAGE BY MOVING AFTER CTD
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(3000));
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ assertTrue(testListener.isCompleted(5000));
currentPlan = subscription.getCurrentPlan();
assertNotNull(currentPlan);
@@ -406,9 +430,10 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(currentPhase.getDuration());
- assertTrue(testListener.isApiCompleted(3000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(6));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
currentPlan = subscription.getCurrentPlan();
@@ -421,7 +446,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -429,6 +454,9 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
protected void testCorrectPhaseAlignmentOnChange() {
+
+ log.info("Starting testCorrectPhaseAlignmentOnChange");
+
try {
SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -436,13 +464,15 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE 2 DAYS AHEAD
- clock.setDeltaFromReality(getDurationDay(1), DAY_IN_MS);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(2));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
// CHANGE IMMEDIATE TO A 3 PHASES PLAN
testListener.reset();
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertTrue(testListener.isApiCompleted(3000));
+ assertTrue(testListener.isCompleted(5000));
testListener.reset();
// CHECK EVERYTHING LOOKS CORRECT
@@ -456,9 +486,11 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
// MOVE AFTER TRIAL PERIOD -> DISCOUNT
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(trialPhase.getDuration());
- assertTrue(testListener.isApiCompleted(3000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ assertTrue(testListener.isCompleted(5000));
trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.DISCOUNT);
@@ -471,6 +503,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
assertEquals(nextPhaseEffectiveDate, expectedNextPhaseDate);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
index 8bbdd2d..0da1169 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
@@ -33,38 +33,38 @@ public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testChangePlanBundleAlignEOTWithNoChargeThroughDate() {
super.testChangePlanBundleAlignEOTWithNoChargeThroughDate();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testChangePlanBundleAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
super.testChangePlanBundleAlignEOTWithChargeThroughDate();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testChangePlanBundleAlignIMM() {
super.testChangePlanBundleAlignIMM();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testMultipleChangeLastIMM() throws EntitlementBillingApiException {
super.testMultipleChangeLastIMM();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testMultipleChangeLastEOT() throws EntitlementBillingApiException {
super.testMultipleChangeLastEOT();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCorrectPhaseAlignmentOnChange() {
super.testCorrectPhaseAlignmentOnChange();
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
index 509b056..1039b85 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
@@ -33,7 +33,7 @@ public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
}
- @Test(enabled= true, groups={"stress"})
+ @Test(enabled= false, groups={"stress"})
public void stressTest() throws Exception {
for (int i = 0; i < MAX_STRESS_ITERATIONS; i++) {
cleanupTest();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
index ef4533d..6517044 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
@@ -24,17 +24,18 @@ import static org.testng.Assert.assertTrue;
import java.util.List;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.events.phase.PhaseEvent;
@@ -56,8 +57,8 @@ public abstract class TestUserApiCreate extends TestApiBase {
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
@@ -69,8 +70,10 @@ public abstract class TestUserApiCreate extends TestApiBase {
assertEquals(subscription.getBundleId(), bundle.getId());
assertEquals(subscription.getStartDate(), requestedDate);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
+ assertListenerStatus();
+
} catch (EntitlementUserApiException e) {
log.error("Unexpected exception",e);
Assert.fail(e.getMessage());
@@ -89,7 +92,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
BillingPeriod term = BillingPeriod.MONTHLY;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), context);
@@ -111,6 +114,8 @@ public abstract class TestUserApiCreate extends TestApiBase {
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+ assertListenerStatus();
+
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -127,7 +132,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
BillingPeriod term = BillingPeriod.MONTHLY;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, null),
@@ -149,7 +154,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
assertNotNull(events);
@@ -160,15 +165,16 @@ public abstract class TestUserApiCreate extends TestApiBase {
DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
assertEquals(nextPhaseChange, nextExpectedPhaseChange);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
-
- clock.setDeltaFromReality(currentPhase.getDuration(), DAY_IN_MS);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
DateTime futureNow = clock.getUTCNow();
assertTrue(futureNow.isAfter(nextPhaseChange));
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -184,7 +190,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
BillingPeriod term = BillingPeriod.ANNUAL;
String planSetName = "gunclubDiscount";
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
// CREATE SUBSCRIPTION
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
@@ -194,27 +200,30 @@ public abstract class TestUserApiCreate extends TestApiBase {
PlanPhase currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
// MOVE TO DISCOUNT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(currentPhase.getDuration(), DAY_IN_MS);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
- assertTrue(testListener.isApiCompleted(2000));
+
// MOVE TO EVERGREEN PHASE + RE-READ SUBSCRIPTION
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(currentPhase.getDuration());
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusYears(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
currentPhase = subscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
@@ -229,17 +238,15 @@ public abstract class TestUserApiCreate extends TestApiBase {
BillingPeriod term = BillingPeriod.ANNUAL;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
assertNotNull(subscription);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
}
-
-
-
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
index 7987d87..e4969f1 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
@@ -32,31 +32,31 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCreateWithRequestedDate() {
super.testCreateWithRequestedDate();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testCreateWithInitialPhase() {
super.testSimpleSubscriptionThroughPhases();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
public void testSimpleCreateSubscription() {
super.testSimpleCreateSubscription();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
protected void testSimpleSubscriptionThroughPhases() {
super.testSimpleSubscriptionThroughPhases();
}
@Override
- @Test(enabled=true, groups={"fast-disabled"})
+ @Test(enabled=true, groups={"fast"})
protected void testSubscriptionWithAddOn() {
super.testSubscriptionWithAddOn();
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
index fdd6e66..0973666 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
@@ -26,19 +26,20 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
import com.ning.billing.entitlement.glue.MockEngineModuleSql;
@@ -69,6 +70,7 @@ public class TestUserApiDemos extends TestApiBase {
@Test(enabled=true, groups="demos")
public void testDemo1() throws EntitlementBillingApiException {
+ log.info("Starting testSubscriptionWithAddOn");
try {
System.out.println("DEMO 1 START");
@@ -80,16 +82,17 @@ public class TestUserApiDemos extends TestApiBase {
displayState(subscription.getId(), "STEP 1. CREATED SUBSCRIPTION");
/* STEP 2. CHANGE PLAN WHILE IN TRIAL */
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertTrue(testListener.isApiCompleted(3000));
+ assertTrue(testListener.isCompleted(5000));
displayState(subscription.getId(), "STEP 2. CHANGED PLAN WHILE IN TRIAL");
/* STEP 3. MOVE TO DISCOUNT PHASE */
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(3000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
displayState(subscription.getId(), "STEP 3. MOVE TO DISCOUNT PHASE");
@@ -103,25 +106,28 @@ public class TestUserApiDemos extends TestApiBase {
billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
testListener.reset();
displayState(subscription.getId(), "STEP 4. SET CTD AND CHANGE PLAN EOT (Shotgun)");
/* STEP 5. CHANGE AGAIN */
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(3000));
testListener.reset();
displayState(subscription.getId(), "STEP 5. CHANGE AGAIN EOT (Pistol)");
/* STEP 6. MOVE TO EOT AND CHECK CHANGE OCCURED */
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
Plan currentPlan = subscription.getCurrentPlan();
assertNotNull(currentPlan);
@@ -136,9 +142,10 @@ public class TestUserApiDemos extends TestApiBase {
displayState(subscription.getId(), "STEP 6. MOVE TO EOT");
/* STEP 7. MOVE TO NEXT PHASE */
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.addDeltaFromReality(currentPhase.getDuration());
- assertTrue(testListener.isApiCompleted(5000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(6));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
currentPlan = subscription.getCurrentPlan();
@@ -154,11 +161,12 @@ public class TestUserApiDemos extends TestApiBase {
displayState(subscription.getId(), "STEP 7. MOVE TO NEXT PHASE");
/* STEP 8. CANCEL IMM (NO CTD) */
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancel(clock.getUTCNow(), false, context);
displayState(subscription.getId(), "STEP 8. CANCELLATION");
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
index c3f6061..c56e0e0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
@@ -25,6 +25,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -32,11 +33,11 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
import com.ning.billing.ErrorCode;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PriceListSet;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
import com.ning.billing.util.clock.DefaultClock;
@@ -52,6 +53,9 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionBadCatalog() {
+
+ log.info("Starting testCreateSubscriptionBadCatalog");
+
// WRONG PRODUCTS
tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NULL_PRODUCT_NAME);
tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NO_SUCH_PRODUCT);
@@ -68,16 +72,19 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionNoBundle() {
+ log.info("Starting testCreateSubscriptionNoBundle");
tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BUNDLE);
}
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionNoBP() {
+ log.info("Starting testCreateSubscriptionNoBP");
tCreateSubscriptionInternal(bundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BP);
}
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionBPExists() {
+ log.info("Starting testCreateSubscriptionBPExists");
try {
createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BP_EXISTS);
@@ -89,6 +96,7 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testRecreateSubscriptionBPNotCancelled() {
+ log.info("Starting testRecreateSubscriptionBPNotCancelled");
try {
SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
try {
@@ -105,6 +113,7 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionAddOnNotAvailable() {
+ log.info("Starting testCreateSubscriptionAddOnNotAvailable");
try {
UUID accountId = UUID.randomUUID();
SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
@@ -118,6 +127,7 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testCreateSubscriptionAddOnIncluded() {
+ log.info("Starting testCreateSubscriptionAddOnIncluded");
try {
UUID accountId = UUID.randomUUID();
SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
@@ -150,10 +160,11 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testChangeSubscriptionNonActive() {
+ log.info("Starting testChangeSubscriptionNonActive");
try {
Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancel(clock.getUTCNow(), false, context);
try {
subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow(), context);
@@ -174,15 +185,17 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=true, groups={"fast"})
public void testChangeSubscriptionFutureCancelled() {
+ log.info("Starting testChangeSubscriptionFutureCancelled");
try {
Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
PlanPhase trialPhase = subscription.getCurrentPhase();
// MOVE TO NEXT PHASE
PlanPhase currentPhase = subscription.getCurrentPhase();
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(currentPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(3000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD TO CANCEL IN FUTURE
@@ -204,6 +217,8 @@ public class TestUserApiError extends TestApiBase {
assertFalse(true);
}
}
+
+ assertListenerStatus();
} catch (Exception e) {
e.printStackTrace();
Assert.assertFalse(true);
@@ -213,10 +228,12 @@ public class TestUserApiError extends TestApiBase {
@Test(enabled=false, groups={"fast"})
public void testCancelBadState() {
+ log.info("Starting testCancelBadState");
}
@Test(enabled=true, groups={"fast"})
public void testUncancelBadState() {
+ log.info("Starting testUncancelBadState");
try {
Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -230,7 +247,7 @@ public class TestUserApiError extends TestApiBase {
assertFalse(true);
}
}
-
+ assertListenerStatus();
} catch (Exception e) {
e.printStackTrace();
Assert.assertFalse(true);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
index b7506dd..389ac5f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
@@ -25,9 +25,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.PriceListSet;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
public abstract class TestUserApiRecreate extends TestApiBase {
@@ -36,9 +36,10 @@ public abstract class TestUserApiRecreate extends TestApiBase {
protected void testRecreateWithBPCanceledThroughSubscription() {
- log.info("Starting testRecreateWithBPCanceled");
+ log.info("Starting testRecreateWithBPCanceledThroughSubscription");
try {
testCreateAndRecreate(false);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
log.error("Unexpected exception",e);
Assert.fail(e.getMessage());
@@ -46,9 +47,10 @@ public abstract class TestUserApiRecreate extends TestApiBase {
}
protected void testCreateWithBPCanceledFromUserApi() {
- log.info("Starting testCreateWithBPCanceled");
+ log.info("Starting testCreateWithBPCanceledFromUserApi");
try {
testCreateAndRecreate(true);
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
log.error("Unexpected exception",e);
Assert.fail(e.getMessage());
@@ -65,8 +67,8 @@ public abstract class TestUserApiRecreate extends TestApiBase {
BillingPeriod term = BillingPeriod.MONTHLY;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
assertNotNull(subscription);
@@ -75,7 +77,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
assertEquals(subscription.getStartDate(), requestedDate);
assertEquals(productName, subscription.getCurrentPlan().getProduct().getName());
- assertTrue(testListener.isApiCompleted(5000));
+ assertTrue(testListener.isCompleted(5000));
// CREATE (AGAIN) WITH NEW PRODUCT
productName = "Pistol";
@@ -95,11 +97,11 @@ public abstract class TestUserApiRecreate extends TestApiBase {
}
// NOW CANCEL ADN THIS SHOULD WORK
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancel(null, false, context);
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.RE_CREATE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.RE_CREATE);
// Avoid ordering issue for events at exact same date; this is actually a real good test, we
// we test it at Beatrix level. At this level that would work for sql tests but not for in memory.
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
index 92ac1b0..7f874de 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
@@ -21,17 +21,18 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.joda.time.DateTime;
+import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.PlanPhase;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
import com.ning.billing.entitlement.glue.MockEngineModuleSql;
@@ -44,7 +45,7 @@ public class TestUserApiScenarios extends TestApiBase {
return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
}
- @Test(enabled=true)
+ @Test(groups={"slow"}, enabled=true)
public void testChangeIMMCancelUncancelChangeEOT() throws EntitlementBillingApiException {
log.info("Starting testChangeIMMCancelUncancelChangeEOT");
@@ -54,14 +55,15 @@ public class TestUserApiScenarios extends TestApiBase {
PlanPhase trialPhase = subscription.getCurrentPhase();
assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Pistol", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
- testListener.isApiCompleted(3000);
+ testListener.isCompleted(5000);
// MOVE TO NEXT PHASE
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
- assertTrue(testListener.isApiCompleted(2000));
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
// SET CTD
Duration ctd = getDurationMonth(1);
@@ -71,22 +73,28 @@ public class TestUserApiScenarios extends TestApiBase {
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
// CANCEL EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CANCEL);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancel(clock.getUTCNow(), false, context);
- assertFalse(testListener.isApiCompleted(2000));
+ assertFalse(testListener.isCompleted(5000));
testListener.reset();
// UNCANCEL
subscription.uncancel(context);
// CHANGE EOT
- testListener.pushNextApiExpectedEvent(NextEvent.CHANGE);
+ testListener.setNonExpectedMode();
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
- assertFalse(testListener.isApiCompleted(2000));
-
- clock.addDeltaFromReality(ctd);
- assertTrue(testListener.isApiCompleted(3000));
+ assertFalse(testListener.isCompleted(5000));
+ testListener.reset();
+
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+ assertTrue(testListener.isCompleted(5000));
+ assertListenerStatus();
} catch (EntitlementUserApiException e) {
Assert.fail(e.getMessage());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
index 90966d8..c208521 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
@@ -28,9 +28,9 @@ import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.api.TestApiListener.NextEvent;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.PriceListSet;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.glue.MockEngineModuleSql;
import com.ning.billing.util.callcontext.CallContext;
@@ -66,7 +66,7 @@ public class TestUserCustomFieldsSql extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testOverwriteCustomFields() {
- log.info("Starting testCreateWithRequestedDate");
+ log.info("Starting testOverwriteCustomFields");
try {
DateTime init = clock.getUTCNow();
@@ -76,8 +76,8 @@ public class TestUserCustomFieldsSql extends TestApiBase {
BillingPeriod term = BillingPeriod.MONTHLY;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
assertNotNull(subscription);
@@ -122,7 +122,7 @@ public class TestUserCustomFieldsSql extends TestApiBase {
@Test(enabled=true, groups={"slow"})
public void testBasicCustomFields() {
- log.info("Starting testCreateWithRequestedDate");
+ log.info("Starting testBasicCustomFields");
try {
DateTime init = clock.getUTCNow();
@@ -132,8 +132,8 @@ public class TestUserCustomFieldsSql extends TestApiBase {
BillingPeriod term = BillingPeriod.MONTHLY;
String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushNextApiExpectedEvent(NextEvent.PHASE);
- testListener.pushNextApiExpectedEvent(NextEvent.CREATE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
assertNotNull(subscription);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index 9b75099..5eb760c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -158,7 +158,6 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
@Override
public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents,
final CallContext context) {
-
synchronized(events) {
events.addAll(initialEvents);
for (final EntitlementEvent cur : initialEvents) {
@@ -285,7 +284,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
@Override
public void cancelSubscription(final UUID subscriptionId, final EntitlementEvent cancelEvent,
final CallContext context, final int seqId) {
- synchronized (cancelEvent) {
+ synchronized(events) {
cancelNextPhaseEvent(subscriptionId);
insertEvent(cancelEvent);
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
index 1241b7d..4521257 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
@@ -15,16 +15,21 @@
*/
package com.ning.billing.jaxrs.json;
+import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
+import java.util.UUID;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonView;
+import org.joda.time.DateTime;
import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.entitlement.api.timeline.BundleTimeline;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfoEvent;
public class AccountTimelineJson {
@@ -52,7 +57,7 @@ public class AccountTimelineJson {
this.payments = payments;
}
- public AccountTimelineJson(Account account, List<Invoice> invoices, List<PaymentInfoEvent> payments, List<BundleTimeline> bundles) {
+ public AccountTimelineJson(Account account, List<Invoice> invoices, List<PaymentAttempt> payments, List<BundleTimeline> bundles) {
this.account = new AccountJsonSimple(account.getId().toString(), account.getExternalKey());
this.bundles = new LinkedList<BundleJsonWithSubscriptions>();
for (BundleTimeline cur : bundles) {
@@ -63,10 +68,13 @@ public class AccountTimelineJson {
this.invoices.add(new InvoiceJson(cur.getTotalAmount(), cur.getId().toString(), cur.getInvoiceDate(), Integer.toString(cur.getInvoiceNumber()), cur.getBalance()));
}
this.payments = new LinkedList<PaymentJson>();
- for (PaymentInfoEvent cur : payments) {
- // STEPH how to link that payment with the invoice ??
- this.payments.add(new PaymentJson(cur.getAmount(), null , cur.getPaymentNumber(), null, cur.getEffectiveDate(), cur.getStatus()));
- }
+ for (PaymentAttempt cur : payments) {
+ String status = cur.getPaymentId() != null ? "Success" : "Failed";
+ BigDecimal paidAmount = cur.getPaymentId() != null ? cur.getAmount() : BigDecimal.ZERO;
+
+ this.payments.add(new PaymentJson(cur.getAmount(), paidAmount, cur.getInvoiceId().toString(), cur.getPaymentId(), cur.getCreatedDate(), cur.getUpdatedDate(),
+ cur.getRetryCount(), cur.getCurrency().toString(), status));
+ }
}
public AccountTimelineJson() {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CustomFieldJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CustomFieldJson.java
new file mode 100644
index 0000000..cb9e36b
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CustomFieldJson.java
@@ -0,0 +1,51 @@
+/*
+ * 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.jaxrs.json;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+
+import com.ning.billing.util.customfield.CustomField;
+
+public class CustomFieldJson {
+
+ private final String name;
+ private final String value;
+
+ public CustomFieldJson() {
+ this.name = null;
+ this.value = null;
+ }
+
+ @JsonCreator
+ public CustomFieldJson(String name, String value) {
+ super();
+ this.name = name;
+ this.value = value;
+ }
+
+ public CustomFieldJson(CustomField input) {
+ this.name = input.getName();
+ this.value = input.getValue();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
index 30264d7..1a33a04 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
@@ -23,6 +23,8 @@ import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonView;
import org.joda.time.DateTime;
+import com.ning.billing.invoice.api.Invoice;
+
public class InvoiceJson {
@JsonView(BundleTimelineViews.Base.class)
@@ -40,6 +42,15 @@ public class InvoiceJson {
@JsonView(BundleTimelineViews.Base.class)
private final BigDecimal balance;
+
+ public InvoiceJson() {
+ this.amount = null;
+ this.invoiceId = null;
+ this.invoiceDate = null;
+ this.invoiceNumber = null;
+ this.balance = null;
+ }
+
@JsonCreator
public InvoiceJson(@JsonProperty("amount") BigDecimal amount,
@JsonProperty("invoice_id") String invoiceId,
@@ -54,6 +65,14 @@ public class InvoiceJson {
this.balance = balance;
}
+ public InvoiceJson(Invoice input) {
+ this.amount = input.getTotalAmount();
+ this.invoiceId = input.getId().toString();
+ this.invoiceDate = input.getInvoiceDate();
+ this.invoiceNumber = String.valueOf(input.getInvoiceNumber());
+ this.balance = input.getBalance();
+ }
+
public BigDecimal getAmount() {
return amount;
}
@@ -73,4 +92,56 @@ public class InvoiceJson {
public BigDecimal getBalance() {
return balance;
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((amount == null) ? 0 : amount.hashCode());
+ result = prime * result + ((balance == null) ? 0 : balance.hashCode());
+ result = prime * result
+ + ((invoiceDate == null) ? 0 : invoiceDate.hashCode());
+ result = prime * result
+ + ((invoiceId == null) ? 0 : invoiceId.hashCode());
+ result = prime * result
+ + ((invoiceNumber == null) ? 0 : invoiceNumber.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ InvoiceJson other = (InvoiceJson) obj;
+ if (amount == null) {
+ if (other.amount != null)
+ return false;
+ } else if (!amount.equals(other.amount))
+ return false;
+ if (balance == null) {
+ if (other.balance != null)
+ return false;
+ } else if (!balance.equals(other.balance))
+ return false;
+ if (invoiceDate == null) {
+ if (other.invoiceDate != null)
+ return false;
+ } else if (!invoiceDate.equals(other.invoiceDate))
+ return false;
+ if (invoiceId == null) {
+ if (other.invoiceId != null)
+ return false;
+ } else if (!invoiceId.equals(other.invoiceId))
+ return false;
+ if (invoiceNumber == null) {
+ if (other.invoiceNumber != null)
+ return false;
+ } else if (!invoiceNumber.equals(other.invoiceNumber))
+ return false;
+ return true;
+ }
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java
index 3a9fd4d..50df2ef 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJson.java
@@ -27,37 +27,55 @@ import com.ning.billing.util.clock.DefaultClock;
public class PaymentJson {
- @JsonView(BundleTimelineViews.Base.class)
private final BigDecimal paidAmount;
-
- @JsonView(BundleTimelineViews.Base.class)
+
+ private final BigDecimal amount;
+
private final String invoiceId;
- @JsonView(BundleTimelineViews.Base.class)
private final String paymentId;
- @JsonView(BundleTimelineViews.Base.class)
private final DateTime requestedDate;
- @JsonView(BundleTimelineViews.Base.class)
private final DateTime effectiveDate;
- @JsonView(BundleTimelineViews.Base.class)
+ private final Integer retryCount;
+
+ private final String currency;
+
private final String status;
+
+ public PaymentJson() {
+ this.amount = null;
+ this.paidAmount = null;
+ this.invoiceId = null;
+ this.paymentId = null;
+ this.requestedDate = null;
+ this.effectiveDate = null;
+ this.currency = null;
+ this.retryCount = null;
+ this.status = null;
+ }
@JsonCreator
- public PaymentJson(@JsonProperty("paid_amount") BigDecimal paidAmount,
+ public PaymentJson(@JsonProperty("amount") BigDecimal amount,
+ @JsonProperty("paid_amount") BigDecimal paidAmount,
@JsonProperty("invoice_id") String invoiceId,
@JsonProperty("payment_id") String paymentId,
@JsonProperty("requested_dt") DateTime requestedDate,
@JsonProperty("effective_dt") DateTime effectiveDate,
+ @JsonProperty("retry_count") Integer retryCount,
+ @JsonProperty("currency") String currency,
@JsonProperty("status") String status) {
super();
+ this.amount = amount;
this.paidAmount = paidAmount;
this.invoiceId = invoiceId;
this.paymentId = paymentId;
this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
this.effectiveDate = DefaultClock.toUTCDateTime(effectiveDate);
+ this.currency = currency;
+ this.retryCount = retryCount;
this.status = status;
}
@@ -84,4 +102,16 @@ public class PaymentJson {
public String getStatus() {
return status;
}
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public Integer getRetryCount() {
+ return retryCount;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
index fea22e6..2f798df 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
@@ -51,6 +51,12 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
@JsonView(BundleTimelineViews.Timeline.class)
private final DateTime effectiveDate;
+ public SubscriptionReadEventJson() {
+ super();
+ this.eventId = null;
+ this.effectiveDate = null;
+ }
+
@JsonCreator
public SubscriptionReadEventJson(@JsonProperty("event_id") String eventId,
@JsonProperty("billing_period") String billingPeriod,
@@ -148,6 +154,15 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
@JsonView(BundleTimelineViews.Timeline.class)
private final String phase;
+ public SubscriptionBaseEventJson() {
+ this.billingPeriod = null;
+ this.requestedDate = null;
+ this.product = null;
+ this.priceList = null;
+ this.eventType = null;
+ this.phase = null;
+ }
+
@JsonCreator
public SubscriptionBaseEventJson(@JsonProperty("billing_period") String billingPeriod,
@JsonProperty("requested_dt") DateTime requestedDate,
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
new file mode 100644
index 0000000..25ef04c
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
@@ -0,0 +1,77 @@
+/*
+ * 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.jaxrs.json;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class TagDefinitionJson {
+
+ private final String name;
+ private final String description;
+
+ public TagDefinitionJson() {
+ this.name = null;
+ this.description = null;
+ }
+
+ @JsonCreator
+ public TagDefinitionJson(@JsonProperty("name") String name,
+ @JsonProperty("description") String description) {
+ super();
+ this.name = name;
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((description == null) ? 0 : description.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TagDefinitionJson other = (TagDefinitionJson) obj;
+ if (description == null) {
+ if (other.description != null)
+ return false;
+ } else if (!description.equals(other.description))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 29883f1..9061eac 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -18,7 +18,7 @@ package com.ning.billing.jaxrs.resources;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import java.net.URI;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -29,6 +29,7 @@ import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -37,12 +38,12 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Collections2;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -61,10 +62,19 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.jaxrs.json.AccountTimelineJson;
import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
+import com.ning.billing.jaxrs.json.CustomFieldJson;
import com.ning.billing.jaxrs.util.Context;
import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.jaxrs.util.TagHelper;
import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.api.TagDefinitionApiException;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.StringCustomField;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
@Singleton
@@ -79,8 +89,10 @@ public class AccountResource implements BaseJaxrsResource {
private final InvoiceUserApi invoiceApi;
private final PaymentApi paymentApi;
private final Context context;
+ private final TagUserApi tagUserApi;
private final JaxrsUriBuilder uriBuilder;
-
+ private final TagHelper tagHelper;
+
@Inject
public AccountResource(final JaxrsUriBuilder uriBuilder,
final AccountUserApi accountApi,
@@ -88,14 +100,18 @@ public class AccountResource implements BaseJaxrsResource {
final InvoiceUserApi invoiceApi,
final PaymentApi paymentApi,
final EntitlementTimelineApi timelineApi,
+ final TagUserApi tagUserApi,
+ final TagHelper tagHelper,
final Context context) {
this.uriBuilder = uriBuilder;
this.accountApi = accountApi;
+ this.tagUserApi = tagUserApi;
this.entitlementApi = entitlementApi;
this.invoiceApi = invoiceApi;
this.paymentApi = paymentApi;
this.timelineApi = timelineApi;
this.context = context;
+ this.tagHelper = tagHelper;
}
@GET
@@ -157,17 +173,22 @@ public class AccountResource implements BaseJaxrsResource {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
- public Response createAccount(AccountJson json) {
+ public Response createAccount(final AccountJson json,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
try {
-
AccountData data = json.toAccountData();
- final Account account = accountApi.createAccount(data, null, null, context.createContext());
- URI uri = UriBuilder.fromPath(account.getId().toString()).build();
- return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
+ final Account account = accountApi.createAccount(data, null, null, context.createContext(createdBy, reason, comment));
+ Response response = uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
+ return response;
} catch (AccountApiException e) {
- log.info(String.format("Failed to create account %s", json), e);
- return Response.status(Status.BAD_REQUEST).build();
+ final String error = String.format("Failed to create account %s", json);
+ log.info(error, e);
+ return Response.status(Status.BAD_REQUEST).entity(error).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
@@ -175,11 +196,15 @@ public class AccountResource implements BaseJaxrsResource {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@Path("/{accountId:" + UUID_PATTERN + "}")
- public Response updateAccount(AccountJson json, @PathParam("accountId") String accountId) {
+ public Response updateAccount(final AccountJson json,
+ @PathParam("accountId") final String accountId,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
try {
AccountData data = json.toAccountData();
UUID uuid = UUID.fromString(accountId);
- accountApi.updateAccount(uuid, data, context.createContext());
+ accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment));
return getAccount(accountId);
} catch (AccountApiException e) {
if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
@@ -188,6 +213,8 @@ public class AccountResource implements BaseJaxrsResource {
log.info(String.format("Failed to update account %s with %s", accountId, json), e);
return Response.status(Status.BAD_REQUEST).build();
}
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
@@ -216,7 +243,7 @@ public class AccountResource implements BaseJaxrsResource {
Account account = accountApi.getAccountById(UUID.fromString(accountId));
List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
- List<PaymentInfoEvent> payments = Collections.emptyList();
+ List<PaymentAttempt> payments = new LinkedList<PaymentAttempt>();
if (invoices.size() > 0) {
Collection<String> tmp = Collections2.transform(invoices, new Function<Invoice, String>() {
@@ -227,8 +254,9 @@ public class AccountResource implements BaseJaxrsResource {
});
List<String> invoicesId = new ArrayList<String>();
invoicesId.addAll(tmp);
-
- payments = paymentApi.getPaymentInfo(invoicesId);
+ for (String curId : invoicesId) {
+ payments.addAll(paymentApi.getPaymentAttemptsForInvoiceId(curId));
+ }
}
List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
@@ -245,4 +273,174 @@ public class AccountResource implements BaseJaxrsResource {
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}
+
+
+ /**************************** TAGS ******************************/
+
+ @GET
+ @Path(BaseJaxrsResource.TAGS + "/{accountId:" + UUID_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response getAccountTags(@PathParam("accountId") String accountId) {
+ try {
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+ List<Tag> tags = account.getTagList();
+ Collection<String> tagNameList = (tags.size() == 0) ?
+ Collections.<String>emptyList() :
+ Collections2.transform(tags, new Function<Tag, String>() {
+ @Override
+ public String apply(Tag input) {
+ return input.getTagDefinitionName();
+ }
+ });
+ return Response.status(Status.OK).entity(tagNameList).build();
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ }
+ }
+
+
+ @POST
+ @Path(BaseJaxrsResource.TAGS + "/{accountId:" + UUID_PATTERN + "}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response createAccountTag(@PathParam("accountId") final String accountId,
+ @QueryParam(QUERY_TAGS) final String tagList,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+
+ try {
+ Preconditions.checkNotNull(tagList, "Query % list cannot be null", QUERY_TAGS);
+
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+
+ List<TagDefinition> input = tagHelper.getTagDifinitionFromTagList(tagList);
+ account.addTagsFromDefinitions(input);
+ Response response = uriBuilder.buildResponse(AccountResource.class, "getAccountTags", account.getId());
+ return response;
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (TagDefinitionApiException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
+ @DELETE
+ @Path(BaseJaxrsResource.TAGS + "/{accountId:" + UUID_PATTERN + "}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response deleteAccountTag(@PathParam("accountId") final String accountId,
+ @QueryParam(QUERY_TAGS) final String tagList,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+
+ try {
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+
+ // Tag APIs needs tome rework...
+ String inputTagList = tagList;
+ if (inputTagList == null) {
+ List<Tag> existingTags = account.getTagList();
+ StringBuilder tmp = new StringBuilder();
+ for (Tag cur : existingTags) {
+ tmp.append(cur.getTagDefinitionName());
+ tmp.append(",");
+ }
+ inputTagList = tmp.toString();
+ }
+
+ List<TagDefinition> input = tagHelper.getTagDifinitionFromTagList(tagList);
+ for (TagDefinition cur : input) {
+ account.removeTag(cur);
+ }
+
+ return Response.status(Status.OK).build();
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (TagDefinitionApiException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
+ /************************ CUSTOM FIELDS ******************************/
+
+ @GET
+ @Path(BaseJaxrsResource.CUSTOM_FIELDS + "/{accountId:" + UUID_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response getAccountCustomFields(@PathParam("accountId") String accountId) {
+ try {
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+ List<CustomField> fields = account.getFieldList();
+ List<CustomFieldJson> result = new LinkedList<CustomFieldJson>();
+ for (CustomField cur : fields) {
+ result.add(new CustomFieldJson(cur));
+ }
+ return Response.status(Status.OK).entity(result).build();
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ }
+ }
+
+
+ @POST
+ @Path(BaseJaxrsResource.CUSTOM_FIELDS + "/{accountId:" + UUID_PATTERN + "}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response createCustomField(@PathParam("accountId") final String accountId,
+ List<CustomFieldJson> customFields,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+
+ try {
+
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+ LinkedList<CustomField> input = new LinkedList<CustomField>();
+ for (CustomFieldJson cur : customFields) {
+ input.add(new StringCustomField(cur.getName(), cur.getValue()));
+ }
+ account.saveFields(input, context.createContext(createdBy, reason, comment));
+ Response response = uriBuilder.buildResponse(AccountResource.class, "getAccountCustomFields", account.getId());
+ return response;
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
+ @DELETE
+ @Path(BaseJaxrsResource.CUSTOM_FIELDS + "/{accountId:" + UUID_PATTERN + "}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response deleteCustomFields(@PathParam("accountId") final String accountId,
+ @QueryParam(QUERY_CUSTOM_FIELDS) final String cutomFieldList,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+
+ try {
+ Account account = accountApi.getAccountById(UUID.fromString(accountId));
+ // STEPH missing API to delete custom fields
+ return Response.status(Status.OK).build();
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
index 79f4b04..2a9e2ee 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
@@ -17,14 +17,25 @@ package com.ning.billing.jaxrs.resources;
public interface BaseJaxrsResource {
- public static final String API_PREFIX = "";
- public static final String API_VERSION = "/1.0";
+ public static final String API_PREFIX = "";
+ public static final String API_VERSION = "/1.0";
+ public static final String API_POSTFIX = "/kb";
+
+ public static final String PREFIX = API_PREFIX + API_VERSION + API_POSTFIX;
public static final String TIMELINE = "timeline";
/*
+ * Metadata Additional headers
+ */
+ public static String HDR_CREATED_BY = "X-Killbill-CreatedBy";
+ public static String HDR_REASON = "X-Killbill-Reason";
+ public static String HDR_COMMENT = "X-Killbill-Comment";
+
+ /*
* Patterns
*/
+ public static String STRING_PATTERN = "\\w+";
public static String UUID_PATTERN = "\\w+-\\w+-\\w+-\\w+-\\w+";
/*
@@ -33,15 +44,30 @@ public interface BaseJaxrsResource {
public static final String QUERY_EXTERNAL_KEY = "external_key";
public static final String QUERY_REQUESTED_DT = "requested_date";
public static final String QUERY_CALL_COMPLETION = "call_completion";
- public static final String QUERY_CALL_TIMEOUT = "call_timeout_sec";
+ public static final String QUERY_CALL_TIMEOUT = "call_timeout_sec";
+ public static final String QUERY_DRY_RUN = "dry_run";
+ public static final String QUERY_TARGET_DATE = "target_date";
+ public static final String QUERY_ACCOUNT_ID = "account_id";
- public static final String ACCOUNTS = "accounts";
- public static final String ACCOUNTS_PATH = API_PREFIX + API_VERSION + "/" + ACCOUNTS;
+ public static final String QUERY_TAGS = "tag_list";
+ public static final String QUERY_CUSTOM_FIELDS = "custom_field_list";
+
+ public static final String ACCOUNTS = "accounts";
+ public static final String ACCOUNTS_PATH = PREFIX + "/" + ACCOUNTS;
public static final String BUNDLES = "bundles";
- public static final String BUNDLES_PATH = API_PREFIX + API_VERSION + "/" + BUNDLES;
+ public static final String BUNDLES_PATH = PREFIX + "/" + BUNDLES;
+
+ public static final String SUBSCRIPTIONS = "subscriptions";
+ public static final String SUBSCRIPTIONS_PATH = PREFIX + "/" + SUBSCRIPTIONS;
+
+ public static final String TAG_DEFINITIONS = "tag_definitions";
+ public static final String TAG_DEFINITIONS_PATH = PREFIX + "/" + TAG_DEFINITIONS;
- public static final String SUBSCRIPTIONS = "subscriptions";
- public static final String SUBSCRIPTIONS_PATH = API_PREFIX + API_VERSION + "/" + SUBSCRIPTIONS;
+ public static final String INVOICES = "invoices";
+ public static final String INVOICES_PATH = PREFIX + "/" + INVOICES;
+
+ public static final String TAGS = "tags";
+ public static final String CUSTOM_FIELDS = "custom_fields";
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
index d3bb1a2..e62d48e 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -24,6 +24,7 @@ import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@@ -102,14 +103,20 @@ public class BundleResource implements BaseJaxrsResource {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
- public Response createBundle(final BundleJsonNoSubsciptions json) {
+ public Response createBundle(final BundleJsonNoSubsciptions json,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
try {
UUID accountId = UUID.fromString(json.getAccountId());
- final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(), context.createContext());
+ final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(),
+ context.createContext(createdBy, reason, comment));
return uriBuilder.buildResponse(BundleResource.class, "getBundle", bundle.getId());
} catch (EntitlementUserApiException e) {
log.info(String.format("Failed to create bundle %s", json), e);
return Response.status(Status.BAD_REQUEST).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index e5a1c97..5cc35bd 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -18,8 +18,14 @@ package com.ning.billing.jaxrs.resources;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@@ -29,34 +35,117 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.entitlement.api.timeline.EntitlementTimelineApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.jaxrs.json.InvoiceJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.jaxrs.util.TagHelper;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.util.api.TagUserApi;
+
+@Path(BaseJaxrsResource.INVOICES_PATH)
+public class InvoiceResource implements BaseJaxrsResource {
-@Path("/1.0/invoice")
-public class InvoiceResource {
+ private static final Logger log = LoggerFactory.getLogger(AccountResource.class);
+ private final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private final AccountUserApi accountApi;
+ private final InvoiceUserApi invoiceApi;
+ private final Context context;
+ private final JaxrsUriBuilder uriBuilder;
+
+ @Inject
+ public InvoiceResource(final AccountUserApi accountApi,
+ final InvoiceUserApi invoiceApi,
+ final Context context,
+ final JaxrsUriBuilder uriBuilder) {
+ this.accountApi = accountApi;
+ this.invoiceApi = invoiceApi;
+ this.context = context;
+ this.uriBuilder = uriBuilder;
+ }
+
@GET
@Produces(APPLICATION_JSON)
- public Response getInvoices(@QueryParam("accountId") String accountId) {
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ public Response getInvoices(@QueryParam(QUERY_ACCOUNT_ID) final String accountId) {
+ try {
+
+ Preconditions.checkNotNull(accountId, "% query parameter must be specified", QUERY_ACCOUNT_ID);
+ accountApi.getAccountById(UUID.fromString(accountId));
+ List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
+ List<InvoiceJson> result = new LinkedList<InvoiceJson>();
+ for (Invoice cur : invoices) {
+ result.add(new InvoiceJson(cur));
+ }
+ return Response.status(Status.OK).entity(result).build();
+ } catch (AccountApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).build();
+ }
}
@GET
@Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}")
@Produces(APPLICATION_JSON)
- public Response getInvoice(@PathParam("invoiceId") String accountId) {
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ public Response getInvoice(@PathParam("invoiceId") String invoiceId) {
+ Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
+ InvoiceJson json = new InvoiceJson(invoice);
+ return Response.status(Status.OK).entity(json).build();
}
@POST
- @Path("/{accountId:\\w+-\\w+-\\w+-\\w+-\\w+}")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
- public Response createFutureInvoice(InvoiceJson invoice,
- @PathParam("accountId") String accountId,
- @QueryParam("targetDate") String targetDate) {
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ public Response createFutureInvoice(final InvoiceJson invoice,
+ @QueryParam(QUERY_ACCOUNT_ID) final String accountId,
+ @QueryParam(QUERY_TARGET_DATE) final String targetDate,
+ @QueryParam(QUERY_DRY_RUN) @DefaultValue("false") final Boolean dryRun,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+
+ try {
+
+ Preconditions.checkNotNull(accountId, "% needs to be specified", QUERY_ACCOUNT_ID);
+ Preconditions.checkNotNull(targetDate, "% needs to be specified", QUERY_TARGET_DATE);
+
+ DateTime inputDate = (targetDate != null) ? DATE_TIME_FORMATTER.parseDateTime(targetDate) : null;
+
+ accountApi.getAccountById(UUID.fromString(accountId));
+ Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun.booleanValue(),
+ context.createContext(createdBy, reason, comment));
+ if (dryRun) {
+ return Response.status(Status.OK).entity(new InvoiceJson(generatedInvoice)).build();
+ } else {
+ return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
+ }
+ } catch (AccountApiException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (InvoiceApiException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ } catch (NullPointerException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
index 259fe9f..aeb3f7a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -26,6 +26,7 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
@@ -103,47 +104,18 @@ public class SubscriptionResource implements BaseJaxrsResource {
}
}
-
- /*
- @GET
- @Path("/{subscriptionId:" + UUID_PATTERN + "}")
- @Produces(APPLICATION_JSON)
- public StreamingOutput getSubscription(@PathParam("subscriptionId") final String subscriptionId) {
-
- UUID uuid = UUID.fromString(subscriptionId);
- final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
- if (subscription == null) {
- throw new WebApplicationException(Response.Status.NO_CONTENT);
- }
- final SubscriptionJson json = new SubscriptionJson(subscription, null, null, null);
- return new StreamingOutput() {
-
- final SubscriptionJson json = new SubscriptionJson(subscription, null, null, null);
-
- @Override
- public void write(OutputStream output) throws IOException,
- WebApplicationException {
-
- final ObjectWriter objWriter = objectMapper.writerWithView(BundleTimelineViews.Base.class);
-
- Writer writer = new StringWriter();
- objWriter.writeValue(writer, json);
- String baseJson = writer.toString();
- output.write(baseJson.getBytes());
- output.flush();
- }
- };
- }
- */
-
+
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response createSubscription(final SubscriptionJsonNoEvents subscription,
- final @QueryParam(QUERY_REQUESTED_DT) String requestedDate,
- final @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") Boolean callCompletion,
- final @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") long timeoutSec) {
+ @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+ @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+ @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
SubscriptionCallCompletionCallback<Subscription> callback = new SubscriptionCallCompletionCallback<Subscription>() {
@@ -168,7 +140,7 @@ public class SubscriptionResource implements BaseJaxrsResource {
}
};
SubscriptionCallCompletion<Subscription> callCompletionCreation = new SubscriptionCallCompletion<Subscription>();
- return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion);
+ return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
}
@PUT
@@ -176,10 +148,13 @@ public class SubscriptionResource implements BaseJaxrsResource {
@Consumes(APPLICATION_JSON)
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
public Response changeSubscriptionPlan(final SubscriptionJsonNoEvents subscription,
- final @PathParam("subscriptionId") String subscriptionId,
- final @QueryParam(QUERY_REQUESTED_DT) String requestedDate,
- final @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") Boolean callCompletion,
- final @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") long timeoutSec) {
+ @PathParam("subscriptionId") final String subscriptionId,
+ @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+ @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+ @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
@@ -222,18 +197,21 @@ public class SubscriptionResource implements BaseJaxrsResource {
}
};
SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
- return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion);
+ return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
}
@PUT
@Path("/{subscriptionId:" + UUID_PATTERN + "}/uncancel")
@Produces(APPLICATION_JSON)
- public Response uncancelSubscriptionPlan(@PathParam("subscriptionId") String subscriptionId) {
+ public Response uncancelSubscriptionPlan(@PathParam("subscriptionId") final String subscriptionId,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
try {
UUID uuid = UUID.fromString(subscriptionId);
Subscription current = entitlementApi.getSubscriptionFromId(uuid);
- current.uncancel(context.createContext());
+ current.uncancel(context.createContext(createdBy, reason, comment));
return Response.status(Status.OK).build();
} catch (EntitlementUserApiException e) {
if(e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
@@ -249,9 +227,12 @@ public class SubscriptionResource implements BaseJaxrsResource {
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
public Response cancelSubscriptionPlan(final @PathParam("subscriptionId") String subscriptionId,
- final @QueryParam(QUERY_REQUESTED_DT) String requestedDate,
- final @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") Boolean callCompletion,
- final @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") long timeoutSec) {
+ @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
+ @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+ @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
@@ -287,7 +268,7 @@ public class SubscriptionResource implements BaseJaxrsResource {
}
};
SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
- return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion);
+ return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
}
private final static class CompletionUserRequestSubscription extends CompletionUserRequestBase {
@@ -332,9 +313,14 @@ public class SubscriptionResource implements BaseJaxrsResource {
private class SubscriptionCallCompletion<T> {
- public Response withSynchronization(final SubscriptionCallCompletionCallback<T> callback, final long timeoutSec, final boolean callCompletion) {
+ public Response withSynchronization(final SubscriptionCallCompletionCallback<T> callback,
+ final long timeoutSec,
+ final boolean callCompletion,
+ final String createdBy,
+ final String reason,
+ final String comment) {
- CallContext ctx = context.createContext();
+ CallContext ctx = context.createContext(createdBy, reason, comment);
CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(ctx.getUserToken()) : null;
try {
if (waiter != null) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
index cc19095..3111240 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -16,6 +16,104 @@
package com.ning.billing.jaxrs.resources;
-public class TagResource {
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.ning.billing.jaxrs.json.TagDefinitionJson;
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.TagDefinitionApiException;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.tag.TagDefinition;
+
+@Singleton
+@Path(BaseJaxrsResource.TAG_DEFINITIONS_PATH)
+public class TagResource implements BaseJaxrsResource {
+
+ private final TagUserApi tagUserApi;
+ private final Context context;
+ private final JaxrsUriBuilder uriBuilder;
+
+ @Inject
+ public TagResource(TagUserApi tagUserApi, final JaxrsUriBuilder uriBuilder, final Context context) {
+ this.tagUserApi = tagUserApi;
+ this.context = context;
+ this.uriBuilder = uriBuilder;
+ }
+
+ @GET
+ @Produces(APPLICATION_JSON)
+ public Response getTagDefinitions() {
+
+ List<TagDefinitionJson> result = new LinkedList<TagDefinitionJson>();
+ List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
+ for (TagDefinition cur : tagDefinitions) {
+ result.add(new TagDefinitionJson(cur.getName(), cur.getDescription()));
+ }
+ return Response.status(Status.OK).entity(result).build();
+ }
+
+ @GET
+ @Path("/{tagDefinitionName:" + STRING_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response getTagDefinition(@PathParam("tagDefinitionName") final String tagDefName) {
+ try {
+ TagDefinition tagDef = tagUserApi.getTagDefinition(tagDefName);
+ TagDefinitionJson json = new TagDefinitionJson(tagDef.getName(), tagDef.getDescription());
+ return Response.status(Status.OK).entity(json).build();
+ } catch (TagDefinitionApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ }
+ }
+
+
+
+ @POST
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response createTagDefinition(final TagDefinitionJson json,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+ try {
+ TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
+ return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getName());
+ } catch (TagDefinitionApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
+
+ @DELETE
+ @Path("/{tagDefinitionName:" + STRING_PATTERN + "}")
+ @Produces(APPLICATION_JSON)
+ public Response deleteTagDefinition(@PathParam("tagDefinitionName") String tagDefName,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment) {
+ try {
+ tagUserApi.deleteTagDefinition(tagDefName, context.createContext(createdBy, reason, comment));
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (TagDefinitionApiException e) {
+ return Response.status(Status.NO_CONTENT).build();
+ } catch (IllegalArgumentException e) {
+ return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+ }
+ }
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
index 004a468..729f166 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
@@ -17,7 +17,9 @@ package com.ning.billing.jaxrs.util;
import java.util.UUID;
+import com.google.common.base.Preconditions;
import com.google.inject.Inject;
+import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.callcontext.CallOrigin;
@@ -37,8 +39,13 @@ public class Context {
this.contextFactory = factory;
}
- // Simplistic until we decide how to populate that
- public CallContext createContext() {
- return contextFactory.createCallContext("Unknown", origin, userType, UUID.randomUUID());
+ public CallContext createContext(final String createdBy, final String reason, final String comment)
+ throws IllegalArgumentException {
+ try {
+ Preconditions.checkNotNull(createdBy, String.format("Header %s needs to be set", BaseJaxrsResource.HDR_CREATED_BY));
+ return contextFactory.createCallContext(createdBy, origin, userType, UUID.randomUUID());
+ } catch (NullPointerException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
index a38a9fe..b351b4c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -26,7 +26,7 @@ import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
public class JaxrsUriBuilder {
- public Response buildResponse(final Class<? extends BaseJaxrsResource> theClass, final String getMethodName, final UUID objectId) {
+ public Response buildResponse(final Class<? extends BaseJaxrsResource> theClass, final String getMethodName, final Object objectId) {
URI uri = UriBuilder.fromPath(objectId.toString()).build();
Response.ResponseBuilder ri = Response.created(uri);
return ri.entity(new Object() {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java
new file mode 100644
index 0000000..e965deb
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java
@@ -0,0 +1,49 @@
+/*
+ * 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.jaxrs.util;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.util.api.TagDefinitionApiException;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.tag.TagDefinition;
+
+public class TagHelper {
+
+ private final TagUserApi tagUserApi;
+
+ @Inject
+ public TagHelper(final TagUserApi tagUserApi) {
+ this.tagUserApi = tagUserApi;
+ }
+
+ public List<TagDefinition> getTagDifinitionFromTagList(final String tagList) throws TagDefinitionApiException {
+ List<TagDefinition> result = new LinkedList<TagDefinition>();
+ String [] tagParts = tagList.split(",\\s*");
+ for (String cur : tagParts) {
+ TagDefinition curDef = tagUserApi.getTagDefinition(cur);
+ // Yack should throw excption
+ if (curDef == null) {
+ throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, cur);
+ }
+ result.add(curDef);
+ }
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/resources/.dont-let-git-remove-this-directory b/jaxrs/src/main/resources/.dont-let-git-remove-this-directory
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jaxrs/src/main/resources/.dont-let-git-remove-this-directory
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
new file mode 100644
index 0000000..df4f4c3
--- /dev/null
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.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.config;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.testng.annotations.Test;
+
+import com.ning.billing.util.config.XMLLoader;
+
+public class TestOverdueConfig {
+ private String xml =
+ "<overdueConfig>" +
+ " <bundleOverdueStates>" +
+ " <state name=\"OD1\">" +
+ " <condition>" +
+ " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " <unit>MONTHS</unit><number>1</number>" +
+ " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " </condition>" +
+ " <externalMessage>Reached OD1</externalMessage>" +
+ " <blockChanges>true</blockChanges>" +
+ " <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+ " </state>" +
+ " <state name=\"OD2\">" +
+ " <condition>" +
+ " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " <unit>MONTHS</unit><number>2</number>" +
+ " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " </condition>" +
+ " <externalMessage>Reached OD1</externalMessage>" +
+ " <blockChanges>true</blockChanges>" +
+ " <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+ " </state>" +
+ " </bundleOverdueStates>" +
+ "</overdueConfig>";
+
+ @Test
+ public void testParseConfig() throws Exception {
+ InputStream is = new ByteArrayInputStream(xml.getBytes());
+ OverdueConfig c = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
+
+ }
+
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index 3ec9e22..227e94a 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -26,11 +26,11 @@ import com.ning.billing.util.bus.BusService;
import com.ning.jetty.base.modules.ServerModuleBuilder;
import com.ning.jetty.core.listeners.SetupServer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.google.inject.Injector;
import com.google.inject.Module;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.SerializationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,6 +72,9 @@ public class KillbillGuiceListener extends SetupServer
killbillBusService = theInjector.getInstance(BusService.class);
killbilleventHandler = theInjector.getInstance(KillbillEventHandler.class);
+ ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
+ mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
+
//
// Fire all Startup levels up to service start
//
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index cb126da..d6c3691 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -31,11 +31,12 @@ import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
import com.ning.billing.invoice.glue.DefaultInvoiceModule;
import com.ning.billing.jaxrs.resources.AccountResource;
import com.ning.billing.jaxrs.resources.BundleResource;
-import com.ning.billing.jaxrs.resources.BundleTimelineResource;
import com.ning.billing.jaxrs.resources.InvoiceResource;
import com.ning.billing.jaxrs.resources.PaymentResource;
import com.ning.billing.jaxrs.resources.SubscriptionResource;
+import com.ning.billing.jaxrs.resources.TagResource;
import com.ning.billing.jaxrs.util.KillbillEventHandler;
+import com.ning.billing.jaxrs.util.TagHelper;
import com.ning.billing.junction.glue.DefaultJunctionModule;
import com.ning.billing.payment.setup.PaymentModule;
import com.ning.billing.util.glue.BusModule;
@@ -61,12 +62,13 @@ public class KillbillServerModule extends AbstractModule
}
protected void configureResources() {
+ bind(TagHelper.class).asEagerSingleton();
bind(AccountResource.class).asEagerSingleton();
bind(BundleResource.class).asEagerSingleton();
bind(SubscriptionResource.class).asEagerSingleton();
- bind(BundleTimelineResource.class).asEagerSingleton();
bind(InvoiceResource.class).asEagerSingleton();
bind(PaymentResource.class).asEagerSingleton();
+ bind(TagResource.class).asEagerSingleton();
bind(KillbillEventHandler.class).asEagerSingleton();
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index 8d971ec..7c19d35 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -16,15 +16,20 @@
package com.ning.billing.jaxrs;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Response.Status;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.PropertyNamingStrategy;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.slf4j.Logger;
@@ -38,7 +43,9 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.jaxrs.json.AccountTimelineJson;
import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
+import com.ning.billing.jaxrs.json.CustomFieldJson;
import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.json.TagDefinitionJson;
import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
import com.ning.http.client.Response;
@@ -48,6 +55,8 @@ public class TestAccount extends TestJaxrsBase {
private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
+
+
@Test(groups="slow", enabled=true)
public void testAccountOk() throws Exception {
@@ -138,6 +147,60 @@ public class TestAccount extends TestJaxrsBase {
Assert.assertEquals(objFromJson.getBundles().size(), 1);
Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().size(), 1);
Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 2);
-
+ }
+
+ @Test(groups="slow", enabled=false)
+ public void testAccountWithTags() throws Exception {
+ //Create Tag definition
+ TagDefinitionJson input = new TagDefinitionJson("yoyo", "nothing more to say");
+ String baseJson = mapper.writeValueAsString(input);
+ Response response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ AccountJson accountJson = createAccount("couroucoucou", "shdwdsqgfhwe", "couroucoucou@yahoo.com");
+ assertNotNull(accountJson);
+
+ Map<String, String> queryParams = new HashMap<String, String>();
+ queryParams.put(BaseJaxrsResource.QUERY_TAGS, input.getName());
+ String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + BaseJaxrsResource.TAGS + "/" + accountJson.getAcountId() ;
+ response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ /*
+ * STEPH Some how Location returns the ID twice (confused) :
+ * Location: http://127.0.0.1:8080/1.0/kb/accounts/tags/ebb5f830-6f0a-4521-9553-521d173169be/ebb5f830-6f0a-4521-9553-521d173169be
+ *
+ String location = response.getHeader("Location");
+ Assert.assertNotNull(location);
+
+ // Retrieves by Id based on Location returned
+ response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ */
+
+ }
+
+ @Test(groups="slow", enabled=false)
+ public void testAccountWithCustomFields() throws Exception {
+
+ AccountJson accountJson = createAccount("carafe", "shdwhwgaz", "carafe@yahoo.com");
+ assertNotNull(accountJson);
+
+ List<CustomFieldJson> customFields = new LinkedList<CustomFieldJson>();
+ customFields.add(new CustomFieldJson("1", "value1"));
+ customFields.add(new CustomFieldJson("2", "value2"));
+ customFields.add(new CustomFieldJson("3", "value3"));
+ String baseJson = mapper.writeValueAsString(customFields);
+
+ String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + BaseJaxrsResource.CUSTOM_FIELDS + "/" + accountJson.getAcountId() ;
+ Response response = doPost(uri,baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+ String location = response.getHeader("Location");
+ Assert.assertNotNull(location);
+
+ // Retrieves by Id based on Location returned
+ response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
}
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
index 0d1f1cd..f0182bd 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
@@ -23,12 +23,12 @@ import java.util.Map;
import javax.ws.rs.core.Response.Status;
-import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.ning.billing.jaxrs.json.AccountJson;
import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
new file mode 100644
index 0000000..9a039fd
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -0,0 +1,126 @@
+/*
+ * 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.jaxrs;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.joda.time.DateTime;
+import org.joda.time.Interval;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
+import com.ning.billing.jaxrs.json.InvoiceJson;
+import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
+import com.ning.http.client.Response;
+
+public class TestInvoice extends TestJaxrsBase {
+
+ private final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
+
+ private static final Logger log = LoggerFactory.getLogger(TestInvoice.class);
+
+
+ @Test(groups="slow", enabled=true)
+ public void testInvoiceOk() throws Exception {
+
+ DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+ clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
+
+
+ AccountJson accountJson = createAccount("poupou", "qhddffrwe", "poupou@yahoo.com");
+ assertNotNull(accountJson);
+
+ BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAcountId(), "9967599");
+ assertNotNull(bundleJson);
+
+ SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+ assertNotNull(subscriptionJson);
+
+ // MOVE AFTER TRIAL
+ Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
+ clock.addDeltaFromReality(it.toDurationMillis());
+
+ crappyWaitForLackOfProperSynchonization();
+
+ String uri = BaseJaxrsResource.INVOICES_PATH;
+ Map<String, String> queryParams = new HashMap<String, String>();
+ queryParams.put(BaseJaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAcountId());
+
+ Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ String baseJson = response.getResponseBody();
+ List<InvoiceJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJson>>() {});
+ assertNotNull(objFromJson);
+ log.info(baseJson);
+ assertEquals(objFromJson.size(), 4);
+
+ // Check we can retrieve an individual invoice
+ uri = BaseJaxrsResource.INVOICES_PATH + "/" + objFromJson.get(0).getInvoiceId();
+ response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+ InvoiceJson firstInvoiceJson = mapper.readValue(baseJson, InvoiceJson.class);
+ assertNotNull(objFromJson);
+ assertEquals(firstInvoiceJson, objFromJson.get(0));
+
+ // Then create a dryRun Invoice
+ DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
+ uri = BaseJaxrsResource.INVOICES_PATH;
+ queryParams.put(BaseJaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
+ queryParams.put(BaseJaxrsResource.QUERY_DRY_RUN, "true");
+ response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+ InvoiceJson futureInvoice = mapper.readValue(baseJson, InvoiceJson.class);
+ assertNotNull(futureInvoice);
+ log.info(baseJson);
+
+ // The one more time with no DryRun
+ queryParams.remove(BaseJaxrsResource.QUERY_DRY_RUN);
+ response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ String location = response.getHeader("Location");
+ Assert.assertNotNull(location);
+
+ // Check again # invoices, should be 5 this time
+ uri = BaseJaxrsResource.INVOICES_PATH;
+ response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+ objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJson>>() {});
+ assertNotNull(objFromJson);
+ log.info(baseJson);
+ assertEquals(objFromJson.size(), 5);
+ }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index 477005e..ce664b3 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -34,7 +34,6 @@ import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.glue.GlobalLockerModule;
import org.apache.commons.io.IOUtils;
-import org.codehaus.jackson.map.ObjectMapper;
import org.eclipse.jetty.servlet.FilterHolder;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
@@ -46,11 +45,15 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.google.inject.Module;
import com.ning.billing.account.glue.AccountModule;
import com.ning.billing.analytics.setup.AnalyticsModule;
+import com.ning.billing.api.TestApiListener;
import com.ning.billing.beatrix.glue.BeatrixModule;
-import com.ning.billing.beatrix.integration.TestBusHandler;
import com.ning.billing.beatrix.integration.TestIntegration;
import com.ning.billing.catalog.api.PriceListSet;
import com.ning.billing.catalog.glue.CatalogModule;
@@ -88,7 +91,7 @@ public class TestJaxrsBase {
private final static String PLUGIN_NAME = "noop";
- protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 5;
+ protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 5;
protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
@@ -107,8 +110,13 @@ public class TestJaxrsBase {
protected AsyncHttpClient httpClient;
protected ObjectMapper mapper;
protected ClockMock clock;
- protected TestBusHandler busHandler;
+ protected TestApiListener busHandler;
+ // Context informtation to be passed around
+ private static final String createdBy = "Toto";
+ private static final String reason = "i am god";
+ private static final String comment = "no comment";
+
public static void loadSystemPropertiesFromClasspath(final String resource) {
final URL url = TestJaxrsBase.class.getResource(resource);
assertNotNull(url);
@@ -224,7 +232,12 @@ public class TestJaxrsBase {
loadConfig();
httpClient = new AsyncHttpClient();
mapper = new ObjectMapper();
- busHandler = new TestBusHandler(null);
+ mapper.registerModule(new JodaModule());
+ mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+ mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
+
+ busHandler = new TestApiListener(null);
this.helper = listener.getMysqlTestingHelper();
this.clock = (ClockMock) listener.getClock();
}
@@ -374,8 +387,10 @@ public class TestJaxrsBase {
BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
if (body != null) {
builder.setBody(body);
+ } else {
+ builder.setBody("{}");
}
- return executeAndWait(builder, timeoutSec);
+ return executeAndWait(builder, timeoutSec, true);
}
protected Response doPut(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
@@ -383,14 +398,16 @@ public class TestJaxrsBase {
BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
if (body != null) {
builder.setBody(body);
+ } else {
+ builder.setBody("{}");
}
- return executeAndWait(builder, timeoutSec);
+ return executeAndWait(builder, timeoutSec, true);
}
protected Response doDelete(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
- return executeAndWait(builder, timeoutSec);
+ return executeAndWait(builder, timeoutSec, true);
}
protected Response doGet(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
@@ -400,10 +417,17 @@ public class TestJaxrsBase {
protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
- return executeAndWait(builder, timeoutSec);
+ return executeAndWait(builder, timeoutSec, false);
}
- private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec) {
+ private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
+
+ if (addContextHeader) {
+ builder.addHeader(BaseJaxrsResource.HDR_CREATED_BY, createdBy);
+ builder.addHeader(BaseJaxrsResource.HDR_REASON, reason);
+ builder.addHeader(BaseJaxrsResource.HDR_COMMENT, comment);
+ }
+
Response response = null;
try {
ListenableFuture<Response> futureStatus =
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
new file mode 100644
index 0000000..c1f460a
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -0,0 +1,114 @@
+/*
+ * 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.jaxrs;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.List;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.jaxrs.json.TagDefinitionJson;
+import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
+import com.ning.http.client.Response;
+
+public class TestTag extends TestJaxrsBase {
+
+ private static final Logger log = LoggerFactory.getLogger(TestTag.class);
+
+ @Test(groups="slow", enabled=true)
+ public void testTagDefinitionOk() throws Exception {
+
+ TagDefinitionJson input = new TagDefinitionJson("blue", "realxing color");
+ String baseJson = mapper.writeValueAsString(input);
+ Response response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ String location = response.getHeader("Location");
+ assertNotNull(location);
+
+ // Retrieves by Id based on Location returned
+ response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+ baseJson = response.getResponseBody();
+ TagDefinitionJson objFromJson = mapper.readValue(baseJson, TagDefinitionJson.class);
+ assertNotNull(objFromJson);
+ assertEquals(objFromJson, input);
+ }
+
+ @Test(groups="slow", enabled=true)
+ public void testMultipleTagDefinitionOk() throws Exception {
+
+ Response response = doGet(BaseJaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ String baseJson = response.getResponseBody();
+
+ List<TagDefinitionJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
+ int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
+
+ TagDefinitionJson input = new TagDefinitionJson("blue", "realxing color");
+ baseJson = mapper.writeValueAsString(input);
+ response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ input = new TagDefinitionJson("red", "hot color");
+ baseJson = mapper.writeValueAsString(input);
+ response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ input = new TagDefinitionJson("yellow", "vibrant color");
+ baseJson = mapper.writeValueAsString(input);
+ response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ input = new TagDefinitionJson("green", "super realxing color");
+ baseJson = mapper.writeValueAsString(input);
+ response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+ response = doGet(BaseJaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+
+ objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
+ assertNotNull(objFromJson);
+ assertEquals(objFromJson.size(), 4 + sizeSystemTag);
+
+ // STEPH currently broken Tag API does not work as expected...
+
+ /*
+ String uri = BaseJaxrsResource.TAG_DEFINITIONS_PATH + "/green";
+ response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+
+ response = doGet(BaseJaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+
+ objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
+ assertNotNull(objFromJson);
+ assertEquals(objFromJson.size(), 3 + sizeSystemTag);
+ */
+ }
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
index 2b1b834..bfce245 100644
--- a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
+++ b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
@@ -19,11 +19,8 @@ package com.ning.billing.util.bus;
import java.util.Collections;
import java.util.Date;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
@@ -40,11 +37,12 @@ import com.ning.billing.util.Hostname;
import com.ning.billing.util.bus.dao.BusEventEntry;
import com.ning.billing.util.bus.dao.PersistentBusSqlDao;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.queue.PersistentQueueBase;
-public class PersistentBus implements Bus {
+public class PersistentBus extends PersistentQueueBase implements Bus {
- private final static int NB_BUS_THREADS = 3;
+ private final static int NB_BUS_THREADS = 1;
private final static long TIMEOUT_MSEC = 15L * 1000L; // 15 sec
private final static long DELTA_IN_PROCESSING_TIME_MS = 1000L * 60L * 5L; // 5 minutes
private final static long SLEEP_TIME_MS = 1000; // 1 sec
@@ -53,16 +51,13 @@ public class PersistentBus implements Bus {
private static final Logger log = LoggerFactory.getLogger(PersistentBus.class);
private final PersistentBusSqlDao dao;
- private final ExecutorService executor;
private final ObjectMapper objectMapper;
private final EventBusDelegate eventBusDelegate;
private final Clock clock;
private final String hostname;
- protected boolean isProcessingEvents;
- private int curActiveThreads;
-
+
private static final class EventBusDelegate extends EventBus {
public EventBusDelegate(String busName) {
@@ -86,115 +81,34 @@ public class PersistentBus implements Bus {
@Inject
public PersistentBus(final IDBI dbi, final Clock clock) {
+ super("Bus", Executors.newFixedThreadPool(NB_BUS_THREADS, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(new ThreadGroup(DefaultBusService.EVENT_BUS_GROUP_NAME),
+ r,
+ DefaultBusService.EVENT_BUS_TH_NAME);
+ }
+ }), NB_BUS_THREADS, TIMEOUT_MSEC, SLEEP_TIME_MS);
this.dao = dbi.onDemand(PersistentBusSqlDao.class);
this.clock = clock;
this.objectMapper = new ObjectMapper();
this.objectMapper.disable(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS);
this.eventBusDelegate = new EventBusDelegate("Killbill EventBus");
- final ThreadGroup group = new ThreadGroup(DefaultBusService.EVENT_BUS_GROUP_NAME);
- this.executor = Executors.newFixedThreadPool(NB_BUS_THREADS, new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- return new Thread(group, r, DefaultBusService.EVENT_BUS_TH_NAME);
- }
- });
this.hostname = Hostname.get();
- this.isProcessingEvents = false;
}
-
@Override
public void start() {
-
- isProcessingEvents = true;
- curActiveThreads = 0;
-
- final PersistentBus thePersistentBus = this;
- final CountDownLatch doneInitialization = new CountDownLatch(NB_BUS_THREADS);
-
- log.info("Starting Persistent BUS with {} threads, countDownLatch = {}", NB_BUS_THREADS, doneInitialization.getCount());
-
- for (int i = 0; i < NB_BUS_THREADS; i++) {
- executor.execute(new Runnable() {
- @Override
- public void run() {
-
- log.info(String.format("PersistentBus thread %s [%d] started",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()));
-
- synchronized(thePersistentBus) {
- curActiveThreads++;
- }
-
- doneInitialization.countDown();
-
- try {
- while (true) {
-
- synchronized(thePersistentBus) {
- if (!isProcessingEvents) {
- thePersistentBus.notify();
- break;
- }
- }
-
- try {
- doProcessEvents();
- } catch (Exception e) {
- log.error(String.format("PersistentBus thread %s [%d] got an exception..",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()), e);
- }
- sleepALittle();
- }
- } catch (InterruptedException e) {
- log.info(Thread.currentThread().getName() + " got interrupted, exting...");
- } catch (Throwable e) {
- log.error(Thread.currentThread().getName() + " got an exception exiting...", e);
- // Just to make it really obvious in the log
- e.printStackTrace();
- } finally {
-
- log.info(String.format("PersistentBus thread %s [%d] exited",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()));
-
- synchronized(thePersistentBus) {
- curActiveThreads--;
- }
- }
- }
-
- private void sleepALittle() throws InterruptedException {
- Thread.sleep(SLEEP_TIME_MS);
- }
- });
- }
- try {
- boolean success = doneInitialization.await(TIMEOUT_MSEC, TimeUnit.MILLISECONDS);
- if (!success) {
- log.warn("Failed to wait for all threads to be started, got {}/{}", doneInitialization.getCount(), NB_BUS_THREADS);
- } else {
- log.info("Done waiting for all threads to be started, got {}/{}", doneInitialization.getCount(), NB_BUS_THREADS);
- }
- } catch (InterruptedException e) {
- log.warn("PersistentBus start sequence got interrupted...");
- }
+ startQueue();
}
-
-
- private BusEvent deserializeBusEvent(final String className, final String json) {
- try {
- Class<?> claz = Class.forName(className);
- return (BusEvent) objectMapper.readValue(json, claz);
- } catch (Exception e) {
- log.error(String.format("Failed to deserialize json object %s for class %s", json, className), e);
- return null;
- }
+
+ @Override
+ public void stop() {
+ stopQueue();
}
-
- private int doProcessEvents() {
+
+ @Override
+ public int doProcessEvents() {
List<BusEventEntry> events = getNextBusEvent();
if (events.size() == 0) {
@@ -212,6 +126,16 @@ public class PersistentBus implements Bus {
return result;
}
+ private BusEvent deserializeBusEvent(final String className, final String json) {
+ try {
+ Class<?> claz = Class.forName(className);
+ return (BusEvent) objectMapper.readValue(json, claz);
+ } catch (Exception e) {
+ log.error(String.format("Failed to deserialize json object %s for class %s", json, className), e);
+ return null;
+ }
+ }
+
private List<BusEventEntry> getNextBusEvent() {
@@ -231,34 +155,6 @@ public class PersistentBus implements Bus {
return Collections.emptyList();
}
-
- @Override
- public void stop() {
- int remaining = 0;
- try {
- synchronized(this) {
- isProcessingEvents = false;
- long ini = System.currentTimeMillis();
- long remainingWaitTimeMs = TIMEOUT_MSEC;
- while (curActiveThreads > 0 && remainingWaitTimeMs > 0) {
- wait(1000);
- remainingWaitTimeMs = TIMEOUT_MSEC - (System.currentTimeMillis() - ini);
- }
- remaining = curActiveThreads;
- }
-
- } catch (InterruptedException ignore) {
- log.info("PersistentBus has been interrupted during stop sequence");
- } finally {
- if (remaining > 0) {
- log.error(String.format("PersistentBus stopped with %d active remaing threads", remaining));
- } else {
- log.info("PersistentBus completed sucesfully shutdown sequence");
- }
- curActiveThreads = 0;
- }
- }
-
@Override
public void register(Object handlerInstance) throws EventBusException {
eventBusDelegate.register(handlerInstance);
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
index 29cd69c..f943d0b 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
@@ -64,7 +64,7 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
public void insertNotification(@Bind(binder = NotificationSqlDaoBinder.class) Notification evt);
@SqlUpdate
- public void insertClaimedHistory(@Bind("sequence_id") int sequenceId, @Bind("owner") String owner, @Bind("claimed_dt") Date clainedDate, @Bind("notification_id") String notificationId);
+ public void insertClaimedHistory(@Bind("owner") String owner, @Bind("claimed_dt") Date clainedDate, @Bind("notification_id") String notificationId);
public static class NotificationSqlDaoBinder extends BinderBase implements Binder<Bind, Notification> {
@Override
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
index c6958c2..3db7ce1 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
@@ -41,10 +41,10 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
}
@Override
- protected int doProcessEvents(final int sequenceId) {
+ public int doProcessEvents() {
logDebug("ENTER doProcessEvents");
- List<Notification> notifications = getReadyNotifications(sequenceId);
+ List<Notification> notifications = getReadyNotifications();
if (notifications.size() == 0) {
logDebug("EXIT doProcessEvents");
return 0;
@@ -85,7 +85,7 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
dao.clearNotification(cleared.getId(), hostname);
}
- private List<Notification> getReadyNotifications(final int seqId) {
+ private List<Notification> getReadyNotifications() {
final Date now = clock.getUTCNow().toDate();
final Date nextAvailable = clock.getUTCNow().plus(config.getDaoClaimTimeMs()).toDate();
@@ -101,7 +101,7 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
cur.getUUID(), cur.getNotificationKey(), cur.getEffectiveDate(), Boolean.valueOf(claimed));
if (claimed) {
claimedNotifications.add(cur);
- dao.insertClaimedHistory(seqId, hostname, now, cur.getUUID().toString());
+ dao.insertClaimedHistory(hostname, now, cur.getUUID().toString());
}
}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
index 14b68e0..d5c2425 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
@@ -22,8 +22,9 @@ import org.joda.time.DateTime;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
+import com.ning.billing.util.queue.QueueLifecycle;
-public interface NotificationQueue {
+public interface NotificationQueue extends QueueLifecycle {
/**
*
@@ -61,25 +62,9 @@ public interface NotificationQueue {
public int processReadyNotification();
/**
- * Stops the queue. Blocks until queue is completely stopped.
- *
- * @see NotificationQueueHandler.completedQueueStop to be notified when the notification thread exited
- */
- public void stopQueue();
-
- /**
- * Starts the queue. Blocks until queue has completely started.
- *
- * @see NotificationQueueHandler.completedQueueStart to be notified when the notification thread started
- */
- public void startQueue();
-
- /**
*
* @return the name of that queue
*/
public String getFullQName();
-
-
}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
index eb3f269..7c82db6 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
@@ -17,10 +17,8 @@
package com.ning.billing.util.notificationq;
import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
@@ -30,48 +28,30 @@ import com.ning.billing.config.NotificationConfig;
import com.ning.billing.util.Hostname;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
+import com.ning.billing.util.queue.PersistentQueueBase;
-public abstract class NotificationQueueBase implements NotificationQueue {
+public abstract class NotificationQueueBase extends PersistentQueueBase implements NotificationQueue {
protected final static Logger log = LoggerFactory.getLogger(NotificationQueueBase.class);
- private static final long MAX_NOTIFICATION_THREAD_WAIT_MS = 10000; // 10 secs
- private static final long NOTIFICATION_THREAD_WAIT_INCREMENT_MS = 1000; // 1 sec
- private static final long NANO_TO_MS = (1000 * 1000);
-
protected static final String NOTIFICATION_THREAD_PREFIX = "Notification-";
- protected final long STOP_WAIT_TIMEOUT_MS = 60000;
+ protected static final long STOP_WAIT_TIMEOUT_MS = 60000;
protected final String svcName;
protected final String queueName;
protected final NotificationQueueHandler handler;
protected final NotificationConfig config;
- protected final Executor executor;
protected final Clock clock;
protected final String hostname;
- protected static final AtomicInteger sequenceId = new AtomicInteger();
-
protected AtomicLong nbProcessedEvents;
- // Use this object's monitor for synchronization (no need for volatile)
- protected boolean isProcessingEvents;
-
- private boolean startedComplete = false;
- private boolean stoppedComplete = false;
-
// Package visibility on purpose
NotificationQueueBase(final Clock clock, final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
- this.clock = clock;
- this.svcName = svcName;
- this.queueName = queueName;
- this.handler = handler;
- this.config = config;
- this.hostname = Hostname.get();
+ super(svcName, Executors.newFixedThreadPool(1, new ThreadFactory() {
- this.executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread th = new Thread(r);
@@ -84,103 +64,21 @@ public abstract class NotificationQueueBase implements NotificationQueue {
});
return th;
}
- });
- }
-
+ }), 1, STOP_WAIT_TIMEOUT_MS, config.getNotificationSleepTimeMs());
- @Override
- public int processReadyNotification() {
- return doProcessEvents(sequenceId.incrementAndGet());
+ this.clock = clock;
+ this.svcName = svcName;
+ this.queueName = queueName;
+ this.handler = handler;
+ this.config = config;
+ this.hostname = Hostname.get();
+ this.nbProcessedEvents = new AtomicLong();
}
@Override
- public void stopQueue() {
- if (config.isNotificationProcessingOff()) {
- completedQueueStop();
- return;
- }
-
- synchronized(this) {
- isProcessingEvents = false;
- try {
- log.info("NotificationQueue requested to stop");
- wait(STOP_WAIT_TIMEOUT_MS);
- log.info("NotificationQueue requested should have exited");
- } catch (InterruptedException e) {
- log.warn("NotificationQueue got interrupted exception when stopping notifications", e);
- }
- }
- waitForNotificationStopCompletion();
- }
-
- @Override
- public void startQueue() {
-
- this.isProcessingEvents = true;
- this.nbProcessedEvents = new AtomicLong();
-
-
- if (config.isNotificationProcessingOff()) {
- log.warn(String.format("KILLBILL NOTIFICATION PROCESSING FOR SVC %s IS OFF !!!", getFullQName()));
- completedQueueStart();
- return;
- }
- final NotificationQueueBase notificationQueue = this;
-
- executor.execute(new Runnable() {
- @Override
- public void run() {
-
- log.info(String.format("NotificationQueue thread %s [%d] started",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()));
-
- // Thread is now started, notify the listener
- completedQueueStart();
-
- try {
- while (true) {
-
- synchronized (notificationQueue) {
- if (!isProcessingEvents) {
- log.info(String.format("NotificationQueue has been requested to stop, thread %s [%d] stopping...",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()));
- notificationQueue.notify();
- break;
- }
- }
-
- // Callback may trigger exceptions in user code so catch anything here and live with it.
- try {
- doProcessEvents(sequenceId.getAndIncrement());
- } catch (Exception e) {
- log.error(String.format("NotificationQueue thread %s [%d] got an exception..",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()), e);
- }
- sleepALittle();
- }
- } catch (InterruptedException e) {
- log.warn(Thread.currentThread().getName() + " got interrupted ", e);
- } catch (Throwable e) {
- log.error(Thread.currentThread().getName() + " got an exception exiting...", e);
- // Just to make it really obvious in the log
- e.printStackTrace();
- } finally {
- completedQueueStop();
- log.info(String.format("NotificationQueue thread %s [%d] exited...",
- Thread.currentThread().getName(),
- Thread.currentThread().getId()));
- }
- }
-
- private void sleepALittle() throws InterruptedException {
- Thread.sleep(config.getNotificationSleepTimeMs());
- }
- });
- waitForNotificationStartCompletion();
+ public int processReadyNotification() {
+ return doProcessEvents();
}
@Override
@@ -188,61 +86,12 @@ public abstract class NotificationQueueBase implements NotificationQueue {
return getFullQName();
}
- private void completedQueueStop() {
- synchronized (this) {
- stoppedComplete = true;
- this.notifyAll();
- }
- }
-
- private void completedQueueStart() {
- synchronized (this) {
- startedComplete = true;
- this.notifyAll();
- }
- }
-
- private void waitForNotificationStartCompletion() {
- waitForNotificationEventCompletion(true);
- }
-
- private void waitForNotificationStopCompletion() {
- waitForNotificationEventCompletion(false);
- }
-
- private void waitForNotificationEventCompletion(boolean startEvent) {
-
- long ini = System.nanoTime();
- synchronized(this) {
- do {
- if ((startEvent ? startedComplete : stoppedComplete)) {
- break;
- }
- try {
- this.wait(NOTIFICATION_THREAD_WAIT_INCREMENT_MS);
- } catch (InterruptedException e ) {
- Thread.currentThread().interrupt();
- throw new NotificationError(e);
- }
- } while (!(startEvent ? startedComplete : stoppedComplete) &&
- (System.nanoTime() - ini) / NANO_TO_MS < MAX_NOTIFICATION_THREAD_WAIT_MS);
-
- if (!(startEvent ? startedComplete : stoppedComplete)) {
- log.error("Could not {} notification thread in {} msec !!!",
- (startEvent ? "start" : "stop"),
- MAX_NOTIFICATION_THREAD_WAIT_MS);
- throw new NotificationError("Failed to start service!!");
- }
- log.info("Notification thread has been {} in {} ms",
- (startEvent ? "started" : "stopped"),
- (System.nanoTime() - ini) / NANO_TO_MS);
- }
- }
@Override
public String getFullQName() {
return svcName + ":" + queueName;
}
- protected abstract int doProcessEvents(int sequenceId);
+ @Override
+ public abstract int doProcessEvents();
}
diff --git a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
new file mode 100644
index 0000000..a6844ad
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
@@ -0,0 +1,159 @@
+/*
+ * 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.queue;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public abstract class PersistentQueueBase implements QueueLifecycle {
+
+ private static final Logger log = LoggerFactory.getLogger(PersistentQueueBase.class);
+
+ private final int nbThreads;
+ private final Executor executor;
+ private final String svcName;
+ private final long sleepTimeMs;
+ private final long waitTimeoutMs;
+
+ private boolean isProcessingEvents;
+ private int curActiveThreads;
+
+ public PersistentQueueBase(final String svcName, final Executor executor, final int nbThreads, final long waitTimeoutMs, final long sleepTimeMs) {
+ this.executor = executor;
+ this.nbThreads = nbThreads;
+ this.svcName = svcName;
+ this.waitTimeoutMs = waitTimeoutMs;
+ this.sleepTimeMs = sleepTimeMs;
+ this.isProcessingEvents = false;
+ this.curActiveThreads = 0;
+ }
+
+ @Override
+ public void startQueue() {
+
+ isProcessingEvents = true;
+ curActiveThreads = 0;
+
+ final PersistentQueueBase thePersistentQ = this;
+ final CountDownLatch doneInitialization = new CountDownLatch(nbThreads);
+
+ log.info(String.format("%s: Starting with %d threads",
+ svcName, nbThreads));
+
+ for (int i = 0; i < nbThreads; i++) {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+
+ log.info(String.format("%s: Thread %s [%d] starting",
+ svcName,
+ Thread.currentThread().getName(),
+ Thread.currentThread().getId()));
+
+ synchronized(thePersistentQ) {
+ curActiveThreads++;
+ }
+
+ doneInitialization.countDown();
+
+ try {
+ while (true) {
+
+ synchronized(thePersistentQ) {
+ if (!isProcessingEvents) {
+ thePersistentQ.notify();
+ break;
+ }
+ }
+
+ try {
+ doProcessEvents();
+ } catch (Exception e) {
+ log.warn(String.format("%s: Thread %s [%d] got an exception, catching and moving on...",
+ svcName,
+ Thread.currentThread().getName(),
+ Thread.currentThread().getId()), e);
+ }
+ sleepALittle();
+ }
+ } catch (InterruptedException e) {
+ log.info(String.format("%s: Thread %s got interrupted, exting... ", svcName, Thread.currentThread().getName()));
+ } catch (Throwable e) {
+ log.error(String.format("%s: Thread %s got an exception, exting... ", svcName, Thread.currentThread().getName()), e);
+ } finally {
+
+ log.info(String.format("%s: Thread %s has exited", svcName, Thread.currentThread().getName()));
+ synchronized(thePersistentQ) {
+ curActiveThreads--;
+ }
+ }
+ }
+
+ private void sleepALittle() throws InterruptedException {
+ Thread.sleep(sleepTimeMs);
+ }
+ });
+ }
+ try {
+ boolean success = doneInitialization.await(sleepTimeMs, TimeUnit.MILLISECONDS);
+ if (!success) {
+
+ log.warn(String.format("%s: Failed to wait for all threads to be started, got %d/%d", svcName, (nbThreads - doneInitialization.getCount()), nbThreads));
+ } else {
+ log.info(String.format("%s: Done waiting for all threads to be started, got %d/%d", svcName, (nbThreads - doneInitialization.getCount()), nbThreads));
+ }
+ } catch (InterruptedException e) {
+ log.warn(String.format("%s: Start sequence, got interrupted", svcName));
+ }
+ }
+
+
+ @Override
+ public void stopQueue() {
+ int remaining = 0;
+ try {
+ synchronized(this) {
+ isProcessingEvents = false;
+ long ini = System.currentTimeMillis();
+ long remainingWaitTimeMs = waitTimeoutMs;
+ while (curActiveThreads > 0 && remainingWaitTimeMs > 0) {
+ wait(1000);
+ remainingWaitTimeMs = waitTimeoutMs - (System.currentTimeMillis() - ini);
+ }
+ remaining = curActiveThreads;
+ }
+
+ } catch (InterruptedException ignore) {
+ log.info(String.format("%s: Stop sequence has been interrupted, remaining active threads = %d", svcName, curActiveThreads));
+ } finally {
+ if (remaining > 0) {
+ log.error(String.format("%s: Stop sequence completed with %d active remaing threads", svcName, curActiveThreads));
+ } else {
+ log.info(String.format("%s: Stop sequence completed with %d active remaing threads", svcName, curActiveThreads));
+ }
+ curActiveThreads = 0;
+ }
+ }
+
+
+ @Override
+ public abstract int doProcessEvents();
+}
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 cec35b1..e32e27b 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -100,7 +100,6 @@ CREATE INDEX `idx_get_ready` ON notifications (`effective_dt`,`created_dt`,`id`
DROP TABLE IF EXISTS claimed_notifications;
CREATE TABLE claimed_notifications (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
- sequence_id int(11) unsigned NOT NULL,
owner_id varchar(64) NOT NULL,
claimed_dt datetime NOT NULL,
notification_id char(36) NOT NULL,
diff --git a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
index 6751f04..5797d5a 100644
--- a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
@@ -88,13 +88,11 @@ insertNotification() ::= <<
insertClaimedHistory(sequence_id, owner, hostname, claimed_dt, notification_id) ::= <<
insert into claimed_notifications (
- sequence_id
- , owner_id
+ owner_id
, claimed_dt
, notification_id
) values (
- :sequence_id
- , :owner
+ :owner
, :claimed_dt
, :notification_id
);
diff --git a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
index 9f4da5e..ab702cb 100644
--- a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
+++ b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
@@ -18,6 +18,13 @@ package com.ning.billing.util.clock;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
+import org.joda.time.Days;
+import org.joda.time.Months;
+import org.joda.time.MutablePeriod;
+import org.joda.time.Period;
+import org.joda.time.ReadablePeriod;
+import org.joda.time.Weeks;
+import org.joda.time.Years;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,8 +32,10 @@ import com.ning.billing.catalog.api.Duration;
import com.ning.billing.catalog.api.TimeUnit;
public class ClockMock implements Clock {
+
+ private MutablePeriod delta = new MutablePeriod();
private static final Logger log = LoggerFactory.getLogger(ClockMock.class);
- DateTime currentTime = new DateTime(DateTimeZone.UTC);
+
@Override
public synchronized DateTime getNow(DateTimeZone tz) {
@@ -35,35 +44,37 @@ public class ClockMock implements Clock {
@Override
public synchronized DateTime getUTCNow() {
- try {
- return currentTime.plus(epsilon).minus(currentTime.getMillisOfSecond());
- } catch(RuntimeException e) {
- throw e;
- }
+ return truncate(adjust(now()));
}
+ private DateTime adjust(DateTime now) {
+ return now.plus(delta);
+ }
+
public synchronized void setTime(DateTime time) {
- adjustTo(time.toDateTime(DateTimeZone.UTC));
- }
+ DateTime prev = getUTCNow();
+ delta = new MutablePeriod(now(), time);
+ logChange(prev);
+ }
public synchronized void addDays(int days) {
- adjustTo(currentTime.plusDays(days));
+ adjustTo(Days.days(days));
}
public synchronized void addWeeks(int weeks) {
- adjustTo(currentTime.plusWeeks(weeks));
+ adjustTo(Weeks.weeks(weeks));
}
public synchronized void addMonths(int months) {
- adjustTo(currentTime.plusMonths(months));
+ adjustTo(Months.months(months));
}
public synchronized void addYears(int years) {
- adjustTo(currentTime.plusMonths(years));
+ adjustTo(Years.years(years));
}
public synchronized void reset() {
- adjustTo(new DateTime(DateTimeZone.UTC));
+ delta = new MutablePeriod();
}
@Override
@@ -71,59 +82,66 @@ public class ClockMock implements Clock {
return getUTCNow().toString();
}
- private void adjustTo(DateTime newTime) {
- if(newTime == null) {
- log.error("Attempting to adjust clock to a null value");
- newTime = new DateTime(DateTimeZone.UTC);
- }
- logClockAdjustment(currentTime, newTime);
- currentTime = newTime;
+ private void adjustTo(ReadablePeriod period) {
+ DateTime prev = getUTCNow();
+ delta.add(period);
+ logChange(prev);
+ }
+
+ private void logChange(DateTime prev) {
+ DateTime now = getUTCNow();
+ log.info(String.format(" ************ ADJUSTING CLOCK FROM %s to %s ********************", prev, now));
}
- private void logClockAdjustment(DateTime prev, DateTime next) {
- log.info(String.format(" ************ ADJUSTING CLOCK FROM %s to %s ********************", prev, next));
+ private DateTime now() {
+ return new DateTime(DateTimeZone.UTC);
}
+ private DateTime truncate(DateTime time) {
+ return time.minus(time.getMillisOfSecond());
+ }
+
//
//Backward compatibility stuff
//
- long epsilon = 0;
-
- public synchronized void setDeltaFromReality(Duration delta, long epsilon) {
- this.epsilon = epsilon;
- addDeltaFromReality(delta);
+ public synchronized void setDeltaFromReality(Duration duration, long epsilon) {
+ DateTime prev = getUTCNow();
+ delta.addMillis((int)epsilon);
+ addDeltaFromReality(duration);
+ logChange(prev);
+
}
public synchronized void addDeltaFromReality(Duration delta) {
- adjustTo(addDurationToDateTime(delta,currentTime));
+ adjustTo(periodFromDuration(delta));
}
public synchronized void setDeltaFromReality(long delta) {
- adjustTo(currentTime.plus(delta));
+ adjustTo(new Period(delta));
}
public synchronized void addDeltaFromReality(long delta) {
- adjustTo(currentTime.plus(delta));
+ adjustTo(new Period(delta));
}
public synchronized void resetDeltaFromReality() {
reset();
}
- public DateTime addDurationToDateTime(Duration duration, DateTime dateTime) {
- if (duration.getUnit() != TimeUnit.UNLIMITED) {return dateTime;}
+ public ReadablePeriod periodFromDuration(Duration duration) {
+ if (duration.getUnit() != TimeUnit.UNLIMITED) {return new Period();}
switch (duration.getUnit()) {
case DAYS:
- return dateTime.plusDays(duration.getNumber());
+ return Days.days(duration.getNumber());
case MONTHS:
- return dateTime.plusMonths(duration.getNumber());
+ return Months.months(duration.getNumber());
case YEARS:
- return dateTime.plusYears(duration.getNumber());
+ return Years.years(duration.getNumber());
case UNLIMITED:
- return dateTime.plusYears(100);
- default:
- return dateTime;
+ return Years.years(100);
+ default:
+ return new Period();
}
}
diff --git a/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java b/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java
new file mode 100644
index 0000000..b31db77
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java
@@ -0,0 +1,162 @@
+/*
+ * 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.clock;
+
+import com.ning.billing.catalog.api.Duration;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// STEPH should really be in tests but not accessible from other sub modules
+public class OldClockMock extends DefaultClock {
+
+ private static final Logger log = LoggerFactory.getLogger(OldClockMock.class);
+
+ private enum DeltaType {
+ DELTA_NONE,
+ DELTA_DURATION,
+ DELTA_ABS
+ }
+
+ private long deltaFromRealityMs;
+ private List<Duration> deltaFromRealityDuration;
+ private long deltaFromRealityDurationEpsilon;
+ private DeltaType deltaType;
+
+ public OldClockMock() {
+ deltaType = DeltaType.DELTA_NONE;
+ deltaFromRealityMs = 0;
+ deltaFromRealityDurationEpsilon = 0;
+ deltaFromRealityDuration = null;
+ }
+
+ @Override
+ public synchronized DateTime getNow(DateTimeZone tz) {
+ return adjust(super.getNow(tz));
+ }
+
+ @Override
+ public synchronized DateTime getUTCNow() {
+ return getNow(DateTimeZone.UTC);
+ }
+
+ private void logClockAdjustment(DateTime prev, DateTime next) {
+ log.info(String.format(" ************ ADJUSTING CLOCK FROM %s to %s ********************", prev, next));
+ }
+
+ public synchronized void setDeltaFromReality(Duration delta, long epsilon) {
+ DateTime prev = getUTCNow();
+ deltaType = DeltaType.DELTA_DURATION;
+ deltaFromRealityDuration = new ArrayList<Duration>();
+ deltaFromRealityDuration.add(delta);
+ deltaFromRealityDurationEpsilon = epsilon;
+ deltaFromRealityMs = 0;
+ logClockAdjustment(prev, getUTCNow());
+ }
+
+ public synchronized void addDeltaFromReality(Duration delta) {
+ DateTime prev = getUTCNow();
+ if (deltaType != DeltaType.DELTA_DURATION) {
+ throw new RuntimeException("ClockMock should be set with type DELTA_DURATION");
+ }
+ deltaFromRealityDuration.add(delta);
+ logClockAdjustment(prev, getUTCNow());
+ }
+
+ public synchronized void setDeltaFromReality(long delta) {
+ DateTime prev = getUTCNow();
+ deltaType = DeltaType.DELTA_ABS;
+ deltaFromRealityDuration = null;
+ deltaFromRealityDurationEpsilon = 0;
+ deltaFromRealityMs = delta;
+ logClockAdjustment(prev, getUTCNow());
+ }
+
+ public synchronized void addDeltaFromReality(long delta) {
+ DateTime prev = getUTCNow();
+ if (deltaType != DeltaType.DELTA_ABS) {
+ throw new RuntimeException("ClockMock should be set with type DELTA_ABS");
+ }
+ deltaFromRealityDuration = null;
+ deltaFromRealityDurationEpsilon = 0;
+ deltaFromRealityMs += delta;
+ logClockAdjustment(prev, getUTCNow());
+ }
+
+ public synchronized void resetDeltaFromReality() {
+ deltaType = DeltaType.DELTA_NONE;
+ deltaFromRealityDuration = null;
+ deltaFromRealityDurationEpsilon = 0;
+ deltaFromRealityMs = 0;
+ }
+
+ private DateTime adjust(DateTime realNow) {
+ switch(deltaType) {
+ case DELTA_NONE:
+ return realNow;
+ case DELTA_ABS:
+ return adjustFromAbsolute(realNow);
+ case DELTA_DURATION:
+ return adjustFromDuration(realNow);
+ default:
+ return null;
+ }
+ }
+
+ private DateTime adjustFromDuration(DateTime input) {
+
+ DateTime result = input;
+ for (Duration cur : deltaFromRealityDuration) {
+ switch (cur.getUnit()) {
+ case DAYS:
+ result = result.plusDays(cur.getNumber());
+ break;
+
+ case MONTHS:
+ result = result.plusMonths(cur.getNumber());
+ break;
+
+ case YEARS:
+ result = result.plusYears(cur.getNumber());
+ break;
+
+ case UNLIMITED:
+ default:
+ throw new RuntimeException("ClockMock is adjusting an unlimited time period");
+ }
+ }
+ if (deltaFromRealityDurationEpsilon != 0) {
+ result = result.plus(deltaFromRealityDurationEpsilon);
+ }
+ return result;
+ }
+
+ private DateTime adjustFromAbsolute(DateTime input) {
+ return truncateMs(input.plus(deltaFromRealityMs));
+ }
+
+ @Override
+ public String toString() {
+ return getUTCNow().toString();
+ }
+
+
+}
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
index e52bf20..4702409 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
@@ -49,7 +49,6 @@ import static org.testng.Assert.assertNotNull;
@Guice(modules = TestNotificationSqlDao.TestNotificationSqlDaoModule.class)
public class TestNotificationSqlDao {
- private static AtomicInteger sequenceId = new AtomicInteger();
private final static String hostname = "Yop";
@Inject
@@ -124,7 +123,7 @@ public class TestNotificationSqlDao {
DateTime nextAvailable = now.plusMinutes(5);
int res = dao.claimNotification(ownerId, nextAvailable.toDate(), notification.getId(), now.toDate());
assertEquals(res, 1);
- dao.insertClaimedHistory(sequenceId.incrementAndGet(), ownerId, now.toDate(), notification.getUUID().toString());
+ dao.insertClaimedHistory(ownerId, now.toDate(), notification.getUUID().toString());
notification = fetchNotification(notification.getUUID().toString());
assertEquals(notification.getNotificationKey(), notificationKey);
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
index 658752a..86ec0ea 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
@@ -75,7 +75,7 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
}
@Override
- protected int doProcessEvents(int sequenceId) {
+ public int doProcessEvents() {
int result = 0;