Search in sources :

Example 1 with InternalTenantContext

use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.

the class TestEhCacheCatalogCache method testExistingTenantCatalog.

//
// Verify CatalogCache returns per tenant catalog:
// 1. We first mock TenantInternalApi to return a different catalog than the default one
// 2. We then mock TenantInternalApi to throw RuntimeException which means catalog was cached and there was no additional call
//    to the TenantInternalApi api (otherwise test would fail with RuntimeException)
//
@Test(groups = "fast")
public void testExistingTenantCatalog() throws CatalogApiException, URISyntaxException, IOException {
    final InternalCallContext differentMultiTenantContext = Mockito.mock(InternalCallContext.class);
    Mockito.when(differentMultiTenantContext.getTenantRecordId()).thenReturn(55667788L);
    final AtomicBoolean shouldThrow = new AtomicBoolean(false);
    final Long multiTenantRecordId = multiTenantContext.getTenantRecordId();
    final Long otherMultiTenantRecordId = otherMultiTenantContext.getTenantRecordId();
    final InputStream tenantInputCatalog = UriAccessor.accessUri(new URI(Resources.getResource("SpyCarAdvanced.xml").toExternalForm()));
    final String tenantCatalogXML = CharStreams.toString(new InputStreamReader(tenantInputCatalog, "UTF-8"));
    final InputStream otherTenantInputCatalog = UriAccessor.accessUri(new URI(Resources.getResource("SpyCarBasic.xml").toExternalForm()));
    final String otherTenantCatalogXML = CharStreams.toString(new InputStreamReader(otherTenantInputCatalog, "UTF-8"));
    Mockito.when(tenantInternalApi.getTenantCatalogs(Mockito.any(InternalTenantContext.class))).thenAnswer(new Answer<List<String>>() {

        @Override
        public List<String> answer(final InvocationOnMock invocation) throws Throwable {
            if (shouldThrow.get()) {
                throw new RuntimeException();
            }
            final InternalTenantContext internalContext = (InternalTenantContext) invocation.getArguments()[0];
            if (multiTenantRecordId.equals(internalContext.getTenantRecordId())) {
                return ImmutableList.<String>of(tenantCatalogXML);
            } else if (otherMultiTenantRecordId.equals(internalContext.getTenantRecordId())) {
                return ImmutableList.<String>of(otherTenantCatalogXML);
            } else {
                return ImmutableList.<String>of();
            }
        }
    });
    // Verify the lookup for a non-cached tenant. No system config is set yet but EhCacheCatalogCache returns a default empty one
    VersionedCatalog differentResult = catalogCache.getCatalog(true, true, differentMultiTenantContext);
    Assert.assertNotNull(differentResult);
    Assert.assertEquals(differentResult.getCatalogName(), "EmptyCatalog");
    // Make sure the cache loader isn't invoked, see https://github.com/killbill/killbill/issues/300
    shouldThrow.set(true);
    differentResult = catalogCache.getCatalog(true, true, differentMultiTenantContext);
    Assert.assertNotNull(differentResult);
    Assert.assertEquals(differentResult.getCatalogName(), "EmptyCatalog");
    shouldThrow.set(false);
    // Set a default config
    catalogCache.loadDefaultCatalog(Resources.getResource("SpyCarBasic.xml").toExternalForm());
    // Verify the lookup for this tenant
    final VersionedCatalog result = catalogCache.getCatalog(true, true, multiTenantContext);
    Assert.assertNotNull(result);
    final Collection<Product> products = result.getProducts(clock.getUTCNow());
    Assert.assertEquals(products.size(), 6);
    // Verify the lookup for another tenant
    final VersionedCatalog otherResult = catalogCache.getCatalog(true, true, otherMultiTenantContext);
    Assert.assertNotNull(otherResult);
    final Collection<Product> otherProducts = otherResult.getProducts(clock.getUTCNow());
    Assert.assertEquals(otherProducts.size(), 3);
    shouldThrow.set(true);
    // Verify the lookup for this tenant
    final VersionedCatalog result2 = catalogCache.getCatalog(true, true, multiTenantContext);
    Assert.assertEquals(result2, result);
    // Verify the lookup with another context for the same tenant
    final InternalCallContext sameMultiTenantContext = Mockito.mock(InternalCallContext.class);
    Mockito.when(sameMultiTenantContext.getAccountRecordId()).thenReturn(9102L);
    Mockito.when(sameMultiTenantContext.getTenantRecordId()).thenReturn(multiTenantRecordId);
    Assert.assertEquals(catalogCache.getCatalog(true, true, sameMultiTenantContext), result);
    // Verify the lookup with the other tenant
    Assert.assertEquals(catalogCache.getCatalog(true, true, otherMultiTenantContext), otherResult);
}
Also used : InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) DefaultProduct(org.killbill.billing.catalog.DefaultProduct) Product(org.killbill.billing.catalog.api.Product) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) URI(java.net.URI) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VersionedCatalog(org.killbill.billing.catalog.VersionedCatalog) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) StandaloneCatalogWithPriceOverride(org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride) Test(org.testng.annotations.Test)

Example 2 with InternalTenantContext

use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.

the class StandaloneCatalogWithPriceOverride method findCurrentPhase.

