killbill-aplcache

Setting up for Overdue NUTS tests

5/17/2012 4:58:03 PM

Changes

Details

diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 860ae6c..1514c0d 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -194,6 +194,7 @@ public enum ErrorCode {
     OVERDUE_CAT_ERROR_ENCOUNTERED(5001,"Catalog error encountered on Overdueable: id='%s', type='%s'"),  
     OVERDUE_TYPE_NOT_SUPPORTED(5002,"Overdue of this type is not supported: id='%s', type='%s'"),  
     OVERDUE_NO_REEVALUATION_INTERVAL(5003,"No valid reevaluation interval for state (name: %s)"),
+    OVERDUE_NOT_CONFIGURED(5004, "No configuration was found for the overdue system"),
     /*
      * 
      * Range 6000: Blocking system
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
index 965e402..dc4aaae 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
@@ -28,19 +28,24 @@ public class BillingState<T extends Blockable> {
 	private final UUID objectId;
 	private final int numberOfUnpaidInvoices;
 	private final BigDecimal balanceOfUnpaidInvoices;
-	private final DateTime dateOfEarliestUnpaidInvoice;
+    private final DateTime dateOfEarliestUnpaidInvoice;
+    private final UUID idOfEarliestUnpaidInvoice;
 	private final PaymentResponse responseForLastFailedPayment;
 	private final Tag[] tags;
 	
-	public BillingState(UUID id, int numberOfUnpaidInvoices, BigDecimal balanceOfUnpaidInvoices,
+	public BillingState(UUID id, 
+	        int numberOfUnpaidInvoices, 
+	        BigDecimal balanceOfUnpaidInvoices,
 			DateTime dateOfEarliestUnpaidInvoice,
+			UUID idOfEarliestUnpaidInvoice,
 			PaymentResponse responseForLastFailedPayment,
 			Tag[] tags) {
 		super();
 		this.objectId = id;
 		this.numberOfUnpaidInvoices = numberOfUnpaidInvoices;
 		this.balanceOfUnpaidInvoices = balanceOfUnpaidInvoices;
-		this.dateOfEarliestUnpaidInvoice = dateOfEarliestUnpaidInvoice;
+        this.dateOfEarliestUnpaidInvoice = dateOfEarliestUnpaidInvoice;
+        this.idOfEarliestUnpaidInvoice = idOfEarliestUnpaidInvoice;
 		this.responseForLastFailedPayment = responseForLastFailedPayment;
 		this.tags = tags;
 	}
@@ -61,7 +66,11 @@ public class BillingState<T extends Blockable> {
 		return dateOfEarliestUnpaidInvoice;
 	}
 	
-	public PaymentResponse getResponseForLastFailedPayment() {
+	public UUID getIdOfEarliestUnpaidInvoice() {
+        return idOfEarliestUnpaidInvoice;
+    }
+
+    public PaymentResponse getResponseForLastFailedPayment() {
 		return responseForLastFailedPayment;
 	}
 
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java b/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
index 15eebc8..14aa4cd 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
@@ -34,15 +34,19 @@ public class BillingStateBundle extends BillingState<SubscriptionBundle> {
     private final PriceList basePlanPriceList;
     private final PhaseType basePlanPhaseType;
     
-	public BillingStateBundle(UUID id, int numberOfUnpaidInvoices, BigDecimal unpaidInvoiceBalance,
+	public BillingStateBundle(UUID id, 
+	        int numberOfUnpaidInvoices, 
+	        BigDecimal unpaidInvoiceBalance,
 			DateTime dateOfEarliestUnpaidInvoice,
+			UUID idOfEarliestUnpaidInvoice,
 			PaymentResponse responseForLastFailedPayment,
 			Tag[] tags, 
 			Product basePlanProduct,
 			BillingPeriod basePlanBillingPeriod, 
 			PriceList basePlanPriceList, PhaseType basePlanPhaseType) {
 		super(id, numberOfUnpaidInvoices, unpaidInvoiceBalance, 
-				dateOfEarliestUnpaidInvoice, responseForLastFailedPayment, tags);
+				dateOfEarliestUnpaidInvoice, idOfEarliestUnpaidInvoice, 
+				responseForLastFailedPayment, tags);
 		
 		this.basePlanProduct = basePlanProduct;
 		this.basePlanBillingPeriod = basePlanBillingPeriod;
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
index 3101c10..eca5b18 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueUserApi.java
@@ -27,4 +27,7 @@ public interface OverdueUserApi {
     public <T extends Blockable> void setOverrideBillingStateForAccount(T overdueable, BillingState<T> state) throws OverdueError;
 
     public <T extends Blockable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueError;
+
+    public <T extends Blockable> BillingState<T> getBillingStateFor(T overdueable) throws OverdueError;
+
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
index 60f77d8..2e120dc 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
@@ -18,8 +18,6 @@ package com.ning.billing.beatrix.integration.overdue;
 
 import com.ning.billing.overdue.OverdueService;
 import com.ning.billing.overdue.glue.DefaultOverdueModule;
-import com.ning.billing.overdue.wrapper.MockOverdueWrapperFactory;
-import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 
 public class IntegrationTestOverdueModule extends DefaultOverdueModule {
    
@@ -28,10 +26,5 @@ public class IntegrationTestOverdueModule extends DefaultOverdueModule {
         bind(OverdueService.class).to(MockOverdueService.class);    
     }
 
-    @Override
-    protected void installOverdueWrapperFactory() {
-       bind(OverdueWrapperFactory.class).to(MockOverdueWrapperFactory.class).asEagerSingleton();
-    }
-    
-    
+     
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
index 059b0a2..cdb323b 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
@@ -20,16 +20,16 @@ import com.google.inject.Inject;
 import com.ning.billing.ovedue.notification.OverdueCheckNotifier;
 import com.ning.billing.overdue.OverdueProperties;
 import com.ning.billing.overdue.OverdueUserApi;
-import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.listener.OverdueListener;
 import com.ning.billing.overdue.service.DefaultOverdueService;
+import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 import com.ning.billing.util.bus.BusService;
 
 public class MockOverdueService extends DefaultOverdueService {
     @Inject
     public MockOverdueService(OverdueUserApi userApi, OverdueProperties properties, OverdueCheckNotifier notifier,
-            BusService busService, OverdueListener listener) {
-        super(userApi, properties, notifier, busService, listener);
+            BusService busService, OverdueListener listener, OverdueWrapperFactory factory) {
+        super(userApi, properties, notifier, busService, listener, factory);
     }
 
     public synchronized void loadConfig() throws ServiceException {
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 8480faf..3bb0bc6 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -53,11 +53,8 @@ import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.overdue.OverdueUserApi;
 import com.ning.billing.overdue.config.OverdueConfig;
-import com.ning.billing.overdue.wrapper.MockOverdueWrapperFactory;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 import com.ning.billing.payment.api.PaymentApi;
-import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentAttempt;
 import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
 import com.ning.billing.util.callcontext.DefaultCallContext;
 import com.ning.billing.util.clock.ClockMock;
@@ -143,7 +140,7 @@ public class TestOverdueIntegration extends TestIntegrationBase {
     public void setupOverdue() throws Exception {
         InputStream is = new ByteArrayInputStream(configXml.getBytes());
         config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
-        ((MockOverdueWrapperFactory)overdueWrapperFactory).setOverdueConfig(config);
+        overdueWrapperFactory.setOverdueConfig(config);
         
         account = accountUserApi.createAccount(getAccountData(25), null, null, context);
         assertNotNull(account);
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index e71a2fd..acc9b85 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -29,6 +29,7 @@ import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.OverdueUserApi;
+import com.ning.billing.overdue.calculator.BillingStateCalculator;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueError;
@@ -41,13 +42,13 @@ public class DefaultOverdueUserApi implements OverdueUserApi {
     
     private final OverdueWrapperFactory factory;
     private final BlockingApi accessApi; 
-    private final OverdueConfig overdueConfig;
+    
+    private OverdueConfig overdueConfig;
    
     @Inject
-    public DefaultOverdueUserApi(OverdueWrapperFactory factory,BlockingApi accessApi, OverdueConfig config,  CatalogService catalogService) {
+    public DefaultOverdueUserApi(OverdueWrapperFactory factory,BlockingApi accessApi, CatalogService catalogService) {
         this.factory = factory;
         this.accessApi = accessApi;
-        this.overdueConfig = config;
     }
     
     @SuppressWarnings("unchecked")
@@ -61,6 +62,13 @@ public class DefaultOverdueUserApi implements OverdueUserApi {
             throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED,overdueable.getId(), overdueable.getClass().getSimpleName());
         }
     }
+     
+    @Override
+    public <T extends Blockable> BillingState<T> getBillingStateFor(T overdueable) throws OverdueError {
+        log.info(String.format("Billing state of of %s requested", overdueable.getId()));
+        OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
+        return wrapper.billingState();
+    }
     
     @Override
     public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(T blockable) throws OverdueError, OverdueApiException {
@@ -75,5 +83,9 @@ public class DefaultOverdueUserApi implements OverdueUserApi {
             T overdueable, BillingState<T> state) {
         throw new NotImplementedException();
     }
-    
+
+    public void setOverdueConfig(OverdueConfig config) {
+        this.overdueConfig = config;
+    }
+ 
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
index ccabe19..a6108db 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
@@ -28,11 +28,11 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
-import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.config.api.BillingState;
+import com.ning.billing.overdue.config.api.OverdueError;
 import com.ning.billing.util.clock.Clock;
 
 public abstract class BillingStateCalculator<T extends Blockable> {
@@ -58,11 +58,11 @@ public abstract class BillingStateCalculator<T extends Blockable> {
         this.clock = clock;
     }
     
-    public abstract BillingState<T> calculateBillingState(T overdueable) throws EntitlementUserApiException;
+    public abstract BillingState<T> calculateBillingState(T overdueable) throws OverdueError;
     
-    protected DateTime earliest(SortedSet<Invoice> unpaidInvoices) {
+    protected Invoice earliest(SortedSet<Invoice> unpaidInvoices) {
         try {
-            return unpaidInvoices.first().getInvoiceDate();
+            return unpaidInvoices.first();
         } catch (NoSuchElementException e) {
             return null;
         }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
index 89a7cc6..1292a59 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -36,6 +36,7 @@ import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.overdue.config.api.BillingStateBundle;
+import com.ning.billing.overdue.config.api.OverdueError;
 import com.ning.billing.overdue.config.api.PaymentResponse;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.tag.Tag;
@@ -49,38 +50,48 @@ public class BillingStateCalculatorBundle  extends BillingStateCalculator<Subscr
         super(invoiceApi, clock);
         this.entitlementApi = entitlementApi;
     }
-    
+
     @Override
-    public BillingStateBundle calculateBillingState(SubscriptionBundle bundle) throws EntitlementUserApiException {
-        
-        SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId());
- 
-        Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
-        
-        UUID id = bundle.getId();
-        int numberOfUnpaidInvoices = unpaidInvoices.size(); 
-        BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices);
-        DateTime dateOfEarliestUnpaidInvoice = earliest(unpaidInvoices);
-        PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
-        Tag[] tags = new Tag[]{}; //TODO MDW
-        Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
-        BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
-        PriceList basePlanPriceList = basePlan.getCurrentPriceList();
-        PhaseType basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
-        
-
-        return new BillingStateBundle( 
-            id, 
-            numberOfUnpaidInvoices, 
-            unpaidInvoiceBalance,
-            dateOfEarliestUnpaidInvoice,
-            responseForLastFailedPayment,
-            tags, 
-            basePlanProduct,
-            basePlanBillingPeriod, 
-            basePlanPriceList, 
-            basePlanPhaseType);
-        
+    public BillingStateBundle calculateBillingState(SubscriptionBundle bundle) throws OverdueError {
+        try {
+            SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId());
+
+            Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
+
+            UUID id = bundle.getId();
+            int numberOfUnpaidInvoices = unpaidInvoices.size(); 
+            BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices);
+            DateTime dateOfEarliestUnpaidInvoice = null;
+            UUID idOfEarliestUnpaidInvoice = null;
+            Invoice invoice = earliest(unpaidInvoices);
+            if(invoice != null) {
+                dateOfEarliestUnpaidInvoice = invoice.getInvoiceDate();
+                idOfEarliestUnpaidInvoice = invoice.getId();
+            }
+            PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
+            Tag[] tags = new Tag[]{}; //TODO MDW
+            Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
+            BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
+            PriceList basePlanPriceList = basePlan.getCurrentPriceList();
+            PhaseType basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
+
+
+            return new BillingStateBundle( 
+                    id, 
+                    numberOfUnpaidInvoices, 
+                    unpaidInvoiceBalance,
+                    dateOfEarliestUnpaidInvoice,
+                    idOfEarliestUnpaidInvoice,
+                    responseForLastFailedPayment,
+                    tags, 
+                    basePlanProduct,
+                    basePlanBillingPeriod, 
+                    basePlanPriceList, 
+                    basePlanPhaseType);
+        } catch (EntitlementUserApiException e) {
+            throw new OverdueError(e);
+        }
+
     }
 
     public SortedSet<Invoice> unpaidInvoicesForBundle(UUID bundleId, UUID accountId) {
@@ -103,6 +114,6 @@ public class BillingStateCalculatorBundle  extends BillingStateCalculator<Subscr
         }
         return false;
     }
-    
-    
+
+
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
index 16d5a51..188fdfc 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
@@ -32,7 +32,7 @@ import com.ning.billing.util.config.ValidationErrors;
 public class OverdueConfig  extends ValidatingConfig<OverdueConfig> {
 
     @XmlElement(required=true, name="bundleOverdueStates")
-    private OverdueStatesBundle bundleOverdueStates;
+    private OverdueStatesBundle bundleOverdueStates = new OverdueStatesBundle();
 
     public DefaultOverdueStateSet<SubscriptionBundle> getBundleStateSet() {
         return bundleOverdueStates;
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
index 3f07db5..9f3386b 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
@@ -18,19 +18,13 @@ package com.ning.billing.overdue.config;
 
 import javax.xml.bind.annotation.XmlElement;
 
-import org.joda.time.DateTime;
-
-import com.ning.billing.ErrorCode;
-import com.ning.billing.catalog.api.Duration;
-import com.ning.billing.catalog.api.TimeUnit;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.overdue.OverdueApiException;
-import com.ning.billing.overdue.OverdueState;
 
 public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBundle>{
 
+    @SuppressWarnings("unchecked")
     @XmlElement(required=true, name="state")
-    private DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates;
+    private DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates = new DefaultOverdueState[0];
 
     @Override
     protected DefaultOverdueState<SubscriptionBundle>[] getStates() {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
index 41b0d86..cbe5a0a 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
@@ -55,7 +55,7 @@ public class DefaultOverdueModule extends AbstractModule implements OverdueModul
     }
 
     protected void installOverdueWrapperFactory() {
-        bind(OverdueWrapperFactory.class).to(OverdueWrapperFactory.class).asEagerSingleton();    
+        bind(OverdueWrapperFactory.class).asEagerSingleton();    
     }
 
     /* (non-Javadoc)
diff --git a/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java b/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
index 267eeb0..e3cfd36 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
@@ -50,6 +50,6 @@ public interface OverdueProperties extends NotificationConfig, KillbillConfig  {
     public int getNumberOfMonthsInFuture();
 
     @Config("killbill.overdue.configUri")
-    @Default("jar:///com/ning/billing/irs/catalog/Catalog.xml")
+    @Default("jar:///com/ning/billing/irs/overdue/Config.xml")
     public String getConfigURI();
 }
\ No newline at end of file
diff --git a/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
index 17f4be1..ada0f15 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
@@ -17,6 +17,7 @@
 package com.ning.billing.overdue.service;
 
 import java.net.URI;
+import java.net.URISyntaxException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,23 +28,26 @@ import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 import com.ning.billing.ovedue.notification.OverdueCheckNotifier;
 import com.ning.billing.overdue.OverdueProperties;
 import com.ning.billing.overdue.OverdueUserApi;
+import com.ning.billing.overdue.api.DefaultOverdueUserApi;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.listener.OverdueListener;
+import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.config.XMLLoader;
 
 public class DefaultOverdueService implements ExtendedOverdueService {
     private static final Logger log = LoggerFactory.getLogger(DefaultOverdueService.class);
-    
+
     public static final String OVERDUE_SERVICE_NAME = "overdue-service";
-    private OverdueUserApi userApi;
+    private final OverdueUserApi userApi;
+    private final OverdueProperties properties;
+    private final OverdueCheckNotifier notifier;
+    private final BusService busService;
+    private final OverdueListener listener;
+    private final OverdueWrapperFactory factory;
+    
     private OverdueConfig overdueConfig;
-    private OverdueProperties properties;
-    private OverdueCheckNotifier notifier;
-    private BusService busService;
-    OverdueListener listener;
-
     private boolean isInitialized;
 
     @Inject
@@ -52,12 +56,14 @@ public class DefaultOverdueService implements ExtendedOverdueService {
             OverdueProperties properties, 
             OverdueCheckNotifier notifier, 
             BusService busService,
-            OverdueListener listener){
+            OverdueListener listener,
+            OverdueWrapperFactory factory){
         this.userApi = userApi;
         this.properties = properties;
         this.notifier = notifier;
         this.busService = busService;
         this.listener = listener;
+        this.factory = factory;
     }
 
     @Override
@@ -84,9 +90,16 @@ public class DefaultOverdueService implements ExtendedOverdueService {
                 overdueConfig = XMLLoader.getObjectFromUri(u, OverdueConfig.class);
 
                 isInitialized = true;
-            } catch (Exception e) {
+            } catch (URISyntaxException e) {
+                overdueConfig = new OverdueConfig();
+            } catch (IllegalArgumentException e) {
+                overdueConfig = new OverdueConfig();
+            }catch (Exception e) {
                 throw new ServiceException(e);
             }
+            
+            factory.setOverdueConfig(overdueConfig);
+            ((DefaultOverdueUserApi)userApi).setOverdueConfig(overdueConfig);
         }
     }
 
@@ -105,7 +118,7 @@ public class DefaultOverdueService implements ExtendedOverdueService {
         try {
             busService.getBus().register(listener);
         } catch (EventBusException e) {
-           log.error("Problem encountered registering OverdueListener on the Event Bus", e);
+            log.error("Problem encountered registering OverdueListener on the Event Bus", e);
         }
     }
 
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index cb693e4..6ec4bf7 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.overdue.wrapper;
 
-import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.overdue.OverdueApiException;
@@ -50,19 +49,24 @@ public class OverdueWrapper<T extends Blockable> {
     }
 
     public OverdueState<T> refresh() throws OverdueError, OverdueApiException {
-        try {
-            OverdueState<T> nextOverdueState;
-            BillingState<T> billingState    = billingStateCalcuator.calculateBillingState(overdueable);
-            String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
-            nextOverdueState                = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
+        if(overdueStateSet == null) { // No configuration available
+            return null;
+        } 
+        
+        OverdueState<T> nextOverdueState;
+        BillingState<T> billingState    = billingState();
+        String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
+        nextOverdueState                = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
 
-            if(nextOverdueState != null && !previousOverdueStateName.equals(nextOverdueState.getName())) {
-                overdueStateApplicator.apply(overdueable, previousOverdueStateName, nextOverdueState); 
-            }
-
-            return nextOverdueState;
-        } catch (EntitlementUserApiException e) {
-            throw new OverdueError(e);
+        if(nextOverdueState != null && !previousOverdueStateName.equals(nextOverdueState.getName())) {
+            overdueStateApplicator.apply(overdueable, previousOverdueStateName, nextOverdueState); 
         }
+
+        return nextOverdueState;
+
+    }
+
+    public BillingState<T> billingState() throws OverdueError {
+        return billingStateCalcuator.calculateBillingState(overdueable);
     }
 }
\ No newline at end of file
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
index 17e2817..3a1df56 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -39,28 +39,30 @@ import com.ning.billing.util.clock.Clock;
 public class OverdueWrapperFactory {
     private static final Logger log =  LoggerFactory.getLogger(OverdueWrapperFactory.class);
 
-    protected  OverdueConfig overdueConfig; //protected and not final so it can be set in testing
     private final EntitlementUserApi entitlementApi;
     private final BillingStateCalculatorBundle billingStateCalcuatorBundle;
     private final OverdueStateApplicator<SubscriptionBundle> overdueStateApplicatorBundle;
     private final BlockingApi api;
     private final Clock clock;
+    private  OverdueConfig overdueConfig;
 
     @Inject
-    public OverdueWrapperFactory(BlockingApi api, OverdueConfig config, Clock clock, 
+    public OverdueWrapperFactory(BlockingApi api, Clock clock, 
             BillingStateCalculatorBundle billingStateCalcuatorBundle, 
             OverdueStateApplicator<SubscriptionBundle> overdueStateApplicatorBundle,
             EntitlementUserApi entitlementApi) {
         this.billingStateCalcuatorBundle = billingStateCalcuatorBundle;
         this.overdueStateApplicatorBundle = overdueStateApplicatorBundle;
         this.entitlementApi = entitlementApi;
-        this.overdueConfig = config;
         this.api = api;
         this.clock = clock;
     }
 
     @SuppressWarnings("unchecked")
     public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(T bloackable) throws OverdueError {
+        if (overdueConfig == null) {
+            throw new OverdueError(ErrorCode.OVERDUE_NOT_CONFIGURED);
+        }
         if(bloackable instanceof SubscriptionBundle) {
             return (OverdueWrapper<T>)new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle)bloackable, api, overdueConfig.getBundleStateSet(), 
                     clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle );
@@ -89,6 +91,9 @@ public class OverdueWrapperFactory {
             throw new OverdueError(e);
         }
     }
-
+    
+    public void setOverdueConfig(OverdueConfig config) {
+        overdueConfig = config;
+    }
 
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
index db9ab74..9f3c647 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
@@ -66,6 +66,7 @@ public class TestBillingStateCalculator {
         ((ZombieControl)invoice).addResult("getInvoiceDate", date);
         ((ZombieControl)invoice).addResult("hashCode", hash++);
         ((ZombieControl)invoice).addResult("getInvoiceItems", invoiceItems);
+        ((ZombieControl)invoice).addResult("getId", UUID.randomUUID());
         
         return invoice;
     }
@@ -93,7 +94,7 @@ public class TestBillingStateCalculator {
         
         BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
         SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L,0L));
-        Assert.assertEquals(calc.earliest(invoices), now);
+        Assert.assertEquals(calc.earliest(invoices).getInvoiceDate(), now);
     }
 
     
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java b/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
index e697f29..08325f2 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
@@ -49,10 +49,11 @@ public class TestCondition {
 				"</condition>";
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
+		UUID unpaidInvoiceId = UUID.randomUUID();		        
 		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 2, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 2, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -67,10 +68,11 @@ public class TestCondition {
 				"</condition>";
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
+        UUID unpaidInvoiceId = UUID.randomUUID();               
 		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), new DateTime(), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
 		Assert.assertTrue(c.evaluate(state1, new DateTime()));
@@ -86,12 +88,13 @@ public class TestCondition {
 				"</condition>";
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
+        UUID unpaidInvoiceId = UUID.randomUUID();               
 		
 		DateTime now = new DateTime();
 		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, now));
 		Assert.assertTrue(c.evaluate(state1, now));
@@ -106,12 +109,13 @@ public class TestCondition {
 				"</condition>";
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
+        UUID unpaidInvoiceId = UUID.randomUUID();               
 		
 		DateTime now = new DateTime();
 		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), PaymentResponse.DO_NOT_HONOR , new Tag[]{});
+		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
+		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.DO_NOT_HONOR , new Tag[]{});
 		
 		Assert.assertTrue(!c.evaluate(state0, now));
 		Assert.assertTrue(c.evaluate(state1, now));
@@ -126,12 +130,13 @@ public class TestCondition {
 				"</condition>";
 		InputStream is = new ByteArrayInputStream(xml.getBytes());
 		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
+        UUID unpaidInvoiceId = UUID.randomUUID();               
 		
 		DateTime now = new DateTime();
 		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag("Tag")});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), 
+		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag("Tag")});
+		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
+		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, 
 				PaymentResponse.DO_NOT_HONOR, 
 				new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF), 
 						  new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index a4d0fa1..5b0207b 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -48,7 +48,9 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.mock.glue.MockInvoiceModule;
 import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.mock.glue.MockPaymentModule;
 import com.ning.billing.ovedue.notification.DefaultOverdueCheckNotifier;
 import com.ning.billing.ovedue.notification.DefaultOverdueCheckPoster;
 import com.ning.billing.ovedue.notification.OverdueCheckPoster;
@@ -65,6 +67,7 @@ import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
+import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
@@ -108,13 +111,12 @@ public class TestOverdueCheckNotifier {
 	@BeforeClass(groups={"slow"})
 	public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
 		//TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
-        final Injector g = Guice.createInjector(Stage.PRODUCTION,  new DefaultOverdueModule() {
+        final Injector g = Guice.createInjector(Stage.PRODUCTION,  new MockInvoiceModule(), new MockPaymentModule(), new BusModule(), new DefaultOverdueModule() {
 			
             protected void configure() {
                 super.configure();
                 bind(Clock.class).to(ClockMock.class).asEagerSingleton();
                 bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
-                bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
                 bind(NotificationQueueService.class).to(DefaultNotificationQueueService.class).asEagerSingleton();
                 final InvoiceConfig invoiceConfig = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
                 bind(InvoiceConfig.class).toInstance(invoiceConfig);
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
index 62785c9..be654bb 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
@@ -35,8 +35,21 @@ import com.ning.billing.payment.api.PaymentProviderAccount;
 
 public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
 
+    private boolean makeAllInvoicesFail;
+
+    public boolean isMakeAllInvoicesFail() {
+        return makeAllInvoicesFail;
+    }
+
+    public void setMakeAllInvoicesFail(boolean makeAllInvoicesFail) {
+        this.makeAllInvoicesFail = makeAllInvoicesFail;
+    } 
+
     @Override
     public Either<PaymentErrorEvent, PaymentInfoEvent> processInvoice(Account account, Invoice invoice) {
+        if (makeAllInvoicesFail) {
+            return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "test error", account.getId(), invoice.getId(), null));
+        }
         PaymentInfoEvent payment = new DefaultPaymentInfoEvent.Builder()
                                              .setPaymentId(UUID.randomUUID().toString())
                                              .setAmount(invoice.getBalance())
diff --git a/payment/src/main/java/com/ning/billing/payment/RetryService.java b/payment/src/main/java/com/ning/billing/payment/RetryService.java
index abc1fde..f754d36 100644
--- a/payment/src/main/java/com/ning/billing/payment/RetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/RetryService.java
@@ -120,7 +120,7 @@ public class RetryService implements KillbillService {
             }
             paymentApi.createPaymentForPaymentAttempt(UUID.fromString(paymentAttemptId), context);
         } catch (PaymentApiException e) {
-            log.error(String.format("Failed to retry payment for %s"), e);
+            log.error(String.format("Failed to retry payment for %s",paymentAttemptId), e);
         }
     }
 }
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 9d35352..304d215 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
@@ -55,7 +55,11 @@ public class XMLLoader {
 	}
 	
 	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri, InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, ValidationException {
-        Object o = unmarshaller(clazz).unmarshal(stream);
+	    if(stream == null) {
+	        return null;
+	    }
+	    
+	    Object o = unmarshaller(clazz).unmarshal(stream);
         if (clazz.isInstance(o)) {
         	@SuppressWarnings("unchecked")
 			T castObject = (T)o;