killbill-aplcache

server: switch to killbill-skeleton This also upgrades

3/8/2014 5:13:45 PM

Details

server/pom.xml 45(+32 -13)

diff --git a/server/pom.xml b/server/pom.xml
index 41fece4..022cbf3 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -41,10 +41,30 @@
             <scope>runtime</scope>
         </dependency>
         <dependency>
+            <groupId>com.codahale.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.codahale.metrics</groupId>
+            <artifactId>metrics-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.codahale.metrics</groupId>
+            <artifactId>metrics-jersey</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.codahale.metrics</groupId>
+            <artifactId>metrics-servlet</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.dmurph</groupId>
             <artifactId>JGoogleAnalyticsTracker</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <scope>compile</scope>
@@ -70,24 +90,20 @@
             <artifactId>h2</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ning</groupId>
-            <artifactId>async-http-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.ning.jetty</groupId>
-            <artifactId>ning-service-skeleton-base</artifactId>
+            <groupId>com.mchange</groupId>
+            <artifactId>c3p0</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.ning.jetty</groupId>
-            <artifactId>ning-service-skeleton-jdbi</artifactId>
+            <groupId>com.ning</groupId>
+            <artifactId>async-http-client</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.yammer.metrics</groupId>
-            <artifactId>metrics-core</artifactId>
+            <groupId>com.palominolabs.metrics</groupId>
+            <artifactId>metrics-guice</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.yammer.metrics</groupId>
-            <artifactId>metrics-guice</artifactId>
+            <groupId>com.sun.jersey.contribs</groupId>
+            <artifactId>jersey-guice</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
@@ -255,6 +271,10 @@
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-skeleton</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
@@ -281,7 +301,6 @@
         <dependency>
             <groupId>org.weakref</groupId>
             <artifactId>jmxutils</artifactId>
-            <version>1.12</version>
         </dependency>
     </dependencies>
     <build>
diff --git a/server/src/main/java/org/killbill/billing/server/config/DaoConfig.java b/server/src/main/java/org/killbill/billing/server/config/DaoConfig.java
new file mode 100644
index 0000000..5aa4234
--- /dev/null
+++ b/server/src/main/java/org/killbill/billing/server/config/DaoConfig.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010-2014 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 org.killbill.billing.server.config;
+
+import org.killbill.billing.server.modules.DataSourceConnectionPoolingType;
+import org.killbill.billing.util.config.KillbillConfig;
+import org.killbill.commons.jdbi.log.LogLevel;
+import org.skife.config.Config;
+import org.skife.config.Default;
+import org.skife.config.Description;
+import org.skife.config.TimeSpan;
+
+public interface DaoConfig extends KillbillConfig {
+
+    @Description("The jdbc url for the database")
+    @Config("org.killbill.dao.url")
+    @Default("jdbc:mysql://127.0.0.1:3306/killbill")
+    String getJdbcUrl();
+
+    @Description("The jdbc user name for the database")
+    @Config("org.killbill.dao.user")
+    @Default("killbill")
+    String getUsername();
+
+    @Description("The jdbc password for the database")
+    @Config("org.killbill.dao.password")
+    @Default("killbill")
+    String getPassword();
+
+    @Description("The minimum allowed number of idle connections to the database")
+    @Config("org.killbill.dao.minIdle")
+    @Default("1")
+    int getMinIdle();
+
+    @Description("The maximum allowed number of active connections to the database")
+    @Config("org.killbill.dao.maxActive")
+    @Default("30")
+    int getMaxActive();
+
+    @Description("How long to wait before a connection attempt to the database is considered timed out")
+    @Config("org.killbill.dao.connectionTimeout")
+    @Default("10s")
+    TimeSpan getConnectionTimeout();
+
+    @Description("The time for a connection to remain unused before it is closed off")
+    @Config("org.killbill.dao.idleMaxAge")
+    @Default("60m")
+    TimeSpan getIdleMaxAge();
+
+    @Description("Any connections older than this setting will be closed off whether it is idle or not. Connections " +
+                 "currently in use will not be affected until they are returned to the pool")
+    @Config("org.killbill.dao.maxConnectionAge")
+    @Default("0m")
+    TimeSpan getMaxConnectionAge();
+
+    @Description("Time for a connection to remain idle before sending a test query to the DB")
+    @Config("org.killbill.dao.idleConnectionTestPeriod")
+    @Default("5m")
+    TimeSpan getIdleConnectionTestPeriod();
+
+    @Description("Log level for SQL queries")
+    @Config("org.killbill.dao.logLevel")
+    @Default("WARN")
+    LogLevel getLogLevel();
+
+    @Description("The TransactionHandler to use for all Handle instances")
+    @Config("org.killbill.dao.transactionHandler")
+    @Default("com.ning.billing.commons.jdbi.transaction.RestartTransactionRunner")
+    String getTransactionHandlerClass();
+
+    @Description("Connection pooling type")
+    @Config("org.killbill.dao.poolingType")
+    @Default("C3P0")
+    DataSourceConnectionPoolingType getConnectionPoolingType();
+}
diff --git a/server/src/main/java/org/killbill/billing/server/healthchecks/KillbillHealthcheck.java b/server/src/main/java/org/killbill/billing/server/healthchecks/KillbillHealthcheck.java
index c4db0f9..5bcdf87 100644
--- a/server/src/main/java/org/killbill/billing/server/healthchecks/KillbillHealthcheck.java
+++ b/server/src/main/java/org/killbill/billing/server/healthchecks/KillbillHealthcheck.java
@@ -13,23 +13,21 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package org.killbill.billing.server.healthchecks;
 
 import org.weakref.jmx.Managed;
 
