killbill-memoizeit

subscription: Fixes #377 Refactor the EventBuilder to make

8/26/2015 9:18:22 PM

Changes

Details

diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/migration/DefaultSubscriptionBaseMigrationApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/migration/DefaultSubscriptionBaseMigrationApi.java
index 2fc9585..01746a9 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/migration/DefaultSubscriptionBaseMigrationApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/migration/DefaultSubscriptionBaseMigrationApi.java
@@ -255,11 +255,11 @@ public class DefaultSubscriptionBaseMigrationApi extends SubscriptionApiBase imp
             int compForApiType(final SubscriptionBaseEvent o1, final SubscriptionBaseEvent o2, final ApiEventType type) {
                 ApiEventType apiO1 = null;
                 if (o1.getType() == EventType.API_USER) {
-                    apiO1 = ((ApiEvent) o1).getEventType();
+                    apiO1 = ((ApiEvent) o1).getApiEventType();
                 }
                 ApiEventType apiO2 = null;
                 if (o2.getType() == EventType.API_USER) {
-                    apiO2 = ((ApiEvent) o2).getEventType();
+                    apiO2 = ((ApiEvent) o2).getApiEventType();
                 }
                 if (apiO1 != null && apiO1.equals(type)) {
                     return -1;
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 5ec8723..33a57d3 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
@@ -20,7 +20,6 @@ package org.killbill.billing.subscription.api.svcs;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -119,7 +118,6 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
         this.notificationQueueService = notificationQueueService;
     }
 
-
     @Override
     public SubscriptionBase createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final DateTime requestedDateWithMs, final InternalCallContext context) throws SubscriptionBaseApiException {
         try {
@@ -509,12 +507,11 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
                     return input.getEffectiveDate();
                 }
             });
-        } catch(NoSuchNotificationQueue noSuchNotificationQueue) {
+        } catch (NoSuchNotificationQueue noSuchNotificationQueue) {
             throw new IllegalStateException(noSuchNotificationQueue);
         }
     }
 
-
     @Override
     public Map<UUID, DateTime> getNextFutureEventForSubscriptions(final SubscriptionBaseTransitionType eventType, final InternalCallContext internalCallContext) {
         final Iterable<SubscriptionBaseEvent> events = dao.getFutureEventsForAccount(internalCallContext);
@@ -524,7 +521,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
                 return (eventType == SubscriptionBaseTransitionType.PHASE && input.getType() == EventType.PHASE) || input.getType() != EventType.PHASE;
             }
         });
-        final Map<UUID, DateTime> result  = filteredEvents.iterator().hasNext() ? new HashMap<UUID, DateTime>() : ImmutableMap.<UUID, DateTime>of();
+        final Map<UUID, DateTime> result = filteredEvents.iterator().hasNext() ? new HashMap<UUID, DateTime>() : ImmutableMap.<UUID, DateTime>of();
         for (SubscriptionBaseEvent cur : filteredEvents) {
             final DateTime targetDate = result.get(cur.getSubscriptionId());
             if (targetDate == null || targetDate.compareTo(cur.getEffectiveDate()) > 0) {
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 5b4c7d7..73de18a 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
@@ -107,7 +107,7 @@ public class DefaultSubscriptionBaseTimeline implements SubscriptionBaseTimeline
 
                 case API_USER:
                     final ApiEvent userEV = (ApiEvent) cur;
-                    apiType = userEV.getEventType();
+                    apiType = userEV.getApiEventType();
                     planName = userEV.getEventPlan();
                     planPhaseName = userEV.getEventPlanPhase();
                     final Plan plan = (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getRequestedDate(), startDate) : null;
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
index a7ae3e9..184c3db 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
@@ -414,7 +414,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
         }
         // Since UNCANCEL are not part of the transitions, we compute a new 'UNCANCEL' transition based on the event right before that UNCANCEL
         // This is used to be able to send a bus event for uncancellation
-        if (prev != null && event.getType() == EventType.API_USER && ((ApiEvent) event).getEventType() == ApiEventType.UNCANCEL) {
+        if (prev != null && event.getType() == EventType.API_USER && ((ApiEvent) event).getApiEventType() == ApiEventType.UNCANCEL) {
             final SubscriptionBaseTransitionData withSeq = new SubscriptionBaseTransitionData((SubscriptionBaseTransitionData) prev, EventType.API_USER, ApiEventType.UNCANCEL, seqId);
             return withSeq;
         }
@@ -583,7 +583,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
 
                 case API_USER:
                     final ApiEvent userEV = (ApiEvent) cur;
-                    apiEventType = userEV.getEventType();
+                    apiEventType = userEV.getApiEventType();
                     isFromDisk = userEV.isFromDisk();
 
                     switch (apiEventType) {
@@ -617,7 +617,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
                         default:
                             throw new SubscriptionBaseError(String.format(
                                     "Unexpected UserEvent type = %s", userEV
-                                            .getEventType().toString()));
+                                            .getApiEventType().toString()));
                     }
                     break;
                 default:
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
index 9bbbd32..63d5d56 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
@@ -65,9 +65,11 @@ import org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey
 import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleModelDao;
 import org.killbill.billing.subscription.engine.dao.model.SubscriptionEventModelDao;
 import org.killbill.billing.subscription.engine.dao.model.SubscriptionModelDao;
