killbill-aplcache
Changes
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java 13(+0 -13)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java 38(+19 -19)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java 5(+0 -5)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java 49(+0 -49)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java 67(+0 -67)
Details
diff --git a/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java b/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
index b44b81d..2567f94 100644
--- a/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
+++ b/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
@@ -25,7 +25,6 @@ import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entity.EntityBase;
import org.killbill.billing.util.UUIDs;
-import org.killbill.clock.Clock;
public class DefaultBlockingState extends EntityBase implements BlockingState {
@@ -87,6 +86,18 @@ public class DefaultBlockingState extends EntityBase implements BlockingState {
0L);
}
+ public DefaultBlockingState(final BlockingState input,
+ final DateTime effectiveDate) {
+ this(input.getBlockedId(),
+ input.getType(),
+ input.getStateName(),
+ input.getService(),
+ input.isBlockChange(),
+ input.isBlockEntitlement(),
+ input.isBlockBilling(),
+ effectiveDate);
+ }
+
@Override
public UUID getBlockedId() {
return blockedId;
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
index c004046..4cab8ea 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
@@ -385,19 +385,6 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
@Override
- public void setBlockingState(final UUID bundleId, final String stateName, final String serviceName, final LocalDate effectiveDate, final boolean blockBilling, final boolean blockEntitlement, final boolean blockChange, final Iterable<PluginProperty> properties, final CallContext context)
- throws EntitlementApiException {
- final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(bundleId, ObjectType.BUNDLE, context);
- super.setBlockingState(bundleId, stateName, serviceName, effectiveDate, blockBilling, blockEntitlement, blockChange, properties, contextWithValidAccountRecordId);
- }
-
- @Override
- public Iterable<BlockingState> getBlockingStatesForServiceAndType(final UUID blockableId, final BlockingStateType blockingStateType, final String serviceName, final TenantContext tenantContext) {
- // Not implemented see #431
- return null;
- }
-
- @Override
public UUID transferEntitlements(final UUID sourceAccountId, final UUID destAccountId, final String externalKey, final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext context) throws EntitlementApiException {
return transferEntitlementsOverrideBillingPolicy(sourceAccountId, destAccountId, externalKey, effectiveDate, BillingActionPolicy.IMMEDIATE, properties, context);
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
index fc63c7b..dc3c5c1 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -29,6 +29,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
import javax.inject.Inject;
+import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
@@ -46,6 +47,7 @@ import org.killbill.billing.entitlement.dao.BlockingStateDao;
import org.killbill.billing.entitlement.engine.core.EntitlementUtils;
import org.killbill.billing.entitlement.plugin.api.EntitlementContext;
import org.killbill.billing.entitlement.plugin.api.OperationType;
+import org.killbill.billing.junction.DefaultBlockingState;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
@@ -300,17 +302,17 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
@Override
- public void addBlockingState(final BlockingState blockingState, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public void addBlockingState(final BlockingState inputBlockingState, @Nullable final LocalDate inputEffectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
// This is in no way an exhaustive arg validation, but to to ensure plugin would not hijack private entitlement state or service name
- if (blockingState.getService() == null || blockingState.getService().equals(EntitlementService.ENTITLEMENT_SERVICE_NAME)) {
+ if (inputBlockingState.getService() == null || inputBlockingState.getService().equals(EntitlementService.ENTITLEMENT_SERVICE_NAME)) {
throw new EntitlementApiException(ErrorCode.SUB_BLOCKING_STATE_INVALID_ARG, "Need to specify a valid serviceName");
}
- if (blockingState.getStateName() == null ||
- blockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CANCELLED) ||
- blockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_BLOCKED) ||
- blockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CLEAR)) {
+ if (inputBlockingState.getStateName() == null ||
+ inputBlockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CANCELLED) ||
+ inputBlockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_BLOCKED) ||
+ inputBlockingState.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CLEAR)) {
throw new EntitlementApiException(ErrorCode.SUB_BLOCKING_STATE_INVALID_ARG, "Need to specify a valid stateName");
}
@@ -320,35 +322,33 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
final UUID bundleId;
final String externalKey;
try {
- switch (blockingState.getType()) {
+ switch (inputBlockingState.getType()) {
case ACCOUNT:
- internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(blockingState.getBlockedId(), ObjectType.ACCOUNT, callContext);
- account = accountApi.getImmutableAccountDataById(blockingState.getBlockedId(), internalCallContextWithValidAccountId);
+ internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(inputBlockingState.getBlockedId(), ObjectType.ACCOUNT, callContext);
+ account = accountApi.getImmutableAccountDataById(inputBlockingState.getBlockedId(), internalCallContextWithValidAccountId);
externalKey = account.getExternalKey();
accountId = account.getId();
bundleId = null;
break;
case SUBSCRIPTION_BUNDLE:
- internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(blockingState.getBlockedId(), ObjectType.BUNDLE, callContext);
- final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getBundleFromId(blockingState.getBlockedId(), internalCallContextWithValidAccountId);
+ internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(inputBlockingState.getBlockedId(), ObjectType.BUNDLE, callContext);
+ final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getBundleFromId(inputBlockingState.getBlockedId(), internalCallContextWithValidAccountId);
externalKey = bundle.getExternalKey();
bundleId = bundle.getId();
accountId = bundle.getAccountId();
- account = accountApi.getImmutableAccountDataById(accountId, internalCallContextWithValidAccountId);
break;
case SUBSCRIPTION:
- internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(blockingState.getBlockedId(), ObjectType.SUBSCRIPTION, callContext);
- final Entitlement entitlement = entitlementInternalApi.getEntitlementForId(blockingState.getBlockedId(), internalCallContextWithValidAccountId);
+ internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(inputBlockingState.getBlockedId(), ObjectType.SUBSCRIPTION, callContext);
+ final Entitlement entitlement = entitlementInternalApi.getEntitlementForId(inputBlockingState.getBlockedId(), internalCallContextWithValidAccountId);
bundleId = entitlement.getBundleId();
accountId = entitlement.getAccountId();
- account = accountApi.getImmutableAccountDataById(accountId, internalCallContextWithValidAccountId);
externalKey = null;
break;
default:
- throw new IllegalStateException("Invalid blockingStateType " + blockingState.getType());
+ throw new IllegalStateException("Invalid blockingStateType " + inputBlockingState.getType());
}
} catch (final AccountApiException e) {
throw new EntitlementApiException(e);
@@ -356,7 +356,8 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
throw new EntitlementApiException(e);
}
-
+ final DateTime effectiveDate = inputEffectiveDate == null ? clock.getUTCNow() : internalCallContextWithValidAccountId.toUTCDateTime(inputEffectiveDate);
+ final DefaultBlockingState blockingState = new DefaultBlockingState(inputBlockingState, effectiveDate);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.ADD_BLOCKING_STATE,
accountId,
@@ -364,13 +365,12 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
bundleId,
externalKey,
new ArrayList<EntitlementSpecifier>(),
- new LocalDate(blockingState.getEffectiveDate(), account.getTimeZone()),
+ internalCallContextWithValidAccountId.toLocalDate(effectiveDate),
null,
null,
properties,
callContext);
-
final WithEntitlementPlugin<Void> addBlockingStateWithPlugin = new WithEntitlementPlugin<Void>() {
@Override
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
index b1a720c..c29b025 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
@@ -230,11 +230,6 @@ public class DefaultEntitlementApiBase {
pluginExecution.executeWithPlugin(resumeWithPlugin, pluginContext);
}
- public void setBlockingState(final UUID bundleId, final String stateName, final String serviceName, final LocalDate localEffectiveDate, boolean blockBilling, boolean blockEntitlement, boolean blockChange, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext)
- throws EntitlementApiException {
- blockUnblockBundle(bundleId, stateName, serviceName, localEffectiveDate, blockBilling, blockEntitlement, blockChange, null, internalCallContext);
- }
-
private UUID blockUnblockBundle(final UUID bundleId, final String stateName, final String serviceName, @Nullable final LocalDate localEffectiveDate, boolean blockBilling, boolean blockEntitlement, boolean blockChange, @Nullable final SubscriptionBase inputBaseSubscription, final InternalCallContext internalCallContext)
throws EntitlementApiException {
final DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(localEffectiveDate, internalCallContext);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
index 7052c35..327046c 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
@@ -280,55 +280,6 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
assertEquals(subscription.getBillingEndDate(), new LocalDate(2013, 8, 7));
}
- @Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/452")
- public void testBlockedEntitlementChange() throws AccountApiException, EntitlementApiException {
- final LocalDate initialDate = new LocalDate(2013, 8, 7);
- clock.setDay(initialDate);
-
- final Account account = createAccount(getAccountData(7));
-
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
-
- // Create entitlement and check each field
- testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- clock.addDays(1);
- assertListenerStatus();
-
- testListener.pushExpectedEvent(NextEvent.BLOCK);
- entitlementApi.setBlockingState(entitlement.getBundleId(), "MY_BLOCK", "test", null, false, false, true, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- try {
- entitlement.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, ImmutableList.<PluginProperty>of(), callContext);
- fail();
- } catch (final EntitlementApiException e) {
- assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
- final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
- assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
- }
-
- try {
- entitlement.changePlanWithDate("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
- fail();
- } catch (final EntitlementApiException e) {
- assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
- final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
- assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
- }
-
- try {
- entitlement.changePlanOverrideBillingPolicy("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
- fail();
- } catch (final EntitlementApiException e) {
- assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
- final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
- assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
- }
- }
-
@Test(groups = "slow")
public void testEntitlementStartedInFuture() throws AccountApiException, EntitlementApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
index 256616d..62824a9 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
@@ -444,73 +444,6 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
}
- @Test(groups = "slow")
- public void testBlockBundle() throws AccountApiException, EntitlementApiException {
- final LocalDate initialDate = new LocalDate(2013, 8, 7);
- clock.setDay(initialDate);
-
- final Account account = createAccount(getAccountData(7));
-
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
-
- // Create entitlement and check each field
- testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- clock.addDays(5);
-
- testListener.pushExpectedEvents(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), "BLOCK", "foo", null, true, true, true, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- List<Entitlement> bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
- assertEquals(bundleEntitlements.size(), 1);
- assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
-
- final BlockingState blockingState = blockingInternalApi.getBlockingStateForService(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "foo", internalCallContext);
- assertTrue(blockingState.isBlockBilling());
- assertTrue(blockingState.isBlockChange());
- assertTrue(blockingState.isBlockEntitlement());
-
- // Check unblocking on another service will not bring the state back to ACTIVE
- clock.addDays(1);
- testListener.pushExpectedEvents(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), "UNBLOCK", "bar", null, false, false, false, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
- assertEquals(bundleEntitlements.size(), 1);
- assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
-
- testListener.pushExpectedEvents(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), "UNBLOCK", "foo", null, false, false, false, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
- assertEquals(bundleEntitlements.size(), 1);
- assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.ACTIVE);
-
- blockingInternalApi.getBlockingStateForService(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "foo", internalCallContext);
- clock.addDays(1);
-
- testListener.pushExpectedEvents(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), "BLOCK", "foo", null, true, true, true, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
- assertEquals(bundleEntitlements.size(), 1);
- assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
-
- // Same day but happened after so should take precedence
- testListener.pushExpectedEvents(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), "UNBLOCK", "foo", null, false, false, false, ImmutableList.<PluginProperty>of(), callContext);
- assertListenerStatus();
-
- bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
- assertEquals(bundleEntitlements.size(), 1);
- assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.ACTIVE);
- }
@Test(groups = "slow")
public void testCreateEntitlementInThePast() throws AccountApiException, EntitlementApiException, SubscriptionBaseApiException {
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
index 171be11..4d6c5f2 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -49,6 +49,7 @@ import com.google.common.collect.ImmutableList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbeddedDB {
@@ -346,7 +347,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, "accountBlock", "svc1", false, true, false, clock.getUTCNow());
- subscriptionApi.addBlockingState(state1, ImmutableList.<PluginProperty>of(), callContext);
+ subscriptionApi.addBlockingState(state1, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement updateEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
@@ -356,7 +357,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state2 = new DefaultBlockingState(createdEntitlement.getId(), BlockingStateType.SUBSCRIPTION, "subscriptionBlock", "svc2", false, false, false, clock.getUTCNow());
- subscriptionApi.addBlockingState(state2, ImmutableList.<PluginProperty>of(), callContext);
+ subscriptionApi.addBlockingState(state2, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Still blocked because this is a different service
@@ -366,7 +367,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Now we remove the blocking state for the same service but at the SUBSCRIPTION level
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state3 = new DefaultBlockingState(createdEntitlement.getId(), BlockingStateType.SUBSCRIPTION, "subscriptionUnBlock", "svc1", false, false, false, clock.getUTCNow());
- subscriptionApi.addBlockingState(state3, ImmutableList.<PluginProperty>of(), callContext);
+ subscriptionApi.addBlockingState(state3, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
updateEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
@@ -374,7 +375,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final DateTime futureEffectiveDate = clock.getUTCNow().plusDays(1);
final BlockingState state4 = new DefaultBlockingState(createdEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "blockBilling", "svc1", true, false, false, futureEffectiveDate);
- subscriptionApi.addBlockingState(state4, ImmutableList.<PluginProperty>of(), callContext);
+ subscriptionApi.addBlockingState(state4, internalCallContext.toLocalDate(futureEffectiveDate), ImmutableList.<PluginProperty>of(), callContext);
final Iterable<BlockingState> blockingStates1 = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.ACCOUNT, BlockingStateType.SUBSCRIPTION), ImmutableList.of("svc1", "svc2"), OrderingType.ASCENDING, SubscriptionApi.PAST_OR_PRESENT_EVENTS, callContext);
verifyBlockingStates(blockingStates1, ImmutableList.<BlockingState>of(state1, state2, state3));
@@ -400,6 +401,131 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
}
+ @Test(groups = "slow")
+ public void testBlockBundle() throws AccountApiException, EntitlementApiException {
+ final LocalDate initialDate = new LocalDate(2013, 8, 7);
+ clock.setDay(initialDate);
+
+ final Account account = createAccount(getAccountData(7));
+
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+ // Create entitlement and check each field
+ testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
+ final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ clock.addDays(5);
+
+ testListener.pushExpectedEvents(NextEvent.BLOCK);
+ final BlockingState state1 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "BLOCK", "foo", true, true, true, null);
+ subscriptionApi.addBlockingState(state1, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ List<Entitlement> bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
+ assertEquals(bundleEntitlements.size(), 1);
+ assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
+
+ final BlockingState blockingState = blockingInternalApi.getBlockingStateForService(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "foo", internalCallContext);
+ assertTrue(blockingState.isBlockBilling());
+ assertTrue(blockingState.isBlockChange());
+ assertTrue(blockingState.isBlockEntitlement());
+
+ // Check unblocking on another service will not bring the state back to ACTIVE
+ clock.addDays(1);
+ testListener.pushExpectedEvents(NextEvent.BLOCK);
+ final BlockingState state2 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "UNBLOCK", "bar", false, false, false, null);
+ subscriptionApi.addBlockingState(state2, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
+ assertEquals(bundleEntitlements.size(), 1);
+ assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
+
+ testListener.pushExpectedEvents(NextEvent.BLOCK);
+ final BlockingState state3 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "UNBLOCK", "foo", false, false, false, null);
+ subscriptionApi.addBlockingState(state3, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
+ assertEquals(bundleEntitlements.size(), 1);
+ assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.ACTIVE);
+
+ blockingInternalApi.getBlockingStateForService(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "foo", internalCallContext);
+ clock.addDays(1);
+
+ testListener.pushExpectedEvents(NextEvent.BLOCK);
+ final BlockingState state4 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "BLOCK", "foo", true, true, true, null);
+ subscriptionApi.addBlockingState(state4, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
+ assertEquals(bundleEntitlements.size(), 1);
+ assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.BLOCKED);
+
+ // Same day but happened after so should take precedence
+ testListener.pushExpectedEvents(NextEvent.BLOCK);
+ final BlockingState state5 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "UNBLOCK", "foo", false, false, false, null);
+ subscriptionApi.addBlockingState(state5, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(baseEntitlement.getBundleId(), callContext);
+ assertEquals(bundleEntitlements.size(), 1);
+ assertEquals(bundleEntitlements.get(0).getState(), EntitlementState.ACTIVE);
+ }
+
+
+ @Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/452")
+ public void testBlockedEntitlementChange() throws AccountApiException, EntitlementApiException {
+ final LocalDate initialDate = new LocalDate(2013, 8, 7);
+ clock.setDay(initialDate);
+
+ final Account account = createAccount(getAccountData(7));
+
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+ // Create entitlement and check each field
+ testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
+ final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ clock.addDays(1);
+ assertListenerStatus();
+
+ testListener.pushExpectedEvent(NextEvent.BLOCK);
+ final BlockingState state = new DefaultBlockingState(entitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "MY_BLOCK", "test", true, false, false, null);
+ subscriptionApi.addBlockingState(state, null, ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+
+ try {
+ entitlement.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, ImmutableList.<PluginProperty>of(), callContext);
+ fail();
+ } catch (final EntitlementApiException e) {
+ assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
+ final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
+ assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
+ }
+
+ try {
+ entitlement.changePlanWithDate("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
+ fail();
+ } catch (final EntitlementApiException e) {
+ assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
+ final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
+ assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
+ }
+
+ try {
+ entitlement.changePlanOverrideBillingPolicy("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null, clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
+ fail();
+ } catch (final EntitlementApiException e) {
+ assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
+ final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
+ assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
+ }
+ }
+
+
private void verifyBlockingStates(final Iterable<BlockingState> result, final List<BlockingState> expected) {
int i = 0;
final Iterator<BlockingState> iterator = result.iterator();
@@ -412,7 +538,7 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
assertEquals(cur.getService(), expectedItem.getService());
assertEquals(cur.getStateName(), expectedItem.getStateName());
assertEquals(cur.getBlockedId(), expectedItem.getBlockedId());
- assertEquals(cur.getEffectiveDate().compareTo(expectedItem.getEffectiveDate()), 0);
+ assertEquals(internalCallContext.toLocalDate(cur.getEffectiveDate()).compareTo(internalCallContext.toLocalDate(expectedItem.getEffectiveDate())), 0);
i++;
}
assertEquals(i, expected.size());
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
index 3867c9f..e5f00d3 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
@@ -132,7 +132,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, stateNameBlock, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
- blockingInternalApi.setBlockingState(state1, internalCallContext);
+ subscriptionApi.addBlockingState(state1, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
@@ -146,7 +146,8 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Add blocking at bundle level.
clock.addDays(1);
testListener.pushExpectedEvent(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), stateNameBlock, service, null, blockBilling, blockEntitlement, blockChange, ImmutableList.<PluginProperty>of(), callContext);
+ final BlockingState state2 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, stateNameBlock, service, blockChange, blockEntitlement, blockBilling, null);
+ subscriptionApi.addBlockingState(state2, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
@@ -156,8 +157,8 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Remove blocking at account level
clock.addDays(1);
testListener.pushExpectedEvent(NextEvent.BLOCK);
- final BlockingState state2 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, stateNameUnBlock, service, false, false, false, clock.getUTCNow());
- blockingInternalApi.setBlockingState(state2, internalCallContext);
+ final BlockingState state3 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, stateNameUnBlock, service, false, false, false, clock.getUTCNow());
+ subscriptionApi.addBlockingState(state3, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext);
@@ -167,7 +168,8 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
// Remove blocking at bundle level.
clock.addDays(1);
testListener.pushExpectedEvent(NextEvent.BLOCK);
- entitlementApi.setBlockingState(baseEntitlement.getBundleId(), stateNameUnBlock, service, null, false, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ final BlockingState state4 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, stateNameUnBlock, service, false, false, false, null);
+ subscriptionApi.addBlockingState(state4, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index 7658730..fb483a6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -44,6 +44,8 @@ import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.catalog.api.BillingActionPolicy;
+import org.killbill.billing.entitlement.api.BlockingState;
+import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.EntitlementApi;
import org.killbill.billing.entitlement.api.EntitlementApiException;
import org.killbill.billing.entitlement.api.SubscriptionApi;
@@ -55,6 +57,7 @@ import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.junction.DefaultBlockingState;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.api.AuditUserApi;
@@ -245,6 +248,7 @@ public class BundleResource extends JaxRsResourceBase {
@ApiResponse(code = 404, message = "Bundle not found")})
public Response addBundleBlockingState(final BlockingStateJson json,
@PathParam(ID_PARAM_NAME) final String id,
+ @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
@QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
@@ -259,8 +263,10 @@ public class BundleResource extends JaxRsResourceBase {
final boolean isBlockEntitlement = (json.isBlockEntitlement() != null && json.isBlockEntitlement());
final boolean isBlockChange = (json.isBlockChange() != null && json.isBlockChange());
- entitlementApi.setBlockingState(bundleId, json.getStateName(), json.getService(), json.getEffectiveDate(), isBlockBilling, isBlockEntitlement, isBlockChange, pluginProperties, callContext);
+ final LocalDate resolvedRequestedDate = requestedDate != null ? toLocalDate(requestedDate, callContext) : toLocalDate(requestedDate, callContext);
+ final BlockingState input = new DefaultBlockingState(bundleId, BlockingStateType.SUBSCRIPTION_BUNDLE, json.getStateName(), json.getService(), isBlockChange, isBlockEntitlement, isBlockBilling, null);
+ subscriptionApi.addBlockingState(input, resolvedRequestedDate, pluginProperties, callContext);
return Response.status(Status.OK).build();
}