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);
}
}
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;
}
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());
}
}
Aggregations