-import com.yammer.metrics.core.HealthCheck;
+import com.codahale.metrics.health.HealthCheck;
 
 public class KillbillHealthcheck extends HealthCheck {
-    public KillbillHealthcheck() {
-        super(KillbillHealthcheck.class.getSimpleName());
-    }
 
     @Override
     public Result check() {
         try {
             // STEPH obviously needs more than that
             return Result.healthy();
-        } catch (Exception e) {
+        } catch (final Exception e) {
             return Result.unhealthy(e);
         }
     }
diff --git a/server/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
index dc5b4a9..d44184d 100644
--- a/server/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
@@ -22,30 +22,39 @@ import javax.management.MBeanServer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 
-import org.skife.config.ConfigurationObjectFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.killbill.billing.beatrix.lifecycle.DefaultLifecycle;
-import org.killbill.bus.api.PersistentBus;
 import org.killbill.billing.jaxrs.resources.JaxRsResourceBase;
 import org.killbill.billing.jaxrs.util.KillbillEventHandler;
-import org.killbill.notificationq.api.NotificationQueueService;
 import org.killbill.billing.server.config.KillbillServerConfig;
 import org.killbill.billing.server.healthchecks.KillbillHealthcheck;
 import org.killbill.billing.server.modules.KillbillServerModule;
 import org.killbill.billing.server.security.TenantFilter;
+import org.killbill.billing.util.jackson.ObjectMapper;
 import org.killbill.billing.util.svcsapi.bus.BusService;
-import com.ning.jetty.base.modules.ServerModuleBuilder;
-import com.ning.jetty.core.listeners.SetupServer;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.commons.skeleton.listeners.GuiceServletContextListener;
+import org.killbill.commons.skeleton.modules.BaseServerModuleBuilder;
+import org.killbill.commons.skeleton.modules.ConfigModule;
+import org.killbill.commons.skeleton.modules.JMXModule;
+import org.killbill.commons.skeleton.modules.JaxrsJacksonModule;
+import org.killbill.commons.skeleton.modules.StatsModule;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.skife.config.ConfigurationObjectFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.servlets.HealthCheckServlet;
+import com.codahale.metrics.servlets.MetricsServlet;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.management.ManagementService;
 
-public class KillbillGuiceListener extends SetupServer {
+public class KillbillGuiceListener extends GuiceServletContextListener {
 
     public static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
 
@@ -70,24 +79,22 @@ public class KillbillGuiceListener extends SetupServer {
     public void contextInitialized(final ServletContextEvent event) {
         config = new ConfigurationObjectFactory(System.getProperties()).build(KillbillServerConfig.class);
 
-        final ServerModuleBuilder builder = new ServerModuleBuilder()
-                .addConfig(KillbillServerConfig.class)
-                .addHealthCheck(KillbillHealthcheck.class)
-                .addJMXExport(KillbillHealthcheck.class)
-                .addJMXExport(NotificationQueueService.class)
-                .addJMXExport(PersistentBus.class)
-                .addModule(getModule(event.getServletContext()))
-                        // Don't filter all requests through Jersey, only the JAX-RS APIs (otherwise,
-                        // things like static resources, favicon, etc. are 404'ed)
-                .setJerseyUriPattern("(" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*")
-                .addJerseyResource("org.killbill.billing.jaxrs.mappers")
-                .addJerseyResource("org.killbill.billing.jaxrs.resources");
+        // Don't filter all requests through Jersey, only the JAX-RS APIs (otherwise,
+        // things like static resources, favicon, etc. are 404'ed)
+        final BaseServerModuleBuilder builder = new BaseServerModuleBuilder().setJaxrsUriPattern("(" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*")
+                                                                             .addJaxrsResource("com.ning.billing.jaxrs.mappers")
+                                                                             .addJaxrsResource("com.ning.billing.jaxrs.resources");
 
         if (config.isMultiTenancyEnabled()) {
             builder.addFilter("/*", TenantFilter.class);
         }
 
-        guiceModule = builder.build();
+        guiceModules = ImmutableList.<Module>of(builder.build(),
+                                                new ConfigModule(KillbillServerConfig.class),
+                                                new JaxrsJacksonModule(new ObjectMapper()),
+                                                new JMXModule(KillbillHealthcheck.class, NotificationQueueService.class, PersistentBus.class),
+                                                new StatsModule(KillbillHealthcheck.class),
+                                                getModule(event.getServletContext()));
 
         super.contextInitialized(event);
 
@@ -96,17 +103,16 @@ public class KillbillGuiceListener extends SetupServer {
         injector = injector(event);
         event.getServletContext().setAttribute(Injector.class.getName(), injector);
 
+        // Metrics initialization
+        event.getServletContext().setAttribute(HealthCheckServlet.HEALTH_CHECK_REGISTRY, injector.getInstance(HealthCheckRegistry.class));
+        event.getServletContext().setAttribute(MetricsServlet.METRICS_REGISTRY, injector.getInstance(MetricRegistry.class));
+
         killbillLifecycle = injector.getInstance(DefaultLifecycle.class);
         killbillBusService = injector.getInstance(BusService.class);
         killbilleventHandler = injector.getInstance(KillbillEventHandler.class);
 
         registerMBeansForCache(injector.getInstance(CacheManager.class));
 
-        /*
-                ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
-                mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
-        */
-
         //
         // Fire all Startup levels up to service start
         //
diff --git a/server/src/main/java/org/killbill/billing/server/modules/DataSourceConnectionPoolingType.java b/server/src/main/java/org/killbill/billing/server/modules/DataSourceConnectionPoolingType.java
new file mode 100644
index 0000000..c152448
--- /dev/null
+++ b/server/src/main/java/org/killbill/billing/server/modules/DataSourceConnectionPoolingType.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2014 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 org.killbill.billing.server.modules;
+
+public enum DataSourceConnectionPoolingType {
+    C3P0,
+    BONECP
+}
diff --git a/server/src/main/java/org/killbill/billing/server/modules/DataSourceProvider.java b/server/src/main/java/org/killbill/billing/server/modules/DataSourceProvider.java
index c30a3fa..9f4d3ad 100644
--- a/server/src/main/java/org/killbill/billing/server/modules/DataSourceProvider.java
+++ b/server/src/main/java/org/killbill/billing/server/modules/DataSourceProvider.java
@@ -22,10 +22,9 @@ import javax.inject.Inject;
 import javax.inject.Provider;
 import javax.sql.DataSource;
 
+import org.killbill.billing.server.config.DaoConfig;
 import org.skife.config.TimeSpan;
 
-import com.ning.jetty.jdbi.config.DaoConfig;
-
 import com.jolbox.bonecp.BoneCPConfig;
 import com.jolbox.bonecp.BoneCPDataSource;
 import com.mchange.v2.c3p0.ComboPooledDataSource;
@@ -47,14 +46,12 @@ public class DataSourceProvider implements Provider<DataSource> {
     private DataSource getDataSource() {
         final DataSource ds;
 
-        // TODO PIERRE DaoConfig is in the skeleton
-        final String dataSource = System.getProperty("com.ning.jetty.jdbi.datasource", "c3p0");
-        if (dataSource.equals("c3p0")) {
+        if (DataSourceConnectionPoolingType.C3P0.equals(config.getConnectionPoolingType())) {
             ds = getC3P0DataSource();
-        } else if (dataSource.equals("bonecp")) {
+        } else if (DataSourceConnectionPoolingType.BONECP.equals(config.getConnectionPoolingType())) {
             ds = getBoneCPDatSource();
         } else {
-            throw new IllegalArgumentException("DataSource " + dataSource + " unsupported");
+            throw new IllegalArgumentException("DataSource " + config.getConnectionPoolingType() + " unsupported");
         }
 
         return ds;
diff --git a/server/src/main/java/org/killbill/billing/server/modules/DBIProvider.java b/server/src/main/java/org/killbill/billing/server/modules/DBIProvider.java
index bdd6a47..96a81df 100644
--- a/server/src/main/java/org/killbill/billing/server/modules/DBIProvider.java
+++ b/server/src/main/java/org/killbill/billing/server/modules/DBIProvider.java
@@ -16,17 +16,9 @@
 
 package org.killbill.billing.server.modules;
 
-import java.util.concurrent.TimeUnit;
-
 import javax.sql.DataSource;
 
-import org.skife.jdbi.v2.DBI;
-import org.skife.jdbi.v2.TimingCollector;
-import org.skife.jdbi.v2.tweak.SQLLog;
-import org.skife.jdbi.v2.tweak.TransactionHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import org.killbill.billing.server.config.DaoConfig;
 import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
 import org.killbill.billing.util.dao.DateTimeArgumentFactory;
 import org.killbill.billing.util.dao.DateTimeZoneArgumentFactory;
@@ -35,25 +27,30 @@ import org.killbill.billing.util.dao.LocalDateArgumentFactory;
 import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
 import org.killbill.billing.util.dao.UUIDArgumentFactory;
 import org.killbill.billing.util.dao.UuidMapper;
-import com.ning.jetty.jdbi.config.DaoConfig;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.TimingCollector;
+import org.skife.jdbi.v2.tweak.SQLLog;
+import org.skife.jdbi.v2.tweak.TransactionHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.jdbi.InstrumentedTimingCollector;
+import com.codahale.metrics.jdbi.strategies.BasicSqlNameStrategy;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-import com.yammer.metrics.core.MetricsRegistry;
-import com.yammer.metrics.jdbi.InstrumentedTimingCollector;
-import com.yammer.metrics.jdbi.strategies.BasicSqlNameStrategy;
 
 public class DBIProvider implements Provider<DBI> {
 
     private static final Logger logger = LoggerFactory.getLogger(DBIProvider.class);
 
     private final DataSource ds;
-    private final MetricsRegistry metricsRegistry;
+    private final MetricRegistry metricsRegistry;
     private final DaoConfig config;
     private SQLLog sqlLog;
 
     @Inject
-    public DBIProvider(final DataSource ds, final MetricsRegistry metricsRegistry, final DaoConfig config) {
+    public DBIProvider(final DataSource ds, final MetricRegistry metricsRegistry, final DaoConfig config) {
         this.ds = ds;
         this.metricsRegistry = metricsRegistry;
         this.config = config;
@@ -90,7 +87,7 @@ public class DBIProvider implements Provider<DBI> {
         }
 
         final BasicSqlNameStrategy basicSqlNameStrategy = new BasicSqlNameStrategy();
-        final TimingCollector timingCollector = new InstrumentedTimingCollector(metricsRegistry, basicSqlNameStrategy, TimeUnit.MILLISECONDS, TimeUnit.SECONDS);
+        final TimingCollector timingCollector = new InstrumentedTimingCollector(metricsRegistry, basicSqlNameStrategy);
         dbi.setTimingCollector(timingCollector);
 
         return dbi;
diff --git a/server/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/server/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index b0bc293..5bd75a2 100644
--- a/server/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -150,7 +150,6 @@ public class KillbillServerModule extends AbstractModule {
         install(new CustomFieldModule());
         install(new AuditModule());
         install(new CatalogModule(configSource));
-        install(new MetricsModule());
         install(new BusModule(configSource));
         install(new NotificationQueueModule(configSource));
         install(new CallContextModule());
diff --git a/server/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java b/server/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
index 3590cff..406f580 100644
--- a/server/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
+++ b/server/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
@@ -23,10 +23,9 @@ import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.codec.Base64;
 import org.apache.shiro.realm.jdbc.JdbcRealm;
 import org.apache.shiro.util.ByteSource;
-import org.skife.config.ConfigurationObjectFactory;
-
+import org.killbill.billing.server.config.DaoConfig;
 import org.killbill.billing.tenant.security.KillbillCredentialsMatcher;
-import com.ning.jetty.jdbi.config.DaoConfig;
+import org.skife.config.ConfigurationObjectFactory;
 
 import com.jolbox.bonecp.BoneCPConfig;
 import com.jolbox.bonecp.BoneCPDataSource;
diff --git a/server/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
index c84fd03..600a728 100644
--- a/server/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
@@ -29,31 +29,23 @@ import javax.servlet.ServletContext;
 import org.apache.shiro.web.servlet.ShiroFilter;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.joda.time.LocalDate;
-import org.skife.config.ConfigSource;
-import org.skife.config.ConfigurationObjectFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeSuite;
-
 import org.killbill.billing.DBTestingHelper;
 import org.killbill.billing.GuicyKillbillTestWithEmbeddedDBModule;
 import org.killbill.billing.KillbillConfigSource;
 import org.killbill.billing.account.glue.DefaultAccountModule;
 import org.killbill.billing.api.TestApiListener;
 import org.killbill.billing.beatrix.glue.BeatrixModule;
-import org.killbill.bus.api.PersistentBus;
 import org.killbill.billing.catalog.glue.CatalogModule;
 import org.killbill.billing.client.KillBillClient;
 import org.killbill.billing.client.KillBillHttpClient;
 import org.killbill.billing.client.model.Tenant;
-import org.killbill.commons.embeddeddb.EmbeddedDB;
 import org.killbill.billing.currency.glue.CurrencyModule;
 import org.killbill.billing.entitlement.glue.DefaultEntitlementModule;
 import org.killbill.billing.invoice.api.InvoiceNotifier;
 import org.killbill.billing.invoice.glue.DefaultInvoiceModule;
 import org.killbill.billing.invoice.notification.NullInvoiceNotifier;
+import org.killbill.billing.jetty.HttpServer;
+import org.killbill.billing.jetty.HttpServerConfig;
 import org.killbill.billing.junction.glue.DefaultJunctionModule;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.osgi.glue.DefaultOSGIModule;
@@ -84,8 +76,15 @@ import org.killbill.billing.util.glue.NotificationQueueModule;
 import org.killbill.billing.util.glue.RecordIdModule;
 import org.killbill.billing.util.glue.SecurityModule;
 import org.killbill.billing.util.glue.TagStoreModule;
-import com.ning.jetty.core.CoreConfig;
-import com.ning.jetty.core.server.HttpServer;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.commons.embeddeddb.EmbeddedDB;
+import org.skife.config.ConfigSource;
+import org.skife.config.ConfigurationObjectFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -114,7 +113,7 @@ public class TestJaxrsBase extends KillbillClient {
 
     protected static TestKillbillGuiceListener listener;
 
-    protected CoreConfig config;
+    protected HttpServerConfig config;
     private HttpServer server;
 
     public static void loadSystemPropertiesFromClasspath(final String resource) {
@@ -207,7 +206,6 @@ public class TestJaxrsBase extends KillbillClient {
             install(new TagStoreModule());
             install(new AuditModule());
             install(new CatalogModule(configSource));
-            install(new MetricsModule());
             install(new BusModule(configSource));
             install(new NotificationQueueModule(configSource));
             install(new CallContextModule());
@@ -297,7 +295,7 @@ public class TestJaxrsBase extends KillbillClient {
 
     protected void loadConfig() {
         if (config == null) {
-            config = new ConfigurationObjectFactory(System.getProperties()).build(CoreConfig.class);
+            config = new ConfigurationObjectFactory(System.getProperties()).build(HttpServerConfig.class);
         }
 
         // For shiro (outside of Guice control)
diff --git a/server/src/test/java/org/killbill/billing/jetty/HttpServer.java b/server/src/test/java/org/killbill/billing/jetty/HttpServer.java
new file mode 100644
index 0000000..86a8813
--- /dev/null
+++ b/server/src/test/java/org/killbill/billing/jetty/HttpServer.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2010-2014 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 org.killbill.billing.jetty;
+
+import java.lang.management.ManagementFactory;
+import java.util.EnumSet;
+import java.util.EventListener;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.management.MBeanServer;
+import javax.servlet.DispatcherType;
+
+import org.eclipse.jetty.jmx.MBeanContainer;
+import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.xml.XmlConfiguration;
+import org.killbill.commons.skeleton.listeners.JULServletContextListener;
+
+import com.google.common.base.Preconditions;
+import com.google.common.io.Resources;
+import com.google.inject.servlet.GuiceFilter;
+
+/**
+ * Embed Jetty
+ */
+public class HttpServer {
+
+    private final Server server;
+
+    public HttpServer() {
+        this.server = new Server();
+        server.setSendServerVersion(false);
+    }
+
+    public HttpServer(final String jettyXml) throws Exception {
+        this();
+        configure(jettyXml);
+    }
+
+    public void configure(final String jettyXml) throws Exception {
+        final XmlConfiguration configuration = new XmlConfiguration(Resources.getResource(jettyXml));
+        configuration.configure(server);
+    }
+
+    public void configure(final HttpServerConfig config, final Iterable<EventListener> eventListeners, final Map<FilterHolder, String> filterHolders) {
+        server.setStopAtShutdown(true);
+
+        // Setup JMX
+        configureJMX(ManagementFactory.getPlatformMBeanServer());
+
+        // Configure main connector
+        configureMainConnector(config.isJettyStatsOn(), config.getServerHost(), config.getServerPort());
+
+        // Configure SSL, if enabled
+        if (config.isSSLEnabled()) {
+            configureSslConnector(config.isJettyStatsOn(), config.getServerSslPort(), config.getSSLkeystoreLocation(), config.getSSLkeystorePassword());
+        }
+
+        // Configure the thread pool
+        configureThreadPool(config);
+
+        // Configure handlers
+        final HandlerCollection handlers = new HandlerCollection();
+        final ServletContextHandler servletContextHandler = createServletContextHandler(config.getResourceBase(), eventListeners, filterHolders);
+        handlers.addHandler(servletContextHandler);
+        final RequestLogHandler logHandler = createLogHandler(config);
+        handlers.addHandler(logHandler);
+        final HandlerList rootHandlers = new HandlerList();
+        rootHandlers.addHandler(handlers);
+        server.setHandler(rootHandlers);
+    }
+
+    @PostConstruct
+    public void start() throws Exception {
+        server.start();
+        Preconditions.checkState(server.isRunning(), "server is not running");
+    }
+
+    @PreDestroy
+    public void stop() throws Exception {
+        server.stop();
+    }
+
+    private void configureJMX(final MBeanServer mbeanServer) {
+        final MBeanContainer mbContainer = new MBeanContainer(mbeanServer);
+        mbContainer.addBean(Log.getLogger(HttpServer.class));
+        server.addBean(mbContainer);
+    }
+
+    private void configureMainConnector(final boolean isStatsOn, final String localIp, final int localPort) {
+        final SelectChannelConnector connector = new SelectChannelConnector();
+        connector.setName("http");
+        connector.setStatsOn(isStatsOn);
+        connector.setHost(localIp);
+        connector.setPort(localPort);
+        server.addConnector(connector);
+    }
+
+    private void configureSslConnector(final boolean isStatsOn, final int localSslPort, final String sslKeyStorePath, final String sslKeyStorePassword) {
+        final SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
+        sslConnector.setName("https");
+        sslConnector.setStatsOn(isStatsOn);
+        sslConnector.setPort(localSslPort);
+        final SslContextFactory sslContextFactory = sslConnector.getSslContextFactory();
+        sslContextFactory.setKeyStorePath(sslKeyStorePath);
+        sslContextFactory.setKeyStorePassword(sslKeyStorePassword);
+        server.addConnector(sslConnector);
+    }
+
+    private void configureThreadPool(final HttpServerConfig config) {
+        final QueuedThreadPool threadPool = new QueuedThreadPool(config.getMaxThreads());
+        threadPool.setMinThreads(config.getMinThreads());
+        threadPool.setName("http-worker");
+        server.setThreadPool(threadPool);
+    }
+
+    private ServletContextHandler createServletContextHandler(final String resourceBase, final Iterable<EventListener> eventListeners, final Map<FilterHolder, String> filterHolders) {
+        final ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.NO_SESSIONS);
+        context.setContextPath("/");
+
+        if (resourceBase != null) {
+            // Required if you want a webapp directory. See ContextHandler#getResource and http://docs.codehaus.org/display/JETTY/Embedding+Jetty
+            final String webapp = this.getClass().getClassLoader().getResource(resourceBase).toExternalForm();
+            context.setResourceBase(webapp);
+        }
+
+        // Jersey insists on using java.util.logging (JUL)
+        final EventListener listener = new JULServletContextListener();
+        context.addEventListener(listener);
+
+        for (final EventListener eventListener : eventListeners) {
+            context.addEventListener(eventListener);
+        }
+
+        for (final FilterHolder filterHolder : filterHolders.keySet()) {
+            context.addFilter(filterHolder, filterHolders.get(filterHolder), EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC));
+        }
+
+        // Make sure Guice filter all requests
+        final FilterHolder filterHolder = new FilterHolder(GuiceFilter.class);
+        context.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC));
+
+        // Backend servlet for Guice - never used
+        final ServletHolder sh = new ServletHolder(DefaultServlet.class);
+        context.addServlet(sh, "/*");
+
+        return context;
+    }
+
+    private RequestLogHandler createLogHandler(final HttpServerConfig config) {
+        final RequestLogHandler logHandler = new RequestLogHandler();
+
+        final RequestLog requestLog = new NCSARequestLog(config.getLogPath());
+        logHandler.setRequestLog(requestLog);
+
+        return logHandler;
+    }
+}
diff --git a/server/src/test/java/org/killbill/billing/jetty/HttpServerConfig.java b/server/src/test/java/org/killbill/billing/jetty/HttpServerConfig.java
new file mode 100644
index 0000000..6d0d580
--- /dev/null
+++ b/server/src/test/java/org/killbill/billing/jetty/HttpServerConfig.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2014 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 org.killbill.billing.jetty;
+
+import org.skife.config.Config;
+import org.skife.config.Default;
+import org.skife.config.DefaultNull;
+
+public interface HttpServerConfig {
+
+    @Config("org.killbill.server.ip")
+    @Default("127.0.0.1")
+    String getServerHost();
+
+    @Config("org.killbill.server.port")
+    @Default("8080")
+    int getServerPort();
+
+    @Config("org.killbill.server.server.ssl.enabled")
+    @Default("false")
+    boolean isSSLEnabled();
+
+    @Config("org.killbill.server.server.ssl.port")
+    @Default("8443")
+    int getServerSslPort();
+
+    @Config("org.killbill.server.jetty.stats")
+    @Default("true")
+    boolean isJettyStatsOn();
+
+    @Config("org.killbill.server.jetty.ssl.keystore")
+    @DefaultNull
+    String getSSLkeystoreLocation();
+
+    @Config("org.killbill.server.jetty.ssl.keystore.password")
+    @DefaultNull
+    String getSSLkeystorePassword();
+
+    @Config("org.killbill.server.jetty.maxThreads")
+    @Default("2000")
+    int getMaxThreads();
+
+    @Config("org.killbill.server.jetty.minThreads")
+    @Default("2")
+    int getMinThreads();
+
+    @Config("org.killbill.server.jetty.logPath")
+    @Default(".logs")
+    String getLogPath();
+
+    @Config("org.killbill.server.jetty.resourceBase")
+    @DefaultNull
+    String getResourceBase();
+}

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

diff --git a/util/pom.xml b/util/pom.xml
index ba8f064..50b3ce3 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -73,10 +73,6 @@
             <artifactId>jmustache</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.yammer.metrics</groupId>
-            <artifactId>metrics-core</artifactId>
-        </dependency>
-        <dependency>
             <groupId>javax.inject</groupId>
             <artifactId>javax.inject</artifactId>
             <scope>provided</scope>