Search in sources :

Example 1 with BlockingState

use of org.killbill.billing.entitlement.api.BlockingState in project killbill by killbill.

the class DefaultBlockingStateDao method getBlockedStatus.

private BlockingAggregator getBlockedStatus(final BlockingStateSqlDao sqlDao, final Handle handle, final UUID blockableId, final BlockingStateType type, @Nullable final UUID bundleId, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
    final List<BlockingState> accountBlockingStates;
    final List<BlockingState> bundleBlockingStates;
    final List<BlockingState> subscriptionBlockingStates;
    if (type == BlockingStateType.SUBSCRIPTION) {
        final UUID accountId = nonEntityDao.retrieveIdFromObjectInTransaction(context.getAccountRecordId(), ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID), handle);
        accountBlockingStates = getBlockingState(sqlDao, accountId, BlockingStateType.ACCOUNT, upToDate, context);
        bundleBlockingStates = getBlockingState(sqlDao, bundleId, BlockingStateType.SUBSCRIPTION_BUNDLE, upToDate, context);
        subscriptionBlockingStates = getBlockingState(sqlDao, blockableId, BlockingStateType.SUBSCRIPTION, upToDate, context);
    } else if (type == BlockingStateType.SUBSCRIPTION_BUNDLE) {
        final UUID accountId = nonEntityDao.retrieveIdFromObjectInTransaction(context.getAccountRecordId(), ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID), handle);
        accountBlockingStates = getBlockingState(sqlDao, accountId, BlockingStateType.ACCOUNT, upToDate, context);
        bundleBlockingStates = getBlockingState(sqlDao, blockableId, BlockingStateType.SUBSCRIPTION_BUNDLE, upToDate, context);
        subscriptionBlockingStates = ImmutableList.<BlockingState>of();
    } else {
        // BlockingStateType.ACCOUNT {
        accountBlockingStates = getBlockingState(sqlDao, blockableId, BlockingStateType.ACCOUNT, upToDate, context);
        bundleBlockingStates = ImmutableList.<BlockingState>of();
        subscriptionBlockingStates = ImmutableList.<BlockingState>of();
    }
    return statelessBlockingChecker.getBlockedState(accountBlockingStates, bundleBlockingStates, subscriptionBlockingStates);
}
Also used : BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID)

Example 2 with BlockingState

use of org.killbill.billing.entitlement.api.BlockingState in project killbill by killbill.

the class ProxyBlockingStateDao method insertTiedBlockingStatesInTheRightOrder.

private static BlockingState insertTiedBlockingStatesInTheRightOrder(final Collection<BlockingState> result, final BlockingState current, final BlockingState next, final boolean prevBlocked, final boolean currentBlocked, final boolean nextBlocked) {
    final BlockingState prev;
    if (prevBlocked && currentBlocked && nextBlocked) {
        // Tricky use case, bail
        return null;
    } else if (prevBlocked && currentBlocked && !nextBlocked) {
        result.add(next);
        result.add(current);
        prev = current;
    } else if (prevBlocked && !currentBlocked && nextBlocked) {
        result.add(current);
        result.add(next);
        prev = next;
    } else if (prevBlocked && !currentBlocked && !nextBlocked) {
        // Tricky use case, bail
        return null;
    } else if (!prevBlocked && currentBlocked && nextBlocked) {
        // Tricky use case, bail
        return null;
    } else if (!prevBlocked && currentBlocked && !nextBlocked) {
        result.add(current);
        result.add(next);
        prev = next;
    } else if (!prevBlocked && !currentBlocked && nextBlocked) {
        result.add(next);
        result.add(current);
        prev = current;
    } else if (!prevBlocked && !currentBlocked && !nextBlocked) {
        // Tricky use case, bail
        return null;
    } else {
        throw new ShouldntHappenException("Marker exception for code clarity");
    }
    return prev;
}
Also used : BlockingState(org.killbill.billing.entitlement.api.BlockingState) ShouldntHappenException(org.killbill.billing.util.customfield.ShouldntHappenException)

Example 3 with BlockingState

use of org.killbill.billing.entitlement.api.BlockingState in project killbill by killbill.

the class EntitlementUtils method setBlockingStatesAndPostBlockingTransitionEvent.

