killbill-memoizeit

Major refactoring from events. What a bad idea right before

11/24/2011 2:00:19 AM

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index df896e8..0a2715f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -40,6 +40,7 @@ import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCreate;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.Clock;
@@ -154,10 +155,15 @@ public class EntitlementUserApi implements IEntitlementUserApi {
                 false);
 
         TimedPhase currentTimedPhase =  planAligner.getCurrentTimedPhaseOnCreate(subscription, plan, realPriceList, effectiveDate);
-        ApiEventCreate creationEvent =
-            new ApiEventCreate(subscription.getId(), bundleStartDate, now, plan.getName(), currentTimedPhase.getPhase().getName(), realPriceList,
-                    requestedDate, effectiveDate, subscription.getActiveVersion());
-
+        ApiEventCreate creationEvent = new ApiEventCreate(new ApiEventBuilder()
+            .setSubscriptionId(subscription.getId())
+            .setEventPlan(plan.getName())
+            .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+            .setEventPriceList(realPriceList)
+            .setActiveVersion(subscription.getActiveVersion())
+            .setProcessedDate(now)
+            .setEffectiveDate(effectiveDate)
+            .setRequestedDate(requestedDate));
 
         TimedPhase nextTimedPhase =  planAligner.getNextTimedPhaseOnCreate(subscription, plan, realPriceList, effectiveDate);
         IPhaseEvent nextPhaseEvent = PhaseEvent.getNextPhaseEvent(nextTimedPhase, subscription, now);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 950af53..a87e73c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -47,8 +47,10 @@ import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCancel;
 import com.ning.billing.entitlement.events.user.ApiEventChange;
+import com.ning.billing.entitlement.events.user.ApiEventCreate;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.ApiEventUncancel;
 import com.ning.billing.entitlement.events.user.IApiEvent;
@@ -180,7 +182,14 @@ public class Subscription extends PrivateFields  implements ISubscription {
 
         ActionPolicy policy = catalog.getPlanCancelPolicy(planPhase);
         DateTime effectiveDate = getPlanChangeEffectiveDate(policy, now);
-        IEvent cancelEvent = new ApiEventCancel(id, bundleStartDate, now, now, effectiveDate, activeVersion);
+
+        IEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+        .setSubscriptionId(id)
+        .setActiveVersion(activeVersion)
+        .setProcessedDate(now)
+        .setEffectiveDate(effectiveDate)
+        .setRequestedDate(now));
+
         dao.cancelSubscription(id, cancelEvent);
         rebuildTransitions();
     }
@@ -191,7 +200,13 @@ public class Subscription extends PrivateFields  implements ISubscription {
             throw new EntitlementUserApiException(ErrorCode.ENT_UNCANCEL_BAD_STATE, id.toString());
         }
         DateTime now = clock.getUTCNow();
-        IEvent uncancelEvent = new ApiEventUncancel(id, bundleStartDate, now, now, now, activeVersion);
+        IEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
+            .setSubscriptionId(id)
+            .setActiveVersion(activeVersion)
+            .setProcessedDate(now)
+            .setRequestedDate(now)
+            .setEffectiveDate(now));
+
         List<IEvent> uncancelEvents = new ArrayList<IEvent>();
         uncancelEvents.add(uncancelEvent);
 
@@ -259,8 +274,16 @@ public class Subscription extends PrivateFields  implements ISubscription {
         DateTime effectiveDate = getPlanChangeEffectiveDate(policy, now);
 
         TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(this, newPlan, newPriceList.getName(), effectiveDate);
-        IEvent changeEvent = new ApiEventChange(id, bundleStartDate, now, newPlan.getName(), currentTimedPhase.getPhase().getName(),
-                newPriceList.getName(), now, effectiveDate, activeVersion);
+
+        IEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
+        .setSubscriptionId(id)
+        .setEventPlan(newPlan.getName())
+        .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+        .setEventPriceList(newPriceList.getName())
+        .setActiveVersion(activeVersion)
+        .setProcessedDate(now)
+        .setEffectiveDate(effectiveDate)
+        .setRequestedDate(now));
 
         TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(this, newPlan, newPriceList.getName(), effectiveDate);
         IPhaseEvent nextPhaseEvent = PhaseEvent.getNextPhaseEvent(nextTimedPhase, this, now);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/IEventSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/IEventSqlDao.java