+import org.killbill.billing.subscription.events.EventBaseBuilder;
 import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
 import org.killbill.billing.subscription.events.SubscriptionBaseEvent.EventType;
 import org.killbill.billing.subscription.events.phase.PhaseEvent;
+import org.killbill.billing.subscription.events.phase.PhaseEventBuilder;
 import org.killbill.billing.subscription.events.user.ApiEvent;
 import org.killbill.billing.subscription.events.user.ApiEventBuilder;
 import org.killbill.billing.subscription.events.user.ApiEventCancel;
@@ -673,7 +675,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
             }
 
             if (cur.getEffectiveDate().compareTo(migrateBillingEvent.getEffectiveDate()) > 0) {
-                if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getEventType() == ApiEventType.CHANGE) {
+                if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getApiEventType() == ApiEventType.CHANGE) {
                     // This is an EOT change that is occurring after the MigrateBilling : returns same list
                     return changeEvents;
                 }
@@ -690,7 +692,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
             final DateTime now = clock.getUTCNow();
             final ApiEventBuilder builder = new ApiEventBuilder()
                     .setActive(true)
-                    .setEventType(ApiEventType.MIGRATE_BILLING)
+                    .setApiEventType(ApiEventType.MIGRATE_BILLING)
                     .setFromDisk(true)
                     .setTotalOrdering(migrateBillingEvent.getTotalOrdering())
                     .setUuid(UUIDs.randomUUID())
@@ -942,10 +944,18 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
                     }
                 }
                 // Set total ordering value of the fake dryRun event to make sure billing events are correctly ordered
+                final SubscriptionBaseEvent curAdjustedDryRun;
                 if (!events.isEmpty()) {
-                    curDryRun.setTotalOrdering(events.get(events.size() - 1).getTotalOrdering() + 1);
+                    final EventBaseBuilder eventBuilder = (curDryRun.getType() == EventType.API_USER) ?
+                                                          new ApiEventBuilder((ApiEvent) curDryRun) :
+                                                          new PhaseEventBuilder((PhaseEvent) curDryRun);
+                    eventBuilder.setTotalOrdering(events.get(events.size() - 1).getTotalOrdering() + 1);
+
+                    curAdjustedDryRun = eventBuilder.build();
+                } else {
+                    curAdjustedDryRun = curDryRun;
                 }
-                events.add(curDryRun);
+                events.add(curAdjustedDryRun);
             }
         }
     }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionEventModelDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionEventModelDao.java
index f6b13df..58d75af 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionEventModelDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionEventModelDao.java
@@ -39,7 +39,6 @@ import org.killbill.billing.subscription.events.user.ApiEventType;
 import org.killbill.billing.subscription.events.user.ApiEventUncancel;
 import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
 import org.killbill.billing.util.dao.TableName;
-import org.killbill.billing.entity.EntityBase;
 import org.killbill.billing.util.entity.dao.EntityModelDao;
 import org.killbill.billing.util.entity.dao.EntityModelDaoBase;
 
