killbill-uncached

analytics: implement account blacklist Add a system property

6/11/2013 1:39:48 PM

Details

diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
index 4800e18..25ab0b5 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.osgi.bundles.analytics;
 
+import java.util.Properties;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
@@ -43,11 +44,23 @@ import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillEventDispatcher.OSGIKillbillEventHandler;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+
 public class AnalyticsListener implements OSGIKillbillEventHandler {
 
     private static final String ANALYTICS_NB_LOCK_TRY_PROPERTY = "killbill.osgi.analytics.lock.count";
     private static final int NB_LOCK_TRY = Integer.parseInt(System.getProperty(ANALYTICS_NB_LOCK_TRY_PROPERTY, "5"));
 
+    // List of account ids to ignore
+    static final String ANALYTICS_ACCOUNTS_BLACKLIST_PROPERTY = "killbill.osgi.analytics.blacklist";
+    private static final Splitter BLACKLIST_SPLITTER = Splitter.on(',')
+                                                               .trimResults()
+                                                               .omitEmptyStrings();
+    private final Iterable<String> accountsBlacklist;
+
     private final LogService logService;
     private final BusinessAccountDao bacDao;
     private final BusinessSubscriptionTransitionDao bstDao;
@@ -62,6 +75,14 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
                              final OSGIKillbillAPI osgiKillbillAPI,
                              final OSGIKillbillDataSource osgiKillbillDataSource,
                              final Executor executor) {
+        this(logService, osgiKillbillAPI, osgiKillbillDataSource, executor, System.getProperties());
+    }
+
+    AnalyticsListener(final OSGIKillbillLogService logService,
+                      final OSGIKillbillAPI osgiKillbillAPI,
+                      final OSGIKillbillDataSource osgiKillbillDataSource,
+                      final Executor executor,
+                      final Properties properties) {
         this.logService = logService;
 
         this.bacDao = new BusinessAccountDao(logService, osgiKillbillAPI, osgiKillbillDataSource, executor);
@@ -74,10 +95,17 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
 
         // TODO Do we still need it?
         this.locker = new MySqlGlobalLocker(osgiKillbillDataSource.getDataSource());
+
+        accountsBlacklist = BLACKLIST_SPLITTER.split(properties.getProperty(ANALYTICS_ACCOUNTS_BLACKLIST_PROPERTY, ""));
     }
 
     @Override
     public void handleKillbillEvent(final ExtBusEvent killbillEvent) {
+        // Don't mirror accounts in the blacklist
+        if (isAccountBlacklisted(killbillEvent.getAccountId())) {
+            return;
+        }
+
         final CallContext callContext = new AnalyticsCallContext(killbillEvent);
 
         switch (killbillEvent.getEventType()) {
@@ -120,6 +148,11 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
         }
     }
 
+    @VisibleForTesting
+    protected boolean isAccountBlacklisted(final UUID accountId) {
+        return Iterables.find(accountsBlacklist, Predicates.<String>equalTo(accountId.toString()), null) != null;
+    }
+
     private void handleAccountEvent(final ExtBusEvent killbillEvent, final CallContext callContext) {
         updateWithAccountLock(killbillEvent, new Callable<Void>() {
             @Override
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
index 9f3bf4a..aa92d17 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
@@ -20,6 +20,7 @@ import java.math.BigDecimal;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
+import javax.sql.DataSource;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -41,16 +42,16 @@ import com.ning.billing.catalog.api.PriceList;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.user.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentType;
-import com.ning.billing.junction.api.Type;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.junction.api.Type;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessEntityBase;
 import com.ning.billing.osgi.bundles.analytics.dao.TestCallContext;
 import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao.BusinessInvoiceItemType;
@@ -421,5 +422,7 @@ public abstract class AnalyticsTestSuiteNoDB {
         Mockito.when(killbillAPI.getRecordIdApi()).thenReturn(recordIdApi);
 
         killbillDataSource = Mockito.mock(OSGIKillbillDataSource.class);
+        final DataSource dataSource = Mockito.mock(DataSource.class);
+        Mockito.when(killbillDataSource.getDataSource()).thenReturn(dataSource);
     }
 }
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestAnalyticsListener.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestAnalyticsListener.java
new file mode 100644
index 0000000..a0eba3c
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestAnalyticsListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.osgi.bundles.analytics;
+
+import java.util.Properties;
+import java.util.UUID;
+
+import org.testng.annotations.Test;
+
+import junit.framework.Assert;
+
+import static com.ning.billing.osgi.bundles.analytics.AnalyticsListener.ANALYTICS_ACCOUNTS_BLACKLIST_PROPERTY;
+
+public class TestAnalyticsListener extends AnalyticsTestSuiteNoDB {
+
+    @Test(groups = "fast")
+    public void testBlacklist() throws Exception {
+        final Properties properties = new Properties();
+        AnalyticsListener analyticsListener = new AnalyticsListener(logService, killbillAPI, killbillDataSource, null);
+
+        // No account is blacklisted
+        Assert.assertFalse(analyticsListener.isAccountBlacklisted(UUID.randomUUID()));
+
+        final UUID blackListedAccountId = UUID.randomUUID();
+        properties.put(ANALYTICS_ACCOUNTS_BLACKLIST_PROPERTY, String.format("%s,%s", UUID.randomUUID(), blackListedAccountId));
+        analyticsListener = new AnalyticsListener(logService, killbillAPI, killbillDataSource, null, properties);
+
+        // Other accounts are blacklisted
+        Assert.assertFalse(analyticsListener.isAccountBlacklisted(UUID.randomUUID()));
+
+        // Blacklist
+        Assert.assertTrue(analyticsListener.isAccountBlacklisted(blackListedAccountId));
+    }
+}