Details
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 3e1dd16..1eb38a9 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -16,15 +16,12 @@
<option name="REPORT_VARIABLES" value="true" />
<option name="REPORT_PARAMETERS" value="true" />
</inspection_tool>
- <inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
- <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
- </inspection_tool>
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_requireAnnotationsFirst" value="true" />
</inspection_tool>
<inspection_tool class="RedundantTypeArguments" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticPseudoFunctionalStyleMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TryWithIdenticalCatches" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeMayBeWeakened" enabled="true" level="WARNING" enabled_by_default="true">
<option name="useRighthandTypeAsWeakestTypeInAssignments" value="true" />
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/caching/DefaultCatalogCache.java b/catalog/src/main/java/org/killbill/billing/catalog/caching/DefaultCatalogCache.java
index 02d5d9d..067bd95 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/caching/DefaultCatalogCache.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/caching/DefaultCatalogCache.java
@@ -18,6 +18,7 @@
package org.killbill.billing.catalog.caching;
import java.util.List;
+import java.util.Set;
import javax.inject.Inject;
@@ -147,7 +148,8 @@ public class DefaultCatalogCache implements CatalogCache {
private DefaultVersionedCatalog getCatalogFromPlugins(final InternalTenantContext internalTenantContext) throws CatalogApiException {
final TenantContext tenantContext = internalCallContextFactory.createTenantContext(internalTenantContext);
- for (final String service : pluginRegistry.getAllServices()) {
+ final Set<String> allServices = pluginRegistry.getAllServices();
+ for (final String service : allServices) {
final CatalogPluginApi plugin = pluginRegistry.getServiceForName(service);
//
@@ -158,9 +160,9 @@ public class DefaultCatalogCache implements CatalogCache {
// (e.g deleted Plans...), then multiple versions must be returned.
//
final DateTime latestCatalogUpdatedDate = plugin.getLatestCatalogVersion(ImmutableList.<PluginProperty>of(), tenantContext);
- // A null latestCatalogUpdatedDate by passing caching, by fetching full catalog from plugin below (compatibility mode with 0.18.x or non optimized plugin api mode)
- //
- if (latestCatalogUpdatedDate != null) {
+ // 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 tenantCatalog = cacheController.get(internalTenantContext.getTenantRecordId(), cacheLoaderArgument);
if (tenantCatalog != null) {
initializeCatalog(tenantCatalog);
@@ -174,10 +176,19 @@ public class DefaultCatalogCache implements CatalogCache {
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());
+ // 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, internalTenantContext);
+
+ // Always clear the cache for safety
cacheController.remove(internalTenantContext.getTenantRecordId());
- cacheController.putIfAbsent(internalTenantContext.getTenantRecordId(), resolvedPluginCatalog);
+ if (cacheable) {
+ cacheController.putIfAbsent(internalTenantContext.getTenantRecordId(), resolvedPluginCatalog);
+ }
+
return resolvedPluginCatalog;
}
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
index 6bd7330..f2f7d67 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
@@ -106,12 +106,15 @@ public class DefaultUnit extends ValidatingConfig<StandaloneCatalog> implements
@Override
public void writeExternal(final ObjectOutput out) throws IOException {
out.writeUTF(name);
- out.writeUTF(prettyName);
+ out.writeBoolean(prettyName != null);
+ if (prettyName != null) {
+ out.writeUTF(prettyName);
+ }
}
@Override
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
this.name = in.readUTF();
- this.prettyName = in.readUTF();
+ this.prettyName = in.readBoolean() ? in.readUTF() : null;
}
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/RuntimeExceptionMapper.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/RuntimeExceptionMapper.java
index 5117e1f..f8cbbaa 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/RuntimeExceptionMapper.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/mappers/RuntimeExceptionMapper.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -42,9 +44,7 @@ public class RuntimeExceptionMapper extends ExceptionMapperBase implements Excep
@Override
public Response toResponse(final RuntimeException exception) {
if (exception instanceof NullPointerException) {
- // Assume bad payload
- exception.printStackTrace();
- log.warn("Exception : " + exception.getMessage());
+ log.warn("Unexpected NullPointerException", exception);
return buildBadRequestResponse(exception, uriInfo);
} else if (exception instanceof WebApplicationException) {
// e.g. com.sun.jersey.api.NotFoundException
diff --git a/util/src/main/java/org/killbill/billing/util/cache/CacheControllerDispatcherProvider.java b/util/src/main/java/org/killbill/billing/util/cache/CacheControllerDispatcherProvider.java
index ce32de0..a99d0be 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/CacheControllerDispatcherProvider.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/CacheControllerDispatcherProvider.java
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
-// Build the abstraction layer between EhCache and Kill Bill
+// Build the abstraction layer between JCache and Kill Bill
public class CacheControllerDispatcherProvider implements Provider<CacheControllerDispatcher> {
private static final Logger logger = LoggerFactory.getLogger(CacheControllerDispatcherProvider.class);
@@ -56,13 +56,13 @@ public class CacheControllerDispatcherProvider implements Provider<CacheControll
final Cache cache = cacheManager.getCache(cacheType.getCacheName(), cacheType.getKeyType(), cacheType.getValueType());
if (cache == null) {
- logger.warn("Cache for cacheName='{}' not configured - check your ehcache.xml", cacheLoader.getCacheType().getCacheName());
+ logger.warn("Cache for cacheName='{}' not configured", cacheLoader.getCacheType().getCacheName());
continue;
}
Preconditions.checkState(!cache.isClosed(), "Cache '%s' should not be closed", cacheType.getCacheName());
- final CacheController<Object, Object> ehCacheBasedCacheController = new KillBillCacheController<Object, Object>(cache, cacheLoader);
- cacheControllers.put(cacheType, ehCacheBasedCacheController);
+ final CacheController<Object, Object> killBillCacheController = new KillBillCacheController<Object, Object>(cache, cacheLoader);
+ cacheControllers.put(cacheType, killBillCacheController);
}
return new CacheControllerDispatcher(cacheControllers);