killbill-memoizeit

Changes

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index 3d0bad2..f58f601 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -34,7 +34,6 @@ import java.util.List;
 public class AnalyticsListener implements IApiListener
 {
     private static final Logger log = LoggerFactory.getLogger(AnalyticsListener.class);
-
     private final EventDao dao;
     private final IEntitlementUserApi entitlementApi;
     private final IAccountUserApi accountApi;
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestEventDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestEventDao.java
index f27db78..c173ccd 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestEventDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestEventDao.java
@@ -16,8 +16,19 @@
 
 package com.ning.billing.analytics.dao;
 
-import com.ning.billing.analytics.*;
-import com.ning.billing.catalog.api.*;
+import com.ning.billing.analytics.BusinessSubscription;
+import com.ning.billing.analytics.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.MockDuration;
+import com.ning.billing.analytics.MockPhase;
+import com.ning.billing.analytics.MockPlan;
+import com.ning.billing.analytics.MockProduct;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.IPlan;
+import com.ning.billing.catalog.api.IPlanPhase;
+import com.ning.billing.catalog.api.IProduct;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.api.user.ISubscription;
 import org.apache.commons.io.IOUtils;
diff --git a/api/src/main/java/com/ning/billing/config/ICatalogConfig.java b/api/src/main/java/com/ning/billing/config/ICatalogConfig.java
index 88fbefb..29699fe 100644
--- a/api/src/main/java/com/ning/billing/config/ICatalogConfig.java
+++ b/api/src/main/java/com/ning/billing/config/ICatalogConfig.java
@@ -17,10 +17,12 @@
 package com.ning.billing.config;
 
 import org.skife.config.Config;
+import org.skife.config.Default;
 
-public interface ICatalogConfig extends IKillbillConfig {
+public interface ICatalogConfig {
 
     @Config("killbill.catalog.uri")
+    @Default("jar:///com/ning/billing/irs/catalog/NingCatalog.xml")
     String getCatalogURI();
-    
+
 }
diff --git a/api/src/main/java/com/ning/billing/lifecycle/IService.java b/api/src/main/java/com/ning/billing/lifecycle/IService.java
index 83c67db..2e4a27f 100644
--- a/api/src/main/java/com/ning/billing/lifecycle/IService.java
+++ b/api/src/main/java/com/ning/billing/lifecycle/IService.java
@@ -16,9 +16,6 @@
 
 package com.ning.billing.lifecycle;
 
-import com.ning.billing.config.IBusinessConfig;
-import com.ning.billing.config.IKillbillConfig;
-
 public interface IService {
 
     public static class ServiceException extends Exception  {
@@ -44,13 +41,17 @@ public interface IService {
 
     /**
      *
-     * @param businessConfig business configuration
-     * @param killbillConfig service detail configuration
+     * @return the name of the service
+     */
+    public String getName();
+
+    /**
+     *
      * @throws ServiceException
      *
      * Initialize the service prior to start
      */
-    public void initialize(IBusinessConfig businessConfig, IKillbillConfig killbillConfig)
+    public void initialize()
         throws ServiceException;
 
     /**
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
index 342e2b5..6f04aa6 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
@@ -16,62 +16,73 @@
 
 package com.ning.billing.catalog;
 
-import java.net.URI;
-
+import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.ICatalogService;
-import com.ning.billing.config.IBusinessConfig;
 import com.ning.billing.config.ICatalogConfig;
-import com.ning.billing.config.IKillbillConfig;
 import com.ning.billing.lifecycle.IService;
 import com.ning.billing.util.config.XMLLoader;
 
-
 public class CatalogService implements IService, Provider<ICatalog>, ICatalogService {
-	
-	private static ICatalog catalog;
-
-
-	@Override
-	public void initialize(IBusinessConfig businessConfig,
-			IKillbillConfig killbillConfig) throws ServiceException {
-		if(killbillConfig instanceof ICatalogConfig) {
-			ICatalogConfig catalogConfig = (ICatalogConfig) killbillConfig;
-			try {
-				catalog = XMLLoader.getObjectFromURI(new URI(catalogConfig.getCatalogURI()), Catalog.class);
-			} catch (Exception e) {
-				throw new ServiceException(e);
-			}
-		} else {
-			throw new ServiceException("Configuration does not include catalog configuration.");
-		}
-	}
-
-	@Override
-	public void start() throws ServiceException {
-		// Intentionally blank
-		
-	}
-
-	@Override
-	public void stop() throws ServiceException {
-		// Intentionally blank
-		
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.ICatlogService#getCatalog()
-	 */
-	@Override
-	public ICatalog getCatalog() {
-		return catalog;
-	}
-
-	
-	// Should be able to use bind(ICatalog.class).toProvider(CatalogService.class);
-	@Override
-	public ICatalog get() {
-		return catalog;
-	}
+
+    private static final String CATALOG_SERVICE_NAME = "catalog-service";
+
+    private static ICatalog catalog;
+
+    private final ICatalogConfig config;
+    private boolean isInitialized;
+
+
+    @Inject
+    public CatalogService(ICatalogConfig config) {
+        this.config = config;
+        System.out.println(config.getCatalogURI());
+        this.isInitialized = false;
+    }
+
+    @Override
+    public synchronized void initialize() throws ServiceException {
+        if (!isInitialized) {
+            try {
+                catalog = XMLLoader.getObjectFromProperty(config.getCatalogURI(), Catalog.class);
+                isInitialized = true;
+            } catch (Exception e) {
+                throw new ServiceException(e);
+            }
+        }
+    }
+
+    public String getName() {
+        return CATALOG_SERVICE_NAME;
+    }
+
+
+    @Override
+    public void start() throws ServiceException {
+        // Intentionally blank
+
+    }
+
+    @Override
+    public void stop() throws ServiceException {
+        // Intentionally blank
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.ning.billing.catalog.ICatlogService#getCatalog()
+     */
+    @Override
+    public ICatalog getCatalog() {
+        return catalog;
+    }
+
+
+    // Should be able to use bind(ICatalog.class).toProvider(CatalogService.class);
+    @Override
+    public ICatalog get() {
+        return catalog;
+    }
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java b/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
index 88f0a5d..b42d12b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
@@ -26,7 +26,7 @@ public class CatalogUserApi implements ICatalogUserApi {
 
     @Override
     public ICatalog getCatalog(final String catalogName) {
-    	String name = catalogName; 
+    	String name = catalogName;
         try {
             return XMLLoader.getObjectFromURI(new File(name).toURI(), Catalog.class);
         } catch (Exception e) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
index 5777cba..a1528ce 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
@@ -38,7 +38,6 @@ public class BillingApi implements IEntitlementBillingApi {
     private final IClock clock;
     private final IEntitlementDao dao;
 
-    @Inject
     public BillingApi(Engine engine, IClock clock, IEntitlementDao dao) {
         super();
         this.engine = engine;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index e664566..c30e2c1 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -51,21 +51,27 @@ public class EntitlementUserApi implements IEntitlementUserApi {
     private final IEntitlementDao dao;
     private final IPlanAligner planAligner;
 
+    private boolean initialized;
+
     private ICatalog catalog;
-    @Inject
+
     public EntitlementUserApi(Engine engine, IClock clock, IPlanAligner planAligner, IEntitlementDao dao) {
         super();
         this.engine = engine;
         this.clock = clock;
         this.dao = dao;
         this.planAligner = planAligner;
+        this.initialized = false;
 
     }
 
     @Override
-    public void initialize(List<IApiListener> listeners) {
-        this.catalog = engine.getCatalog();
-        engine.registerApiObservers(listeners);
+    public synchronized void initialize(List<IApiListener> listeners) {
+        if (!initialized) {
+            this.catalog = engine.getCatalog();
+            engine.registerApiObservers(listeners);
+            initialized = true;
+        }
     }
 
     @Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
index 437f21c..9389969 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
@@ -19,9 +19,9 @@ package com.ning.billing.entitlement.engine.core;
 import java.util.List;
 
 import com.google.inject.Inject;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class ApiEventProcessor extends ApiEventProcessorBase {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
index b83b0be..cf20530 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
@@ -29,9 +29,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public abstract class ApiEventProcessorBase implements IApiEventProcessor {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
index d0e1b02..0db9538 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
@@ -25,60 +25,75 @@ import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.ICatalogUserApi;
 import com.ning.billing.catalog.api.IPlan;
+import com.ning.billing.config.IEntitlementConfig;
 
-import com.ning.billing.entitlement.IEntitlementSystem;
+import com.ning.billing.entitlement.IEntitlementService;
 import com.ning.billing.entitlement.alignment.IPlanAligner;
 import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
 import com.ning.billing.entitlement.alignment.PlanAligner;
+import com.ning.billing.entitlement.api.billing.BillingApi;
+import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.IApiListener;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
-import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
-public class Engine implements IEventListener, IEntitlementSystem {
+public class Engine implements IEventListener, IEntitlementService {
+
+    private static final String ENTITLEMENT_SERVICE_NAME = "entitlement-service";
 
     private final static Logger log = LoggerFactory.getLogger(Engine.class);
     private static Engine instance = null;
 
     private final IClock clock;
-    private final ICatalog catalog;
+
     private final IEntitlementDao dao;
     private final IApiEventProcessor apiEventProcessor;
-    private final ICatalogUserApi catalogApi;
+    private final ICatalogService catalogService;
     private final IPlanAligner planAligner;
-
+    private final IEntitlementUserApi userApi;
+    private final IEntitlementBillingApi billingApi;
     private List<IApiListener> observers;
+    private ICatalog catalog;
+
 
     @Inject
-    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor, ICatalogUserApi catalogApi,
+    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor, ICatalogService catalogService,
             IPlanAligner planAligner, IEntitlementConfig config) {
         super();
         this.clock = clock;
-        this.catalogApi = catalogApi;
         this.dao = dao;
         this.apiEventProcessor = apiEventProcessor;
         this.planAligner = planAligner;
-        this.catalog = readCatalogFromConfig(config.getCatalogConfigFileName());
+        this.catalogService = catalogService;
         this.observers = null;
+        this.userApi = new EntitlementUserApi(this, clock, planAligner, dao);
+        this.billingApi = new BillingApi(this, clock, dao);
         instance = this;
 
-        // STEPH yack
-        ((PlanAligner) planAligner).init(catalog);
     }
 
     @Override
+    public String getName() {
+        return ENTITLEMENT_SERVICE_NAME;
+    }
+
+
+    @Override
     public void initialize() {
-        // TODO Auto-generated method stub
+        this.catalog = catalogService.getCatalog();
+        // STEPH yack
+        ((PlanAligner) planAligner).init(catalog);
 
     }
 
@@ -92,6 +107,18 @@ public class Engine implements IEventListener, IEntitlementSystem {
         apiEventProcessor.stopNotifications();
     }
 
+    @Override
+    public IEntitlementUserApi getUserApi(List<IApiListener> listeners) {
+        userApi.initialize(listeners);
+        return userApi;
+    }
+
+    @Override
+    public IEntitlementBillingApi getBillingApi() {
+        return billingApi;
+    }
+
+
     public void registerApiObservers(List<IApiListener> observers) {
         this.observers = observers;
     }
@@ -152,10 +179,6 @@ public class Engine implements IEventListener, IEntitlementSystem {
     }
 
 
-    private ICatalog readCatalogFromConfig(String configFile) {
-        return catalogApi.getCatalog(configFile);
-    }
-
     //
     // STEPH would be nice to have those go away..
     //
@@ -181,5 +204,4 @@ public class Engine implements IEventListener, IEntitlementSystem {
         return planAligner;
     }
 
-
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index 8dfc34a..db4e375 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.api.user.ISubscription;
 import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -42,7 +43,6 @@ import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.Hostname;
 import com.ning.billing.util.clock.IClock;
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
index fd27374..6074d94 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
@@ -21,13 +21,10 @@ import org.skife.config.ConfigurationObjectFactory;
 import com.google.inject.AbstractModule;
 import com.ning.billing.catalog.CatalogUserApi;
 import com.ning.billing.catalog.api.ICatalogUserApi;
-import com.ning.billing.entitlement.IEntitlementSystem;
+import com.ning.billing.config.IEntitlementConfig;
+import com.ning.billing.entitlement.IEntitlementService;
 import com.ning.billing.entitlement.alignment.IPlanAligner;
 import com.ning.billing.entitlement.alignment.PlanAligner;
-import com.ning.billing.entitlement.api.billing.BillingApi;
-import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
-import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.engine.core.ApiEventProcessor;
 import com.ning.billing.entitlement.engine.core.Engine;
 import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
@@ -44,10 +41,6 @@ public class EntitlementModule extends AbstractModule {
         bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
     }
 
-    protected void installAccount() {
-//        bind(IAccount.class).to(CatalogUserApi.class);
-    }
-
     protected void installClock() {
         bind(IClock.class).to(Clock.class).asEagerSingleton();
     }
@@ -66,19 +59,11 @@ public class EntitlementModule extends AbstractModule {
     }
 
     protected void installEntitlementCore() {
-        bind(IEntitlementSystem.class).to(Engine.class).asEagerSingleton();
+        bind(IEntitlementService.class).to(Engine.class).asEagerSingleton();
         bind(Engine.class).asEagerSingleton();
         bind(IPlanAligner.class).to(PlanAligner.class).asEagerSingleton();
     }
 
-    protected void installUserApi() {
-        bind(IEntitlementUserApi.class).to(EntitlementUserApi.class).asEagerSingleton();
-    }
-
-    protected void installBillingApi() {
-        bind(IEntitlementBillingApi.class).to(BillingApi.class).asEagerSingleton();
-    }
-
 
     @Override
     protected void configure() {
@@ -88,7 +73,5 @@ public class EntitlementModule extends AbstractModule {
         installApiEventProcessor();
         installEntitlementDao();
         installEntitlementCore();
-        installUserApi();
-        installBillingApi();
     }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
index 0f9806d..13786fb 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
@@ -45,10 +45,12 @@ import com.ning.billing.account.api.IAccount;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.ICatalogUserApi;
 import com.ning.billing.catalog.api.IDuration;
 import com.ning.billing.catalog.api.TimeUnit;
-import com.ning.billing.entitlement.IEntitlementSystem;
+import com.ning.billing.config.IEntitlementConfig;
+import com.ning.billing.entitlement.IEntitlementService;
 import com.ning.billing.entitlement.api.ApiTestListener;
 import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
 import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
@@ -59,7 +61,7 @@ import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
+import com.ning.billing.lifecycle.IService.ServiceException;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.IClock;
 
@@ -69,11 +71,11 @@ public abstract class TestUserApiBase {
 
     protected static final long DAY_IN_MS = (24 * 3600 * 1000);
 
-    protected IEntitlementSystem service;
-    protected Engine engine;
+    protected IEntitlementService entitlementService;
+    //protected Engine engine;
     protected IEntitlementUserApi entitlementApi;
     protected IEntitlementBillingApi billingApi;
-    protected ICatalogUserApi catalogApi;
+    protected ICatalogService catalogService;
     protected IEntitlementConfig config;
     protected IEntitlementDao dao;
     protected ClockMock clock;
@@ -110,20 +112,21 @@ public abstract class TestUserApiBase {
         loadSystemPropertiesFromClasspath("/entitlement.properties");
         final Injector g = getInjector();
 
-        service = g.getInstance(IEntitlementSystem.class);
-        engine = g.getInstance(Engine.class);
-        entitlementApi = g.getInstance(IEntitlementUserApi.class);
-        catalogApi = g.getInstance(ICatalogUserApi.class);
-        billingApi = g.getInstance(IEntitlementBillingApi.class);
+        entitlementService = g.getInstance(IEntitlementService.class);
+        catalogService = g.getInstance(ICatalogService.class);
         config = g.getInstance(IEntitlementConfig.class);
         dao = g.getInstance(IEntitlementDao.class);
         clock = (ClockMock) g.getInstance(IClock.class);
         try {
 
-            service.initialize();
+            catalogService.initialize();
+            entitlementService.initialize();
             init();
         } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
+        } catch (ServiceException e) {
+            e.printStackTrace();
+            Assert.fail(e.getMessage());
         }
     }
 
@@ -133,37 +136,46 @@ public abstract class TestUserApiBase {
         account = getAccount();
         assertNotNull(account);
 
-        catalog = catalogApi.getCatalog(config.getCatalogConfigFileName());
+        catalog = catalogService.getCatalog();
         assertNotNull(catalog);
 
         testListener = new ApiTestListener();
         List<IApiListener> listeners =  new ArrayList<IApiListener>();
         listeners.add(testListener);
-        entitlementApi.initialize(listeners);
+        entitlementApi = entitlementService.getUserApi(listeners);
+        billingApi = entitlementService.getBillingApi();
 
     }
 
     @BeforeMethod(groups={"setup"})
     public void setupTest() {
-        log.warn("\n");
-        log.warn("RESET TEST FRAMEWORK\n\n");
-
-        testListener.reset();
-        clock.resetDeltaFromReality();
-        ((IEntitlementDaoMock) dao).reset();
         try {
-            bundle = entitlementApi.createBundleForAccount(account, "myDefaultBundle");
-        } catch (EntitlementUserApiException e) {
+            log.warn("\n");
+            log.warn("RESET TEST FRAMEWORK\n\n");
+
+            testListener.reset();
+            clock.resetDeltaFromReality();
+            ((IEntitlementDaoMock) dao).reset();
+            try {
+                bundle = entitlementApi.createBundleForAccount(account, "myDefaultBundle");
+            } catch (EntitlementUserApiException e) {
+                Assert.fail(e.getMessage());
+            }
+            assertNotNull(bundle);
+            entitlementService.start();
+        } catch (ServiceException e) {
             Assert.fail(e.getMessage());
         }
-        assertNotNull(bundle);
-        service.start();
     }
 
     @AfterMethod(groups={"setup"})
     public void cleanupTest() {
-        service.stop();
-        log.warn("DONE WITH TEST\n");
+        try {
+            entitlementService.stop();
+            log.warn("DONE WITH TEST\n");
+        } catch (ServiceException e) {
+            Assert.fail(e.getMessage());
+        }
     }
 
     // Glue magic to invoke the real test
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
index 05fe153..896c592 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
@@ -22,6 +22,7 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
 
 public class TestUserApiCancelMemory extends TestUserApiCancel {
@@ -29,7 +30,7 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"fast"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
index 84f11e2..58e8891 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
@@ -21,6 +21,7 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
 
 public class TestUserApiCancelSql extends TestUserApiCancel {
@@ -30,7 +31,7 @@ public class TestUserApiCancelSql extends TestUserApiCancel {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @Test(enabled= true, groups={"stress"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
index 56c1a74..acb5e69 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
@@ -21,13 +21,14 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
 
 public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
index 30ace87..174b85e 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
@@ -21,6 +21,7 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
 
 public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
@@ -29,7 +30,7 @@ public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @Test(enabled= true, groups={"stress"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
index 8ec02d7..1c119f8 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
@@ -21,6 +21,7 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
 
 public class TestUserApiCreateMemory extends TestUserApiCreate {
@@ -28,7 +29,7 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"fast"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
index 58fa52b..328976f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
@@ -21,13 +21,14 @@ import org.testng.annotations.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
+import com.ning.billing.entitlement.glue.CatalogModuleMock;
 import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
 
 public class TestUserApiCreateSql extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"sql"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
index 4089936..38aed83 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
@@ -19,9 +19,9 @@ package com.ning.billing.entitlement.engine.core;
 import java.util.List;
 
 import com.google.inject.Inject;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class ApiEventProcessorMemoryMock extends ApiEventProcessorBase {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
index 143b069..cc574ee 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.api.TimeUnit;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.api.user.ISubscription;
 import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -38,11 +39,8 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
-import com.ning.billing.entitlement.events.phase.IPhaseEvent;
-import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementDaoMemoryMock implements IEntitlementDao, IEntitlementDaoMock {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
index 114021e..24d6bff 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
 import com.google.inject.Inject;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementDaoSqlMock extends EntitlementDao implements IEntitlementDaoMock {
diff --git a/entitlement/src/test/resources/entitlement.properties b/entitlement/src/test/resources/entitlement.properties
index 372ce23..fb7a7c5 100644
--- a/entitlement/src/test/resources/entitlement.properties
+++ b/entitlement/src/test/resources/entitlement.properties
@@ -1,4 +1,4 @@
-killbill.entitlement.catalog.config.file=src/test/resources/testInput.xml
+killbill.catalog.uri=src/test/resources/testInput.xml
 killbill.entitlement.dao.claim.time=60000
 killbill.entitlement.dao.ready.max=1
 killbill.entitlement.engine.notifications.sleep=500
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
index 7bfcf0b..74334e8 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.util.config;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -40,6 +41,18 @@ public class XMLLoader {
 	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
 	public static Logger log = LoggerFactory.getLogger(XMLLoader.class);
 
+	public static <T extends ValidatingConfig<T>> T getObjectFromProperty(String property, Class<T> objectType) throws Exception {
+		if (property == null) {
+			return null;
+		}
+		//TODO: fix this! - yuk!
+		URI uri = (property.startsWith(URI_SCHEME_FOR_CLASSPATH)) ?
+				new URI(property) :
+					new File("src/test/resources/testInput.xml").toURI();
+				return getObjectFromURI(uri, objectType);
+	}
+
+	
 	public static <T extends ValidatingConfig<T>> T getObjectFromURI(URI uri, Class<T> objectType) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
         String scheme = uri.getScheme();
         if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {