killbill-memoizeit

Revamp og killbill lifecycle

11/9/2011 9:47:25 PM

Changes

Details

diff --git a/account/src/main/java/com/ning/billing/account/api/AccountService.java b/account/src/main/java/com/ning/billing/account/api/AccountService.java
new file mode 100644
index 0000000..0ce4941
--- /dev/null
+++ b/account/src/main/java/com/ning/billing/account/api/AccountService.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2011 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.account.api;
+
+import com.google.inject.Inject;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
+
+public class AccountService implements IAccountService {
+
+    private static final String ACCOUNT_SERVICE_NAME = "account-service";
+
+    private final IAccountUserApi accountApi;
+
+    @Inject
+    public AccountService(IAccountUserApi api) {
+        this.accountApi = api;
+    }
+
+    @Override
+    public String getName() {
+        return ACCOUNT_SERVICE_NAME;
+    }
+
+    @Override
+    public IAccountUserApi getAccountUserApi() {
+        return accountApi;
+    }
+
+    @LyfecycleHandlerType(LyfecycleLevel.INIT_SERVICE)
+    public void initialize() {
+    }
+}
diff --git a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
index 4f0ec7a..ce44014 100644
--- a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
+++ b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
@@ -19,7 +19,9 @@ package com.ning.billing.account.glue;
 import org.skife.config.ConfigurationObjectFactory;
 
 import com.google.inject.AbstractModule;
+import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.IAccountService;
 import com.ning.billing.account.api.IAccountUserApi;
 import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.account.dao.IAccountDao;
@@ -39,11 +41,16 @@ public class AccountModule extends AbstractModule {
         bind(IAccountUserApi.class).to(AccountUserApi.class).asEagerSingleton();
     }
 
+    protected void installAcountService() {
+        bind(IAccountService.class).to(AccountService.class).asEagerSingleton();
+    }
+
     @Override
     protected void configure() {
         installConfig();
         installAccountDao();
         installAccountUserApi();
+        installAcountService();
     }
 
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/IAccountService.java b/api/src/main/java/com/ning/billing/account/api/IAccountService.java
new file mode 100644
index 0000000..fa5a9fe
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/account/api/IAccountService.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010-2011 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.account.api;
+
+import com.ning.billing.lifecycle.IService;
+
+public interface IAccountService extends IService {
+
+    public IAccountUserApi getAccountUserApi();
+}
diff --git a/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java b/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java
index aa0a1ba..520fca4 100644
--- a/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java
+++ b/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java
@@ -26,14 +26,65 @@ import java.lang.annotation.Target;
 public @interface LyfecycleHandlerType {
 
 
+    //
+    // The level themselves are still work in progress depending on what we really need
+    //
     public enum LyfecycleLevel {
-        LOAD_CATALOG,
-        INIT_BUS,
-        REGISTER_EVENTS,
-        START_SERVICE,
-        STOP_SERVICE,
-        UNREGISTER_EVENTS,
-        SHUTDOWN
+
+        /**
+         * Load and validate catalog (only for catalog subsytem)
+         */
+        LOAD_CATALOG(Sequence.STARTUP),
+        /**
+         * Initialize event bus (only for the event bus)
+         */
+        INIT_BUS(Sequence.STARTUP),
+        /**
+         * Service specific initalization
+         */
+        INIT_SERVICE(Sequence.STARTUP),
+        /**
+         * Service register their interest in events
+         */
+        REGISTER_EVENTS(Sequence.STARTUP),
+        /**
+         * Service start
+         * - API call should not work
+         * - Events might be triggered
+         * - Batch processing jobs started
+         */
+        START_SERVICE(Sequence.STARTUP),
+        /**
+         * Stop service
+         */
+        STOP_SERVICE(Sequence.SHUTOWN),
+        /**
+         * Unregister interest in events
+         */
+        UNREGISTER_EVENTS(Sequence.SHUTOWN),
+        /**
+         * Stop bus
+         */
+        STOP_BUS(Sequence.SHUTOWN),
+        /**
+         * Any service specific shutdown action before the end
+         */
+        SHUTDOWN(Sequence.SHUTOWN);
+
+        public enum Sequence {
+            STARTUP,
+            SHUTOWN
+        };
+
+        private Sequence seq;
+
+        LyfecycleLevel(Sequence seq) {
+            this.seq = seq;
+        }
+
+        public Sequence getSequence() {
+            return seq;
+        }
     }
 
     public LyfecycleLevel value();
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
index ca8e994..3f13baf 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
@@ -40,12 +40,13 @@ import com.google.inject.Injector;
 import com.ning.billing.lifecycle.IService;
 import com.ning.billing.lifecycle.LyfecycleHandlerType;
 import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel.Sequence;
 
 
 public class Lifecycle {
 
     private final static Logger log = LoggerFactory.getLogger(Lifecycle.class);
-    private final SetMultimap<LyfecycleLevel, LifecycleHandler> handlersByLevel;
+    private final SetMultimap<LyfecycleLevel, LifecycleHandler<? extends IService>> handlersByLevel;
 
     private final ServiceFinder serviceFinder;
 
@@ -55,14 +56,14 @@ public class Lifecycle {
     public Lifecycle(Injector injector) {
 
         this.serviceFinder = new ServiceFinder(Lifecycle.class.getClassLoader());
-        this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LyfecycleLevel, Collection<LifecycleHandler>>(),
-
-                new Supplier<Set<LifecycleHandler>>() {
-                  @Override
-                  public Set<LifecycleHandler> get() {
-                    return new CopyOnWriteArraySet<LifecycleHandler>();
-                  }
-                });
+        this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LyfecycleLevel, Collection<LifecycleHandler<? extends IService>>>(),
+
+                new Supplier<Set<LifecycleHandler<? extends IService>>>() {
+            @Override
+            public Set<LifecycleHandler<? extends IService>> get() {
+                return new CopyOnWriteArraySet<LifecycleHandler<? extends IService>>();
+            }
+        });
         this.injector = injector;
     }
 
@@ -74,23 +75,41 @@ public class Lifecycle {
         }
     }
 
