killbill-memoizeit

util: don't always use RO DB by default Unless plugins explicitly

4/23/2018 2:50:14 AM

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 0be4e28..746f4bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.141.58</version>
+        <version>0.141.59-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.19.11-SNAPSHOT</version>

util/pom.xml 1(+0 -1)

diff --git a/util/pom.xml b/util/pom.xml
index 946d4c3..bb6f930 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -201,7 +201,6 @@
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-osgi-api</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
diff --git a/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java b/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
index c751f83..80abe6d 100644
--- a/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
+++ b/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
@@ -22,6 +22,11 @@ import java.lang.reflect.Method;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 import org.killbill.billing.KillbillApi;
+import org.killbill.billing.callcontext.DefaultTenantContext;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.osgi.api.ROTenantContext;
+import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.commons.profiling.Profiling;
 import org.killbill.commons.profiling.Profiling.WithProfilingCallback;
 import org.killbill.commons.profiling.ProfilingFeature.ProfilingFeatureType;
@@ -59,6 +64,11 @@ public class KillbillApiAopModule extends AbstractModule {
             return prof.executeWithProfiling(ProfilingFeatureType.API, invocation.getMethod().getName(), new WithProfilingCallback() {
                 @Override
                 public Object execute() throws Throwable {
+                    final boolean useRODBIfAvailable = shouldUseRODBIfAvailable(invocation);
+                    if (!useRODBIfAvailable) {
+                        setDirtyDBFlag();
+                    }
+
                     try {
                         logger.debug("Entering API call {}, arguments: {}", invocation.getMethod(), invocation.getArguments());
                         final Object proceed = invocation.proceed();
@@ -70,6 +80,39 @@ public class KillbillApiAopModule extends AbstractModule {
                 }
             });
         }
+
+        private boolean shouldUseRODBIfAvailable(final MethodInvocation invocation) {
+            // Verify if the flag is already set for re-entrant calls
+            if (getDirtyDBFlag()) {
+                return false;
+            }
+
+            final Object[] arguments = invocation.getArguments();
+            if (arguments.length == 0) {
+                return false;
+            }
+
+            // Snowflakes from server filters
+            final boolean safeROOperations = "getTenantByApiKey".equals(invocation.getMethod().getName()) || "login".equals(invocation.getMethod().getName());
+            if (safeROOperations) {
+                return true;
+            }
+
+            for (int i = arguments.length - 1; i >= 0; i--) {
+                final Object argument = arguments[i];
+                // DefaultTenantContext belongs to killbill-internal-api and shouldn't be used by plugins
+                final boolean fromJAXRS = argument instanceof DefaultTenantContext && !(argument instanceof CallContext);
+                // Kill Bill internal re-entrant calls
+                final boolean fromInternalAPIs = argument instanceof InternalTenantContext && !(argument instanceof InternalCallContext);
+                // RO DB explicitly requested by a plugin
+                final boolean pluginRequestROInstance = argument instanceof ROTenantContext && !(argument instanceof CallContext);
+                if (fromJAXRS || fromInternalAPIs || pluginRequestROInstance) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
     }
 
     public static void setDirtyDBFlag() {