Search in sources :

Example 6 with DefaultVersionedCatalog

use of org.killbill.billing.catalog.DefaultVersionedCatalog in project killbill by killbill.

the class DefaultCatalogUserApi method uploadCatalog.

@Override
public void uploadCatalog(final String catalogXML, final CallContext callContext) throws CatalogApiException {
    final InternalTenantContext internalTenantContext = createInternalTenantContext(callContext);
    try {
        VersionedCatalog versionedCatalog = catalogService.getFullCatalog(false, true, internalTenantContext);
        if (versionedCatalog == null) {
            // If this is the first version
            versionedCatalog = new DefaultVersionedCatalog();
        }
        // Validation purpose:  Will throw if bad XML or catalog validation fails
        final InputStream stream = new ByteArrayInputStream(catalogXML.getBytes());
        final StaticCatalog newCatalogVersion = XMLLoader.getObjectFromStream(stream, StandaloneCatalog.class);
        final ValidationErrors errors = new ValidationErrors();
        // Fix for https://github.com/killbill/killbill/issues/1481
        ((DefaultVersionedCatalog) versionedCatalog).add((StandaloneCatalog) newCatalogVersion);
        ((DefaultVersionedCatalog) versionedCatalog).validate(null, errors);
        if (!errors.isEmpty()) {
            // Bummer ValidationException CTOR is private to package...
            // final ValidationException validationException = new ValidationException(errors);
            // throw new CatalogApiException(errors, ErrorCode.CAT_INVALID_FOR_TENANT, internalTenantContext.getTenantRecordId());
            logger.info("Failed to load new catalog version: " + errors.toString());
            throw new CatalogApiException(ErrorCode.CAT_INVALID_FOR_TENANT, internalTenantContext.getTenantRecordId());
        }
        tenantApi.addTenantKeyValue(TenantKey.CATALOG.toString(), catalogXML, callContext);
        catalogCache.clearCatalog(internalTenantContext);
    } catch (final TenantApiException e) {
        throw new CatalogApiException(e);
    } catch (final ValidationException e) {
        throw new CatalogApiException(e, ErrorCode.CAT_INVALID_FOR_TENANT, internalTenantContext.getTenantRecordId());
    } catch (final JAXBException e) {
        throw new CatalogApiException(e, ErrorCode.CAT_INVALID_FOR_TENANT, internalTenantContext.getTenantRecordId());
    } catch (final IOException e) {
        throw new IllegalStateException(e);
    } catch (final TransformerException e) {
        throw new IllegalStateException(e);
    } catch (final SAXException e) {
        throw new IllegalStateException(e);
    }
}
Also used : ValidationException(org.killbill.xmlloader.ValidationException) ValidationErrors(org.killbill.xmlloader.ValidationErrors) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) JAXBException(javax.xml.bind.JAXBException) DefaultVersionedCatalog(org.killbill.billing.catalog.DefaultVersionedCatalog) IOException(java.io.IOException) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog) SAXException(org.xml.sax.SAXException) VersionedCatalog(org.killbill.billing.catalog.api.VersionedCatalog) DefaultVersionedCatalog(org.killbill.billing.catalog.DefaultVersionedCatalog) ByteArrayInputStream(java.io.ByteArrayInputStream) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) TenantApiException(org.killbill.billing.tenant.api.TenantApiException) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) TransformerException(javax.xml.transform.TransformerException)

Example 7 with DefaultVersionedCatalog

use of org.killbill.billing.catalog.DefaultVersionedCatalog in project killbill by killbill.

the class DefaultCatalogCache method getCatalogFromPlugins.

private VersionedCatalog getCatalogFromPlugins(final InternalTenantContext internalTenantContext) throws CatalogApiException {
    final TenantContext tenantContext = internalCallContextFactory.createTenantContext(internalTenantContext);
    final Set<String> allServices = pluginRegistry.getAllServices();
    for (final String service : allServices) {
        final CatalogPluginApi plugin = pluginRegistry.getServiceForName(service);
        // 
        // Beware plugin implementors:  latestCatalogUpdatedDate returned by the plugin should also match the effectiveDate of the VersionedCatalog.
        // 
        // However, this is the plugin choice to return one, or many catalog versions (StandaloneCatalog), Kill Bill catalog module does not care.
        // As a guideline, if plugin keeps seeing new Plans/Products, this can all fit into the same version; however if there is a true versioning
        // (e.g deleted Plans...), then multiple versions must be returned.
        // 
        final DateTime latestCatalogUpdatedDate = plugin.getLatestCatalogVersion(ImmutableList.<PluginProperty>of(), tenantContext);
        // A null latestCatalogUpdatedDate bypasses caching, by fetching full catalog from plugin below (compatibility mode with 0.18.x or non optimized plugin api mode)
        final boolean cacheable = latestCatalogUpdatedDate != null;
        if (cacheable) {
            final DefaultVersionedCatalog versionedCatalog = cacheController.get(internalTenantContext.getTenantRecordId(), cacheLoaderArgument);
            if (versionedCatalog != null) {
                if (versionedCatalog.getCurrentVersion().getEffectiveDate().compareTo(latestCatalogUpdatedDate.toDate()) == 0) {
                    // Current cached version matches the one from the plugin
                    return versionedCatalog;
                }
            }
        }
        final VersionedPluginCatalog pluginCatalog = plugin.getVersionedPluginCatalog(ImmutableList.<PluginProperty>of(), tenantContext);
        // First plugin that gets something (for that tenant) returns it
        if (pluginCatalog != null) {
            // The log entry is only interesting if there are multiple plugins
            if (allServices.size() > 1) {
                logger.info("Returning catalog from plugin {} on tenant {} ", service, internalTenantContext.getTenantRecordId());
            }
            final DefaultVersionedCatalog resolvedPluginCatalog = versionedCatalogMapper.toVersionedCatalog(pluginCatalog);
            // Always clear the cache for safety
            cacheController.remove(internalTenantContext.getTenantRecordId());
            if (cacheable) {
                cacheController.putIfAbsent(internalTenantContext.getTenantRecordId(), resolvedPluginCatalog);
            }
            return resolvedPluginCatalog;
        }
    }
    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) DefaultVersionedCatalog(org.killbill.billing.catalog.DefaultVersionedCatalog) CatalogPluginApi(org.killbill.billing.catalog.plugin.api.CatalogPluginApi) DateTime(org.joda.time.DateTime)

Example 8 with DefaultVersionedCatalog

use of org.killbill.billing.catalog.DefaultVersionedCatalog in project killbill by killbill.

the class DefaultCatalogCache method getCatalog.

@Override
public VersionedCatalog getCatalog(final boolean useDefaultCatalog, final boolean filterTemplateCatalog, final boolean internalUse, final InternalTenantContext tenantContext) throws CatalogApiException {
    // 
    if (internalUse) {
        Preconditions.checkState(tenantContext.getAccountRecordId() != null, "Unexpected null accountRecordId in context issued from internal Kill Bill service");
    }
    final VersionedCatalog pluginVersionedCatalog = getCatalogFromPlugins(tenantContext);
    if (pluginVersionedCatalog != null) {
        return pluginVersionedCatalog;
    }
    if (InternalCallContextFactory.INTERNAL_TENANT_RECORD_ID.equals(tenantContext.getTenantRecordId())) {
        return useDefaultCatalog ? defaultCatalog : null;
    }
    // but to be on the safe side;;
    try {
        DefaultVersionedCatalog tenantCatalog = cacheController.get(tenantContext.getTenantRecordId(), filterTemplateCatalog ? cacheLoaderArgumentWithTemplateFiltering : cacheLoaderArgument);
        // for test purpose.
        if (useDefaultCatalog && tenantCatalog == null) {
            tenantCatalog = new DefaultVersionedCatalog();
            for (final StaticCatalog cur : defaultCatalog.getVersions()) {
                final StandaloneCatalogWithPriceOverride curWithOverride = new StandaloneCatalogWithPriceOverride(cur, priceOverride, tenantContext.getTenantRecordId(), internalCallContextFactory);
                tenantCatalog.add(curWithOverride);
            }
            initializeCatalog(tenantCatalog);
            cacheController.putIfAbsent(tenantContext.getTenantRecordId(), tenantCatalog);
        }
        return tenantCatalog;
    } catch (final IllegalStateException e) {
        throw new CatalogApiException(ErrorCode.CAT_INVALID_FOR_TENANT, tenantContext.getTenantRecordId());
    }
}
Also used : StandaloneCatalogWithPriceOverride(org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride) VersionedCatalog(org.killbill.billing.catalog.api.VersionedCatalog) DefaultVersionedCatalog(org.killbill.billing.catalog.DefaultVersionedCatalog) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) DefaultVersionedCatalog(org.killbill.billing.catalog.DefaultVersionedCatalog) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog) PriceOverride(org.killbill.billing.catalog.override.PriceOverride) StandaloneCatalogWithPriceOverride(org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride)

Aggregations

DefaultVersionedCatalog (org.killbill.billing.catalog.DefaultVersionedCatalog)8 StandaloneCatalogWithPriceOverride (org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride)4 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)4 StandaloneCatalog (org.killbill.billing.catalog.StandaloneCatalog)3 StaticCatalog (org.killbill.billing.catalog.api.StaticCatalog)3 VersionedCatalog (org.killbill.billing.catalog.api.VersionedCatalog)3 ValidationException (org.killbill.xmlloader.ValidationException)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 InputStream (java.io.InputStream)2 ExecutionException (java.util.concurrent.ExecutionException)2 JAXBException (javax.xml.bind.JAXBException)2 InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)2 PriceOverride (org.killbill.billing.catalog.override.PriceOverride)2 Test (org.testng.annotations.Test)2 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 URL (java.net.URL)1 ArrayList (java.util.ArrayList)1