public void setBlockingStatesAndPostBlockingTransitionEvent(final Iterable<BlockingState> blockingStates, @Nullable final UUID bundleId, final InternalCallContext internalCallContext) {
    final ImmutableMap.Builder<BlockingState, Optional<UUID>> states = new ImmutableMap.Builder<BlockingState, Optional<UUID>>();
    final Optional<UUID> bundleIdOptional = Optional.<UUID>fromNullable(bundleId);
    for (final BlockingState blockingState : blockingStates) {
        states.put(blockingState, bundleIdOptional);
    }
    dao.setBlockingStatesAndPostBlockingTransitionEvent(states.build(), internalCallContext);
}
Also used : Optional(com.google.common.base.Optional) BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 4 with BlockingState

use of org.killbill.billing.entitlement.api.BlockingState in project killbill by killbill.

the class EventsStreamBuilder method buildForAccount.

// Special signature for ProxyBlockingStateDao to save a DAO call
public AccountEventsStreams buildForAccount(final Map<UUID, List<SubscriptionBase>> subscriptions, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
    // Retrieve the account
    final ImmutableAccountData account;
    try {
        account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
    } catch (AccountApiException e) {
        throw new EntitlementApiException(e);
    }
    if (subscriptions.isEmpty()) {
        // Bail early
        return new DefaultAccountEventsStreams(account);
    }
    // Retrieve the bundles
    final List<SubscriptionBaseBundle> bundles = subscriptionInternalApi.getBundlesForAccount(account.getId(), internalTenantContext);
    // Map bundle id -> bundles
    final Map<UUID, SubscriptionBaseBundle> bundlesPerId = new HashMap<UUID, SubscriptionBaseBundle>();
    for (final SubscriptionBaseBundle bundle : bundles) {
        bundlesPerId.put(bundle.getId(), bundle);
    }
    // Retrieve the blocking states
    final List<BlockingState> blockingStatesForAccount = defaultBlockingStateDao.getBlockingAllForAccountRecordId(internalTenantContext);
    // Optimization: build lookup tables for blocking states states
    final Collection<BlockingState> accountBlockingStates = new LinkedList<BlockingState>();
    final Map<UUID, List<BlockingState>> blockingStatesPerSubscription = new HashMap<UUID, List<BlockingState>>();
    final Map<UUID, List<BlockingState>> blockingStatesPerBundle = new HashMap<UUID, List<BlockingState>>();
    for (final BlockingState blockingState : blockingStatesForAccount) {
        if (BlockingStateType.SUBSCRIPTION.equals(blockingState.getType())) {
            if (blockingStatesPerSubscription.get(blockingState.getBlockedId()) == null) {
                blockingStatesPerSubscription.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
            }
            blockingStatesPerSubscription.get(blockingState.getBlockedId()).add(blockingState);
        } else if (BlockingStateType.SUBSCRIPTION_BUNDLE.equals(blockingState.getType())) {
            if (blockingStatesPerBundle.get(blockingState.getBlockedId()) == null) {
                blockingStatesPerBundle.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
            }
            blockingStatesPerBundle.get(blockingState.getBlockedId()).add(blockingState);
        } else if (BlockingStateType.ACCOUNT.equals(blockingState.getType()) && account.getId().equals(blockingState.getBlockedId())) {
            accountBlockingStates.add(blockingState);
        }
    }
    // Build the EventsStream objects
    final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
    final Map<UUID, Collection<EventsStream>> entitlementsPerBundle = new HashMap<UUID, Collection<EventsStream>>();
    for (final UUID bundleId : subscriptions.keySet()) {
        final SubscriptionBaseBundle bundle = bundlesPerId.get(bundleId);
        final List<SubscriptionBase> allSubscriptionsForBundle = subscriptions.get(bundleId);
        final SubscriptionBase baseSubscription = findBaseSubscription(allSubscriptionsForBundle);
        final List<BlockingState> bundleBlockingStates = MoreObjects.firstNonNull(blockingStatesPerBundle.get(bundleId), ImmutableList.<BlockingState>of());
        if (entitlementsPerBundle.get(bundleId) == null) {
            entitlementsPerBundle.put(bundleId, new LinkedList<EventsStream>());
        }
        for (final SubscriptionBase subscription : allSubscriptionsForBundle) {
            final List<BlockingState> subscriptionBlockingStatesOnDisk = MoreObjects.firstNonNull(blockingStatesPerSubscription.get(subscription.getId()), ImmutableList.<BlockingState>of());
            // We cannot always use blockingStatesForAccount here: we need subscriptionBlockingStates to contain the events not on disk when building an EventsStream
            // for an add-on - which means going through the magic of ProxyBlockingStateDao, which will recursively
            // create EventsStream objects. To avoid an infinite recursion, bypass ProxyBlockingStateDao when it's not
            // needed, i.e. if this EventStream is for a standalone or a base subscription
            final List<BlockingState> subscriptionBlockingStates;
            if (baseSubscription == null || subscription.getId().equals(baseSubscription.getId())) {
                subscriptionBlockingStates = subscriptionBlockingStatesOnDisk;
            } else {
                subscriptionBlockingStates = blockingStateDao.getBlockingHistory(subscriptionBlockingStatesOnDisk, blockingStatesForAccount, account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, internalTenantContext);
            }
            // Merge the BlockingStates
            final Collection<BlockingState> blockingStateSet = new LinkedHashSet<BlockingState>(accountBlockingStates);
            blockingStateSet.addAll(bundleBlockingStates);
            blockingStateSet.addAll(subscriptionBlockingStates);
            final List<BlockingState> blockingStates = ProxyBlockingStateDao.sortedCopy(blockingStateSet);
            final EventsStream eventStream = buildForEntitlement(account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, blockingStates, bcdCache, internalTenantContext);
            entitlementsPerBundle.get(bundleId).add(eventStream);
        }
    }
    return new DefaultAccountEventsStreams(account, bundles, entitlementsPerBundle);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) HashMap(java.util.HashMap) EventsStream(org.killbill.billing.entitlement.EventsStream) BlockingState(org.killbill.billing.entitlement.api.BlockingState) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) AccountApiException(org.killbill.billing.account.api.AccountApiException) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) DefaultAccountEventsStreams(org.killbill.billing.entitlement.api.svcs.DefaultAccountEventsStreams) UUID(java.util.UUID) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) LinkedList(java.util.LinkedList) Collection(java.util.Collection)

Example 5 with BlockingState

use of org.killbill.billing.entitlement.api.BlockingState in project killbill by killbill.

the class DefaultEntitlementService method blockAddOnsIfRequired.

private void blockAddOnsIfRequired(final EntitlementNotificationKey key, final DefaultEntitlement entitlement, final TenantContext callContext, final InternalCallContext internalCallContext) throws EntitlementApiException {
    final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
    final Collection<BlockingState> blockingStates = entitlement.computeAddOnBlockingStates(key.getEffectiveDate(), notificationEvents, callContext, internalCallContext);
    // Record the new state first, then insert the notifications to avoid race conditions
    entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(blockingStates, entitlement.getBundleId(), internalCallContext);
    for (final NotificationEvent notificationEvent : notificationEvents) {
        recordFutureNotification(key.getEffectiveDate(), notificationEvent, internalCallContext);
    }
}
Also used : ArrayList(java.util.ArrayList) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) BlockingState(org.killbill.billing.entitlement.api.BlockingState)

Aggregations

BlockingState (org.killbill.billing.entitlement.api.BlockingState)46 UUID (java.util.UUID)24 DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)22 Test (org.testng.annotations.Test)15 DateTime (org.joda.time.DateTime)13 ArrayList (java.util.ArrayList)8 HashMap (java.util.HashMap)6 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)6 LocalDate (org.joda.time.LocalDate)5 ImmutableList (com.google.common.collect.ImmutableList)4 LinkedList (java.util.LinkedList)4 List (java.util.List)4 Account (org.killbill.billing.account.api.Account)4 BillingEvent (org.killbill.billing.junction.BillingEvent)4 Optional (com.google.common.base.Optional)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 TreeSet (java.util.TreeSet)3 AccountApiException (org.killbill.billing.account.api.AccountApiException)3 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)3 BlockingStateType (org.killbill.billing.entitlement.api.BlockingStateType)3