Search in sources :

Example 11 with EventsStream

use of org.killbill.billing.entitlement.EventsStream 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 VersionedCatalog catalog, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
    // Retrieve the account
    final ImmutableAccountData account;
    final int accountBCD;
    try {
        account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
        accountBCD = accountInternalApi.getBCD(internalTenantContext);
    } catch (final 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(catalog, 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>> eventsStreamPerBundle = new HashMap<UUID, Collection<EventsStream>>();
    final Map<UUID, Collection<SubscriptionBase>> subscriptionsPerBundle = new HashMap<UUID, Collection<SubscriptionBase>>();
    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 (eventsStreamPerBundle.get(bundleId) == null) {
            eventsStreamPerBundle.put(bundleId, new LinkedList<EventsStream>());
        }
        if (subscriptionsPerBundle.get(bundleId) == null) {
            subscriptionsPerBundle.put(bundleId, allSubscriptionsForBundle);
        }
        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 Collection<BlockingState> subscriptionBlockingStates;
            if (baseSubscription == null || subscription.getId().equals(baseSubscription.getId())) {
                subscriptionBlockingStates = subscriptionBlockingStatesOnDisk;
            } else {
                subscriptionBlockingStates = blockingStateDao.getBlockingHistory(subscriptionBlockingStatesOnDisk, blockingStatesForAccount, account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, accountBCD, catalog, 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, accountBCD, bcdCache, catalog, internalTenantContext);
            eventsStreamPerBundle.get(bundleId).add(eventStream);
        }
    }
    return new DefaultAccountEventsStreams(account, bundles, subscriptionsPerBundle, eventsStreamPerBundle);
}
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 12 with EventsStream

use of org.killbill.billing.entitlement.EventsStream in project killbill by killbill.

the class ProxyBlockingStateDao method addBlockingStatesNotOnDisk.

// Special signature for OptimizedProxyBlockingStateDao
protected List<BlockingState> addBlockingStatesNotOnDisk(@Nullable final UUID blockableId, @Nullable final BlockingStateType blockingStateType, final Collection<BlockingState> blockingStatesOnDiskCopy, final Iterable<SubscriptionBase> baseSubscriptionsToConsider, final Iterable<EventsStream> eventsStreams) {
    final Map<UUID, EventsStream> baseSubscriptionIdToEventsStream = new HashMap<UUID, EventsStream>();
    for (final EventsStream eventsStream : eventsStreams) {
        baseSubscriptionIdToEventsStream.put(eventsStream.getSubscriptionBase().getId(), eventsStream);
    }
    // Compute the blocking states not on disk for all base subscriptions
    final DateTime now = clock.getUTCNow();
    for (final SubscriptionBase baseSubscription : baseSubscriptionsToConsider) {
        final EventsStream eventsStream = baseSubscriptionIdToEventsStream.get(baseSubscription.getId());
        // First, check to see if the base entitlement is cancelled
        final Collection<BlockingState> blockingStatesNotOnDisk = eventsStream.computeAddonsBlockingStatesForFutureSubscriptionBaseEvents();
        // Inject the extra blocking states into the stream if needed
        for (final BlockingState blockingState : blockingStatesNotOnDisk) {
            // If this entitlement is actually already cancelled, add the cancellation event we computed
            // only if it's prior to the blocking state on disk (e.g. add-on future cancelled but base plan cancelled earlier).
            BlockingState cancellationBlockingStateOnDisk = null;
            boolean overrideCancellationBlockingStateOnDisk = false;
            if (isEntitlementCancellationBlockingState(blockingState)) {
                cancellationBlockingStateOnDisk = findEntitlementCancellationBlockingState(blockingState.getBlockedId(), blockingStatesOnDiskCopy);
                overrideCancellationBlockingStateOnDisk = cancellationBlockingStateOnDisk != null && blockingState.getEffectiveDate().isBefore(cancellationBlockingStateOnDisk.getEffectiveDate());
            }
            if ((blockingStateType == null || // blocking states for other add-ons on that base subscription
            (BlockingStateType.SUBSCRIPTION.equals(blockingStateType) && blockingState.getBlockedId().equals(blockableId))) && (cancellationBlockingStateOnDisk == null || overrideCancellationBlockingStateOnDisk)) {
                final BlockingStateModelDao blockingStateModelDao = new BlockingStateModelDao(blockingState, now, now);
                blockingStatesOnDiskCopy.add(BlockingStateModelDao.toBlockingState(blockingStateModelDao));
                if (overrideCancellationBlockingStateOnDisk) {
                    blockingStatesOnDiskCopy.remove(cancellationBlockingStateOnDisk);
                }
            }
        }
    }
    // Return the sorted list
    return sortedCopy(blockingStatesOnDiskCopy);
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) EventsStream(org.killbill.billing.entitlement.EventsStream) HashMap(java.util.HashMap) BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID) DateTime(org.joda.time.DateTime)

Example 13 with EventsStream

use of org.killbill.billing.entitlement.EventsStream in project killbill by killbill.

the class TestEntitlementUtils method computeBlockingStatesForAssociatedAddonsViaAccount.

private Collection<BlockingState> computeBlockingStatesForAssociatedAddonsViaAccount(final DefaultEntitlement baseEntitlement, final DateTime effectiveDate) throws EntitlementApiException {
    final AccountEventsStreams accountEventsStreams = eventsStreamBuilder.buildForAccount(internalCallContext);
    final EventsStream eventsStream = Iterables.<EventsStream>find(Iterables.<EventsStream>concat(accountEventsStreams.getEventsStreams().values()), new Predicate<EventsStream>() {

        @Override
        public boolean apply(final EventsStream input) {
            return input.getSubscriptionBase().getId().equals(baseEntitlement.getId());
        }
    });
    return eventsStream.computeAddonsBlockingStatesForNextSubscriptionBaseEvent(effectiveDate);
}
Also used : EventsStream(org.killbill.billing.entitlement.EventsStream) AccountEventsStreams(org.killbill.billing.entitlement.AccountEventsStreams)

Aggregations

EventsStream (org.killbill.billing.entitlement.EventsStream)13 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)7 HashMap (java.util.HashMap)5 LinkedList (java.util.LinkedList)5 UUID (java.util.UUID)5 DateTime (org.joda.time.DateTime)4 AccountEventsStreams (org.killbill.billing.entitlement.AccountEventsStreams)4 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)4 ImmutableList (com.google.common.collect.ImmutableList)3 Collection (java.util.Collection)3 List (java.util.List)3 BlockingState (org.killbill.billing.entitlement.api.BlockingState)3 EntitlementApiException (org.killbill.billing.entitlement.api.EntitlementApiException)3 SubscriptionBaseBundle (org.killbill.billing.subscription.api.user.SubscriptionBaseBundle)3 ArrayList (java.util.ArrayList)2 LinkedHashSet (java.util.LinkedHashSet)2 AccountApiException (org.killbill.billing.account.api.AccountApiException)2 ImmutableAccountData (org.killbill.billing.account.api.ImmutableAccountData)2 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)2 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)2