/* * Copyright 2010-2013 Ning, Inc. * Copyright 2014-2016 Groupon, Inc * Copyright 2014-2016 The Billing Project, LLC * * The Billing Project 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 org.killbill.billing.entitlement.engine.core; import java.util.Map; import java.util.UUID; import javax.annotation.Nullable; import javax.inject.Inject; import org.killbill.billing.callcontext.InternalCallContext; import org.killbill.billing.callcontext.InternalTenantContext; import org.killbill.billing.entitlement.DefaultEntitlementService; import org.killbill.billing.entitlement.api.BlockingState; import org.killbill.billing.entitlement.api.BlockingStateType; import org.killbill.billing.entitlement.api.DefaultEntitlementApi; import org.killbill.billing.entitlement.dao.BlockingStateDao; import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi; import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException; import org.killbill.notificationq.api.NotificationQueueService; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; public class EntitlementUtils { protected final NotificationQueueService notificationQueueService; private final BlockingStateDao dao; private final SubscriptionBaseInternalApi subscriptionBaseInternalApi; @Inject public EntitlementUtils(final BlockingStateDao dao, final SubscriptionBaseInternalApi subscriptionBaseInternalApi, final NotificationQueueService notificationQueueService) { this.dao = dao; this.subscriptionBaseInternalApi = subscriptionBaseInternalApi; this.notificationQueueService = notificationQueueService; } 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); } public void setBlockingStateAndPostBlockingTransitionEvent(final Map<BlockingState, UUID> blockingStates, final InternalCallContext internalCallContext) { final ImmutableMap.Builder<BlockingState, Optional<UUID>> states = new ImmutableMap.Builder<BlockingState, Optional<UUID>>(); for (final BlockingState blockingState : blockingStates.keySet()) { states.put(blockingState, Optional.<UUID>fromNullable(blockingStates.get(blockingState))); } dao.setBlockingStatesAndPostBlockingTransitionEvent(states.build(), internalCallContext); } public void setBlockingStateAndPostBlockingTransitionEvent(final BlockingState state, final InternalCallContext context) { UUID bundleId = null; // We only need the bundle id in case of subscriptions (at the account level, we don't need it and at the bundle level, we already have it) if (state.getType() == BlockingStateType.SUBSCRIPTION) { try { bundleId = subscriptionBaseInternalApi.getSubscriptionFromId(state.getBlockedId(), context).getBundleId(); } catch (final SubscriptionBaseApiException e) { throw new RuntimeException(e); } } dao.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableMap.<BlockingState, Optional<UUID>>of(state, Optional.<UUID>fromNullable(bundleId)), context); } /** * @param externalKey the bundle externalKey * @param tenantContext the context * @return the id of the first subscription (BASE or STANDALONE) that is still active for that key */ public UUID getFirstActiveSubscriptionIdForKeyOrNull(final String externalKey, final InternalTenantContext tenantContext) { final Iterable<UUID> nonAddonUUIDs = subscriptionBaseInternalApi.getNonAOSubscriptionIdsForKey(externalKey, tenantContext); return Iterables.tryFind(nonAddonUUIDs, new Predicate<UUID>() { @Override public boolean apply(final UUID input) { final BlockingState state = dao.getBlockingStateForService(input, BlockingStateType.SUBSCRIPTION, DefaultEntitlementService.ENTITLEMENT_SERVICE_NAME, tenantContext); return (state == null || !state.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CANCELLED)); } }).orNull(); } }