-    public void fireStages() {
+    public void fireStartupSequence() {
+        for (LyfecycleLevel level : LyfecycleLevel.values()) {
+            if (level.getSequence() == Sequence.SHUTOWN) {
+                break;
+            }
+            doFireStage(level);
+        }
+    }
+
+    public void fireShutdownSequence() {
         for (LyfecycleLevel level : LyfecycleLevel.values()) {
-            log.info("Firing stage {}", level);
-            Set<LifecycleHandler> handlers = handlersByLevel.get(level);
-            for (LifecycleHandler cur : handlers) {
-                log.debug("Calling handler {}", cur.getMethod().getName());
-                try {
-                    Method method = cur.getMethod();
-                    Object target = cur.getTarget();
-                    method.invoke(target);
-                } catch (Exception e) {
-                    log.warn("Failed to invoke lifecycle handler", e);
-                }
+            if (level.getSequence() == Sequence.STARTUP) {
+                continue;
             }
+            doFireStage(level);
         }
     }
 
+    private void doFireStage(LyfecycleLevel level) {
+        log.info("Killbill lifecycle firing stage {}", level);
+        Set<LifecycleHandler<? extends IService>> handlers = handlersByLevel.get(level);
+        for (LifecycleHandler<? extends IService> cur : handlers) {
+
+            try {
+                Method method = cur.getMethod();
+                IService target = cur.getTarget();
+                log.debug("Killbill lifecycle calling handler {} for service {}", cur.getMethod().getName(), target.getName());
+                method.invoke(target);
+            } catch (Exception e) {
+                log.warn("Killbill lifecycle failed to invoke lifecycle handler", e);
+            }
+        }
+
+    }
+
     private Set<? extends IService> findServices() {
 
         Set<IService> result = new TreeSet<IService>();
@@ -98,7 +117,6 @@ public class Lifecycle {
         for (Class<? extends IService> cur : services) {
             log.debug("Found service {}", cur);
             try {
-                IService service = injector.getInstance(cur);
                 result.add(injector.getInstance(cur));
             } catch (Exception e) {
                 log.warn("Failed to inject {}", cur.getName());
@@ -109,15 +127,15 @@ public class Lifecycle {
     }
 
 
-    public Multimap<LyfecycleLevel, LifecycleHandler> findAllHandlers(IService service) {
-        Multimap<LyfecycleLevel, LifecycleHandler> methodsInService =
+    public Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> findAllHandlers(IService service) {
+        Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> methodsInService =
             HashMultimap.create();
         Class<? extends IService> clazz = service.getClass();
         for (Method method : clazz.getMethods()) {
             LyfecycleHandlerType annotation = method.getAnnotation(LyfecycleHandlerType.class);
             if (annotation != null) {
                 LyfecycleLevel level = annotation.value();
-                LifecycleHandler handler = new LifecycleHandler(service, method);
+                LifecycleHandler<? extends IService> handler = new  LifecycleHandler<IService>(service, method);
                 methodsInService.put(level, handler);
             }
         }
@@ -125,16 +143,16 @@ public class Lifecycle {
     }
 
 
-    private final class LifecycleHandler {
-        private final Object target;
+    private final class LifecycleHandler<T> {
+        private final T target;
         private final Method method;
 
-        public LifecycleHandler(Object target, Method method) {
+        public LifecycleHandler(T target, Method method) {
             this.target = target;
             this.method = method;
         }
 
-        public Object getTarget() {
+        public T getTarget() {
             return target;
         }
 
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
index ffaf641..b604276 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
@@ -73,7 +73,7 @@ public class ServiceFinder {
 	}
 
     /*
-     *  Code originally from Kris Dover <krisdover@hotmail.com> and adapated for my purpose
+     *  Code originally from Kris Dover <krisdover@hotmail.com> and adapted for my purpose.
      *
      */
 	private static Set<Class<? extends IService>> findClasses(ClassLoader classLoader,
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
index 9314368..5c0c742 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TreeSet;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeClass;
@@ -29,7 +25,6 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.IEntitlementService;
 import com.ning.billing.lifecycle.IService;
 import com.ning.billing.lifecycle.Lifecycled;
 import com.ning.billing.lifecycle.LyfecycleHandlerType;
@@ -40,7 +35,11 @@ public class TestLifecycle {
 
     private final static Logger log = LoggerFactory.getLogger(TestLifecycle.class);
 
-    @Lifecycled
+    private Service1 s1;
+    private Service2 s2;
+
+    private Lifecycle lifecycle;
+
     public static class Service1 implements IService {
 
         @LyfecycleHandlerType(LyfecycleLevel.INIT_BUS)
@@ -75,10 +74,6 @@ public class TestLifecycle {
     }
 
 
-    private Service1 s1;
-    private Service2 s2;
-
-    private Lifecycle lifecycle;
 
     @BeforeClass(groups={"fast"})
     public void setup() {
@@ -91,7 +86,7 @@ public class TestLifecycle {
 
     @Test
     public void testLifecycle() {
-        lifecycle.fireStages();
+        lifecycle.fireStartupSequence();
     }
 
 
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 a7dde73..ba58e05 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
@@ -22,6 +22,8 @@ import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.config.ICatalogConfig;
 import com.ning.billing.lifecycle.IService;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
 import com.ning.billing.util.config.XMLLoader;
 
 public class CatalogService implements IService, Provider<ICatalog>, ICatalogService {
@@ -31,7 +33,7 @@ public class CatalogService implements IService, Provider<ICatalog>, ICatalogSer
     private static ICatalog catalog;
 
     private final ICatalogConfig config;
-    private final boolean isInitialized;
+    private boolean isInitialized;
 
 
     @Inject
@@ -41,9 +43,7 @@ public class CatalogService implements IService, Provider<ICatalog>, ICatalogSer
         this.isInitialized = false;
     }
 
-
-    /*
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.LOAD_CATALOG)
     public synchronized void initialize() throws ServiceException {
         if (!isInitialized) {
             try {
@@ -55,20 +55,6 @@ public class CatalogService implements IService, Provider<ICatalog>, ICatalogSer
         }
     }
 
-    @Override
-    public void start() throws ServiceException {
-        // Intentionally blank
-
-    }
-
-    @Override
-    public void stop() throws ServiceException {
-        // Intentionally blank
-
-    }
-    */
-
-
 
     @Override
     public String getName() {
diff --git a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
index 5191977..deb2305 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
@@ -20,7 +20,9 @@ import org.skife.config.ConfigurationObjectFactory;
 
 import com.google.inject.AbstractModule;
 import com.ning.billing.catalog.CatalogService;
+import com.ning.billing.catalog.CatalogUserApi;
 import com.ning.billing.catalog.api.ICatalogService;
+import com.ning.billing.catalog.api.ICatalogUserApi;
 import com.ning.billing.config.ICatalogConfig;
 
 public class CatalogModule extends AbstractModule {
@@ -30,10 +32,15 @@ public class CatalogModule extends AbstractModule {
         bind(ICatalogConfig.class).toInstance(config);
     }
 
+    protected void installCatalog() {
+        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
+        bind(ICatalogService.class).to(CatalogService.class).asEagerSingleton();
+    }
+
     @Override
     protected void configure() {
         installConfig();
-        bind(ICatalogService.class).to(CatalogService.class).asEagerSingleton();
+        installCatalog();
     }
 
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index 7856dab..0d9ac8d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -21,7 +21,9 @@ import java.util.List;
 
 import org.joda.time.DateTime;
 
+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.IDuration;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
@@ -35,16 +37,13 @@ import com.ning.billing.util.clock.Clock;
 
 public class PlanAligner implements IPlanAligner {
 
-    // STEPH this is a bit broken right now until we figure out to retrieve ICatalog
-    private /*final*/ ICatalog catalog;
+    private final ICatalogService catalogService;
 
-    public PlanAligner() {
-        //this.catalog = Engine.getInstance().getCatalog();
+    @Inject
+    public PlanAligner(ICatalogService catalogService) {
+        this.catalogService = catalogService;
     }
 
-    public void init(ICatalog catalog) {
-        this.catalog = catalog;
-    }
 
     private enum WhichPhase {
         CURRENT,
@@ -87,6 +86,8 @@ public class PlanAligner implements IPlanAligner {
     private TimedPhase getTimedPhaseOnCreate(Subscription subscription,
             IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
 
+        ICatalog catalog = catalogService.getCatalog();
+
             PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
                     plan.getProduct().getCategory(),
                     plan.getBillingPeriod(),
@@ -111,6 +112,8 @@ public class PlanAligner implements IPlanAligner {
     private TimedPhase getTimedPhaseOnChange(Subscription subscription,
             IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
 
+        ICatalog catalog = catalogService.getCatalog();
+
         IPlanPhase currentPhase = subscription.getCurrentPhase();
         IPlan currentPlan = subscription.getCurrentPlan();
         String currentPriceList = subscription.getCurrentPriceList();
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 c30e2c1..8561ce0 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
@@ -22,7 +22,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.IAccount;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -42,6 +41,7 @@ import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventCreate;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.entitlement.glue.InjectorMagic;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementUserApi implements IEntitlementUserApi {
@@ -68,7 +68,7 @@ public class EntitlementUserApi implements IEntitlementUserApi {
     @Override
     public synchronized void initialize(List<IApiListener> listeners) {
         if (!initialized) {
-            this.catalog = engine.getCatalog();
+            this.catalog = InjectorMagic.getCatlog();
             engine.registerApiObservers(listeners);
             initialized = true;
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 6e07f7c..a5cd11e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -49,6 +49,7 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.ApiEventUncancel;
 import com.ning.billing.entitlement.events.user.IUserEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.entitlement.glue.InjectorMagic;
 import com.ning.billing.util.clock.IClock;
 
 public class Subscription extends PrivateFields  implements ISubscription {
@@ -146,12 +147,10 @@ public class Subscription extends PrivateFields  implements ISubscription {
     public Subscription(UUID id, UUID bundleId, ProductCategory category, DateTime bundleStartDate, DateTime startDate, DateTime ctd, DateTime ptd, long activeVersion) {
 
         super();
-
-        Engine engine = Engine.getInstance();
-        this.clock = engine.getClock();
-        this.dao = engine.getDao();
-        this.catalog = engine.getCatalog();
-        this.planAligner = engine.getPlanAligner();
+        this.clock = InjectorMagic.getClock();
+        this.dao = InjectorMagic.getEntitlementDao();
+        this.catalog = InjectorMagic.getCatlog();
+        this.planAligner = InjectorMagic.getPlanAligner();
         this.id = id;
         this.bundleId = bundleId;
         this.startDate = startDate;
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 597d3e5..dd33ae5 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
@@ -17,7 +17,6 @@
 package com.ning.billing.entitlement.engine.core;
 
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -26,14 +25,12 @@ 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.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.IEntitlementService;
 import com.ning.billing.entitlement.api.billing.BillingApi;
 import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
@@ -46,6 +43,8 @@ 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.IUserEvent;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
 import com.ning.billing.util.clock.IClock;
 
 public class Engine implements IEventListener, IEntitlementService {
@@ -53,34 +52,27 @@ 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 IEntitlementDao dao;
     private final IApiEventProcessor apiEventProcessor;
-    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, ICatalogService catalogService,
+    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor,
             IPlanAligner planAligner, IEntitlementConfig config) {
         super();
         this.clock = clock;
         this.dao = dao;
         this.apiEventProcessor = apiEventProcessor;
         this.planAligner = planAligner;
-        this.catalogService = catalogService;
         this.observers = null;
         this.userApi = new EntitlementUserApi(this, clock, planAligner, dao);
         this.billingApi = new BillingApi(this, clock, dao);
-        instance = this;
-
     }
 
     @Override
@@ -89,26 +81,19 @@ public class Engine implements IEventListener, IEntitlementService {
     }
 
 
-    /*
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.INIT_SERVICE)
     public void initialize() {
-        this.catalog = catalogService.getCatalog();
-        // STEPH yack
-        ((PlanAligner) planAligner).init(catalog);
-
     }
 
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
     public void start() {
         apiEventProcessor.startNotifications(this);
     }
 
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.STOP_SERVICE)
     public void stop() {
         apiEventProcessor.stopNotifications();
     }
-    */
-
 
     @Override
     public IEntitlementUserApi getUserApi(List<IApiListener> listeners) {
@@ -180,31 +165,4 @@ public class Engine implements IEventListener, IEntitlementService {
             dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent);
         }
     }
-
-
-    //
-    // STEPH would be nice to have those go away..
-    //
-
-    // For non Guice classes
-    public synchronized static Engine getInstance() {
-        return instance;
-    }
-
-    public IClock getClock() {
-        return clock;
-    }
-
-    public ICatalog getCatalog() {
-        return catalog;
-    }
-
-    public IEntitlementDao getDao() {
-        return dao;
-    }
-
-    public IPlanAligner getPlanAligner() {
-        return planAligner;
-    }
-
 }
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 6074d94..d303b30 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
@@ -19,12 +19,12 @@ package com.ning.billing.entitlement.glue;
 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.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.IEntitlementService;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
 import com.ning.billing.entitlement.engine.core.ApiEventProcessor;
 import com.ning.billing.entitlement.engine.core.Engine;
 import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
@@ -37,9 +37,6 @@ import com.ning.billing.util.clock.IClock;
 
 public class EntitlementModule extends AbstractModule {
 
-    protected void installCatalog() {
-        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
-    }
 
     protected void installClock() {
         bind(IClock.class).to(Clock.class).asEagerSingleton();
@@ -64,12 +61,15 @@ public class EntitlementModule extends AbstractModule {
         bind(IPlanAligner.class).to(PlanAligner.class).asEagerSingleton();
     }
 
+    protected void installInjectorMagic() {
+        bind(InjectorMagic.class).asEagerSingleton();
+    }
 
     @Override
     protected void configure() {
+        installInjectorMagic();
         installConfig();
         installClock();
-        installCatalog();
         installApiEventProcessor();
         installEntitlementDao();
         installEntitlementCore();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java
new file mode 100644
index 0000000..8e845da
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010-2011 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.entitlement.glue;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
+import com.ning.billing.entitlement.alignment.IPlanAligner;
+import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
+import com.ning.billing.util.clock.IClock;
+
+//
+// Allows to return Guice injected singleton in a non guice context
+//
+public class InjectorMagic {
+
+    // public void testng only
+    public static InjectorMagic instance;
+
+    private final Injector injector;
+
+    @Inject
+    public InjectorMagic(Injector injector) {
+        this.injector = injector;
+        synchronized(InjectorMagic.class) {
+            if (instance == null) {
+                instance = this;
+            }
+        }
+    }
+
+
+    public static IClock getClock() {
+        return InjectorMagic.get().getInstance(IClock.class);
+    }
+
+    public static ICatalog getCatlog() {
+        ICatalogService catalogService = InjectorMagic.get().getInstance(ICatalogService.class);
+        return catalogService.getCatalog();
+    }
+
+    public static IEntitlementDao getEntitlementDao() {
+        return InjectorMagic.get().getInstance(IEntitlementDao.class);
+    }
+
+    public static IPlanAligner getPlanAligner() {
+        return InjectorMagic.get().getInstance(IPlanAligner.class);
+    }
+
+
+    public static Injector get() {
+        if (instance == null) {
+            throw new RuntimeException("Trying to retrieve injector too early");
+        }
+        return instance.getInjector();
+    }
+
+    private Injector getInjector() {
+        return injector;
+    }
+}
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 15b124c..d93303f 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
@@ -36,23 +36,26 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.BeforeTest;
 
 import com.google.inject.Injector;
 import com.ning.billing.account.api.IAccount;
+import com.ning.billing.catalog.CatalogService;
 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.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.IEntitlementService;
 import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
 import com.ning.billing.entitlement.engine.core.Engine;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
@@ -61,6 +64,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.InjectorMagic;
 import com.ning.billing.lifecycle.IService.ServiceException;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.IClock;
@@ -72,7 +76,6 @@ public abstract class TestUserApiBase {
     protected static final long DAY_IN_MS = (24 * 3600 * 1000);
 
     protected IEntitlementService entitlementService;
-    //protected Engine engine;
     protected IEntitlementUserApi entitlementApi;
     protected IEntitlementBillingApi billingApi;
     protected ICatalogService catalogService;
@@ -85,6 +88,7 @@ public abstract class TestUserApiBase {
     protected ApiTestListener testListener;
     protected ISubscriptionBundle bundle;
 
+    private InjectorMagic injectorMagic;
 
     public static void loadSystemPropertiesFromClasspath( final String resource )
     {
@@ -98,20 +102,20 @@ public abstract class TestUserApiBase {
         }
     }
 
+    @AfterClass(groups={"setup"})
+    public void tearDown() {
+        InjectorMagic.instance = null;
+    }
 
     @BeforeClass(groups={"setup"})
     public void setup() {
 
-        // Does not see to work ...
-        /*
-        TimeZone tz  = TimeZone.getDefault();
-        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
-        tz  = TimeZone.getDefault();
-         */
-
         loadSystemPropertiesFromClasspath("/entitlement.properties");
         final Injector g = getInjector();
 
+        injectorMagic = g.getInstance(InjectorMagic.class);
+
+
         entitlementService = g.getInstance(IEntitlementService.class);
         catalogService = g.getInstance(ICatalogService.class);
         config = g.getInstance(IEntitlementConfig.class);
@@ -119,20 +123,14 @@ public abstract class TestUserApiBase {
         clock = (ClockMock) g.getInstance(IClock.class);
         try {
 
-            /*
-            catalogService.initialize();
-            entitlementService.initialize();
-*/
+            ((CatalogService) catalogService).initialize();
+            ((Engine)entitlementService).initialize();
             init();
         } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
-        }
-            /*
         } catch (ServiceException e) {
-            e.printStackTrace();
             Assert.fail(e.getMessage());
         }
-        */
     }
 
     protected abstract Injector getInjector();
@@ -154,41 +152,29 @@ public abstract class TestUserApiBase {
 
     @BeforeMethod(groups={"setup"})
     public void setupTest() {
-        /*
+
+        log.warn("\n");
+        log.warn("RESET TEST FRAMEWORK\n\n");
+
+        testListener.reset();
+        clock.resetDeltaFromReality();
+        ((IEntitlementDaoMock) dao).reset();
         try {
-            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);
-            // STEPH
-            //entitlementService.start();
-        } catch (ServiceException e) {
+            bundle = entitlementApi.createBundleForAccount(account, "myDefaultBundle");
+        } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
         }
-        */
+        assertNotNull(bundle);
+
+        ((Engine)entitlementService).start();
     }
 
     @AfterMethod(groups={"setup"})
     public void cleanupTest() {
-        /*
-        try {
-            // STEPH
-            //entitlementService.stop();
-            log.warn("DONE WITH TEST\n");
 
-        } catch (ServiceException e) {
-            Assert.fail(e.getMessage());
 
-        }
-            */
+        ((Engine)entitlementService).stop();
+        log.warn("DONE WITH TEST\n");
     }
 
     // Glue magic to invoke the real test
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 38c55f2..184f18d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -43,7 +43,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
     protected void testCancelSubscriptionIMMReal() {
 
-        log.info("Starting testChangeSubscriptionEOTWithNoChargeThroughDate");
+        log.info("Starting testCancelSubscriptionIMM");
 
         try {
 
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 896c592..00c2bab 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
@@ -16,7 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.inject.Guice;
@@ -30,7 +29,7 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"fast"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index 8816503..9662ef6 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -73,7 +73,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
     private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
         String toProd, BillingPeriod toTerm, String toPlanSet) {
 
-        log.info("Starting testChangeSubscriptionEOTWithNoChargeThroughDate");
+        log.info("Starting testChangePlanBundleAlignEOTWithNoChargeThroughDateReal");
 
         try {
 
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 acb5e69..4455436 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
@@ -28,7 +28,7 @@ public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
 
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 1c119f8..429652c 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
@@ -29,7 +29,7 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"fast"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/CatalogModuleMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/CatalogModuleMock.java
index 565a854..3b24fe8 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/CatalogModuleMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/CatalogModuleMock.java
@@ -20,4 +20,5 @@ import com.ning.billing.catalog.glue.CatalogModule;
 
 public class CatalogModuleMock extends CatalogModule {
 
+
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
index e930cb2..3a701cc 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
@@ -17,21 +17,12 @@
 package com.ning.billing.entitlement.glue;
 
 
-import org.skife.config.ConfigurationObjectFactory;
-import org.skife.jdbi.v2.DBI;
-
-import com.ning.billing.dbi.DBIProvider;
-import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.entitlement.engine.core.ApiEventProcessorMemoryMock;
 import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
 import com.ning.billing.entitlement.engine.dao.EntitlementDaoMemoryMock;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
-import com.ning.billing.entitlement.glue.EntitlementModule;
-import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.clock.IClock;
-
 
-public class EngineModuleMemoryMock extends EntitlementModule {
+public class EngineModuleMemoryMock extends EngineModuleMock {
     @Override
     protected void installApiEventProcessor() {
         bind(IApiEventProcessor.class).to(ApiEventProcessorMemoryMock.class).asEagerSingleton();
@@ -42,20 +33,9 @@ public class EngineModuleMemoryMock extends EntitlementModule {
         bind(IEntitlementDao.class).to(EntitlementDaoMemoryMock.class).asEagerSingleton();
     }
 
-    @Override
-    protected void installClock() {
-        bind(IClock.class).to(ClockMock.class).asEagerSingleton();
-    }
-
-    protected void installDBI() {
-        bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
-        final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
-        bind(DbiConfig.class).toInstance(config);
-    }
 
     @Override
     protected void configure() {
         super.configure();
-        installDBI();
     }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java
new file mode 100644
index 0000000..d70a2f7
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2011 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.entitlement.glue;
+
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.clock.IClock;
+
+public class EngineModuleMock extends EntitlementModule {
+
+    @Override
+    protected void installClock() {
+        bind(IClock.class).to(ClockMock.class).asEagerSingleton();
+    }
+
+    @Override
+    protected void configure() {
+        super.configure();
+    }
+
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
index 6fdc8e5..9dd1c2d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
@@ -26,7 +26,7 @@ import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.IClock;
 
-public class EngineModuleSqlMock extends EntitlementModule {
+public class EngineModuleSqlMock extends EngineModuleMock {
 
 
     @Override