@@ -83,7 +82,7 @@ public class SubscriptionEventModelDao extends EntityModelDaoBase implements Ent
         super(src.getId(), src.getCreatedDate(), src.getUpdatedDate());
         this.totalOrdering = src.getTotalOrdering();
         this.eventType = src.getType();
-        this.userType = eventType == EventType.API_USER ? ((ApiEvent) src).getEventType() : null;
+        this.userType = eventType == EventType.API_USER ? ((ApiEvent) src).getApiEventType() : null;
         this.requestedDate = src.getRequestedDate();
         this.effectiveDate = src.getEffectiveDate();
         this.subscriptionId = src.getSubscriptionId();
@@ -206,36 +205,18 @@ public class SubscriptionEventModelDao extends EntityModelDaoBase implements Ent
                 .setActiveVersion(src.getCurrentVersion())
                 .setActive(src.isActive());
 
-        SubscriptionBaseEvent result = null;
+        SubscriptionBaseEvent result;
         if (src.getEventType() == EventType.PHASE) {
-            result = new PhaseEventData(new PhaseEventBuilder(base).setPhaseName(src.getPhaseName()));
+            result = (new PhaseEventBuilder(base).setPhaseName(src.getPhaseName())).build();
         } else if (src.getEventType() == EventType.API_USER) {
             final ApiEventBuilder builder = new ApiEventBuilder(base)
                     .setEventPlan(src.getPlanName())
                     .setEventPlanPhase(src.getPhaseName())
                     .setEventPriceList(src.getPriceListName())
-                    .setEventType(src.getUserType())
+                    .setApiEventType(src.getUserType())
+                    .setApiEventType(src.getUserType())
                     .setFromDisk(true);
-
-            if (src.getUserType() == ApiEventType.CREATE) {
-                result = new ApiEventCreate(builder);
-            } else if (src.getUserType() == ApiEventType.RE_CREATE) {
-                result = new ApiEventReCreate(builder);
-            } else if (src.getUserType() == ApiEventType.MIGRATE_ENTITLEMENT) {
-                result = new ApiEventMigrateSubscription(builder);
-            } else if (src.getUserType() == ApiEventType.MIGRATE_BILLING) {
-                result = new ApiEventMigrateBilling(builder);
-            } else if (src.getUserType() == ApiEventType.TRANSFER) {
-                result = new ApiEventTransfer(builder);
-            } else if (src.getUserType() == ApiEventType.CHANGE) {
-                result = new ApiEventChange(builder);
-            } else if (src.getUserType() == ApiEventType.CANCEL) {
-                result = new ApiEventCancel(builder);
-            } else if (src.getUserType() == ApiEventType.RE_CREATE) {
-                result = new ApiEventReCreate(builder);
-            } else if (src.getUserType() == ApiEventType.UNCANCEL) {
-                result = new ApiEventUncancel(builder);
-            }
+            result = builder.build();
         } else {
             throw new SubscriptionBaseError(String.format("Can't figure out event %s", src.getEventType()));
         }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/EventBase.java b/subscription/src/main/java/org/killbill/billing/subscription/events/EventBase.java
index 95d86d1..35fdd1e 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/EventBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/EventBase.java
@@ -31,9 +31,9 @@ public abstract class EventBase implements SubscriptionBaseEvent {
     private final DateTime requestedDate;
     private final DateTime effectiveDate;
 
-    private long totalOrdering;
-    private long activeVersion;
-    private boolean isActive;
+    private final long totalOrdering;
+    private final long activeVersion;
+    private final boolean isActive;
 
     public EventBase(final EventBaseBuilder<?> builder) {
         this.totalOrdering = builder.getTotalOrdering();
@@ -88,20 +88,10 @@ public abstract class EventBase implements SubscriptionBaseEvent {
     }
 
     @Override
-    public void setActiveVersion(final long activeVersion) {
-        this.activeVersion = activeVersion;
-    }
-
-    @Override
     public boolean isActive() {
         return isActive;
     }
 
-    @Override
-    public void setTotalOrdering(final long totalOrdering) {
-        this.totalOrdering = totalOrdering;
-    }
-
     //
     // Really used for unit tests only as the sql implementation relies on date first and then event insertion
     //
@@ -128,7 +118,7 @@ public abstract class EventBase implements SubscriptionBaseEvent {
         } else if (getType() != other.getType()) {
             return (getType() == EventType.PHASE) ? -1 : 1;
         } else if (getType() == EventType.API_USER) {
-            return ((ApiEvent) this).getEventType().compareTo(((ApiEvent) other).getEventType());
+            return ((ApiEvent) this).getApiEventType().compareTo(((ApiEvent) other).getApiEventType());
         } else {
             return uuid.compareTo(other.getId());
         }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/EventBaseBuilder.java b/subscription/src/main/java/org/killbill/billing/subscription/events/EventBaseBuilder.java
index ea022cf..7487b8a 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/EventBaseBuilder.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/EventBaseBuilder.java
@@ -22,7 +22,7 @@ import org.joda.time.DateTime;
 import org.killbill.billing.util.UUIDs;
 
 @SuppressWarnings("unchecked")
-public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
+public abstract class EventBaseBuilder<T extends EventBaseBuilder<T>> {
 
     private long totalOrdering;
     private UUID uuid;
@@ -40,12 +40,26 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
         this.isActive = true;
     }
 
+
+    public EventBaseBuilder(final SubscriptionBaseEvent event) {
+        this.uuid = event.getId();
+        this.subscriptionId = event.getSubscriptionId();
+        this.requestedDate = event.getRequestedDate();
+        this.effectiveDate = event.getEffectiveDate();
+        this.createdDate = event.getCreatedDate();
+        this.updatedDate = event.getUpdatedDate();
+        this.activeVersion = event.getActiveVersion();
+        this.isActive = event.isActive();
+        this.totalOrdering = event.getTotalOrdering();
+    }
+
     public EventBaseBuilder(final EventBaseBuilder<?> copy) {
         this.uuid = copy.uuid;
         this.subscriptionId = copy.subscriptionId;
         this.requestedDate = copy.requestedDate;
         this.effectiveDate = copy.effectiveDate;
         this.createdDate = copy.getCreatedDate();
+        this.updatedDate = copy.getUpdatedDate();
         this.activeVersion = copy.activeVersion;
         this.isActive = copy.isActive;
         this.totalOrdering = copy.totalOrdering;
@@ -131,4 +145,6 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
     public boolean isActive() {
         return isActive;
     }
+
+    public abstract SubscriptionBaseEvent build();
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/phase/PhaseEventBuilder.java b/subscription/src/main/java/org/killbill/billing/subscription/events/phase/PhaseEventBuilder.java
index 21f22e8..10f676f 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/phase/PhaseEventBuilder.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/phase/PhaseEventBuilder.java
@@ -27,6 +27,11 @@ public class PhaseEventBuilder extends EventBaseBuilder<PhaseEventBuilder> {
         super();
     }
 
+    public PhaseEventBuilder(final PhaseEvent phaseEvent) {
+        super(phaseEvent);
+        this.phaseName = phaseEvent.getPhase();
+    }
+
     public PhaseEventBuilder(final EventBaseBuilder<?> base) {
         super(base);
     }
@@ -39,4 +44,8 @@ public class PhaseEventBuilder extends EventBaseBuilder<PhaseEventBuilder> {
     public String getPhaseName() {
         return phaseName;
     }
+
+    public PhaseEvent build() {
+        return new PhaseEventData(this);
+    }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/SubscriptionBaseEvent.java b/subscription/src/main/java/org/killbill/billing/subscription/events/SubscriptionBaseEvent.java
index 23b5b20..c610aa0 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/SubscriptionBaseEvent.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/SubscriptionBaseEvent.java
@@ -34,12 +34,8 @@ public interface SubscriptionBaseEvent extends Comparable<SubscriptionBaseEvent>
 
     public long getTotalOrdering();
 
-    public void setTotalOrdering(long totalOrdering);
-
     public long getActiveVersion();
 
-    public void setActiveVersion(long activeVersion);
-
     public boolean isActive();
 
     public DateTime getRequestedDate();
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEvent.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEvent.java
index a1bf77f..ea13387 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEvent.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEvent.java
@@ -25,7 +25,7 @@ public interface ApiEvent extends SubscriptionBaseEvent {
 
     public String getEventPlanPhase();
 
-    public ApiEventType getEventType();
+    public ApiEventType getApiEventType();
 
     public String getPriceList();
 
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBase.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBase.java
index 140b2a4..be40564 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBase.java
@@ -20,7 +20,7 @@ import org.killbill.billing.subscription.events.EventBase;
 
 public class ApiEventBase extends EventBase implements ApiEvent {
 
-    private final ApiEventType eventType;
+    private final ApiEventType apiEventType;
     // Only valid for CREATE/CHANGE
     private final String eventPlan;
     private final String eventPlanPhase;
@@ -29,7 +29,7 @@ public class ApiEventBase extends EventBase implements ApiEvent {
 
     public ApiEventBase(final ApiEventBuilder builder) {
         super(builder);
-        this.eventType = builder.getEventType();
+        this.apiEventType = builder.getApiEventType();
         this.eventPriceList = builder.getEventPriceList();
         this.eventPlan = builder.getEventPlan();
         this.eventPlanPhase = builder.getEventPlanPhase();
@@ -37,8 +37,8 @@ public class ApiEventBase extends EventBase implements ApiEvent {
     }
 
     @Override
-    public ApiEventType getEventType() {
-        return eventType;
+    public ApiEventType getApiEventType() {
+        return apiEventType;
     }
 
     @Override
@@ -70,10 +70,10 @@ public class ApiEventBase extends EventBase implements ApiEvent {
     @Override
     public String toString() {
         return "ApiEventBase [ getId()= " + getId()
-               + " eventType=" + eventType
+               + " apiEventType=" + apiEventType
                + ", eventPlan=" + eventPlan
                + ", eventPlanPhase=" + eventPlanPhase
-               + ", getEventType()=" + getEventType()
+               + ", getApiEventType()=" + getApiEventType()
                + ", getEventPlan()=" + getEventPlan()
                + ", getEventPlanPhase()=" + getEventPlanPhase()
                + ", getType()=" + getType()
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBuilder.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBuilder.java
index 2568e76..18cedb6 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBuilder.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventBuilder.java
@@ -18,26 +18,33 @@ package org.killbill.billing.subscription.events.user;
 
 import org.killbill.billing.subscription.events.EventBaseBuilder;
 
-
 public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
 
-    private ApiEventType eventType;
+    private ApiEventType apiEventType;
     private String eventPlan;
     private String eventPlanPhase;
     private String eventPriceList;
     private boolean fromDisk;
 
-
     public ApiEventBuilder() {
         super();
     }
 
+    public ApiEventBuilder(final ApiEvent apiEvent) {
+        super(apiEvent);
+        this.apiEventType = apiEvent.getApiEventType();
+        this.eventPlan = apiEvent.getEventPlan();
+        this.eventPlanPhase = apiEvent.getEventPlanPhase();
+        this.eventPriceList = apiEvent.getPriceList();
+        this.fromDisk = apiEvent.isFromDisk();
+    }
+
     public ApiEventBuilder(final EventBaseBuilder<?> base) {
         super(base);
     }
 
-    public ApiEventType getEventType() {
-        return eventType;
+    public ApiEventType getApiEventType() {
+        return apiEventType;
     }
 
     public String getEventPlan() {
@@ -61,8 +68,8 @@ public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
         return this;
     }
 
-    public ApiEventBuilder setEventType(final ApiEventType eventType) {
-        this.eventType = eventType;
+    public ApiEventBuilder setApiEventType(final ApiEventType eventType) {
+        this.apiEventType = eventType;
         return this;
     }
 
@@ -80,4 +87,30 @@ public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
         this.eventPriceList = eventPriceList;
         return this;
     }
+    
+    public ApiEventBase build() {
+        final ApiEventBase result;
+        if (apiEventType == ApiEventType.CREATE) {
+            result = new ApiEventCreate(this);
+        } else if (apiEventType == ApiEventType.RE_CREATE) {
+            result = new ApiEventReCreate(this);
+        } else if (apiEventType == ApiEventType.MIGRATE_ENTITLEMENT) {
+            result = new ApiEventMigrateSubscription(this);
+        } else if (apiEventType == ApiEventType.MIGRATE_BILLING) {
+            result = new ApiEventMigrateBilling(this);
+        } else if (apiEventType == ApiEventType.TRANSFER) {
+            result = new ApiEventTransfer(this);
+        } else if (apiEventType == ApiEventType.CHANGE) {
+            result = new ApiEventChange(this);
+        } else if (apiEventType == ApiEventType.CANCEL) {
+            result = new ApiEventCancel(this);
+        } else if (apiEventType == ApiEventType.RE_CREATE) {
+            result = new ApiEventReCreate(this);
+        } else if (apiEventType == ApiEventType.UNCANCEL) {
+            result = new ApiEventUncancel(this);
+        } else {
+            throw new IllegalStateException("Unknown ApiEventType " + apiEventType);
+        }
+        return result;
+    }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCancel.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCancel.java
index 5634f72..55c40e8 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCancel.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCancel.java
@@ -20,6 +20,6 @@ public class ApiEventCancel extends ApiEventBase {
 
 
     public ApiEventCancel(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.CANCEL));
+        super(builder.setApiEventType(ApiEventType.CANCEL));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventChange.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventChange.java
index dd440fc..05b5878 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventChange.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventChange.java
@@ -20,6 +20,6 @@ package org.killbill.billing.subscription.events.user;
 public class ApiEventChange extends ApiEventBase {
 
     public ApiEventChange(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.CHANGE));
+        super(builder.setApiEventType(ApiEventType.CHANGE));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCreate.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCreate.java
index 84d856e..e1b068c 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCreate.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventCreate.java
@@ -20,6 +20,6 @@ package org.killbill.billing.subscription.events.user;
 public class ApiEventCreate extends ApiEventBase {
 
     public ApiEventCreate(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.CREATE));
+        super(builder.setApiEventType(ApiEventType.CREATE));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateBilling.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateBilling.java
index d4b17c1..cc1e3a8 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateBilling.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateBilling.java
@@ -18,6 +18,6 @@ package org.killbill.billing.subscription.events.user;
 
 public class ApiEventMigrateBilling extends ApiEventBase {
     public ApiEventMigrateBilling(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.MIGRATE_BILLING));
+        super(builder.setApiEventType(ApiEventType.MIGRATE_BILLING));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateSubscription.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateSubscription.java
index 7594d91..6194af2 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateSubscription.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventMigrateSubscription.java
@@ -19,6 +19,6 @@ package org.killbill.billing.subscription.events.user;
 public class ApiEventMigrateSubscription extends ApiEventBase {
 
     public ApiEventMigrateSubscription(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.MIGRATE_ENTITLEMENT));
+        super(builder.setApiEventType(ApiEventType.MIGRATE_ENTITLEMENT));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventReCreate.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventReCreate.java
index 2b1e025..76fe64b 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventReCreate.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventReCreate.java
@@ -19,6 +19,6 @@ package org.killbill.billing.subscription.events.user;
 public class ApiEventReCreate extends ApiEventBase {
 
     public ApiEventReCreate(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.RE_CREATE));
+        super(builder.setApiEventType(ApiEventType.RE_CREATE));
     }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventTransfer.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventTransfer.java
index d432b0a..a304b72 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventTransfer.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventTransfer.java
@@ -17,7 +17,7 @@ package org.killbill.billing.subscription.events.user;
 
 public class ApiEventTransfer extends ApiEventBase {
     public ApiEventTransfer(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.TRANSFER));
+        super(builder.setApiEventType(ApiEventType.TRANSFER));
     }
 
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventUncancel.java b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventUncancel.java
index 5e56d95..5f3755c 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventUncancel.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/events/user/ApiEventUncancel.java
@@ -19,6 +19,6 @@ package org.killbill.billing.subscription.events.user;
 public class ApiEventUncancel extends ApiEventBase {
 
     public ApiEventUncancel(final ApiEventBuilder builder) {
-        super(builder.setEventType(ApiEventType.UNCANCEL));
+        super(builder.setApiEventType(ApiEventType.UNCANCEL));
     }
 }
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/alignment/TestPlanAligner.java b/subscription/src/test/java/org/killbill/billing/subscription/alignment/TestPlanAligner.java
index 75172ff..4d7a3e6 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/alignment/TestPlanAligner.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/alignment/TestPlanAligner.java
@@ -223,7 +223,7 @@ public class TestPlanAligner extends SubscriptionTestSuiteNoDB {
         eventBuilder.setFromDisk(true);
         eventBuilder.setActiveVersion(activeVersion);
 
-        return new ApiEventBase(eventBuilder.setEventType(apiEventType));
+        return new ApiEventBase(eventBuilder.setApiEventType(apiEventType));
     }
 
     private TimedPhase getNextTimedPhaseOnChange(final DefaultSubscriptionBase defaultSubscriptionBase,
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
index 02a39de..6483634 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
@@ -101,7 +101,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
         Assert.assertEquals(events.size(), 1);
         Assert.assertEquals(events.get(0).getType(), EventType.API_USER);
         Assert.assertEquals(events.get(0).getEffectiveDate(), transferDate);
-        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getEventType(), ApiEventType.TRANSFER);
+        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getApiEventType(), ApiEventType.TRANSFER);
     }
 
     @Test(groups = "fast")
@@ -115,7 +115,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
         Assert.assertEquals(events.size(), 1);
         Assert.assertEquals(events.get(0).getType(), EventType.API_USER);
         Assert.assertEquals(events.get(0).getEffectiveDate(), transferDate);
-        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getEventType(), ApiEventType.TRANSFER);
+        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getApiEventType(), ApiEventType.TRANSFER);
     }
 
     @Test(groups = "fast")
@@ -129,7 +129,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
         Assert.assertEquals(events.size(), 1);
         Assert.assertEquals(events.get(0).getType(), EventType.API_USER);
         Assert.assertEquals(events.get(0).getEffectiveDate(), transferDate);
-        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getEventType(), ApiEventType.TRANSFER);
+        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getApiEventType(), ApiEventType.TRANSFER);
     }
 
     @Test(groups = "fast")
@@ -143,7 +143,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
         Assert.assertEquals(events.size(), 1);
         Assert.assertEquals(events.get(0).getType(), EventType.API_USER);
         Assert.assertEquals(events.get(0).getEffectiveDate(), transferDate);
-        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getEventType(), ApiEventType.TRANSFER);
+        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getApiEventType(), ApiEventType.TRANSFER);
     }
 
     @Test(groups = "fast")
@@ -157,7 +157,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
         Assert.assertEquals(events.size(), 1);
         Assert.assertEquals(events.get(0).getType(), EventType.API_USER);
         Assert.assertEquals(events.get(0).getEffectiveDate(), migrateSubscriptionEventEffectiveDate);
-        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getEventType(), ApiEventType.TRANSFER);
+        Assert.assertEquals(((ApiEventTransfer) events.get(0)).getApiEventType(), ApiEventType.TRANSFER);
     }
 
     private List<SubscriptionBaseEvent> transferBundle(final DateTime migrateSubscriptionEventEffectiveDate, final DateTime migrateBillingEventEffectiveDate,
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
index 3034a36..487a3d9 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
@@ -125,7 +125,7 @@ public class TestSubscriptionHelper {
                     assertEquals(cur.getEffectiveDate(), expPhaseChange);
                 } else if (cur instanceof ApiEvent) {
                     final ApiEvent uEvent = (ApiEvent) cur;
-                    assertEquals(ApiEventType.CHANGE, uEvent.getEventType());
+                    assertEquals(ApiEventType.CHANGE, uEvent.getApiEventType());
                     assertEquals(foundChange, false);
                     foundChange = true;
                 } else {
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
index 6cc963b..1d95133 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
@@ -394,7 +394,7 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
                     continue;
                 }
                 if (cur.getType() == EventType.API_USER &&
-                    ApiEventType.CHANGE == ((ApiEvent) cur).getEventType() &&
+                    ApiEventType.CHANGE == ((ApiEvent) cur).getApiEventType() &&
                     cur.getEffectiveDate().isAfter(clock.getUTCNow())) {
                     it.remove();
                     break;
@@ -416,7 +416,7 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
                     continue;
                 }
                 if (cur.getType() == EventType.API_USER &&
-                    ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
+                    ((ApiEvent) cur).getApiEventType() == ApiEventType.CANCEL) {
                     it.remove();
                     foundCancel = true;
                     break;