killbill-memoizeit

Refine catalog usage model

3/13/2014 11:11:50 PM

Details

diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
index 85b5bd6..a8ac56d 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
@@ -18,18 +18,26 @@ package org.killbill.billing.catalog;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlIDREF;
 
+import org.killbill.billing.ErrorCode;
 import org.killbill.billing.catalog.api.Block;
+import org.killbill.billing.catalog.api.BlockType;
+import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.InternationalPrice;
 import org.killbill.billing.catalog.api.Unit;
 import org.killbill.billing.util.config.catalog.ValidatingConfig;
+import org.killbill.billing.util.config.catalog.ValidationError;
 import org.killbill.billing.util.config.catalog.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultBlock extends ValidatingConfig<StandaloneCatalog> implements Block {
 
+    @XmlAttribute(required = false)
+    private BlockType type = BlockType.VANILLA;
+
     @XmlElement(required = true)
     @XmlIDREF
     private DefaultUnit unit;
@@ -40,10 +48,18 @@ public class DefaultBlock extends ValidatingConfig<StandaloneCatalog> implements
     @XmlElement(required = true)
     private DefaultInternationalPrice prices;
 
+    @XmlElement(required = false)
+    private Double minTopUpCredit;
+
     // Not defined in catalog
     private DefaultUsage usage;
 
     @Override
+    public BlockType getType() {
+        return type;
+    }
+
+    @Override
     public Unit getUnit() {
         return unit;
     }
@@ -59,10 +75,32 @@ public class DefaultBlock extends ValidatingConfig<StandaloneCatalog> implements
     }
 
     @Override
-    public ValidationErrors validate(final StandaloneCatalog root, final ValidationErrors errors) {
+    public Double getMinTopUpCredit() throws CatalogApiException {
+        if (type != BlockType.TOP_UP) {
+            throw new CatalogApiException(ErrorCode.CAT_NOT_TOP_UP_BLOCK, usage.getPhase().getName());
+        }
+        return minTopUpCredit;
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        if (type == BlockType.TOP_UP && minTopUpCredit == null) {
+            errors.add(new ValidationError(String.format("TOP_UP block needs to define minTopUpCredit for phase %s",
+                                                         usage.getPhase().toString()), catalog.getCatalogURI(), DefaultUsage.class, ""));
+        }
         return errors;
     }
 
+    public DefaultBlock setType(final BlockType type) {
+        this.type = type;
+        return this;
+    }
+
+    public DefaultBlock setPrices(final DefaultInternationalPrice prices) {
+        this.prices = prices;
+        return this;
+    }
+
     public DefaultBlock setUnit(final DefaultUnit unit) {
         this.unit = unit;
         return this;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
index fec873b..105a629 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
@@ -25,6 +25,7 @@ import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.Block;
 import org.killbill.billing.catalog.api.InternationalPrice;
 import org.killbill.billing.catalog.api.Tier;
+import org.killbill.billing.catalog.api.TieredBlock;
 import org.killbill.billing.catalog.api.UsageType;
 import org.killbill.billing.util.config.catalog.ValidatingConfig;
 import org.killbill.billing.util.config.catalog.ValidationError;
@@ -38,8 +39,8 @@ public class DefaultTier extends ValidatingConfig<StandaloneCatalog> implements 
     private DefaultLimit[] limits = new DefaultLimit[0];
 
     @XmlElementWrapper(name = "blocks", required = false)
-    @XmlElement(name = "block", required = true)
-    private DefaultBlock[] blocks = new DefaultBlock[0];
+    @XmlElement(name = "tieredBlock", required = true)
+    private DefaultTieredBlock[] blocks = new DefaultTieredBlock[0];
 
     // Used to define a fixed price for the whole tier section
     @XmlElement(required = false)
@@ -59,7 +60,7 @@ public class DefaultTier extends ValidatingConfig<StandaloneCatalog> implements 
     }
 
     @Override
-    public Block[] getBlocks() {
+    public DefaultTieredBlock[] getTieredBlocks() {
         return blocks;
     }
 
@@ -78,7 +79,7 @@ public class DefaultTier extends ValidatingConfig<StandaloneCatalog> implements 
         return this;
     }
 
-    public DefaultTier setBlocks(final DefaultBlock[] blocks) {
+    public DefaultTier setBlocks(final DefaultTieredBlock[] blocks) {
         this.blocks = blocks;
         return this;
     }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
new file mode 100644
index 0000000..e8ee088
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 The Billing Project, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.catalog;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+import org.killbill.billing.catalog.api.BlockType;
+import org.killbill.billing.catalog.api.TieredBlock;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class DefaultTieredBlock extends DefaultBlock implements TieredBlock {
+
+    @XmlElement(required = true)
+    private Double max;
+
+    @Override
+    public Double getMax() {
+        return max;
+    }
+
+    public DefaultTieredBlock setMax(final Double max) {
+        this.max = max;
+        return this;
+    }
+
+    @Override
+    public BlockType getType() {
+        return BlockType.TIERED;
+    }
+
+    @Override
+    public DefaultTieredBlock setType(final BlockType type) {
+        super.setType(BlockType.TIERED);
+        return this;
+    }
+}
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
index d5c172c..3987355 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
@@ -19,6 +19,7 @@ package org.killbill.billing.catalog.io;
 import java.math.BigDecimal;
 
 import org.killbill.billing.catalog.CatalogTestSuiteNoDB;
+import org.killbill.billing.catalog.DefaultTieredBlock;
 import org.killbill.billing.catalog.StandaloneCatalog;
 import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
@@ -138,6 +139,9 @@ public class TestXMLReader extends CatalogTestSuiteNoDB {
             assertEquals(usage.getBlocks()[0].getPrice().getPrices().length, 1);
             assertEquals(usage.getBlocks()[0].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
             assertEquals(usage.getBlocks()[0].getPrice().getPrices()[0].getValue(), new BigDecimal("0.10"));
+
+            assertEquals(usage.getBlocks()[0].getMinTopUpCredit(), new Double("5"));
+
         } catch (Exception e) {
             Assert.fail(e.toString());
         }
@@ -212,19 +216,21 @@ public class TestXMLReader extends CatalogTestSuiteNoDB {
 
             assertEquals(usage.getTiers().length, 1);
 
-
-            assertEquals(usage.getTiers()[0].getBlocks().length, 2);
-            assertEquals(usage.getTiers()[0].getBlocks()[0].getUnit().getName(), "cell-phone-minutes");
-            assertEquals(usage.getTiers()[0].getBlocks()[0].getSize(), new Double("1000"));
-            assertEquals(usage.getTiers()[0].getBlocks()[0].getPrice().getPrices().length, 1);
-            assertEquals(usage.getTiers()[0].getBlocks()[0].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
-            assertEquals(usage.getTiers()[0].getBlocks()[0].getPrice().getPrices()[0].getValue(), new BigDecimal("0.5"));
-
-            assertEquals(usage.getTiers()[0].getBlocks()[1].getUnit().getName(), "Mbytes");
-            assertEquals(usage.getTiers()[0].getBlocks()[1].getSize(), new Double("512"));
-            assertEquals(usage.getTiers()[0].getBlocks()[1].getPrice().getPrices().length, 1);
-            assertEquals(usage.getTiers()[0].getBlocks()[1].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
-            assertEquals(usage.getTiers()[0].getBlocks()[1].getPrice().getPrices()[0].getValue(), new BigDecimal("0.3"));
+            assertEquals(usage.getTiers()[0].getTieredBlocks().length, 2);
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getUnit().getName(), "cell-phone-minutes");
+
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getSize(), new Double("1000"));
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getMax(), new Double("10000"));
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getPrice().getPrices().length, 1);
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[0].getPrice().getPrices()[0].getValue(), new BigDecimal("0.5"));
+
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getUnit().getName(), "Mbytes");
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getSize(), new Double("512"));
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getMax(), new Double("512000"));
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getPrice().getPrices().length, 1);
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
+            assertEquals(usage.getTiers()[0].getTieredBlocks()[1].getPrice().getPrices()[0].getValue(), new BigDecimal("0.3"));
         } catch (Exception e) {
             Assert.fail(e.toString());
         }
diff --git a/catalog/src/test/resources/UsageExperimental.xml b/catalog/src/test/resources/UsageExperimental.xml
index 7fab1ff..cd18fd9 100644
--- a/catalog/src/test/resources/UsageExperimental.xml
+++ b/catalog/src/test/resources/UsageExperimental.xml
@@ -138,20 +138,16 @@
                     <usage billingMode="IN_ADVANCE" usageType="CONSUMABLE">
                         <billingPeriod>NO_BILLING_PERIOD</billingPeriod>
                         <blocks>
-                            <block>
+                            <block type="TOP_UP">
                                 <unit>fastrack-tokens</unit>
                                 <size>10</size>
-                                <!-- Specify to refill account when 'account' value drops to min
-                                Unclear if this should really be a block attribute.
-                                -->
-                                <!-- <min>5</min> -->
-
                                 <prices>
                                     <price>
                                         <currency>BTC</currency>
                                         <value>0.10</value>
                                     </price>
                                 </prices>
+                                <minTopUpCredit>5</minTopUpCredit>
                             </block>
                         </blocks>
                     </usage>
@@ -238,7 +234,7 @@
                         <tiers>
                             <tier>
                                 <blocks>
-                                    <block>
+                                    <tieredBlock>
                                         <unit>cell-phone-minutes</unit>
                                         <size>1000</size>
                                         <prices>
@@ -247,8 +243,9 @@
                                                 <value>0.5</value>
                                             </price>
                                         </prices>
-                                    </block>
-                                    <block>
+                                        <max>10000</max>
+                                    </tieredBlock>
+                                    <tieredBlock>
                                         <unit>Mbytes</unit>
                                         <size>512</size>
                                         <prices>
@@ -257,7 +254,8 @@
                                                 <value>0.3</value>
                                             </price>
                                         </prices>
-                                    </block>
+                                        <max>512000</max>
+                                    </tieredBlock>
                                 </blocks>
                             </tier>
                         </tiers>