@Override
public PlanPhase findCurrentPhase(final String phaseName) throws CatalogApiException {
    final String planName = DefaultPlanPhase.planName(phaseName);
    final Matcher m = DefaultPriceOverride.CUSTOM_PLAN_NAME_PATTERN.matcher(planName);
    if (m.matches()) {
        final InternalTenantContext internalTenantContext = createInternalTenantContext();
        final Plan plan = priceOverride.getOverriddenPlan(planName, this, internalTenantContext);
        return plan.findPhase(phaseName);
    }
    return super.findCurrentPhase(phaseName);
}
Also used : Matcher(java.util.regex.Matcher) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) Plan(org.killbill.billing.catalog.api.Plan) PriceOverride(org.killbill.billing.catalog.override.PriceOverride) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) DefaultPriceOverride(org.killbill.billing.catalog.override.DefaultPriceOverride)

Example 3 with InternalTenantContext

use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.

the class EhCacheCatalogCache method getCatalogFromPlugins.

private VersionedCatalog getCatalogFromPlugins(final InternalTenantContext internalTenantContext) throws CatalogApiException {
    final TenantContext tenantContext = internalCallContextFactory.createTenantContext(internalTenantContext);
    for (final String service : pluginRegistry.getAllServices()) {
        final CatalogPluginApi plugin = pluginRegistry.getServiceForName(service);
        final VersionedPluginCatalog pluginCatalog = plugin.getVersionedPluginCatalog(ImmutableList.<PluginProperty>of(), tenantContext);
        // First plugin that gets something (for that tenant) returns it
        if (pluginCatalog != null) {
            logger.info("Returning catalog from plugin {} on tenant {} ", service, internalTenantContext.getTenantRecordId());
            return versionedCatalogMapper.toVersionedCatalog(pluginCatalog, internalTenantContext);
        }
    }
    return null;
}
Also used : VersionedPluginCatalog(org.killbill.billing.catalog.plugin.api.VersionedPluginCatalog) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) TenantContext(org.killbill.billing.util.callcontext.TenantContext) CatalogPluginApi(org.killbill.billing.catalog.plugin.api.CatalogPluginApi)

Example 4 with InternalTenantContext

use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.

the class EhCacheStateMachineConfigCache method createCacheLoaderArgument.

private CacheLoaderArgument createCacheLoaderArgument(final String pluginName) {
    final Object[] args = new Object[2];
    args[0] = loaderCallback;
    args[1] = pluginName;
    final ObjectType irrelevant = null;
    final InternalTenantContext notUsed = null;
    return new CacheLoaderArgument(irrelevant, args, notUsed);
}
Also used : ObjectType(org.killbill.billing.ObjectType) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) CacheLoaderArgument(org.killbill.billing.util.cache.CacheLoaderArgument)

Example 5 with InternalTenantContext

use of org.killbill.billing.callcontext.InternalTenantContext in project killbill by killbill.

the class DefaultInvoiceUserApi method insertCreditForInvoice.

private InvoiceItem insertCreditForInvoice(final UUID accountId, final UUID invoiceId, final BigDecimal amount, final LocalDate effectiveDate, final Currency currency, final boolean autoCommit, final String description, final CallContext context) throws InvoiceApiException {
    if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new InvoiceApiException(ErrorCode.CREDIT_AMOUNT_INVALID, amount);
    }
    final WithAccountLock withAccountLock = new WithAccountLock() {

        private InvoiceItem creditItem;

        @Override
        public List<Invoice> prepareInvoices() throws InvoiceApiException {
            final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
            final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
            // Create an invoice for that credit if it doesn't exist
            final Invoice invoiceForCredit;
            if (invoiceId == null) {
                final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
                invoiceForCredit = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
            } else {
                invoiceForCredit = getInvoiceAndCheckCurrency(invoiceId, currency, context);
                if (InvoiceStatus.COMMITTED.equals(invoiceForCredit.getStatus())) {
                    throw new InvoiceApiException(ErrorCode.INVOICE_ALREADY_COMMITTED, invoiceId);
                }
            }
            // Create the new credit
            creditItem = new CreditAdjInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), invoiceForCredit.getId(), accountId, effectiveDate, description, // Note! The amount is negated here!
            amount.negate(), currency);
            invoiceForCredit.addInvoiceItem(creditItem);
            return ImmutableList.<Invoice>of(invoiceForCredit);
        }
    };
    final Collection<InvoiceItem> creditInvoiceItems = Collections2.<InvoiceItem>filter(invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, context), new Predicate<InvoiceItem>() {

        @Override
        public boolean apply(final InvoiceItem invoiceItem) {
            return InvoiceItemType.CREDIT_ADJ.equals(invoiceItem.getInvoiceItemType());
        }
    });
    Preconditions.checkState(creditInvoiceItems.size() == 1, "Should have created a single credit invoice item: " + creditInvoiceItems);
    return creditInvoiceItems.iterator().next();
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) Invoice(org.killbill.billing.invoice.api.Invoice) HtmlInvoice(org.killbill.billing.invoice.template.HtmlInvoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock) LocalDate(org.joda.time.LocalDate) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Aggregations

InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)92 UUID (java.util.UUID)15 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)13 CacheLoaderArgument (org.killbill.billing.util.cache.CacheLoaderArgument)11 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)10 ArrayList (java.util.ArrayList)9 ObjectType (org.killbill.billing.ObjectType)9 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)9 TenantContext (org.killbill.billing.util.callcontext.TenantContext)9 ImmutableList (com.google.common.collect.ImmutableList)8 List (java.util.List)8 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)8 IOException (java.io.IOException)7 InputStream (java.io.InputStream)7 DateTime (org.joda.time.DateTime)7 LocalDate (org.joda.time.LocalDate)7 Predicate (com.google.common.base.Predicate)6 AccountApiException (org.killbill.billing.account.api.AccountApiException)6 VersionedCatalog (org.killbill.billing.catalog.api.VersionedCatalog)6 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)6