Skip to content

Commit

Permalink
Add pluginProperties through all (non get) entitlement apis
Browse files Browse the repository at this point in the history
Plug new EnitlementPluginApi through all calls
  • Loading branch information
sbrossie committed Jul 3, 2015
1 parent 24ff793 commit e6ec1e7
Show file tree
Hide file tree
Showing 16 changed files with 524 additions and 332 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.killbill.billing.entitlement.engine.core.BlockingTransitionNotificationKey; import org.killbill.billing.entitlement.engine.core.BlockingTransitionNotificationKey;
import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKey; import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKey;
import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKeyAction; import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKeyAction;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.platform.api.LifecycleHandlerType; import org.killbill.billing.platform.api.LifecycleHandlerType;
import org.killbill.billing.platform.api.LifecycleHandlerType.LifecycleLevel; import org.killbill.billing.platform.api.LifecycleHandlerType.LifecycleLevel;
import org.killbill.billing.util.callcontext.CallContext; import org.killbill.billing.util.callcontext.CallContext;
Expand All @@ -49,6 +50,7 @@
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;


import com.google.common.collect.ImmutableList;
import com.google.inject.Inject; import com.google.inject.Inject;


public class DefaultEntitlementService implements EntitlementService { public class DefaultEntitlementService implements EntitlementService {
Expand Down Expand Up @@ -132,9 +134,9 @@ private void processEntitlementNotification(final EntitlementNotificationKey key
EntitlementNotificationKeyAction.CANCEL.equals(entitlementNotificationKeyAction)) { EntitlementNotificationKeyAction.CANCEL.equals(entitlementNotificationKeyAction)) {
((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), callContext, internalCallContext); ((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), callContext, internalCallContext);
} else if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) { } else if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) {
entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext); entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
} else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) { } else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) {
entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext); entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
} }
} catch (final EntitlementApiException e) { } catch (final EntitlementApiException e) {
log.error("Error processing event for entitlement {}" + entitlement.getId(), e); log.error("Error processing event for entitlement {}" + entitlement.getId(), e);
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@
import org.killbill.billing.util.callcontext.CallOrigin; import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.UserType; import org.killbill.billing.util.callcontext.UserType;


import com.google.common.base.MoreObjects;


public class DefaultEntitlementContext implements EntitlementContext { public class DefaultEntitlementContext implements EntitlementContext {


private final OperationType operationType; private final OperationType operationType;
private final UUID accountId; private final UUID accountId;
private final UUID destinationAccountId;
private final UUID bundleId; private final UUID bundleId;
private final PlanPhaseSpecifier spec; private final PlanPhaseSpecifier spec;
private final String externalKey; private final String externalKey;
Expand All @@ -61,6 +61,7 @@ public DefaultEntitlementContext(final EntitlementContext prev,
@Nullable final PriorEntitlementResult pluginResult) { @Nullable final PriorEntitlementResult pluginResult) {
this(prev.getOperationType(), this(prev.getOperationType(),
prev.getAccountId(), prev.getAccountId(),
prev.getDestinationAccountId(),
prev.getBundleId(), prev.getBundleId(),
pluginResult != null && pluginResult.getAdjustedPlanPhaseSpecifier() != null ? pluginResult.getAdjustedPlanPhaseSpecifier() : prev.getPlanPhaseSpecifier(), pluginResult != null && pluginResult.getAdjustedPlanPhaseSpecifier() != null ? pluginResult.getAdjustedPlanPhaseSpecifier() : prev.getPlanPhaseSpecifier(),
prev.getExternalKey(), prev.getExternalKey(),
Expand All @@ -72,21 +73,23 @@ public DefaultEntitlementContext(final EntitlementContext prev,


public DefaultEntitlementContext(final OperationType operationType, public DefaultEntitlementContext(final OperationType operationType,
final UUID accountId, final UUID accountId,
final UUID destinationAccountId,
final UUID bundleId, final UUID bundleId,
final PlanPhaseSpecifier spec, final PlanPhaseSpecifier spec,
final String externalKey, final String externalKey,
final List<PlanPhasePriceOverride> planPhasePriceOverrides, final List<PlanPhasePriceOverride> planPhasePriceOverrides,
final LocalDate effectiveDate, final LocalDate effectiveDate,
final Iterable<PluginProperty> pluginProperties, final Iterable<PluginProperty> pluginProperties,
final CallContext callContext) { final CallContext callContext) {
this(operationType, accountId, bundleId, spec, externalKey, planPhasePriceOverrides, effectiveDate, pluginProperties, this(operationType, accountId, destinationAccountId, bundleId, spec, externalKey, planPhasePriceOverrides, effectiveDate, pluginProperties,
callContext.getUserToken(), callContext.getUserName(), callContext.getCallOrigin(), callContext.getUserType(), callContext.getReasonCode(), callContext.getUserToken(), callContext.getUserName(), callContext.getCallOrigin(), callContext.getUserType(), callContext.getReasonCode(),
callContext.getComments(), callContext.getCreatedDate(), callContext.getUpdatedDate(), callContext.getTenantId()); callContext.getComments(), callContext.getCreatedDate(), callContext.getUpdatedDate(), callContext.getTenantId());
} }




public DefaultEntitlementContext(final OperationType operationType, public DefaultEntitlementContext(final OperationType operationType,
final UUID accountId, final UUID accountId,
final UUID destinationAccountId,
final UUID bundleId, final UUID bundleId,
final PlanPhaseSpecifier spec, final PlanPhaseSpecifier spec,
final String externalKey, final String externalKey,
Expand All @@ -104,6 +107,7 @@ public DefaultEntitlementContext(final OperationType operationType,
final UUID tenantId) { final UUID tenantId) {
this.operationType = operationType; this.operationType = operationType;
this.accountId = accountId; this.accountId = accountId;
this.destinationAccountId = destinationAccountId;
this.bundleId = bundleId; this.bundleId = bundleId;
this.spec = spec; this.spec = spec;
this.externalKey = externalKey; this.externalKey = externalKey;
Expand Down Expand Up @@ -131,6 +135,11 @@ public UUID getAccountId() {
return accountId; return accountId;
} }


@Override
public UUID getDestinationAccountId() {
return destinationAccountId;
}

@Override @Override
public UUID getBundleId() { public UUID getBundleId() {
return bundleId; return bundleId;
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2014-2015 Groupon, Inc
* Copyright 2014-2015 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.api;

import javax.inject.Inject;

import org.killbill.billing.ErrorCode;
import org.killbill.billing.entitlement.plugin.api.EntitlementContext;
import org.killbill.billing.entitlement.plugin.api.EntitlementPluginApi;
import org.killbill.billing.entitlement.plugin.api.EntitlementPluginApiException;
import org.killbill.billing.entitlement.plugin.api.OnFailureEntitlementResult;
import org.killbill.billing.entitlement.plugin.api.OnSuccessEntitlementResult;
import org.killbill.billing.entitlement.plugin.api.PriorEntitlementResult;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EntitlementPluginExecution {

private static final Logger log = LoggerFactory.getLogger(EntitlementPluginExecution.class);

private final EntitlementApi entitlementApi;
private final OSGIServiceRegistration<EntitlementPluginApi> pluginRegistry;

public interface WithEntitlementPlugin<T> {
T doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException;
}


@Inject
public EntitlementPluginExecution(final EntitlementApi entitlementApi, final OSGIServiceRegistration<EntitlementPluginApi> pluginRegistry) {
this.entitlementApi = entitlementApi;
this.pluginRegistry = pluginRegistry;
}

public <T> T executeWithPlugin(final WithEntitlementPlugin<T> callback, final EntitlementContext pluginContext) throws EntitlementApiException {

try {
final PriorEntitlementResult priorEntitlementResult = executePluginPriorCalls(pluginContext);
if (priorEntitlementResult != null && priorEntitlementResult.isAborted()) {
throw new EntitlementApiException(ErrorCode.ENT_PLUGIN_API_ABORTED);
}
final EntitlementContext updatedPluginContext = new DefaultEntitlementContext(pluginContext, priorEntitlementResult);
try {
T result = callback.doCall(entitlementApi, updatedPluginContext);
executePluginOnSuccessCalls(updatedPluginContext);
return result;
} catch (final EntitlementApiException e) {
executePluginOnFailureCalls(updatedPluginContext);
throw e;
}
} catch (final EntitlementPluginApiException e) {
throw new EntitlementApiException(ErrorCode.ENT_PLUGIN_API_ABORTED, e.getMessage());
}
}

private PriorEntitlementResult executePluginPriorCalls(final EntitlementContext entitlementContextArg) throws EntitlementPluginApiException {

// Return as soon as the first plugin aborts, or the last result for the last plugin
PriorEntitlementResult prevResult = null;

EntitlementContext currentContext = entitlementContextArg;
for (final String pluginName : pluginRegistry.getAllServices()) {
final EntitlementPluginApi plugin = pluginRegistry.getServiceForName(pluginName);
if (plugin == null) {
// First call to plugin, we log warn, if plugin is not registered
log.warn("Skipping unknown entitlement control plugin {} when fetching results", pluginName);
continue;
}
prevResult = plugin.priorCall(currentContext, currentContext.getPluginProperties());
if (prevResult.isAborted()) {
break;
}
currentContext = new DefaultEntitlementContext(currentContext, prevResult);
}
return prevResult;
}

private OnSuccessEntitlementResult executePluginOnSuccessCalls(final EntitlementContext context) throws EntitlementPluginApiException {
for (final String pluginName : pluginRegistry.getAllServices()) {
final EntitlementPluginApi plugin = pluginRegistry.getServiceForName(pluginName);
if (plugin != null) {
plugin.onSuccessCall(context, context.getPluginProperties());
}
}
return null;
}

private OnFailureEntitlementResult executePluginOnFailureCalls(final EntitlementContext context) throws EntitlementPluginApiException {
for (final String pluginName : pluginRegistry.getAllServices()) {
final EntitlementPluginApi plugin = pluginRegistry.getServiceForName(pluginName);
if (plugin != null) {
plugin.onFailureCall(context, context.getPluginProperties());
}
}
return null;
}
}
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@


import org.killbill.billing.account.api.AccountInternalApi; import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalTenantContext; import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.entitlement.api.EntitlementPluginExecution;
import org.killbill.clock.Clock; import org.killbill.clock.Clock;
import org.killbill.billing.entitlement.AccountEntitlements; import org.killbill.billing.entitlement.AccountEntitlements;
import org.killbill.billing.entitlement.AccountEventsStreams; import org.killbill.billing.entitlement.AccountEventsStreams;
Expand Down Expand Up @@ -57,14 +58,17 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
private final EventsStreamBuilder eventsStreamBuilder; private final EventsStreamBuilder eventsStreamBuilder;
private final EntitlementUtils entitlementUtils; private final EntitlementUtils entitlementUtils;
private final NotificationQueueService notificationQueueService; private final NotificationQueueService notificationQueueService;
private final EntitlementPluginExecution pluginExecution;


@Inject @Inject
public DefaultEntitlementInternalApi(final EntitlementApi entitlementApi, final InternalCallContextFactory internalCallContextFactory, public DefaultEntitlementInternalApi(final EntitlementApi entitlementApi, final EntitlementPluginExecution pluginExecution,
final InternalCallContextFactory internalCallContextFactory,
final SubscriptionBaseInternalApi subscriptionInternalApi, final SubscriptionBaseInternalApi subscriptionInternalApi,
final AccountInternalApi accountApi, final BlockingStateDao blockingStateDao, final Clock clock, final AccountInternalApi accountApi, final BlockingStateDao blockingStateDao, final Clock clock,
final BlockingChecker checker, final NotificationQueueService notificationQueueService, final BlockingChecker checker, final NotificationQueueService notificationQueueService,
final EventsStreamBuilder eventsStreamBuilder, final EntitlementUtils entitlementUtils) { final EventsStreamBuilder eventsStreamBuilder, final EntitlementUtils entitlementUtils) {
this.entitlementApi = entitlementApi; this.entitlementApi = entitlementApi;
this.pluginExecution= pluginExecution;
this.internalCallContextFactory = internalCallContextFactory; this.internalCallContextFactory = internalCallContextFactory;
this.subscriptionInternalApi = subscriptionInternalApi; this.subscriptionInternalApi = subscriptionInternalApi;
this.clock = clock; this.clock = clock;
Expand All @@ -89,7 +93,7 @@ public AccountEntitlements getAllEntitlementsForAccountId(final UUID accountId,
} }


for (final EventsStream eventsStream : accountEventsStreams.getEventsStreams().get(bundleId)) { for (final EventsStream eventsStream : accountEventsStreams.getEventsStreams().get(bundleId)) {
final Entitlement entitlement = new DefaultEntitlement(eventsStream, eventsStreamBuilder, entitlementApi, final Entitlement entitlement = new DefaultEntitlement(eventsStream, eventsStreamBuilder, entitlementApi, pluginExecution,
blockingStateDao, subscriptionInternalApi, checker, notificationQueueService, blockingStateDao, subscriptionInternalApi, checker, notificationQueueService,
entitlementUtils, dateHelper, clock, internalCallContextFactory); entitlementUtils, dateHelper, clock, internalCallContextFactory);
entitlementsPerBundle.get(bundleId).add(entitlement); entitlementsPerBundle.get(bundleId).add(entitlement);
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.killbill.billing.entitlement.api.DefaultEntitlementApi; import org.killbill.billing.entitlement.api.DefaultEntitlementApi;
import org.killbill.billing.entitlement.api.DefaultSubscriptionApi; import org.killbill.billing.entitlement.api.DefaultSubscriptionApi;
import org.killbill.billing.entitlement.api.EntitlementApi; import org.killbill.billing.entitlement.api.EntitlementApi;
import org.killbill.billing.entitlement.api.EntitlementPluginExecution;
import org.killbill.billing.entitlement.api.SubscriptionApi; import org.killbill.billing.entitlement.api.SubscriptionApi;
import org.killbill.billing.entitlement.api.svcs.DefaultEntitlementInternalApi; import org.killbill.billing.entitlement.api.svcs.DefaultEntitlementInternalApi;
import org.killbill.billing.entitlement.api.svcs.DefaultInternalBlockingApi; import org.killbill.billing.entitlement.api.svcs.DefaultInternalBlockingApi;
Expand All @@ -50,6 +51,7 @@ public DefaultEntitlementModule(final KillbillConfigSource configSource) {


protected void installEntitlementPluginApi() { protected void installEntitlementPluginApi() {
bind(new TypeLiteral<OSGIServiceRegistration<EntitlementPluginApi>>() {}).toProvider(DefaultEntitlementProviderPluginRegistryProvider.class).asEagerSingleton(); bind(new TypeLiteral<OSGIServiceRegistration<EntitlementPluginApi>>() {}).toProvider(DefaultEntitlementProviderPluginRegistryProvider.class).asEagerSingleton();
bind(EntitlementPluginExecution.class).asEagerSingleton();
} }


@Override @Override
Expand Down
Loading

1 comment on commit e6ec1e7

@pierre
Copy link
Member

@pierre pierre commented on e6ec1e7 Jul 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.