index 3c2180d..ff53ef2 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/IEventSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/IEventSqlDao.java
@@ -38,11 +38,14 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
+import com.ning.billing.entitlement.events.EventBaseBuilder;
 import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEventBuilder;
+import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCancel;
 import com.ning.billing.entitlement.events.user.ApiEventChange;
 import com.ning.billing.entitlement.events.user.ApiEventCreate;
@@ -125,7 +128,7 @@ public interface IEventSqlDao extends Transactional<IEventSqlDao>, CloseMe, Tran
 
         @Override
         public IEvent map(int index, ResultSet r, StatementContext ctx)
-                throws SQLException {
+        throws SQLException {
 
             UUID id = UUID.fromString(r.getString("event_id"));
             EventType eventType = EventType.valueOf(r.getString("event_type"));
@@ -143,28 +146,47 @@ public interface IEventSqlDao extends Transactional<IEventSqlDao>, CloseMe, Tran
             UUID processingOwner = (r.getString("processing_owner") != null) ? UUID.fromString(r.getString("processing_owner")) : null;
             IEventLyfecycleState processingState = IEventLyfecycleState.valueOf(r.getString("processing_state"));
 
+            EventBaseBuilder<?> base = ((eventType == EventType.PHASE) ?
+                    new PhaseEventBuilder() :
+                        new ApiEventBuilder())
+                        .setUuid(id)
+                        .setSubscriptionId(subscriptionId)
+                        .setRequestedDate(requestedDate)
+                        .setEffectiveDate(effectiveDate)
+                        .setProcessedDate(createdDate)
+                        .setActiveVersion(currentVersion)
+                        .setActive(isActive)
+                        .setProcessingOwner(processingOwner)
+                        .setNextAvailableProcessingTime(nextAvailableDate)
+                        .setProcessingState(processingState);
+
+
             IEvent result = null;
             if (eventType == EventType.PHASE) {
-                result = new PhaseEvent(id, subscriptionId, phaseName, requestedDate, effectiveDate, createdDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.CREATE) {
-                result = new ApiEventCreate(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.CHANGE) {
-                result = new ApiEventChange(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.CANCEL) {
-                result = new ApiEventCancel(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.PAUSE) {
-                result = new ApiEventPause(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.RESUME) {
-                result = new ApiEventResume(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
-            } else if (userType == ApiEventType.UNCANCEL) {
-                result = new ApiEventUncancel(id, subscriptionId, createdDate, planName, phaseName, priceListName, requestedDate, effectiveDate,
-                        currentVersion, isActive, processingOwner, nextAvailableDate, processingState);
+                EventBaseBuilder<PhaseEventBuilder> realBase = (EventBaseBuilder<PhaseEventBuilder>) base;
+                result = new PhaseEvent(new PhaseEventBuilder(realBase).setPhaseName(phaseName));
+            } else if (eventType == EventType.API_USER) {
+
+                EventBaseBuilder<ApiEventBuilder> realBase = (EventBaseBuilder<ApiEventBuilder>) base;
+                ApiEventBuilder builder = new ApiEventBuilder(realBase)
+                    .setEventPlan(planName)
+                    .setEventPlanPhase(phaseName)
+                    .setEventPriceList(priceListName)
+                    .setEventType(userType);
+
+                if (userType == ApiEventType.CREATE) {
+                    result = new ApiEventCreate(builder);
+                } else if (userType == ApiEventType.CHANGE) {
+                    result = new ApiEventChange(builder);
+                } else if (userType == ApiEventType.CANCEL) {
+                    result = new ApiEventCancel(builder);
+                } else if (userType == ApiEventType.PAUSE) {
+                    result = new ApiEventPause(builder);
+                } else if (userType == ApiEventType.RESUME) {
+                    result = new ApiEventResume(builder);
+                } else if (userType == ApiEventType.UNCANCEL) {
+                    result = new ApiEventUncancel(builder);
+                }
             } else {
                 throw new EntitlementError(String.format("Can't deserialize event %s", eventType));
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
index b1e9f02..84e0b50 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
@@ -40,6 +40,20 @@ public abstract class EventBase implements IEvent {
     private DateTime nextAvailableProcessingTime;
     private IEventLyfecycleState processingState;
 
+    public EventBase(EventBaseBuilder builder) {
+        this.uuid = builder.getUuid();
+        this.subscriptionId = builder.getSubscriptionId();
+        this.requestedDate = builder.getRequestedDate();
+        this.effectiveDate = builder.getEffectiveDate();
+        this.processedDate = builder.getProcessedDate();
+
+        this.activeVersion = builder.getActiveVersion();
+        this.isActive = builder.isActive();
+        this.processingOwner = builder.getProcessingOwner();
+        this.nextAvailableProcessingTime = builder.getNextAvailableProcessingTime();
+        this.processingState = builder.getProcessingState();
+    }
+
     public EventBase(UUID subscriptionId, DateTime requestedDate,
             DateTime effectiveDate, DateTime processedDate,
             long activeVersion, boolean isActive) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
new file mode 100644
index 0000000..69980a3
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.events;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
+
+@SuppressWarnings("unchecked")
+public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
+
+    private UUID uuid;
+    private UUID subscriptionId;
+    private DateTime requestedDate;
+    private DateTime effectiveDate;
+    private DateTime processedDate;
+
+    private long activeVersion;
+    private boolean isActive;
+    private UUID processingOwner;
+    private DateTime nextAvailableProcessingTime;
+    private IEventLyfecycleState processingState;
+
+
+    public EventBaseBuilder() {
+        this.uuid = UUID.randomUUID();
+        this.isActive = true;
+        this.processingState = IEventLyfecycleState.AVAILABLE;
+    }
+
+    public EventBaseBuilder(EventBaseBuilder<?> copy) {
+        this.uuid = copy.uuid;
+        this.subscriptionId = copy.subscriptionId;
+        this.requestedDate = copy.requestedDate;
+        this.effectiveDate = copy.effectiveDate;
+        this.processedDate = copy.processedDate;
+
+        this.activeVersion = copy.activeVersion;
+        this.isActive = copy.isActive;
+        this.processingOwner = copy.processingOwner;
+        this.nextAvailableProcessingTime = copy.nextAvailableProcessingTime;
+        this.processingState = copy.processingState;
+    }
+
+    public T setUuid(UUID uuid) {
+        this.uuid = uuid;
+        return (T) this;
+    }
+
+    public T setSubscriptionId(UUID subscriptionId) {
+        this.subscriptionId = subscriptionId;
+        return (T) this;
+    }
+
+    public T setRequestedDate(DateTime requestedDate) {
+        this.requestedDate = requestedDate;
+        return (T) this;
+    }
+
+    public T setEffectiveDate(DateTime effectiveDate) {
+        this.effectiveDate = effectiveDate;
+        return (T) this;
+    }
+
+    public T setProcessedDate(DateTime processedDate) {
+        this.processedDate = processedDate;
+        return (T) this;
+    }
+
+    public T setActiveVersion(long activeVersion) {
+        this.activeVersion = activeVersion;
+        return (T) this;
+    }
+
+    public T setActive(boolean isActive) {
+        this.isActive = isActive;
+        return (T) this;
+    }
+
+    public T setProcessingOwner(UUID processingOwner) {
+        this.processingOwner = processingOwner;
+        return (T) this;
+    }
+
+    public T setNextAvailableProcessingTime(DateTime nextAvailableProcessingTime) {
+        this.nextAvailableProcessingTime = nextAvailableProcessingTime;
+        return (T) this;
+    }
+
+    public T setProcessingState(IEventLyfecycleState processingState) {
+        this.processingState = processingState;
+        return (T) this;
+    }
+
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    public UUID getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    public DateTime getRequestedDate() {
+        return requestedDate;
+    }
+
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    public DateTime getProcessedDate() {
+        return processedDate;
+    }
+
+    public long getActiveVersion() {
+        return activeVersion;
+    }
+
+    public boolean isActive() {
+        return isActive;
+    }
+
+    public UUID getProcessingOwner() {
+        return processingOwner;
+    }
+
+    public DateTime getNextAvailableProcessingTime() {
+        return nextAvailableProcessingTime;
+    }
+
+    public IEventLyfecycleState getProcessingState() {
+        return processingState;
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
index 9c6bbba..7c2d228 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
@@ -16,39 +16,23 @@
 
 package com.ning.billing.entitlement.events.phase;
 
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
 import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.events.EventBase;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
 
 
 public class PhaseEvent extends EventBase implements IPhaseEvent {
 
     private final String phaseName;
 
-    public PhaseEvent(UUID subscriptionId, IPlanPhase phase, DateTime requestedDate,
-            DateTime effectiveDate, DateTime processedDate, long activeVersion) {
-        super(subscriptionId, requestedDate, effectiveDate, processedDate, activeVersion, true);
-        this.phaseName = phase.getName();
+    public PhaseEvent(PhaseEventBuilder builder) {
+        super(builder);
+        this.phaseName = builder.getPhaseName();
     }
 
-
-    public PhaseEvent(UUID id, UUID subscriptionId, String phaseName, DateTime requestedDate,
-            DateTime effectiveDate, DateTime processedDate,
-            long activeVersion, boolean isActiveVersion,
-            UUID processingOwner, DateTime nextAvailableProcessingTime,
-            IEventLyfecycleState processingState) {
-        super(id, subscriptionId, requestedDate, effectiveDate, processedDate, activeVersion, isActiveVersion, processingOwner, nextAvailableProcessingTime, processingState);
-        this.phaseName = phaseName;
-    }
-
-
     @Override
     public EventType getType() {
         return EventType.PHASE;
@@ -76,9 +60,12 @@ public class PhaseEvent extends EventBase implements IPhaseEvent {
     public static final IPhaseEvent getNextPhaseEvent(TimedPhase nextTimedPhase, Subscription subscription, DateTime now) {
         return (nextTimedPhase == null) ?
                 null :
-                    new PhaseEvent(subscription.getId(), nextTimedPhase.getPhase(), now, nextTimedPhase.getStartPhase(),
-                            now,  subscription.getActiveVersion());
-
+                    new PhaseEvent(new PhaseEventBuilder()
+                        .setSubscriptionId(subscription.getId())
+                        .setRequestedDate(now)
+                        .setEffectiveDate(nextTimedPhase.getStartPhase())
+                        .setProcessedDate(now)
+                        .setActiveVersion(subscription.getActiveVersion())
+                        .setPhaseName(nextTimedPhase.getPhase().getName()));
     }
-
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java
new file mode 100644
index 0000000..00ac8e2
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.events.phase;
+
+import com.ning.billing.entitlement.events.EventBaseBuilder;
+
+public class PhaseEventBuilder extends EventBaseBuilder<PhaseEventBuilder> {
+
+    private String phaseName;
+
+    public PhaseEventBuilder() {
+        super();
+    }
+
+    public PhaseEventBuilder(EventBaseBuilder<PhaseEventBuilder> base) {
+        super(base);
+    }
+
+    public PhaseEventBuilder setPhaseName(String phaseName) {
+        this.phaseName = phaseName;
+        return this;
+    }
+
+    public String getPhaseName() {
+        return phaseName;
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
index e1b9177..d4012dd 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
@@ -36,6 +36,15 @@ public class ApiEventBase extends EventBase implements IApiEvent {
     private final String eventPriceList;
 
 
+    public ApiEventBase(ApiEventBuilder builder) {
+        super(builder);
+        this.eventType = builder.getEventType();
+        this.eventPriceList = builder.getEventPriceList();
+        this.eventPlan = builder.getEventPlan();
+        this.eventPlanPhase = builder.getEventPlanPhase();
+    }
+
+
     public ApiEventBase(UUID subscriptionId, DateTime bundleStartDate, DateTime processed, String planName, String phaseName,
             String priceList, DateTime requestedDate,  ApiEventType eventType, DateTime effectiveDate, long activeVersion) {
         super(subscriptionId, requestedDate, effectiveDate, processed, activeVersion, true);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java
new file mode 100644
index 0000000..cd3857e
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.events.user;
+
+import com.ning.billing.entitlement.events.EventBaseBuilder;
+
+public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
+
+    private ApiEventType eventType;
+    private String eventPlan;
+    private String eventPlanPhase;
+    private String eventPriceList;
+
+    public ApiEventBuilder() {
+        super();
+    }
+
+    public ApiEventBuilder(EventBaseBuilder<ApiEventBuilder> base) {
+        super(base);
+    }
+
+    public ApiEventType getEventType() {
+        return eventType;
+    }
+
+    public String getEventPlan() {
+        return eventPlan;
+    }
+
+    public String getEventPlanPhase() {
+        return eventPlanPhase;
+    }
+
+    public String getEventPriceList() {
+        return eventPriceList;
+    }
+
+    public ApiEventBuilder setEventType(ApiEventType eventType) {
+        this.eventType = eventType;
+        return this;
+    }
+
+    public ApiEventBuilder setEventPlan(String eventPlan) {
+        this.eventPlan = eventPlan;
+        return this;
+    }
+
+    public ApiEventBuilder setEventPlanPhase(String eventPlanPhase) {
+        this.eventPlanPhase = eventPlanPhase;
+        return this;
+    }
+
+    public ApiEventBuilder setEventPriceList(String eventPriceList) {
+        this.eventPriceList = eventPriceList;
+        return this;
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
index a3806d2..5df11ba 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
@@ -16,23 +16,10 @@
 
 package com.ning.billing.entitlement.events.user;
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
-
 public class ApiEventCancel extends ApiEventBase {
 
-    public ApiEventCancel(UUID subscriptionId, DateTime bundleStartDate, DateTime now, DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, bundleStartDate, now, requestedDate, ApiEventType.CANCEL, effectiveDate, version);
-    }
 
-    public ApiEventCancel(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase,
-            String priceList, DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.CANCEL, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
+    public ApiEventCancel(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.CANCEL));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
index 40584f5..3770a2f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
@@ -17,25 +17,10 @@
 package com.ning.billing.entitlement.events.user;
 
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
-
 
 public class ApiEventChange extends ApiEventBase {
 
-    public ApiEventChange(UUID subscriptionId,  DateTime bundleStartDate, DateTime now, String planName, String phaseName, String priceList,
-            DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, bundleStartDate, now, planName, phaseName, priceList, requestedDate, ApiEventType.CHANGE, effectiveDate, version);
-    }
-
-    public ApiEventChange(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase, String priceList,
-            DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.CHANGE, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
+    public ApiEventChange(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.CHANGE));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
index 2b12e7e..df1879d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
@@ -17,26 +17,10 @@
 package com.ning.billing.entitlement.events.user;
 
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
 
 public class ApiEventCreate extends ApiEventBase {
 
-
-    public ApiEventCreate(UUID subscriptionId, DateTime bundleStartDate, DateTime now, String planName, String phaseName, String priceList,
-            DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, bundleStartDate, now, planName, phaseName, priceList, requestedDate, ApiEventType.CREATE, effectiveDate, version);
-    }
-
-
-    public ApiEventCreate(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase, String priceList,
-            DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.CREATE, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
+    public ApiEventCreate(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.CREATE));
     }
-
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventPause.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventPause.java
index a6ff4b4..8574cfc 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventPause.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventPause.java
@@ -17,23 +17,11 @@
 package com.ning.billing.entitlement.events.user;
 
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
 
 public class ApiEventPause extends ApiEventBase {
 
-    public ApiEventPause(UUID subscriptionId, DateTime now, DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, null, now, requestedDate, ApiEventType.PAUSE, effectiveDate, version);
-    }
 
-    public ApiEventPause(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase,
-            String priceList, DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.PAUSE, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
+    public ApiEventPause(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.PAUSE));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventResume.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventResume.java
index f8bf26f..34f8f87 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventResume.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventResume.java
@@ -17,25 +17,9 @@
 package com.ning.billing.entitlement.events.user;
 
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
-
-
 public class ApiEventResume extends ApiEventBase {
 
-    public ApiEventResume(UUID subscriptionId, DateTime now, DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, null, now, requestedDate, ApiEventType.RESUME, effectiveDate, version);
+    public ApiEventResume(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.RESUME));
     }
-
-    public ApiEventResume(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase,
-            String priceList, DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.RESUME, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
-    }
-
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
index b5433f1..93d8029 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
@@ -16,21 +16,9 @@
 
 package com.ning.billing.entitlement.events.user;
 
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-
-
 public class ApiEventUncancel extends ApiEventBase {
 
-    public ApiEventUncancel(UUID subscriptionId, DateTime bundleStartDate, DateTime now, DateTime requestedDate, DateTime effectiveDate, long version) {
-        super(subscriptionId, bundleStartDate, now, requestedDate, ApiEventType.UNCANCEL, effectiveDate, version);
-    }
-
-    public ApiEventUncancel(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase,
-            String priceList, DateTime requestedDate, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
-        super(id, subscriptionId, processed, eventPlan, eventPhase, priceList, requestedDate, ApiEventType.UNCANCEL, effectiveDate,
-                activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
+    public ApiEventUncancel(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.UNCANCEL));
     }
 }