killbill-uncached

Details

jaxrs/pom.xml 5(+5 -0)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 66a787f..bca2b90 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -101,6 +101,11 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
+            <artifactId>killbill-platform-server</artifactId>
+            <classifier>classes</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-test</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index e9af063..18099f0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -61,6 +61,7 @@ import org.killbill.billing.payment.api.PaymentApiException;
 import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.api.TransactionStatus;
+import org.killbill.billing.server.healthchecks.KillbillHealthcheck;
 import org.killbill.billing.tenant.api.Tenant;
 import org.killbill.billing.tenant.api.TenantApiException;
 import org.killbill.billing.tenant.api.TenantUserApi;
@@ -115,6 +116,7 @@ public class AdminResource extends JaxRsResourceBase {
     private final RecordIdApi recordIdApi;
     private final PersistentBus persistentBus;
     private final NotificationQueueService notificationQueueService;
+    private final KillbillHealthcheck killbillHealthcheck;
 
     @Inject
     public AdminResource(final JaxrsUriBuilder uriBuilder,
@@ -130,6 +132,7 @@ public class AdminResource extends JaxRsResourceBase {
                          final RecordIdApi recordIdApi,
                          final PersistentBus persistentBus,
                          final NotificationQueueService notificationQueueService,
+                         final KillbillHealthcheck killbillHealthcheck,
                          final Clock clock,
                          final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, null, clock, context);
@@ -140,6 +143,7 @@ public class AdminResource extends JaxRsResourceBase {
         this.cacheControllerDispatcher = cacheControllerDispatcher;
         this.persistentBus = persistentBus;
         this.notificationQueueService = notificationQueueService;
+        this.killbillHealthcheck = killbillHealthcheck;
     }
 
     @GET
@@ -421,6 +425,26 @@ public class AdminResource extends JaxRsResourceBase {
         return Response.status(Status.OK).build();
     }
 
+    @POST
+    @Path("/" + HEALTHCHECK)
+    @Produces(APPLICATION_JSON)
+    @ApiOperation(value = "Put the host out of rotation")
+    @ApiResponses(value = {})
+    public Response putInRotation(@javax.ws.rs.core.Context final HttpServletRequest request) {
+        killbillHealthcheck.putInRotation();
+        return Response.status(Status.OK).build();
+    }
+
+    @DELETE
+    @Path("/" + HEALTHCHECK)
+    @Produces(APPLICATION_JSON)
+    @ApiOperation(value = "Put the host out of rotation")
+    @ApiResponses(value = {})
+    public Response putOutOfRotation(@javax.ws.rs.core.Context final HttpServletRequest request) {
+        killbillHealthcheck.putOutOfRotation();
+        return Response.status(Status.OK).build();
+    }
+
     private Iterable<NotificationEventWithMetadata<NotificationEvent>> getNotifications(@Nullable final String queueName,
                                                                                         @Nullable final String serviceName,
                                                                                         final boolean includeInProcessing,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index b7d6a38..38a3986 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -285,6 +285,7 @@ public interface JaxrsResource {
     public static final String TRANSFER_CREDIT = "transferCredit";
 
     public static final String CACHE = "cache";
+    public static final String HEALTHCHECK = "healthcheck";
 
     public static final String QUERY_INCLUDED_DELETED = "includedDeleted";
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 44a8fa5..6230736 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.140.34</version>
+        <version>0.140.38</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.18.12-SNAPSHOT</version>
diff --git a/profiles/killbill/pom.xml b/profiles/killbill/pom.xml
index c59a4cd..97d679a 100644
--- a/profiles/killbill/pom.xml
+++ b/profiles/killbill/pom.xml
@@ -179,6 +179,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.bgee.log4jdbc-log4j2</groupId>
+            <artifactId>log4jdbc-log4j2-jdbc4</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.codehaus.janino</groupId>
             <artifactId>janino</artifactId>
             <scope>runtime</scope>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
index 902ba81..d79edbe 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/CleanupListener.java
@@ -28,6 +28,8 @@ import javax.servlet.ServletContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.sf.log4jdbc.sql.jdbcapi.DriverSpy;
+
 public class CleanupListener implements ServletContextListener {
 
     private static final Logger logger = LoggerFactory.getLogger(CleanupListener.class);
@@ -38,16 +40,6 @@ public class CleanupListener implements ServletContextListener {
 
     @Override
     public void contextDestroyed(final ServletContextEvent servletContextEvent) {
-        final Enumeration<Driver> drivers = DriverManager.getDrivers();
-        while (drivers.hasMoreElements()) {
-            try {
-                final Driver driver = drivers.nextElement();
-                DriverManager.deregisterDriver(driver);
-            } catch (final SQLException e) {
-                logger.warn("Unable to de-register driver", e);
-            }
-        }
-
         // See http://docs.oracle.com/cd/E17952_01/connector-j-relnotes-en/news-5-1-23.html
         try {
             Class.forName("com.mysql.jdbc.AbandonedConnectionCleanupThread");
@@ -65,5 +57,23 @@ public class CleanupListener implements ServletContextListener {
         } catch (final ClassNotFoundException ignored) {
             // MariaDB driver not used
         }
+
+        try {
+            // Invoke DriverSpy directly if it hasn't been already, as it will statically load drivers
+            DriverManager.deregisterDriver(new DriverSpy());
+        } catch (final SQLException e) {
+            logger.warn("Unable to de-register driver", e);
+        }
+
+        // This needs to be last, as drivers above will invoke registerDriver statically
+        final Enumeration<Driver> drivers = DriverManager.getDrivers();
+        while (drivers.hasMoreElements()) {
+            try {
+                final Driver driver = drivers.nextElement();
+                DriverManager.deregisterDriver(driver);
+            } catch (final SQLException e) {
+                logger.warn("Unable to de-register driver", e);
+            }
+        }
     }
 }
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
index 79838b1..0fcb600 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
@@ -32,6 +32,7 @@ import org.killbill.billing.server.filters.ProfilingContainerResponseFilter;
 import org.killbill.billing.server.filters.RequestDataFilter;
 import org.killbill.billing.server.filters.ResponseCorsFilter;
 import org.killbill.billing.server.modules.KillbillServerModule;
+import org.killbill.billing.server.notifications.PushNotificationListener;
 import org.killbill.billing.server.security.TenantFilter;
 import org.killbill.bus.api.PersistentBus;
 import org.killbill.commons.skeleton.modules.BaseServerModuleBuilder;
@@ -127,6 +128,8 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
 
     @Override
     protected void stopLifecycleStage2() {
+        super.stopLifecycleStage2();
+
         try {
             killbillBusService.getBus().unregister(killbilleventHandler);
         } catch (final PersistentBus.EventBusException e) {
@@ -147,4 +150,12 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
         beanConfig.setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html");
         beanConfig.setScan(true);
     }
+
+    @Override
+    protected void stopLifecycleStage3() {
+        super.stopLifecycleStage3();
+
+        final PushNotificationListener pushNotificationListener = injector.getInstance(PushNotificationListener.class);
+        pushNotificationListener.shutdown();
+    }
 }
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index b2b0c49..0e1627d 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -132,9 +132,13 @@ public class KillbillServerModule extends KillbillPlatformModule {
     }
 
     @Override
-    protected void configureEmbeddedDB() {
-        embeddedDB = new KillBillEmbeddedDBProvider(daoConfig).get();
-        bind(EmbeddedDB.class).toInstance(embeddedDB);
+    protected void configureEmbeddedDBs() {
+        mainEmbeddedDB = new KillBillEmbeddedDBProvider(daoConfig).get();
+        bind(EmbeddedDB.class).toInstance(mainEmbeddedDB);
+
+        // Same database, but different pool: clone the object so the shutdown sequence cleans the pool properly
+        shiroEmbeddedDB = new KillBillEmbeddedDBProvider(daoConfig).get();
+        bind(EmbeddedDB.class).annotatedWith(Names.named(SHIRO_DATA_SOURCE_ID_NAMED)).toInstance(shiroEmbeddedDB);
     }
 
     @Override
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
index afa18cf..0f35812 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
@@ -113,6 +113,10 @@ public class PushNotificationListener {
         }
     }
 
+    public void shutdown() {
+        httpClient.close();
+    }
+
     private void dispatchCallback(final UUID tenantId, final ExtBusEvent event, final Iterable<String> callbacks) throws IOException {
         final NotificationJson notification = new NotificationJson(event);
         final String body = mapper.writeValueAsString(notification);
diff --git a/profiles/killbill/src/main/webapp/WEB-INF/web.xml b/profiles/killbill/src/main/webapp/WEB-INF/web.xml
index 43dda36..12e57ed 100644
--- a/profiles/killbill/src/main/webapp/WEB-INF/web.xml
+++ b/profiles/killbill/src/main/webapp/WEB-INF/web.xml
@@ -53,6 +53,13 @@
         <filter-name>guiceFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
+
+    <context-param>
+        <!-- We want to make sure the Logback shutdown happens last -->
+        <param-name>logbackDisableServletContainerInitializer</param-name>
+        <param-value>true</param-value>
+    </context-param>
+
     <listener>
         <!-- Jersey insists on using java.util.logging (JUL) -->
         <listener-class>org.killbill.commons.skeleton.listeners.JULServletContextListener</listener-class>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
index 1506cc6..8bd3e49 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCatalog.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * 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
@@ -27,7 +27,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.catalog.api.BillingPeriod;
-import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.catalog.api.TimeUnit;
@@ -41,7 +40,6 @@ import org.killbill.billing.client.model.Product;
 import org.killbill.billing.client.model.SimplePlan;
 import org.killbill.billing.client.model.Tenant;
 import org.killbill.billing.client.model.Usage;
-import org.killbill.billing.jaxrs.json.AdminPaymentJson;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -153,12 +151,12 @@ public class TestCatalog extends TestJaxrsBase {
         Assert.assertEquals(foundBasePlans, allBasePlans);
     }
 
-    @Test(groups = "slow", description = "Try to retrieve a json version of the catalog with an invalid date",
-            expectedExceptions = KillBillClientException.class,
-            expectedExceptionsMessageRegExp = "There is no catalog version that applies for the given date.*")
+    @Test(groups = "slow", description = "Try to retrieve a json version of the catalog with an invalid date")
     public void testCatalogInvalidDate() throws Exception {
         final List<Catalog> catalogsJson = killBillClient.getJSONCatalog(DateTime.parse("2008-01-01"), requestOptions);
-        Assert.fail();
+        Assert.assertEquals(catalogsJson.size(), 1);
+        // Return the oldest catalog
+        Assert.assertEquals(catalogsJson.get(0).getEffectiveDate().compareTo(new DateTime(2011, 1, 1, 0, 0).toDate()), 0);
     }
 
     @Test(groups = "slow", description = "Can create a simple Plan into a per-tenant catalog")
diff --git a/profiles/killpay/src/main/webapp/WEB-INF/web.xml b/profiles/killpay/src/main/webapp/WEB-INF/web.xml
index 61f297d..e73a20c 100644
--- a/profiles/killpay/src/main/webapp/WEB-INF/web.xml
+++ b/profiles/killpay/src/main/webapp/WEB-INF/web.xml
@@ -52,6 +52,13 @@
         <filter-name>guiceFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
+
+    <context-param>
+        <!-- We want to make sure the Logback shutdown happens last -->
+        <param-name>logbackDisableServletContainerInitializer</param-name>
+        <param-value>true</param-value>
+    </context-param>
+
     <listener>
         <!-- Jersey insists on using java.util.logging (JUL) -->
         <listener-class>org.killbill.commons.skeleton.listeners.JULServletContextListener</listener-class>