killbill-memoizeit

Details

diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
index fe34af6..49f5267 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
@@ -17,6 +17,7 @@
 package org.killbill.billing.catalog.rules;
 
 
+import org.killbill.billing.catalog.DefaultPrice;
 import org.killbill.billing.catalog.DefaultPriceList;
 import org.killbill.billing.catalog.DefaultProduct;
 import org.killbill.billing.catalog.StandaloneCatalog;
@@ -24,6 +25,7 @@ import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanSpecifier;
+import org.killbill.billing.catalog.api.PriceList;
 import org.killbill.billing.catalog.api.Product;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.catalog.api.StaticCatalog;
@@ -50,10 +52,26 @@ public abstract class DefaultCase<T> extends ValidatingConfig<StandaloneCatalog>
     }
 
     protected boolean satisfiesCase(final PlanSpecifier planPhase, final StaticCatalog c) throws CatalogApiException {
-        return (getProduct() == null || getProduct().equals(c.findCurrentProduct(planPhase.getProductName()))) &&
-               (getProductCategory() == null || getProductCategory().equals(c.findCurrentProduct(planPhase.getProductName()).getCategory())) &&
-                (getBillingPeriod() == null || getBillingPeriod().equals(planPhase.getBillingPeriod())) &&
-                (getPriceList() == null || getPriceList().equals(c.findCurrentPricelist(planPhase.getPriceListName())));
+        final Product product;
+        final BillingPeriod billingPeriod;
+        final ProductCategory productCategory;
+        final PriceList priceList;
+        if (planPhase.getPlanName() != null) {
+            final Plan plan = c.findCurrentPlan(planPhase.getPlanName());
+            product = plan.getProduct();
+            billingPeriod = plan.getRecurringBillingPeriod();
+            productCategory = plan.getProduct().getCategory();
+            priceList = c.findCurrentPricelist(plan.getPriceListName());
+        } else {
+            product = c.findCurrentProduct(planPhase.getProductName());
+            billingPeriod = planPhase.getBillingPeriod();
+            productCategory = product.getCategory();
+            priceList = getPriceList() != null ? c.findCurrentPricelist(planPhase.getPriceListName()) : null;
+        }
+        return (getProduct() == null || getProduct().equals(product)) &&
+               (getProductCategory() == null || getProductCategory().equals(productCategory)) &&
+               (getBillingPeriod() == null || getBillingPeriod().equals(billingPeriod)) &&
+               (getPriceList() == null || getPriceList().equals(priceList));
     }
 
     public static <K> K getResult(final DefaultCase<K>[] cases, final PlanSpecifier planSpec, final StaticCatalog catalog) throws CatalogApiException {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
index 525a5d7..a046406 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
@@ -77,16 +77,53 @@ public abstract class DefaultCaseChange<T> extends ValidatingConfig<StandaloneCa
     public T getResult(final PlanPhaseSpecifier from,
                        final PlanSpecifier to, final StaticCatalog catalog) throws CatalogApiException {
 
+
+
+        final Product inFromProduct;
+        final BillingPeriod inFromBillingPeriod;
+        final ProductCategory inFromProductCategory;
+        final PriceList inFromPriceList;
+        if (from.getPlanName() != null) {
+            final Plan plan = catalog.findCurrentPlan(from.getPlanName());
+            inFromProduct = plan.getProduct();
+            inFromBillingPeriod = plan.getRecurringBillingPeriod();
+            inFromProductCategory = plan.getProduct().getCategory();
+            inFromPriceList = catalog.findCurrentPricelist(plan.getPriceListName());
+        } else {
+            inFromProduct = catalog.findCurrentProduct(from.getProductName());
+            inFromBillingPeriod = from.getBillingPeriod();
+            inFromProductCategory = inFromProduct.getCategory();
+            inFromPriceList = from.getPriceListName() != null ? catalog.findCurrentPricelist(from.getPriceListName()) : null;
+        }
+
+        final Product inToProduct;
+        final BillingPeriod inToBillingPeriod;
+        final ProductCategory inToProductCategory;
+        final PriceList inToPriceList;
+        if (to.getPlanName() != null) {
+            final Plan plan = catalog.findCurrentPlan(to.getPlanName());
+            inToProduct = plan.getProduct();
+            inToBillingPeriod = plan.getRecurringBillingPeriod();
+            inToProductCategory = plan.getProduct().getCategory();
+            inToPriceList = catalog.findCurrentPricelist(plan.getPriceListName());
+        } else {
+            inToProduct = catalog.findCurrentProduct(to.getProductName());
+            inToBillingPeriod = to.getBillingPeriod();
+            inToProductCategory = inToProduct.getCategory();
+            inToPriceList = to.getPriceListName() != null ? catalog.findCurrentPricelist(to.getPriceListName()) : null;
+        }
+
+
         if (
                 (phaseType == null || from.getPhaseType() == phaseType) &&
-                (fromProduct == null || fromProduct.equals(catalog.findCurrentProduct(from.getProductName()))) &&
-                (fromProductCategory == null || fromProductCategory.equals(catalog.findCurrentProduct(from.getProductName()).getCategory())) &&
-                (fromBillingPeriod == null || fromBillingPeriod.equals(from.getBillingPeriod())) &&
-                (this.toProduct == null || this.toProduct.equals(catalog.findCurrentProduct(to.getProductName()))) &&
-                (toProductCategory == null || toProductCategory.equals(catalog.findCurrentProduct(to.getProductName()).getCategory())) &&
-                (toBillingPeriod == null || toBillingPeriod.equals(to.getBillingPeriod())) &&
-                (fromPriceList == null || fromPriceList.equals(catalog.findCurrentPricelist(from.getPriceListName()))) &&
-                (toPriceList == null || toPriceList.equals(catalog.findCurrentPricelist(to.getPriceListName())))
+                (fromProduct == null || fromProduct.equals(inFromProduct)) &&
+                (fromProductCategory == null || fromProductCategory.equals(inFromProductCategory)) &&
+                (fromBillingPeriod == null || fromBillingPeriod.equals(inFromBillingPeriod)) &&
+                (this.toProduct == null || this.toProduct.equals(inToProduct)) &&
+                (this.toProductCategory == null || this.toProductCategory.equals(inToProductCategory)) &&
+                (this.toBillingPeriod == null || this.toBillingPeriod.equals(inToBillingPeriod)) &&
+                (fromPriceList == null || fromPriceList.equals(inFromPriceList)) &&
+                (toPriceList == null || toPriceList.equals(inToPriceList))
                 ) {
             return getResult();
         }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePhase.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePhase.java
index f0a0011..cf656ef 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePhase.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCasePhase.java
@@ -33,8 +33,7 @@ public abstract class DefaultCasePhase<T> extends DefaultCaseStandardNaming<T> {
 
     public T getResult(final PlanPhaseSpecifier specifier, final StaticCatalog c) throws CatalogApiException {
         if ((phaseType == null || specifier.getPhaseType() == phaseType)
-                && satisfiesCase(new PlanSpecifier(specifier), c)
-                ) {
+                && satisfiesCase(new PlanSpecifier(specifier), c)) {
             return getResult();
         }
         return null;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
index 34dd757..99efa9c 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultPlanRules.java
@@ -119,21 +119,25 @@ public class DefaultPlanRules extends ValidatingConfig<StandaloneCatalog> implem
         return (result != null) ? result : BillingAlignment.ACCOUNT;
     }
 
-    public PlanChangeResult planChange(final PlanPhaseSpecifier from, PlanSpecifier to, final StaticCatalog catalog) throws CatalogApiException {
-        final DefaultPriceList toPriceList;
-        if (to.getPriceListName() == null) { // Pricelist may be null because it is unspecified this is the principal use-case
-            toPriceList = findPriceList(from, catalog);
-            to = new PlanSpecifier(to.getProductName(), to.getBillingPeriod(), toPriceList.getName());
-        } else {
-            toPriceList = (DefaultPriceList) catalog.findCurrentPricelist(to.getPriceListName());
-        }
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final StaticCatalog catalog) throws CatalogApiException {
+
+        final DefaultPriceList toPriceList = to.getPriceListName() != null ?
+                                             (DefaultPriceList) catalog.findCurrentPricelist(to.getPriceListName()) :
+                                             findPriceList(from, catalog);
+
+        // If we use old scheme {product, billingPeriod, pricelist}, ensure pricelist is correct
+        // (Pricelist may be null because if it is unspecified this is the principal use-case)
+        final PlanSpecifier toWithPriceList = to.getPlanName() == null ?
+                                              new PlanSpecifier(to.getProductName(), to.getBillingPeriod(), toPriceList.getName()) :
+                                              to;
 
-        final BillingActionPolicy policy = getPlanChangePolicy(from, to, catalog);
+
+        final BillingActionPolicy policy = getPlanChangePolicy(from, toWithPriceList, catalog);
         if (policy == BillingActionPolicy.ILLEGAL) {
-            throw new IllegalPlanChange(from, to);
+            throw new IllegalPlanChange(from, toWithPriceList);
         }
 
-        final PlanAlignmentChange alignment = getPlanChangeAlignment(from, to, catalog);
+        final PlanAlignmentChange alignment = getPlanChangeAlignment(from, toWithPriceList, catalog);
 
         return new PlanChangeResult(toPriceList, policy, alignment);
     }
@@ -146,13 +150,6 @@ public class DefaultPlanRules extends ValidatingConfig<StandaloneCatalog> implem
 
     public BillingActionPolicy getPlanChangePolicy(final PlanPhaseSpecifier from,
                                                    final PlanSpecifier to, final StaticCatalog catalog) throws CatalogApiException {
-        if (from.getProductName().equals(to.getProductName()) &&
-            from.getBillingPeriod() == to.getBillingPeriod() &&
-            from.getPriceListName().equals(to.getPriceListName())) {
-            return BillingActionPolicy.ILLEGAL;
-        }
-        //Plan toPlan = catalog.findPlan()
-
         final BillingActionPolicy result = DefaultCaseChange.getResult(changeCase, from, to, catalog);
         return (result != null) ? result : BillingActionPolicy.END_OF_TERM;
     }
@@ -160,7 +157,8 @@ public class DefaultPlanRules extends ValidatingConfig<StandaloneCatalog> implem
     private DefaultPriceList findPriceList(final PlanSpecifier specifier, final StaticCatalog catalog) throws CatalogApiException {
         DefaultPriceList result = DefaultCase.getResult(priceListCase, specifier, catalog);
         if (result == null) {
-            result = (DefaultPriceList) catalog.findCurrentPricelist(specifier.getPriceListName());
+            final String priceListName = specifier.getPlanName() != null ? catalog.findCurrentPlan(specifier.getPlanName()).getPriceListName() : specifier.getPriceListName();
+            result = (DefaultPriceList) catalog.findCurrentPricelist(priceListName);
         }
         return result;
     }
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
index 92464c1..e207fff 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
@@ -632,7 +632,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertion(Result.FOO, cr,
                   product1.getName(), product2.getName(),
                   BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                  cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                  priceList1.getName(), priceList2.getName(),
                   PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
@@ -711,7 +711,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertion(Result.FOO, cr,
                   product1.getName(), product2.getName(),
                   BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                  priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                  priceList1.getName(), priceList2.getName(),
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
index d5acda6..66fa6bf 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
@@ -56,24 +56,6 @@ public class TestPlanRules extends CatalogTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testCannotChangeToSamePlan() throws CatalogApiException {
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
-        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-        final PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
-        final PlanSpecifier to = new PlanSpecifier(product1.getName(), BillingPeriod.MONTHLY, priceList1.getName());
-
-        try {
-            cat.getPlanRules().planChange(from, to, cat);
-            Assert.fail("We did not see an exception when  trying to change plan to the same plan");
-        } catch (IllegalPlanChange e) {
-            // Correct - cannot change to the same plan
-        } catch (CatalogApiException e) {
-            Assert.fail("", e);
-        }
-    }
-
-    @Test(groups = "fast")
     public void testExistingPriceListIsKept() throws CatalogApiException {
         final DefaultProduct product1 = cat.getCurrentProducts()[0];
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index a73e8f2..fa032bb 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -237,19 +237,13 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
         final Plan nextPlan = (transition.getNextPlan() != null) ? catalog.findPlan(transition.getNextPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
 
         final Plan plan = (transition.getTransitionType() != SubscriptionBaseTransitionType.CANCEL) ? nextPlan : prevPlan;
-        final Product product = plan.getProduct();
 
         final PlanPhase prevPhase = (transition.getPreviousPhase() != null) ? catalog.findPhase(transition.getPreviousPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
         final PlanPhase nextPhase = (transition.getNextPhase() != null) ? catalog.findPhase(transition.getNextPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-
         final PlanPhase phase = (transition.getTransitionType() != SubscriptionBaseTransitionType.CANCEL) ? nextPhase : prevPhase;
 
-        final BillingPeriod billingPeriod = phase.getRecurring() != null ? phase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD;
+        return new PlanPhaseSpecifier(plan.getName(), phase.getPhaseType());
 
-        return new PlanPhaseSpecifier(product.getName(),
-                                      billingPeriod,
-                                      transition.getNextPriceList(),
-                                      phase.getPhaseType());
     }
 
     private boolean is_AUTO_INVOICING_OFF(final List<Tag> tags) {
diff --git a/profiles/killbill/src/main/resources/killbill-server.properties b/profiles/killbill/src/main/resources/killbill-server.properties
index 1790759..19f583a 100644
--- a/profiles/killbill/src/main/resources/killbill-server.properties
+++ b/profiles/killbill/src/main/resources/killbill-server.properties
@@ -22,7 +22,7 @@ org.killbill.jruby.context.version=RUBY2_0
 # KILLBILL GENERIC PROPERTIES
 #
 # Database config
-org.killbill.dao.url=jdbc:mysql://127.0.0.1:3306/killbill
+org.killbill.dao.url=jdbc:mysql://127.0.0.1:3306/killbill_0_17_x
 org.killbill.dao.user=root
 org.killbill.dao.password=root
 org.killbill.dao.logLevel=DEBUG
@@ -61,7 +61,7 @@ org.killbill.tenant.broadcast.rate=1s
 # PLUGIN SPECIFIC PROPERTIES
 #
 # Database config (OSGI plugins)
-org.killbill.billing.osgi.dao.url=jdbc:mysql://127.0.0.1:3306/killbill
+org.killbill.billing.osgi.dao.url=jdbc:mysql://127.0.0.1:3306/killbill_0_17_x
 org.killbill.billing.osgi.dao.user=root
 org.killbill.billing.osgi.dao.password=root
 
@@ -82,7 +82,8 @@ org.killbill.server.test.mode=true
 # Set payment calls to timeout after 5 sec -- mostly for integration tests
 org.killbill.payment.plugin.timeout=5s
 
-org.killbill.payment.retry.days=
+org.killbill.payment.retry.days=1,1,1
+
 
 org.killbill.notificationq.analytics.tableName=analytics_notifications
 org.killbill.notificationq.analytics.historyTableName=analytics_notifications_history
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java b/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
index c69fb70..0d9d275 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
@@ -38,7 +38,6 @@ import org.killbill.billing.catalog.api.PlanAlignmentCreate;
 import org.killbill.billing.catalog.api.PlanPhase;
 import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
 import org.killbill.billing.catalog.api.PlanSpecifier;
-import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
 import org.killbill.billing.subscription.api.user.SubscriptionBaseTransitionData;
 import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
@@ -116,7 +115,7 @@ public class PlanAligner extends BaseAligner {
                                                    final String priceList,
                                                    final DateTime effectiveDate,
                                                    final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException {
-        return getTimedPhaseOnChange(subscription, plan, priceList, effectiveDate, WhichPhase.CURRENT, context);
+        return getTimedPhaseOnChange(subscription, plan, effectiveDate, WhichPhase.CURRENT, context);
     }
 
     /**
@@ -136,7 +135,7 @@ public class PlanAligner extends BaseAligner {
                                                 final String priceList,
                                                 final DateTime effectiveDate,
                                                 final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException {
-        return getTimedPhaseOnChange(subscription, plan, priceList, effectiveDate, WhichPhase.NEXT, context);
+        return getTimedPhaseOnChange(subscription, plan, effectiveDate, WhichPhase.NEXT, context);
     }
 
     /**
@@ -170,9 +169,7 @@ public class PlanAligner extends BaseAligner {
                                                  subscription.getBundleStartDate(),
                                                  lastPlanTransition.getPreviousPhase(),
                                                  lastPlanTransition.getPreviousPlan(),
-                                                 lastPlanTransition.getPreviousPriceList().getName(),
                                                  lastPlanTransition.getNextPlan(),
-                                                 lastPlanTransition.getNextPriceList().getName(),
                                                  effectiveDate,
                                                  lastPlanTransition.getEffectiveTransitionTime(),
                                                  subscription.getAllTransitions().get(0).getNextPhase().getPhaseType(),
@@ -197,9 +194,7 @@ public class PlanAligner extends BaseAligner {
             throws CatalogApiException, SubscriptionBaseApiException {
         final Catalog catalog = catalogService.getFullCatalog(true, true, context);
 
-        final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
-                                                              plan.getRecurringBillingPeriod(),
-                                                              priceList);
+        final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getName());
 
         final DateTime planStartDate;
         final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, effectiveDate);
@@ -219,7 +214,6 @@ public class PlanAligner extends BaseAligner {
 
     private TimedPhase getTimedPhaseOnChange(final DefaultSubscriptionBase subscription,
                                              final Plan nextPlan,
-                                             final String nextPriceList,
                                              final DateTime effectiveDate,
                                              final WhichPhase which,
                                              final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException {
@@ -227,9 +221,7 @@ public class PlanAligner extends BaseAligner {
                                      subscription.getBundleStartDate(),
                                      subscription.getCurrentPhase(),
                                      subscription.getCurrentPlan(),
-                                     subscription.getCurrentPriceList().getName(),
                                      nextPlan,
-                                     nextPriceList,
                                      effectiveDate,
                                      // This method is only called while doing the change, hence we want to pass the change effective date
                                      effectiveDate,
@@ -242,25 +234,17 @@ public class PlanAligner extends BaseAligner {
                                              final DateTime bundleStartDate,
                                              final PlanPhase currentPhase,
                                              final Plan currentPlan,
-                                             final String currentPriceList,
                                              final Plan nextPlan,
-                                             final String priceList,
                                              final DateTime effectiveDate,
                                              final DateTime lastOrCurrentChangeEffectiveDate,
                                              final PhaseType originalInitialPhase,
                                              final WhichPhase which,
                                              final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException {
         final Catalog catalog = catalogService.getFullCatalog(true, true, context);
-        final ProductCategory currentCategory = currentPlan.getProduct().getCategory();
-        final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                                                                                 currentPlan.getRecurringBillingPeriod(),
-                                                                                 currentPriceList,
+        final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getName(),
                                                                                  currentPhase.getPhaseType());
 
-        final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getProduct().getName(),
-                                                                nextPlan.getRecurringBillingPeriod(),
-                                                                priceList);
-
+        final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getName());
         final PhaseType initialPhase;
         final DateTime planStartDate;
         final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, effectiveDate);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index fe63e13..dbf1446 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -584,9 +584,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
                             if (policy == null) {
 
                                 final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
-                                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                                                                                       subscriptionForCancellation.getCurrentPlan().getRecurringBillingPeriod(),
-                                                                                       subscriptionForCancellation.getCurrentPriceList().getName(),
+                                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(),
                                                                                        subscriptionForCancellation.getCurrentPhase().getPhaseType());
                                 policy = catalogService.getFullCatalog(true, true, context).planCancelPolicy(spec, utcNow);
                             }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
index 552f878..9c677fd 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
@@ -124,7 +124,7 @@ public class DefaultSubscriptionBaseTimeline implements SubscriptionBaseTimeline
             final String planNameWithClosure = planName;
             final String planPhaseNameWithClosure = planPhaseName;
             final Integer billCycleDayLocalWithClosure = billCycleDayLocal;
-            final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, priceListName, phaseType);
+            final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(planName, phaseType);
             result.add(new ExistingEvent() {
                 @Override
                 public SubscriptionBaseTransitionType getSubscriptionTransitionType() {
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
index a814c2a..cffcd6b 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
@@ -179,9 +179,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
         final DateTime now = clock.getUTCNow();
 
         final Plan currentPlan = subscription.getCurrentPlan();
-        final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                                                                    subscription.getCurrentPlan().getRecurringBillingPeriod(),
-                                                                    subscription.getCurrentPriceList().getName(), null);
+        final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getName(), null);
 
         try {
             final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
@@ -377,9 +375,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
             final Plan currentPlan = subscription.getCurrentPlan();
 
             final PriceList currentPriceList = subscription.getCurrentPriceList();
-            final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                                                                            currentPlan.getRecurringBillingPeriod(),
-                                                                            currentPriceList.getName(),
+            final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getName(),
                                                                             subscription.getCurrentPhase().getPhaseType());
             planChangeResult = catalogService.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, effectiveDate);
         } catch (final CatalogApiException e) {