killbill-aplcache
Changes
entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java 25(+16 -9)
entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java 8(+3 -5)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java 42(+17 -25)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java 19(+5 -14)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java 36(+24 -12)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java 26(+14 -12)
entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java 8(+4 -4)
entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java 7(+5 -2)
invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java 12(+8 -4)
invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg 10(+6 -4)
invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg 10(+6 -4)
invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java 16(+11 -5)
invoice/src/test/java/com/ning/billing/invoice/notification/MockNextBillingDateNotifier.java 34(+34 -0)
invoice/src/test/java/com/ning/billing/invoice/notification/MockNextBillingDatePoster.java 36(+7 -29)
invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java 73(+45 -28)
util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.sql.stg 17(+17 -0)
Details
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
index 0dd8740..7b5ed63 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
@@ -19,27 +19,24 @@ package com.ning.billing.account.api;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.entity.ExtendedEntityBase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.customfield.CustomizableEntityBase;
-import com.ning.billing.util.tag.DefaultTagStore;
-import com.ning.billing.util.tag.DescriptiveTag;
-import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
-
-public class DefaultAccount extends CustomizableEntityBase implements Account {
- //public final static String OBJECT_TYPE = "Account";
-
- private final String externalKey;
+
+import javax.annotation.Nullable;
+
+public class DefaultAccount extends ExtendedEntityBase implements Account {
+ private final String externalKey;
private final String email;
private final String name;
private final int firstNameLength;
private final Currency currency;
private final int billCycleDay;
private final String paymentProviderName;
- private final DefaultTagStore tags;
private final DateTimeZone timeZone;
private final String locale;
private final String address1;
@@ -50,57 +47,40 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
private final String country;
private final String postalCode;
private final String phone;
- private final DateTime createdDate;
- private final DateTime updatedDate;
+ private final String updatedBy;
+ private final DateTime updatedDate;
- /**
- * This call is used to create a new account
- * @param data
- * @param createdDate
- */
- public DefaultAccount(final AccountData data, DateTime createdDate) {
- this(UUID.randomUUID(), data.getExternalKey(), data.getEmail(), data.getName(), data.getFirstNameLength(),
- data.getCurrency(), data.getBillCycleDay(), data.getPaymentProviderName(),
- data.getTimeZone(), data.getLocale(),
- data.getAddress1(), data.getAddress2(), data.getCompanyName(),
- data.getCity(), data.getStateOrProvince(), data.getCountry(),
- data.getPostalCode(), data.getPhone(), createdDate, createdDate);
+ //intended for creation and migration
+ public DefaultAccount(final String createdBy, final DateTime createdDate,
+ final String updatedBy, final DateTime updatedDate,
+ final AccountData data) {
+ this(UUID.randomUUID(), createdBy, createdDate, updatedBy, updatedDate, data);
}
- //intended for creation
- public DefaultAccount(final AccountData data) {
- this(UUID.randomUUID(), data, null, null);
- }
-
- // Intended for migration
- public DefaultAccount(final AccountData data, DateTime createdDate, DateTime updatedDate) {
- this(UUID.randomUUID(), data, createdDate, updatedDate);
+ public DefaultAccount(final AccountData data) {
+ this(UUID.randomUUID(), null, null, null, null, data);
}
- //intended for update
- public DefaultAccount(final UUID id, final AccountData data, DateTime createdDate, DateTime updatedDate) {
- this(id, data.getExternalKey(), data.getEmail(), data.getName(), data.getFirstNameLength(),
- data.getCurrency(), data.getBillCycleDay(), data.getPaymentProviderName(),
- data.getTimeZone(), data.getLocale(),
- data.getAddress1(), data.getAddress2(), data.getCompanyName(),
- data.getCity(), data.getStateOrProvince(), data.getCountry(),
- data.getPostalCode(), data.getPhone(), createdDate, updatedDate);
+ public DefaultAccount(final UUID id, final AccountData data) {
+ this(id, null, null, null, null, data);
}
-
/**
* This call is used to update an existing account
*
- * @param id
- * @param data
+ * @param id UUID id of the existing account to update
+ * @param data AccountData new data for the existing account
*/
- public DefaultAccount(final UUID id, final AccountData data) {
+ public DefaultAccount(final UUID id, @Nullable final String createdBy, @Nullable final DateTime createdDate,
+ @Nullable final String updatedBy, @Nullable final DateTime updatedDate,
+ final AccountData data) {
this(id, data.getExternalKey(), data.getEmail(), data.getName(), data.getFirstNameLength(),
data.getCurrency(), data.getBillCycleDay(), data.getPaymentProviderName(),
data.getTimeZone(), data.getLocale(),
data.getAddress1(), data.getAddress2(), data.getCompanyName(),
data.getCity(), data.getStateOrProvince(), data.getCountry(),
- data.getPostalCode(), data.getPhone(), null, null);
+ data.getPostalCode(), data.getPhone(), createdBy, createdDate,
+ updatedBy, updatedDate);
}
/**
@@ -126,14 +106,17 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
* @param createdDate
* @param updatedDate
*/
- public DefaultAccount(final UUID id, final String externalKey, final String email, final String name, final int firstNameLength,
- final Currency currency, final int billCycleDay, final String paymentProviderName,
- final DateTimeZone timeZone, final String locale,
- final String address1, final String address2, final String companyName,
- final String city,
- final String stateOrProvince, final String country, final String postalCode, final String phone, DateTime createdDate, DateTime updatedDate) {
-
- super(id);
+ public DefaultAccount(final UUID id, final String externalKey, final String email,
+ final String name, final int firstNameLength,
+ final Currency currency, final int billCycleDay, final String paymentProviderName,
+ final DateTimeZone timeZone, final String locale,
+ final String address1, final String address2, final String companyName,
+ final String city, final String stateOrProvince, final String country,
+ final String postalCode, final String phone,
+ final String createdBy, final DateTime createdDate,
+ final String updatedBy, final DateTime updatedDate) {
+
+ super(id, createdBy, createdDate);
this.externalKey = externalKey;
this.email = email;
this.name = name;
@@ -151,14 +134,28 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
this.postalCode = postalCode;
this.country = country;
this.phone = phone;
- this.createdDate = createdDate == null ? new DateTime(DateTimeZone.UTC) : createdDate; // This is a fallback, we are only expecting these to be set to null
- this.updatedDate = updatedDate == null ? new DateTime(DateTimeZone.UTC) : updatedDate; // in the case that the account is being updated. In which case the values are ignored anyway
- this.tags = new DefaultTagStore(id, getObjectName());
+ this.updatedBy = updatedBy;
+ this.updatedDate = updatedDate;
}
- @Override
+ @Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveFields(List<CustomField> fields, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearPersistedFields(CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public String getObjectName() {
- return "Account";
+ return ObjectType;
}
@Override
@@ -176,20 +173,6 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
return email;
}
- public DefaultTagStore getTags() {
- return tags;
- }
-
- @Override
- public DateTime getCreatedDate() {
- return createdDate;
- }
-
- @Override
- public DateTime getUpdatedDate() {
- return updatedDate;
- }
-
@Override
public int getFirstNameLength() {
return firstNameLength;
@@ -255,79 +238,47 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
return country;
}
- @Override
- public String getPhone() {
- return phone;
- }
-
- @Override
- public List<Tag> getTagList() {
- return tags.getEntityList();
- }
-
- @Override
- public boolean hasTag(String tagName) {
- return tags.containsTag(tagName);
- }
-
- @Override
- public void addTag(TagDefinition definition, String addedBy, DateTime dateAdded) {
- Tag tag = new DescriptiveTag(definition, addedBy, dateAdded);
- tags.add(tag) ;
- }
-
- @Override
- public void addTags(List<Tag> tags) {
- if (tags != null) {
- this.tags.add(tags);
- }
- }
+ @Override
+ public String getUpdatedBy() {
+ return updatedBy;
+ }
- @Override
- public void clearTags() {
- this.tags.clear();
- }
-
- @Override
- public void removeTag(TagDefinition definition) {
- tags.remove(definition.getName());
- }
+ @Override
+ public DateTime getUpdatedDate() {
+ return updatedDate;
+ }
- @Override
- public boolean generateInvoice() {
- return tags.generateInvoice();
+ @Override
+ public String getPhone() {
+ return phone;
}
- @Override
- public boolean processPayment() {
- return tags.processPayment();
- }
-
- @Override
+ @Override
public MutableAccountData toMutableAccountData() {
return new DefaultMutableAccountData(this);
}
-
+
@Override
public String toString() {
- return "DefaultAccount [externalKey=" + externalKey + ", email=" + email +
- ", name=" + name + ", " +
- "firstNameLength=" + firstNameLength +
- ", phone=" + phone + ", " +
- "currency=" + currency +
- ", billCycleDay=" + billCycleDay +
- ", paymentProviderName=" + paymentProviderName +
+ return "DefaultAccount [externalKey=" + externalKey +
+ ", email=" + email +
+ ", name=" + name +
+ ", firstNameLength=" + firstNameLength +
+ ", phone=" + phone +
+ ", currency=" + currency +
+ ", billCycleDay=" + billCycleDay +
+ ", paymentProviderName=" + paymentProviderName +
", timezone=" + timeZone +
", locale=" + locale +
- ", address1" + address1 +
- ", address2" + address2 +
- ", companyName" + companyName +
- ", city" + city +
- ", stateOrProvince" + stateOrProvince +
- ", postalCode" + postalCode +
- ", country" +
- ", tags=" + tags +
- ", createdDate=" + createdDate +
- ", updatedDate=" + updatedDate + "]";
+ ", address1=" + address1 +
+ ", address2=" + address2 +
+ ", companyName=" + companyName +
+ ", city=" + city +
+ ", stateOrProvince=" + stateOrProvince +
+ ", postalCode=" + postalCode +
+ ", country=" + country +
+ ", tags=" + tags +
+ ", fields=" + fields +
+ "]";
}
}
\ No newline at end of file
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
index 95eb5d8..ed18ffb 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
@@ -43,7 +43,9 @@ public class AccountBuilder {
private String country;
private String postalCode;
private String phone;
+ private String createdBy;
private DateTime createdDate;
+ private String updatedBy;
private DateTime updatedDate;
public AccountBuilder() {
@@ -139,12 +141,22 @@ public class AccountBuilder {
return this;
}
- public AccountBuilder createdDate(DateTime createdDate) {
+ public AccountBuilder createdBy(final String createdBy) {
+ this.createdBy = createdBy;
+ return this;
+ }
+
+ public AccountBuilder createdDate(final DateTime createdDate) {
this.createdDate = createdDate;
return this;
}
- public AccountBuilder updatedDate(DateTime updatedDate) {
+ public AccountBuilder updatedBy(final String updatedBy) {
+ this.updatedBy = updatedBy;
+ return this;
+ }
+
+ public AccountBuilder updatedDate(final DateTime updatedDate) {
this.updatedDate = updatedDate;
return this;
}
@@ -154,7 +166,6 @@ public class AccountBuilder {
currency, billingCycleDay, paymentProviderName,
timeZone, locale,
address1, address2, companyName, city, stateOrProvince, country,
- postalCode, phone,
- createdDate, updatedDate);
+ postalCode, phone, createdBy, createdDate, updatedBy, updatedDate);
}
}
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index c1204cf..cab3e42 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -28,29 +28,32 @@ import com.ning.billing.account.api.DefaultAccount;
import com.ning.billing.account.api.MigrationAccountData;
import com.ning.billing.account.api.DefaultMutableAccountData;
import com.ning.billing.account.dao.AccountDao;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.tag.Tag;
+import org.joda.time.DateTime;
public class DefaultAccountUserApi implements com.ning.billing.account.api.AccountUserApi {
+ private final CallContextFactory factory;
private final AccountDao dao;
- private Clock clock;
@Inject
- public DefaultAccountUserApi(final AccountDao dao, final Clock clock) {
+ public DefaultAccountUserApi(final CallContextFactory factory, final AccountDao dao) {
+ this.factory = factory;
this.dao = dao;
- this.clock = clock;
}
@Override
- public Account createAccount(final AccountData data, final List<CustomField> fields, final List<Tag> tags) throws AccountApiException {
- Account account = new DefaultAccount(data, clock.getUTCNow());
- account.addFields(fields);
+ public Account createAccount(final AccountData data, final List<CustomField> fields,
+ final List<Tag> tags, final CallContext context) throws AccountApiException {
+ Account account = new DefaultAccount(data);
+ account.setFields(fields);
account.addTags(tags);
try {
- dao.create(account);
+ dao.create(account, context);
} catch (EntityPersistenceException e) {
throw new AccountApiException(e, ErrorCode.ACCOUNT_CREATION_FAILED);
}
@@ -79,21 +82,21 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
}
@Override
- public void updateAccount(final Account account) throws AccountApiException {
+ public void updateAccount(final Account account, final CallContext context) throws AccountApiException {
try {
- dao.update(account);
+ dao.update(account, context);
} catch (EntityPersistenceException e) {
throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
}
}
@Override
- public void updateAccount(final UUID accountId, final AccountData accountData)
+ public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context)
throws AccountApiException {
Account account = new DefaultAccount(accountId, accountData);
try {
- dao.update(account);
+ dao.update(account, context);
} catch (EntityPersistenceException e) {
throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
}
@@ -101,30 +104,33 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
}
@Override
- public void updateAccount(final String externalKey, final AccountData accountData) throws AccountApiException {
+ public void updateAccount(final String externalKey, final AccountData accountData, final CallContext context) throws AccountApiException {
UUID accountId = getIdFromKey(externalKey);
if(accountId == null) {
throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
}
- updateAccount(accountId, accountData);
+
+ updateAccount(accountId, accountData, context);
}
@Override
- public void deleteAccountByKey(final String externalKey) throws AccountApiException {
- dao.deleteByKey(externalKey);
+ public void deleteAccountByKey(final String externalKey, final CallContext context) throws AccountApiException {
+ dao.deleteByKey(externalKey, context);
}
@Override
- public Account migrateAccount(MigrationAccountData data,
- List<CustomField> fields, List<Tag> tags)
- throws AccountApiException {
-
- Account account = new DefaultAccount(data, data.getCreatedDate(), data.getUpdatedDate());
- account.addFields(fields);
+ public Account migrateAccount(final MigrationAccountData data, final List<CustomField> fields,
+ final List<Tag> tags, final CallContext context)
+ throws AccountApiException {
+ DateTime createdDate = data.getCreatedDate() == null ? context.getCreatedDate() : data.getCreatedDate();
+ DateTime updatedDate = data.getUpdatedDate() == null ? context.getUpdatedDate() : data.getUpdatedDate();
+ CallContext migrationContext = factory.toMigrationCallContext(context, createdDate, updatedDate);
+ Account account = new DefaultAccount(data);
+ account.setFields(fields);
account.addTags(tags);
try {
- dao.create(account);
+ dao.create(account, migrationContext);
} catch (EntityPersistenceException e) {
throw new AccountApiException(e, ErrorCode.ACCOUNT_CREATION_FAILED);
}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
new file mode 100644
index 0000000..a4a00a8
--- /dev/null
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
@@ -0,0 +1,67 @@
+/*
+ * 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.account.dao;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.Currency;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@BindingAnnotation(AccountBinder.AccountBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface AccountBinder {
+ public static class AccountBinderFactory implements BinderFactory {
+ @Override
+ public Binder<AccountBinder, Account> build(Annotation annotation) {
+ return new Binder<AccountBinder, Account>() {
+ @Override
+ public void bind(@SuppressWarnings("rawtypes") SQLStatement q, AccountBinder bind, Account account) {
+ q.bind("id", account.getId().toString());
+ q.bind("externalKey", account.getExternalKey());
+ q.bind("email", account.getEmail());
+ q.bind("name", account.getName());
+ q.bind("firstNameLength", account.getFirstNameLength());
+ Currency currency = account.getCurrency();
+ q.bind("currency", (currency == null) ? null : currency.toString());
+ q.bind("billingCycleDay", account.getBillCycleDay());
+ q.bind("paymentProviderName", account.getPaymentProviderName());
+ DateTimeZone timeZone = account.getTimeZone();
+ q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
+ q.bind("locale", account.getLocale());
+ q.bind("address1", account.getAddress1());
+ q.bind("address2", account.getAddress2());
+ q.bind("companyName", account.getCompanyName());
+ q.bind("city", account.getCity());
+ q.bind("stateOrProvince", account.getStateOrProvince());
+ q.bind("country", account.getCountry());
+ q.bind("postalCode", account.getPostalCode());
+ q.bind("phone", account.getPhone());
+ }
+ };
+ }
+ }
+}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index 774a1e6..d25a3ea 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -19,7 +19,7 @@ package com.ning.billing.account.dao;
import java.util.UUID;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.util.entity.EntityDao;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.entity.UpdatableEntityDao;
public interface AccountDao extends UpdatableEntityDao<Account> {
@@ -33,5 +33,5 @@ public interface AccountDao extends UpdatableEntityDao<Account> {
*/
public UUID getIdFromKey(String externalKey) throws AccountApiException;
- public void deleteByKey(String externalKey) throws AccountApiException;
+ public void deleteByKey(String externalKey, CallContext context) throws AccountApiException;
}
\ No newline at end of file
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountHistorySqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountHistorySqlDao.java
new file mode 100644
index 0000000..8d1a46e
--- /dev/null
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountHistorySqlDao.java
@@ -0,0 +1,34 @@
+/*
+ * 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.account.dao;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+@ExternalizedSqlViaStringTemplate3
+public interface AccountHistorySqlDao extends Transmogrifier {
+ @SqlUpdate
+ public void insertAccountHistoryFromTransaction(@AccountBinder final Account account,
+ @Bind("historyId") final String historyId,
+ @Bind("changeType") String changeType,
+ @CallContextBinder CallContext context);
+}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index dfa9b89..2c400d5 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -16,25 +16,18 @@
package com.ning.billing.account.dao;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.Date;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.entity.MapperBase;
+import com.ning.billing.util.entity.UpdatableEntityDao;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
-import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
@@ -47,7 +40,6 @@ import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.user.AccountBuilder;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.util.UuidMapper;
-import com.ning.billing.util.entity.UpdatableEntityDao;
@ExternalizedSqlViaStringTemplate3
@RegisterMapper({UuidMapper.class, AccountSqlDao.AccountMapper.class})
@@ -60,25 +52,18 @@ public interface AccountSqlDao extends UpdatableEntityDao<Account>, Transactiona
@Override
@SqlUpdate
- public void create(@AccountBinder Account account);
+ public void create(@AccountBinder Account account, @CallContextBinder final CallContext context);
@Override
@SqlUpdate
- public void update(@AccountBinder Account account);
+ public void update(@AccountBinder Account account, @CallContextBinder final CallContext context);
@SqlUpdate
public void deleteByKey(@Bind("externalKey") final String key);
- public static class AccountMapper implements ResultSetMapper<Account> {
-
- private DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
- final Timestamp resultStamp = rs.getTimestamp(fieldName);
- return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class AccountMapper extends MapperBase implements ResultSetMapper<Account> {
@Override
public Account map(int index, ResultSet result, StatementContext context) throws SQLException {
-
UUID id = UUID.fromString(result.getString("id"));
String externalKey = result.getString("external_key");
String email = result.getString("email");
@@ -90,8 +75,6 @@ public interface AccountSqlDao extends UpdatableEntityDao<Account>, Transactiona
Currency currency = (currencyString == null) ? null : Currency.valueOf(currencyString);
String paymentProviderName = result.getString("payment_provider_name");
- DateTime createdDate = getDate(result, "created_dt");
- DateTime updatedDate = getDate(result, "updated_dt");
String timeZoneId = result.getString("time_zone");
DateTimeZone timeZone = (timeZoneId == null) ? null : DateTimeZone.forID(timeZoneId);
@@ -107,6 +90,11 @@ public interface AccountSqlDao extends UpdatableEntityDao<Account>, Transactiona
String country = result.getString("country");
String phone = result.getString("phone");
+ String createdBy = result.getString("created_by");
+ DateTime createdDate = getDate(result, "created_date");
+ String updatedBy = result.getString("updated_by");
+ DateTime updatedDate = getDate(result, "updated_date");
+
return new AccountBuilder(id).externalKey(externalKey).email(email)
.name(name).firstNameLength(firstNameLength)
.phone(phone).currency(currency)
@@ -117,51 +105,9 @@ public interface AccountSqlDao extends UpdatableEntityDao<Account>, Transactiona
.companyName(companyName)
.city(city).stateOrProvince(stateOrProvince)
.postalCode(postalCode).country(country)
- .createdDate(createdDate)
- .updatedDate(updatedDate)
+ .createdBy(createdBy).createdDate(createdDate)
+ .updatedBy(updatedBy).updatedDate(updatedDate)
.build();
}
}
-
- @BindingAnnotation(AccountBinder.AccountBinderFactory.class)
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.PARAMETER})
- public @interface AccountBinder {
- public static class AccountBinderFactory implements BinderFactory {
- @Override
- public Binder<AccountBinder, Account> build(Annotation annotation) {
- return new Binder<AccountBinder, Account>() {
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
- @Override
- public void bind(@SuppressWarnings("rawtypes") SQLStatement q, AccountBinder bind, Account account) {
- q.bind("id", account.getId().toString());
- q.bind("externalKey", account.getExternalKey());
- q.bind("email", account.getEmail());
- q.bind("name", account.getName());
- q.bind("firstNameLength", account.getFirstNameLength());
- Currency currency = account.getCurrency();
- q.bind("currency", (currency == null) ? null : currency.toString());
- q.bind("billingCycleDay", account.getBillCycleDay());
- q.bind("paymentProviderName", account.getPaymentProviderName());
- DateTimeZone timeZone = account.getTimeZone();
- q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
- q.bind("locale", account.getLocale());
- q.bind("address1", account.getAddress1());
- q.bind("address2", account.getAddress2());
- q.bind("companyName", account.getCompanyName());
- q.bind("city", account.getCity());
- q.bind("stateOrProvince", account.getStateOrProvince());
- q.bind("country", account.getCountry());
- q.bind("postalCode", account.getPostalCode());
- q.bind("phone", account.getPhone());
- q.bind("createdDate", getDate(account.getCreatedDate()));
- q.bind("updatedDate", getDate(account.getUpdatedDate()));
- }
- };
- }
- }
- }
}
diff --git a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
index f6e51f4..60e0a14 100644
--- a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
+++ b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
@@ -24,7 +24,7 @@ import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.account.api.DefaultAccountService;
import com.ning.billing.account.api.user.DefaultAccountUserApi;
import com.ning.billing.account.dao.AccountDao;
-import com.ning.billing.account.dao.DefaultAccountDao;
+import com.ning.billing.account.dao.AuditedAccountDao;
public class AccountModule extends AbstractModule {
@@ -34,7 +34,7 @@ public class AccountModule extends AbstractModule {
}
protected void installAccountDao() {
- bind(AccountDao.class).to(DefaultAccountDao.class).asEagerSingleton();
+ bind(AccountDao.class).to(AuditedAccountDao.class).asEagerSingleton();
}
protected void installAccountUserApi() {
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountHistorySqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountHistorySqlDao.sql.stg
new file mode 100644
index 0000000..c64c29f
--- /dev/null
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountHistorySqlDao.sql.stg
@@ -0,0 +1,15 @@
+group AccountHistorySqlDao;
+
+insertAccountHistoryFromTransaction() ::= <<
+ INSERT INTO account_history
+ (history_id, id, external_key, email, name, first_name_length, currency,
+ billing_cycle_day, payment_provider_name, time_zone, locale,
+ address1, address2, company_name, city, state_or_province,
+ country, postal_code, phone, change_type, updated_by, date)
+ VALUES
+ (:historyId, :id, :externalKey, :email, :name, :firstNameLength, :currency,
+ :billingCycleDay, :paymentProviderName, :timeZone, :locale,
+ :address1, :address2, :companyName, :city, :stateOrProvince,
+ :country, :postalCode, :phone, :changeType, :userName, :createdDate);
+>>
+;
\ No newline at end of file
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
index 7e93ff2..2838ef8 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
@@ -18,12 +18,13 @@ accountFields(prefix) ::= <<
<prefix>state_or_province,
<prefix>country,
<prefix>postal_code,
- <prefix>phone,
- <prefix>created_dt,
- <prefix>updated_dt
+ <prefix>phone,
+ <prefix>created_by,
+ <prefix>created_date,
+ <prefix>updated_by,
+ <prefix>updated_date
>>
-
create() ::= <<
INSERT INTO accounts
(<accountFields()>)
@@ -31,7 +32,7 @@ create() ::= <<
(:id, :externalKey, :email, :name, :firstNameLength, :currency, :billingCycleDay,
:paymentProviderName, :timeZone, :locale,
:address1, :address2, :companyName, :city, :stateOrProvince, :country, :postalCode, :phone,
- :createdDate, :updatedDate);
+ :userName, :createdDate, :userName, :updatedDate);
>>
update() ::= <<
@@ -41,7 +42,7 @@ update() ::= <<
time_zone = :timeZone, locale = :locale,
address1 = :address1, address2 = :address2, company_name = :companyName, city = :city, state_or_province = :stateOrProvince,
country = :country, postal_code = :postalCode, phone = :phone,
- updated_dt = NOW()
+ updated_date = :updatedDate, updated_by = :userName
WHERE id = :id;
>>
@@ -59,19 +60,19 @@ getAccountByKey() ::= <<
getById() ::= <<
SELECT <accountFields()>
- FROM accounts
- WHERE id = :id;
+ FROM accounts
+ WHERE id = :id;
>>
get() ::= <<
SELECT <accountFields()>
- FROM accounts;
+ FROM accounts;
>>
getIdFromKey() ::= <<
SELECT id
- FROM accounts
- WHERE external_key = :externalKey;
+ FROM accounts
+ WHERE external_key = :externalKey;
>>
test() ::= <<
diff --git a/account/src/main/resources/com/ning/billing/account/ddl.sql b/account/src/main/resources/com/ning/billing/account/ddl.sql
index fd2f6f8..ff9a41c 100644
--- a/account/src/main/resources/com/ning/billing/account/ddl.sql
+++ b/account/src/main/resources/com/ning/billing/account/ddl.sql
@@ -18,8 +18,11 @@ CREATE TABLE accounts (
country varchar(50) DEFAULT NULL,
postal_code varchar(11) DEFAULT NULL,
phone varchar(25) DEFAULT NULL,
- created_dt datetime,
- updated_dt datetime,
+ migrated bool DEFAULT false,
+ created_date datetime NOT NULL,
+ created_by varchar(50) NOT NULL,
+ updated_date datetime DEFAULT NULL,
+ updated_by varchar(50) DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
CREATE UNIQUE INDEX accounts_external_key ON accounts(external_key);
@@ -27,6 +30,7 @@ CREATE UNIQUE INDEX accounts_email ON accounts(email);
DROP TABLE IF EXISTS account_history;
CREATE TABLE account_history (
+ history_id char(36) NOT NULL,
id char(36) NOT NULL,
external_key varchar(128) NULL,
email varchar(50) NOT NULL,
@@ -45,28 +49,8 @@ CREATE TABLE account_history (
country varchar(50) DEFAULT NULL,
postal_code varchar(11) DEFAULT NULL,
phone varchar(25) DEFAULT NULL,
+ change_type char(6) NOT NULL,
+ updated_by varchar(50) NOT NULL,
date datetime
) ENGINE=innodb;
-CREATE INDEX account_id ON account_history(id);
-
-CREATE TRIGGER store_account_history_on_insert AFTER INSERT ON accounts
- FOR EACH ROW
- INSERT INTO account_history (id, external_key, email, name, first_name_length, currency,
- billing_cycle_day, payment_provider_name, time_zone, locale,
- address1, address2, company_name, city, state_or_province,
- country, postal_code, phone, date)
- VALUES (NEW.id, NEW.external_key, NEW.email, NEW.name, NEW.first_name_length, NEW.currency,
- NEW.billing_cycle_day, NEW.payment_provider_name, NEW.time_zone, NEW.locale,
- NEW.address1, NEW.address2, NEW.company_name, NEW.city, NEW.state_or_province,
- NEW.country, NEW.postal_code, NEW.phone, NEW.created_dt);
-
-CREATE TRIGGER store_account_history_on_update AFTER UPDATE ON accounts
- FOR EACH ROW
- INSERT INTO account_history (id, external_key, email, name, first_name_length, currency,
- billing_cycle_day, payment_provider_name, time_zone, locale,
- address1, address2, company_name, city, state_or_province,
- country, postal_code, phone, date)
- VALUES (NEW.id, NEW.external_key, NEW.email, NEW.name, NEW.first_name_length, NEW.currency,
- NEW.billing_cycle_day, NEW.payment_provider_name, NEW.time_zone, NEW.locale,
- NEW.address1, NEW.address2, NEW.company_name, NEW.city, NEW.state_or_province,
- NEW.country, NEW.postal_code, NEW.phone, NEW.updated_dt);
+CREATE INDEX account_id ON account_history(id);
\ No newline at end of file
diff --git a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
index 1d49c45..265b933 100644
--- a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
+++ b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
@@ -16,13 +16,12 @@
package com.ning.billing.account.api;
-import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
-import org.joda.time.DateTime;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTimeZone;
import com.ning.billing.catalog.api.Currency;
@@ -40,7 +39,6 @@ public class MockAccountUserApi implements AccountUserApi {
Currency currency,
int billCycleDay,
String paymentProviderName,
- BigDecimal balance,
final DateTimeZone timeZone,
final String locale,
final String address1,
@@ -55,14 +53,15 @@ public class MockAccountUserApi implements AccountUserApi {
Account result = new DefaultAccount(id, externalKey, email, name,
firstNameLength, currency, billCycleDay, paymentProviderName,
timeZone, locale, address1, address2, companyName, city,
- stateOrProvince, country, postalCode, phone, null, null);
+ stateOrProvince, country, postalCode, phone, null, null, null, null);
accounts.add(result);
return result;
}
@Override
- public Account createAccount(AccountData data, List<CustomField> fields, List<Tag> tags) throws AccountApiException {
- Account result = new DefaultAccount(data, new DateTime());
+ public Account createAccount(final AccountData data, final List<CustomField> fields,
+ final List<Tag> tags, final CallContext context) throws AccountApiException {
+ Account result = new DefaultAccount(data);
accounts.add(result);
return result;
}
@@ -103,38 +102,38 @@ public class MockAccountUserApi implements AccountUserApi {
}
@Override
- public void updateAccount(Account account) {
+ public void updateAccount(final Account account, final CallContext context) {
throw new UnsupportedOperationException();
}
@Override
- public void deleteAccountByKey(String externalKey)
+ public void deleteAccountByKey(final String externalKey, final CallContext context)
throws AccountApiException {
for (Account account : accounts) {
if (externalKey.equals(account.getExternalKey())) {
- accounts.remove(account.getId());
+ accounts.remove(account);
}
}
}
@Override
- public Account migrateAccount(MigrationAccountData data,
- List<CustomField> fields, List<Tag> tags)
+ public Account migrateAccount(final MigrationAccountData data,
+ final List<CustomField> fields, final List<Tag> tags, final CallContext context)
throws AccountApiException {
- Account result = new DefaultAccount(data, data.getCreatedDate(), data.getUpdatedDate());
+ Account result = new DefaultAccount(data);
accounts.add(result);
return result;
}
@Override
- public void updateAccount(String key, AccountData accountData)
+ public void updateAccount(final String key, final AccountData accountData, final CallContext context)
throws AccountApiException {
throw new UnsupportedOperationException();
}
@Override
- public void updateAccount(UUID accountId, AccountData accountData)
+ public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context)
throws AccountApiException {
throw new UnsupportedOperationException();
}
diff --git a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
index 964eb6a..92b316a 100644
--- a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
@@ -20,6 +20,11 @@ import static org.testng.Assert.fail;
import java.io.IOException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
import org.apache.commons.io.IOUtils;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.IDBI;
@@ -41,6 +46,8 @@ public abstract class AccountDaoTestBase {
protected AccountDao accountDao;
protected IDBI dbi;
+ protected CallContext context;
+
@BeforeClass(alwaysRun = true)
protected void setup() throws IOException {
// Health check test to make sure MySQL is setup properly
@@ -59,6 +66,10 @@ public abstract class AccountDaoTestBase {
accountDao = injector.getInstance(AccountDao.class);
accountDao.test();
+ Clock clock = injector.getInstance(Clock.class);
+ context = new DefaultCallContextFactory(clock).createCallContext("Vizzini", CallOrigin.TEST, UserType.TEST);
+
+
BusService busService = injector.getInstance(BusService.class);
((DefaultBusService) busService).startBus();
}
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index b351709..7cfc3f1 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -28,6 +28,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountChangeNotification;
import com.ning.billing.account.api.user.DefaultAccountChangeNotification;
import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.Bus.EventBusException;
@@ -41,7 +42,7 @@ public class MockAccountDao implements AccountDao {
}
@Override
- public void create(Account account) {
+ public void create(Account account, CallContext context) {
accounts.put(account.getId().toString(), account);
try {
@@ -83,7 +84,7 @@ public class MockAccountDao implements AccountDao {
}
@Override
- public void update(Account account) {
+ public void update(Account account, CallContext context) {
Account currentAccount = accounts.put(account.getId().toString(), account);
AccountChangeNotification changeEvent = new DefaultAccountChangeNotification(account.getId(), currentAccount, account);
@@ -98,10 +99,10 @@ public class MockAccountDao implements AccountDao {
}
@Override
- public void deleteByKey(String externalKey) throws AccountApiException {
+ public void deleteByKey(String externalKey, CallContext context) throws AccountApiException {
for (Account account : accounts.values()) {
if (externalKey.equals(account.getExternalKey())) {
- accounts.remove(account.getId());
+ accounts.remove(account.getId().toString());
}
}
}
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
index fd99ec5..10d904f 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
@@ -18,6 +18,7 @@ package com.ning.billing.account.dao;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -25,7 +26,6 @@ import java.util.List;
import java.util.UUID;
import com.ning.billing.util.entity.EntityPersistenceException;
-import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.testng.annotations.Test;
@@ -35,7 +35,6 @@ import com.ning.billing.account.api.AccountData;
import com.ning.billing.account.api.DefaultAccount;
import com.ning.billing.account.api.user.AccountBuilder;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.clock.DefaultClock;
import com.ning.billing.util.tag.DefaultTagDefinition;
import com.ning.billing.util.tag.Tag;
import com.ning.billing.util.tag.TagDefinition;
@@ -53,9 +52,6 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
String locale = "EN-US";
DateTimeZone timeZone = DateTimeZone.forID("America/Los_Angeles");
- DateTime createdDate = new DateTime(DateTimeZone.UTC);
- DateTime updatedDate = new DateTime(DateTimeZone.UTC);
-
int firstNameLength = firstName.length();
return new AccountBuilder().externalKey(thisKey)
.name(name)
@@ -64,15 +60,13 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
.email(thisEmail)
.currency(Currency.USD)
.locale(locale)
- .timeZone(timeZone)
- .createdDate(createdDate)
- .updatedDate(updatedDate);
+ .timeZone(timeZone);
}
@Test
public void testBasic() throws EntityPersistenceException {
Account a = createTestAccountBuilder().build();
- accountDao.create(a);
+ accountDao.create(a, context);
String key = a.getExternalKey();
Account r = accountDao.getAccountByKey(key);
@@ -92,7 +86,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
@Test
public void testLongPhoneNumber() throws EntityPersistenceException {
Account account = createTestAccountBuilder().phone("123456789012345678901234").build();
- accountDao.create(account);
+ accountDao.create(account, context);
Account saved = accountDao.getAccountByKey(account.getExternalKey());
assertNotNull(saved);
@@ -102,7 +96,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
@Test(expectedExceptions = {EntityPersistenceException.class})
public void testOverlyLongPhoneNumber() throws EntityPersistenceException {
Account account = createTestAccountBuilder().phone("12345678901234567890123456").build();
- accountDao.create(account);
+ accountDao.create(account, context);
}
@Test
@@ -113,7 +107,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
String name = account.getName();
int firstNameLength = account.getFirstNameLength();
- accountDao.create(account);
+ accountDao.create(account, context);
account = accountDao.getById(id.toString());
assertNotNull(account);
@@ -131,7 +125,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
String fieldValue = "testField1_value";
account.setFieldValue(fieldName, fieldValue);
- accountDao.create(account);
+ accountDao.create(account, context);
Account thisAccount = accountDao.getAccountByKey(account.getExternalKey());
assertNotNull(thisAccount);
@@ -142,29 +136,25 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
@Test
public void testTags() throws EntityPersistenceException {
Account account = createTestAccountBuilder().build();
- TagDefinition definition = new DefaultTagDefinition("Test Tag", "For testing only", "Test System");
+ TagDefinition definition = new DefaultTagDefinition("Test Tag", "For testing only");
TagDefinitionSqlDao tagDescriptionDao = dbi.onDemand(TagDefinitionSqlDao.class);
- tagDescriptionDao.create(definition);
+ tagDescriptionDao.create(definition, context);
- String addedBy = "testTags()";
- DateTime dateAdded = new DefaultClock().getUTCNow();
- account.addTag(definition, addedBy, dateAdded);
+ account.addTag(definition);
assertEquals(account.getTagList().size(), 1);
- accountDao.create(account);
+ accountDao.create(account, context);
Account thisAccount = accountDao.getById(account.getId().toString());
List<Tag> tagList = thisAccount.getTagList();
assertEquals(tagList.size(), 1);
Tag tag = tagList.get(0);
assertEquals(tag.getTagDefinitionName(), definition.getName());
- assertEquals(tag.getAddedBy(), addedBy);
- assertEquals(tag.getAddedDate().compareTo(dateAdded), 0);
}
@Test
public void testGetIdFromKey() throws EntityPersistenceException {
Account account = createTestAccountBuilder().build();
- accountDao.create(account);
+ accountDao.create(account, context);
try {
UUID accountId = accountDao.getIdFromKey(account.getExternalKey());
@@ -183,7 +173,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
@Test
public void testUpdate() throws Exception {
final Account account = createTestAccountBuilder().build();
- accountDao.create(account);
+ accountDao.create(account, context);
AccountData accountData = new AccountData() {
@Override
@@ -270,8 +260,8 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
}
};
- Account updatedAccount = new DefaultAccount(account.getId(), accountData);
- accountDao.update(updatedAccount);
+ Account updatedAccount = new DefaultAccount(account.getId(), null, null, null, null, accountData);
+ accountDao.update(updatedAccount, context);
Account savedAccount = accountDao.getAccountByKey(account.getExternalKey());
@@ -298,8 +288,8 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
DefaultAccount account = new DefaultAccount(accountId, "extKey123456", "myemail123456@glam.com",
"John Smith", 4, Currency.USD, 15, null,
DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
- null, null, null, null, null, null, null, null,null,null);
- accountDao.create(account);
+ null, null, null, null, null, null, null, null, null, null, null, null);
+ accountDao.create(account, context);
String address1 = "123 address 1";
String address2 = "456 address 2";
@@ -314,9 +304,9 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
"John Smith", 4, Currency.USD, 15, null,
DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
address1, address2, companyName, city, stateOrProvince, country,
- postalCode, phone, null,null);
+ postalCode, phone, null, null, null, null);
- accountDao.update(updatedAccount);
+ accountDao.update(updatedAccount, context);
Account savedAccount = accountDao.getById(accountId.toString());
@@ -340,15 +330,17 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
"John Smith", 4, Currency.USD, 15, null,
DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
"123 address 1", "456 address 2", null, "Cambridge Bay",
- "Nunavut", "Canada", "X0B 0C0", "18001112222", null, null);
- accountDao.create(account);
+ "Nunavut", "Canada", "X0B 0C0", "18001112222",
+ null, null, null, null);
+ accountDao.create(account, context);
DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey654321", "myemail654321@glam.com",
"John Smith", 4, Currency.USD, 15, null,
DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
- null, null, null, null, null, null, null, null, null, null);
+ null, null, null, null, null, null, null, null,
+ null, null, null, null);
- accountDao.update(updatedAccount);
+ accountDao.update(updatedAccount, context);
Account savedAccount = accountDao.getById(accountId.toString());
@@ -371,31 +363,32 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
DefaultAccount account = new DefaultAccount(accountId, originalExternalKey, "myemail1337@glam.com",
"John Smith", 4, Currency.USD, 15, null,
- null, null, null, null, null, null, null, null, null, null, null, null);
- accountDao.create(account);
+ null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null);
+ accountDao.create(account, context);
DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey1338", "myemail1337@glam.com",
"John Smith", 4, Currency.USD, 15, null,
- null, null, null, null, null, null, null, null, null, null,null, null);
- accountDao.update(updatedAccount);
+ null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null);
+ accountDao.update(updatedAccount, context);
}
@Test
public void testDelete() throws AccountApiException, EntityPersistenceException {
Account a = createTestAccountBuilder().build();
- accountDao.create(a);
+ accountDao.create(a, context);
String key = a.getExternalKey();
Account r = accountDao.getAccountByKey(key);
assertNotNull(r);
assertEquals(r.getExternalKey(), a.getExternalKey());
- accountDao.deleteByKey(key);
+ accountDao.deleteByKey(key, context);
Account s = accountDao.getAccountByKey(key);
- assertTrue(s==null);
-
+ assertNull(s);
}
}
diff --git a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithEmbeddedDb.java b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithEmbeddedDb.java
index 1a894a7..f263971 100644
--- a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithEmbeddedDb.java
+++ b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithEmbeddedDb.java
@@ -18,7 +18,11 @@ package com.ning.billing.account.glue;
import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.util.clock.MockClockModule;
+import com.ning.billing.util.customfield.CustomFieldMapper;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.glue.TagStoreModule;
import org.skife.jdbi.v2.IDBI;
import java.io.IOException;
@@ -41,8 +45,11 @@ public class AccountModuleWithEmbeddedDb extends AccountModule {
@Override
protected void configure() {
bind(IDBI.class).toInstance(helper.getDBI());
- super.configure();
install(new BusModule());
install(new MockClockModule());
+ install(new CallContextModule());
+ install(new TagStoreModule());
+ install(new FieldStoreModule());
+ super.configure();
}
}
diff --git a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
index 1c65c3c..74fe321 100644
--- a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
+++ b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
@@ -19,6 +19,9 @@ package com.ning.billing.account.glue;
import com.ning.billing.account.dao.AccountDao;
import com.ning.billing.account.dao.MockAccountDao;
import com.ning.billing.util.clock.MockClockModule;
+import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.tag.MockTagStoreModuleMemory;
public class AccountModuleWithMocks extends AccountModule {
@Override
@@ -27,10 +30,12 @@ public class AccountModuleWithMocks extends AccountModule {
bind(AccountDao.class).to(MockAccountDao.class);
}
-
@Override
protected void configure() {
super.configure();
install(new MockClockModule());
+ install(new CallContextModule());
+ install(new MockTagStoreModuleMemory());
+ install(new FieldStoreModule());
}
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index 5c7ffae..1aafa7c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -18,6 +18,9 @@ package com.ning.billing.analytics;
import com.ning.billing.invoice.glue.InvoiceModule;
import com.ning.billing.payment.setup.PaymentModule;
+import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
import org.skife.jdbi.v2.IDBI;
import com.ning.billing.account.glue.AccountModule;
import com.ning.billing.analytics.setup.AnalyticsModule;
@@ -31,6 +34,8 @@ import com.ning.billing.util.glue.ClockModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
+import java.lang.reflect.Field;
+
public class AnalyticsTestModule extends AnalyticsModule
{
@Override
@@ -39,13 +44,16 @@ public class AnalyticsTestModule extends AnalyticsModule
super.configure();
// Need to configure a few more things for the EventBus
+ install(new ClockModule());
+ install(new CallContextModule());
+ install(new FieldStoreModule());
+ install(new TagStoreModule());
install(new AccountModule());
install(new CatalogModule());
install(new BusModule());
install(new EntitlementModule());
install(new InvoiceModule());
install(new PaymentModule());
- install(new ClockModule());
install(new TagStoreModule());
install(new NotificationQueueModule());
@@ -54,5 +62,7 @@ public class AnalyticsTestModule extends AnalyticsModule
bind(MysqlTestingHelper.class).toInstance(helper);
final IDBI dbi = helper.getDBI();
bind(IDBI.class).toInstance(dbi);
+
+ bind(TagDefinitionSqlDao.class).toInstance(dbi.onDemand(TagDefinitionSqlDao.class));
}
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 059efaa..59ad218 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -68,6 +68,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransition;
import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.events.user.ApiEventType;
+import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceCreationNotification;
import com.ning.billing.invoice.api.user.DefaultInvoiceCreationNotification;
import com.ning.billing.invoice.dao.InvoiceDao;
@@ -77,6 +78,10 @@ import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfo;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.DefaultClock;
import com.ning.billing.util.tag.DefaultTagDefinition;
@@ -90,13 +95,14 @@ public class TestAnalyticsService {
private static final String KEY = "12345";
private static final String ACCOUNT_KEY = "pierre-12345";
private static final Currency ACCOUNT_CURRENCY = Currency.EUR;
- private static final DefaultTagDefinition TAG_ONE = new DefaultTagDefinition("batch20", "something", "pierre");
- private static final DefaultTagDefinition TAG_TWO = new DefaultTagDefinition("awesome", "something", "pierre");
+ private static final DefaultTagDefinition TAG_ONE = new DefaultTagDefinition("batch20", "something");
+ private static final DefaultTagDefinition TAG_TWO = new DefaultTagDefinition("awesome", "something");
private static final BigDecimal INVOICE_AMOUNT = BigDecimal.valueOf(1243.11);
private static final String PAYMENT_METHOD = "Paypal";
private static final String CARD_COUNTRY = "France";
private final Clock clock = new DefaultClock();
+ private final CallContext context = new DefaultCallContextFactory(clock).createCallContext("Analytics Test", CallOrigin.TEST, UserType.TEST);
@Inject
private AccountUserApi accountApi;
@@ -149,17 +155,16 @@ public class TestAnalyticsService {
// Killbill generic setup
setupBusAndMySQL();
-
- tagDao.create(TAG_ONE);
- tagDao.create(TAG_TWO);
+ tagDao.create(TAG_ONE, context);
+ tagDao.create(TAG_TWO, context);
final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, ACCOUNT_CURRENCY);
try {
final List<Tag> tags = new ArrayList<Tag>();
- tags.add(new DescriptiveTag(TAG_ONE, "pierre", clock.getUTCNow()));
- tags.add(new DescriptiveTag(TAG_TWO, "pierre", clock.getUTCNow()));
+ tags.add(new DescriptiveTag(TAG_ONE));
+ tags.add(new DescriptiveTag(TAG_TWO));
- final Account storedAccount = accountApi.createAccount(account, null, tags);
+ final Account storedAccount = accountApi.createAccount(account, null, tags, context);
// Create events for the bus and expected results
createSubscriptionTransitionEvent(storedAccount);
@@ -243,16 +248,16 @@ public class TestAnalyticsService {
}
private void createInvoiceAndPaymentCreationEvents(final Account account) {
- final DefaultInvoice invoice = new DefaultInvoice(account.getId(), clock.getUTCNow(), ACCOUNT_CURRENCY, clock);
+ final DefaultInvoice invoice = new DefaultInvoice(account.getId(), clock.getUTCNow(), clock.getUTCNow(), ACCOUNT_CURRENCY);
final FixedPriceInvoiceItem invoiceItem = new FixedPriceInvoiceItem(
- UUID.randomUUID(), invoice.getId(), UUID.randomUUID(), "somePlan", "somePhase", clock.getUTCNow(), clock.getUTCNow().plusDays(1),
- INVOICE_AMOUNT, ACCOUNT_CURRENCY, clock.getUTCNow()
- );
+ UUID.randomUUID(), invoice.getId(), account.getId(), UUID.randomUUID(), UUID.randomUUID(), "somePlan", "somePhase", clock.getUTCNow(), clock.getUTCNow().plusDays(1),
+ INVOICE_AMOUNT, ACCOUNT_CURRENCY, context.getUserName(), clock.getUTCNow());
invoice.addInvoiceItem(invoiceItem);
- invoiceDao.create(invoice);
- Assert.assertEquals(invoiceDao.getInvoicesByAccount(account.getId()).size(), 1);
- Assert.assertEquals(invoiceDao.getInvoicesByAccount(account.getId()).get(0).getInvoiceItems().size(), 1);
+ invoiceDao.create(invoice, context);
+ List<Invoice> invoices = invoiceDao.getInvoicesByAccount(account.getId());
+ Assert.assertEquals(invoices.size(), 1);
+ Assert.assertEquals(invoices.get(0).getInvoiceItems().size(), 1);
// It doesn't really matter what the events contain - the listener will go back to the db
invoiceCreationNotification = new DefaultInvoiceCreationNotification(invoice.getId(), account.getId(),
@@ -261,8 +266,8 @@ public class TestAnalyticsService {
paymentInfoNotification = new PaymentInfo.Builder().setPaymentId(UUID.randomUUID().toString()).setPaymentMethod(PAYMENT_METHOD).setCardCountry(CARD_COUNTRY).build();
final PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice.getId(), account.getId(), BigDecimal.TEN,
ACCOUNT_CURRENCY, clock.getUTCNow(), clock.getUTCNow(), paymentInfoNotification.getPaymentId(), 1);
- paymentDao.createPaymentAttempt(paymentAttempt);
- paymentDao.savePaymentInfo(paymentInfoNotification);
+ paymentDao.createPaymentAttempt(paymentAttempt, context);
+ paymentDao.savePaymentInfo(paymentInfoNotification, context);
Assert.assertEquals(paymentDao.getPaymentInfo(Arrays.asList(invoice.getId().toString())).size(), 1);
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
index ac7ed34..5e94f15 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -19,13 +19,13 @@ package com.ning.billing.analytics;
import java.util.List;
import java.util.UUID;
-import org.apache.commons.lang.NotImplementedException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.DefaultMutableAccountData;
+import com.ning.billing.account.api.MutableAccountData;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.tag.Tag;
import com.ning.billing.util.tag.TagDefinition;
@@ -140,88 +140,113 @@ public class MockAccount implements Account
}
@Override
+ public String getCreatedBy() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public String getFieldValue(String fieldName) {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public void setFieldValue(String fieldName, String fieldValue) {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+ throw new UnsupportedOperationException();
}
@Override
public List<CustomField> getFieldList() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setFields(List<CustomField> fields) {
+ throw new UnsupportedOperationException();
}
@Override
- public void addFields(List<CustomField> fields) {
- throw new NotImplementedException();
+ public void saveFields(List<CustomField> fields, CallContext context) {
+ throw new UnsupportedOperationException();
}
@Override
public void clearFields() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearPersistedFields(CallContext context) {
+ throw new UnsupportedOperationException();
}
@Override
public String getObjectName() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public List<Tag> getTagList() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public boolean hasTag(String tagName) {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
- public void addTag(TagDefinition definition, String addedBy, DateTime dateAdded) {
- throw new NotImplementedException();
+ public void addTag(TagDefinition definition) {
+ throw new UnsupportedOperationException();
}
@Override
public void addTags(List<Tag> tags) {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public void clearTags() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public void removeTag(TagDefinition definition) {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public boolean generateInvoice() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
public boolean processPayment() {
- throw new NotImplementedException();
+ throw new UnsupportedOperationException();
}
@Override
- public DateTime getCreatedDate() {
- return new DateTime(DateTimeZone.UTC);
+ public String getUpdatedBy() {
+ throw new UnsupportedOperationException();
}
@Override
public DateTime getUpdatedDate() {
- return new DateTime(DateTimeZone.UTC);
+ throw new UnsupportedOperationException();
}
@Override
- public DefaultMutableAccountData toMutableAccountData() {
- throw new NotImplementedException();
+ public MutableAccountData toMutableAccountData() {
+ throw new UnsupportedOperationException();
}
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
index c410698..85ec378 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
@@ -28,7 +28,7 @@ import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.account.api.DefaultAccount;
import com.ning.billing.account.api.MigrationAccountData;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.tag.Tag;
@@ -36,23 +36,21 @@ public class MockIAccountUserApi implements AccountUserApi
{
private final AccountData account;
private final UUID id;
- private Clock clock;
- public MockIAccountUserApi(final String accountKey, final Currency currency, final Clock clock)
+ public MockIAccountUserApi(final String accountKey, final Currency currency)
{
this.id = UUID.randomUUID();
account = new MockAccount(id, accountKey, currency);
- this.clock = clock;
}
@Override
- public Account createAccount(final AccountData data, final List<CustomField> fields, final List<Tag> tags)
+ public Account createAccount(final AccountData data, final List<CustomField> fields, final List<Tag> tags, final CallContext context)
{
throw new UnsupportedOperationException();
}
@Override
- public void updateAccount(final Account account) {
+ public void updateAccount(final Account account, final CallContext context) {
throw new UnsupportedOperationException();
}
@@ -64,7 +62,7 @@ public class MockIAccountUserApi implements AccountUserApi
@Override
public Account getAccountById(final UUID uid) {
- return new DefaultAccount(account, clock.getUTCNow());
+ return new DefaultAccount(account);
}
@Override
@@ -79,25 +77,25 @@ public class MockIAccountUserApi implements AccountUserApi
}
@Override
- public void deleteAccountByKey(String externalKey) {
+ public void deleteAccountByKey(String externalKey, final CallContext context) {
throw new UnsupportedOperationException();
}
@Override
public Account migrateAccount(MigrationAccountData data,
- List<CustomField> fields, List<Tag> tags)
+ List<CustomField> fields, List<Tag> tags, final CallContext context)
throws AccountApiException {
throw new UnsupportedOperationException();
}
@Override
- public void updateAccount(String key, AccountData accountData)
+ public void updateAccount(String key, AccountData accountData, final CallContext context)
throws AccountApiException {
throw new UnsupportedOperationException();
}
@Override
- public void updateAccount(UUID accountId, AccountData accountData)
+ public void updateAccount(UUID accountId, AccountData accountData, CallContext context)
throws AccountApiException {
throw new NotImplementedException();
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
index 9d7b5c3..cce9984 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
@@ -31,7 +31,11 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+
public class MockSubscription implements Subscription
{
@@ -69,6 +73,16 @@ public class MockSubscription implements Subscription
}
@Override
+ public String getCreatedBy() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public UUID getBundleId()
{
return BUNDLE_ID;
@@ -158,12 +172,22 @@ public class MockSubscription implements Subscription
}
@Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public List<CustomField> getFieldList() {
throw new UnsupportedOperationException();
}
@Override
- public void addFields(List<CustomField> fields) {
+ public void setFields(List<CustomField> fields) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveFields(List<CustomField> fields, CallContext context) {
throw new UnsupportedOperationException();
}
@@ -173,7 +197,52 @@ public class MockSubscription implements Subscription
}
@Override
+ public void clearPersistedFields(CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public String getObjectName() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public List<Tag> getTagList() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasTag(String tagName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addTag(TagDefinition definition) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addTags(List<Tag> tags) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearTags() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeTag(TagDefinition definition) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean generateInvoice() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean processPayment() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
index f24b8f2..ca782b9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
@@ -16,9 +16,10 @@
package com.ning.billing.analytics;
-
import java.util.UUID;
+import javax.annotation.Nullable;
+
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.testng.Assert;
@@ -36,8 +37,6 @@ import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.util.clock.ClockMock;
-
public class TestAnalyticsListener
{
@@ -58,7 +57,7 @@ public class TestAnalyticsListener
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception
{
- final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, new MockIEntitlementUserApi(bundleUUID, KEY), new MockIAccountUserApi(ACCOUNT_KEY, CURRENCY, new ClockMock()));
+ final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, new MockIEntitlementUserApi(bundleUUID, KEY), new MockIAccountUserApi(ACCOUNT_KEY, CURRENCY));
listener = new AnalyticsListener(recorder, null);
}
@@ -120,8 +119,8 @@ public class TestAnalyticsListener
final BusinessSubscriptionEvent eventType,
final DateTime requestedTransitionTime,
final DateTime effectiveTransitionTime,
- final BusinessSubscription previousSubscription,
- final Subscription.SubscriptionState nextState
+ @Nullable final BusinessSubscription previousSubscription,
+ @Nullable final Subscription.SubscriptionState nextState
)
{
return new BusinessSubscriptionTransition(
diff --git a/api/src/main/java/com/ning/billing/account/api/Account.java b/api/src/main/java/com/ning/billing/account/api/Account.java
index 2f50390..65abdf1 100644
--- a/api/src/main/java/com/ning/billing/account/api/Account.java
+++ b/api/src/main/java/com/ning/billing/account/api/Account.java
@@ -16,18 +16,13 @@
package com.ning.billing.account.api;
-import org.joda.time.DateTime;
-
import com.ning.billing.catalog.api.overdue.Overdueable;
-import com.ning.billing.util.customfield.CustomizableEntity;
+import com.ning.billing.util.customfield.Customizable;
import com.ning.billing.util.entity.UpdatableEntity;
import com.ning.billing.util.tag.Taggable;
-public interface Account extends AccountData, CustomizableEntity, UpdatableEntity, Taggable, Overdueable {
- public DateTime getCreatedDate();
-
- public DateTime getUpdatedDate();
-
- public MutableAccountData toMutableAccountData();
-
+public interface Account extends AccountData, Customizable, UpdatableEntity, Taggable, Overdueable{
+ public static String ObjectType = "account";
+
+ public MutableAccountData toMutableAccountData();
}
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
index 6ac392d..2ab04dc 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
@@ -19,17 +19,18 @@ package com.ning.billing.account.api;
import java.util.List;
import java.util.UUID;
-import org.joda.time.DateTimeZone;
-
-import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.tag.Tag;
-public interface AccountUserApi {
+import javax.annotation.Nullable;
- public Account createAccount(AccountData data, List<CustomField> fields, List<Tag> tags) throws AccountApiException;
+public interface AccountUserApi {
+ public Account createAccount(AccountData data, @Nullable List<CustomField> fields,
+ @Nullable List<Tag> tags, CallContext context) throws AccountApiException;
- public Account migrateAccount(MigrationAccountData data, List<CustomField> fields, List<Tag> tags) throws AccountApiException;
+ public Account migrateAccount(MigrationAccountData data, @Nullable List<CustomField> fields,
+ @Nullable List<Tag> tags, CallContext context) throws AccountApiException;
/***
*
@@ -37,12 +38,12 @@ public interface AccountUserApi {
* @param account
* @throws AccountApiException
*/
- public void updateAccount(Account account) throws AccountApiException;
+ public void updateAccount(Account account, CallContext context) throws AccountApiException;
+
+ public void updateAccount(String key, AccountData accountData, CallContext context) throws AccountApiException;
+
+ public void updateAccount(UUID accountId, AccountData accountData, CallContext context) throws AccountApiException;
- public void updateAccount(String key, AccountData accountData) throws AccountApiException;
-
- public void updateAccount(UUID accountId, AccountData accountData) throws AccountApiException;
-
public Account getAccountByKey(String key);
public Account getAccountById(UUID accountId);
@@ -51,5 +52,5 @@ public interface AccountUserApi {
public UUID getIdFromKey(String externalKey) throws AccountApiException;
- public void deleteAccountByKey(String externalKey) throws AccountApiException;
+ public void deleteAccountByKey(String externalKey, CallContext context) throws AccountApiException;
}
diff --git a/api/src/main/java/com/ning/billing/config/InvoiceConfig.java b/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
index 78cc02f..f56d3c2 100644
--- a/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
+++ b/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
@@ -36,4 +36,8 @@ public interface InvoiceConfig {
@Config("killbill.notifications.off")
@Default("false")
public boolean isEventProcessingOff();
+
+ @Config("killbill.invoice.maxNumberOfMonthsInFuture")
+ @Default("36")
+ public int getNumberOfMonthsInFuture();
}
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 2ed8b14..7304f5b 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -26,10 +26,10 @@ import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.PriceList;
import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.util.customfield.CustomizableEntity;
+import com.ning.billing.util.entity.ExtendedEntity;
-public interface Subscription extends CustomizableEntity {
+public interface Subscription extends ExtendedEntity {
public void cancel(DateTime requestedDate, boolean eot)
throws EntitlementUserApiException;
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 4cd4d9f..9ef5338 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -136,6 +136,13 @@ public enum ErrorCode {
/*
*
+ * Range 3950: Tags
+ *
+ */
+ TAG_DOES_NOT_EXIST(3950, "The tag does not exist (name: %s)"),
+
+ /*
+ *
* Range 4000: INVOICE
*
*/
diff --git a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
index 406160e..0cf30ab 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
@@ -16,15 +16,17 @@
package com.ning.billing.invoice.api;
-import com.ning.billing.util.entity.Entity;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.ExtendedEntity;
import org.joda.time.DateTime;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
-public interface Invoice extends Entity {
+public interface Invoice extends ExtendedEntity {
+ public static String ObjectType = "invoice";
+
boolean addInvoiceItem(InvoiceItem item);
boolean addInvoiceItems(List<InvoiceItem> items);
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
index 4082403..b7ab8b1 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
@@ -26,10 +26,12 @@ import java.util.UUID;
public interface InvoiceItem extends Entity, Comparable<InvoiceItem> {
UUID getInvoiceId();
- UUID getSubscriptionId();
+ UUID getAccountId();
UUID getBundleId();
+ UUID getSubscriptionId();
+
String getPlanName();
String getPhaseName();
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItemType.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItemType.java
new file mode 100644
index 0000000..ce066a4
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItemType.java
@@ -0,0 +1,28 @@
+/*
+ * 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.invoice.api;
+
+public enum InvoiceItemType {
+ FIXED,
+ RECURRING,
+ REVERSAL,
+ MIGRATION,
+ REFUND,
+ CHARGE_BACK,
+ ADD_CREDIT,
+ USE_CREDIT
+}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
index 5cdf0de..29f175b 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
@@ -22,7 +22,7 @@ import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.util.entity.Entity;
-public interface InvoicePayment {
+public interface InvoicePayment extends Entity {
UUID getPaymentAttemptId();
UUID getInvoiceId();
@@ -32,6 +32,4 @@ public interface InvoicePayment {
BigDecimal getAmount();
Currency getCurrency();
-
- DateTime getCreatedDate();
}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index 84292c4..9fb0bb3 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -20,6 +20,7 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
@@ -38,10 +39,10 @@ public interface InvoicePaymentApi {
public InvoicePayment getInvoicePayment(UUID paymentAttemptId);
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment);
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context);
- public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate);
+ public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
- public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate);
+ public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 0ee9cd8..66016df 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -16,6 +16,7 @@
package com.ning.billing.invoice.api;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import java.math.BigDecimal;
@@ -32,9 +33,13 @@ public interface InvoiceUserApi {
public Invoice getInvoice(UUID invoiceId);
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment);
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context);
public Collection<Invoice> getUnpaidInvoicesByAccountId(UUID accountId, DateTime upToDate);
- public Invoice triggerInvoiceGeneration(UUID accountId, DateTime targetDate, boolean dryrun) throws InvoiceApiException;
+ public Invoice triggerInvoiceGeneration(UUID accountId, DateTime targetDate, boolean dryRun, CallContext context) throws InvoiceApiException;
+
+ public void tagInvoiceAsWrittenOff(UUID invoiceId, CallContext context);
+
+ public void tagInvoiceAsNotWrittenOff(UUID invoiceId, CallContext context);
}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/test/InvoiceTestApi.java b/api/src/main/java/com/ning/billing/invoice/api/test/InvoiceTestApi.java
index 9edcd8c..6c00934 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/test/InvoiceTestApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/test/InvoiceTestApi.java
@@ -17,7 +17,8 @@
package com.ning.billing.invoice.api.test;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.util.callcontext.CallContext;
public interface InvoiceTestApi {
- public void create(Invoice invoice);
+ public void create(Invoice invoice, CallContext context);
}
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index 57c76a0..9076256 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -22,38 +22,39 @@ import java.util.UUID;
import javax.annotation.Nullable;
import com.ning.billing.account.api.Account;
+import com.ning.billing.util.callcontext.CallContext;
public interface PaymentApi {
- Either<PaymentError, Void> updatePaymentGateway(String accountKey);
+ Either<PaymentError, Void> updatePaymentGateway(String accountKey, CallContext context);
Either<PaymentError, PaymentMethodInfo> getPaymentMethod(@Nullable String accountKey, String paymentMethodId);
Either<PaymentError, List<PaymentMethodInfo>> getPaymentMethods(String accountKey);
- Either<PaymentError, String> addPaymentMethod(@Nullable String accountKey, PaymentMethodInfo paymentMethod);
+ Either<PaymentError, String> addPaymentMethod(@Nullable String accountKey, PaymentMethodInfo paymentMethod, CallContext context);
- Either<PaymentError, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo);
+ Either<PaymentError, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo, CallContext context);
- Either<PaymentError, Void> deletePaymentMethod(String accountKey, String paymentMethodId);
+ Either<PaymentError, Void> deletePaymentMethod(String accountKey, String paymentMethodId, CallContext context);
- List<Either<PaymentError, PaymentInfo>> createPayment(String accountKey, List<String> invoiceIds);
- List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds);
- Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId);
+ List<Either<PaymentError, PaymentInfo>> createPayment(String accountKey, List<String> invoiceIds, CallContext context);
+ List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds, CallContext context);
+ Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId, CallContext context);
- List<Either<PaymentError, PaymentInfo>> createRefund(Account account, List<String> invoiceIds); //TODO
+ List<Either<PaymentError, PaymentInfo>> createRefund(Account account, List<String> invoiceIds, CallContext context); //TODO
Either<PaymentError, PaymentProviderAccount> getPaymentProviderAccount(String accountKey);
- Either<PaymentError, String> createPaymentProviderAccount(Account account);
+ Either<PaymentError, String> createPaymentProviderAccount(Account account, CallContext context);
- Either<PaymentError, Void> updatePaymentProviderAccountContact(String accountKey);
+ Either<PaymentError, Void> updatePaymentProviderAccountContact(String accountKey, CallContext context);
PaymentAttempt getPaymentAttemptForPaymentId(String id);
List<PaymentInfo> getPaymentInfo(List<String> invoiceIds);
- PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId);
+ List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId);
PaymentInfo getPaymentInfoForPaymentAttemptId(String paymentAttemptId);
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java b/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
index 8085310..15ac4ee 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
@@ -59,8 +59,8 @@ public class PaymentAttempt {
this.paymentAttemptDate = paymentAttemptDate == null ? new DateTime(DateTimeZone.UTC) : paymentAttemptDate;
this.paymentId = paymentId;
this.retryCount = retryCount == null ? 0 : retryCount;
- this.createdDate = createdDate == null ? new DateTime(DateTimeZone.UTC) : createdDate;
- this.updatedDate = updatedDate == null ? new DateTime(DateTimeZone.UTC) : updatedDate;
+ this.createdDate = createdDate;
+ this.updatedDate = updatedDate;
}
public PaymentAttempt(UUID paymentAttemptId,
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
index b0fbca6..e325d9a 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
@@ -38,7 +38,7 @@ public class PaymentInfo implements BusEvent {
private final String paymentMethodId;
private final String paymentMethod;
private final String cardType;
- private final String cardCoutry;
+ private final String cardCountry;
private final DateTime effectiveDate;
private final DateTime createdDate;
private final DateTime updatedDate;
@@ -70,7 +70,7 @@ public class PaymentInfo implements BusEvent {
this.paymentMethodId = paymentMethodId;
this.paymentMethod = paymentMethod;
this.cardType = cardType;
- this.cardCoutry = cardCountry;
+ this.cardCountry = cardCountry;
this.effectiveDate = effectiveDate;
this.createdDate = createdDate == null ? new DateTime(DateTimeZone.UTC) : createdDate;
this.updatedDate = updatedDate == null ? new DateTime(DateTimeZone.UTC) : updatedDate;
@@ -88,7 +88,7 @@ public class PaymentInfo implements BusEvent {
src.paymentMethodId,
src.paymentMethod,
src.cardType,
- src.cardCoutry,
+ src.cardCountry,
src.effectiveDate,
src.createdDate,
src.updatedDate);
@@ -131,7 +131,7 @@ public class PaymentInfo implements BusEvent {
}
public String getCardCountry() {
- return cardCoutry;
+ return cardCountry;
}
public String getReferenceId() {
@@ -191,7 +191,7 @@ public class PaymentInfo implements BusEvent {
this.paymentMethodId = src.paymentMethodId;
this.paymentMethod = src.paymentMethod;
this.cardType = src.cardType;
- this.cardCountry = src.cardCoutry;
+ this.cardCountry = src.cardCountry;
this.createdDate = src.createdDate;
this.updatedDate = src.updatedDate;
}
@@ -303,7 +303,7 @@ public class PaymentInfo implements BusEvent {
paymentMethodId,
paymentMethod,
cardType,
- cardCoutry,
+ cardCountry,
effectiveDate,
createdDate,
updatedDate);
@@ -319,7 +319,7 @@ public class PaymentInfo implements BusEvent {
if (amount != null ? !(amount.compareTo(that.amount) == 0) : that.amount != null) return false;
if (bankIdentificationNumber != null ? !bankIdentificationNumber.equals(that.bankIdentificationNumber) : that.bankIdentificationNumber != null)
return false;
- if (cardCoutry != null ? !cardCoutry.equals(that.cardCoutry) : that.cardCoutry != null) return false;
+ if (cardCountry != null ? !cardCountry.equals(that.cardCountry) : that.cardCountry != null) return false;
if (cardType != null ? !cardType.equals(that.cardType) : that.cardType != null) return false;
if (createdDate != null ? !(getUnixTimestamp(createdDate) == getUnixTimestamp(that.createdDate)) : that.createdDate != null) return false;
if (effectiveDate != null ? !(getUnixTimestamp(effectiveDate) == getUnixTimestamp(that.effectiveDate)) : that.effectiveDate != null)
@@ -342,7 +342,7 @@ public class PaymentInfo implements BusEvent {
@Override
public String toString() {
- return "PaymentInfo [paymentId=" + paymentId + ", amount=" + amount + ", refundAmount=" + refundAmount + ", paymentNumber=" + paymentNumber + ", bankIdentificationNumber=" + bankIdentificationNumber + ", status=" + status + ", type=" + type + ", referenceId=" + referenceId + ", paymentMethodId=" + paymentMethodId + ", paymentMethod=" + paymentMethod + ", cardType=" + cardType + ", cardCountry=" + cardCoutry + ", effectiveDate=" + effectiveDate + ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + "]";
+ return "PaymentInfo [paymentId=" + paymentId + ", amount=" + amount + ", refundAmount=" + refundAmount + ", paymentNumber=" + paymentNumber + ", bankIdentificationNumber=" + bankIdentificationNumber + ", status=" + status + ", type=" + type + ", referenceId=" + referenceId + ", paymentMethodId=" + paymentMethodId + ", paymentMethod=" + paymentMethod + ", cardType=" + cardType + ", cardCountry=" + cardCountry + ", effectiveDate=" + effectiveDate + ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + "]";
}
private static long getUnixTimestamp(final DateTime dateTime) {
diff --git a/api/src/main/java/com/ning/billing/util/api/TagUserApi.java b/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
index 1c2bd7a..d5cb8f2 100644
--- a/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/TagUserApi.java
@@ -18,6 +18,7 @@ package com.ning.billing.util.api;
import java.util.List;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import com.ning.billing.util.tag.Tag;
@@ -26,7 +27,7 @@ import com.ning.billing.util.tag.TagDefinition;
public interface TagUserApi {
/***
*
- * @return
+ * @return the list of all available tag definitions
*/
public List<TagDefinition> getTagDefinitions();
@@ -34,25 +35,27 @@ public interface TagUserApi {
*
* @param name Identifies the definition.
* @param description Describes the use of the definition.
- * @param createdBy The name of person who created the definition.
- * @return
+ * @param context The call context, for auditing purposes
+ * @return the newly created tag definition
* @throws TagDefinitionApiException
*/
- public TagDefinition create(String name, String description, String createdBy) throws TagDefinitionApiException;
+ public TagDefinition create(String name, String description, CallContext context) throws TagDefinitionApiException;
/***
*
* @param definitionName Identifies the definition.
+ * @param context The call context, for auditing purposes
* @throws TagDefinitionApiException
*/
- public void deleteAllTagsForDefinition(String definitionName) throws TagDefinitionApiException;
+ public void deleteAllTagsForDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
/***
*
* @param definitionName Identifies the definition.
+ * @param context The call context, for auditing purposes
* @throws TagDefinitionApiException
*/
- public void deleteTagDefinition(String definitionName) throws TagDefinitionApiException;
+ public void deleteTagDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
/**
@@ -64,20 +67,16 @@ public interface TagUserApi {
public TagDefinition getTagDefinition(String name) throws TagDefinitionApiException;
/**
- * @param addedBy
- * @param addedDate
- * @param controlTagType
- * @throws TagApiException
+ * @param controlTagName
+ * @throws TagDefinitionApiException
*/
- public Tag createControlTag(String controlTagName, String addedBy, DateTime addedDate) throws TagDefinitionApiException;
+ public Tag createControlTag(String controlTagName) throws TagDefinitionApiException;
/**
* @param tagDefinitionName
- * @param addedBy
- * @param addedDate
* @return
*/
- public Tag createDescriptiveTag(String tagDefinitionName, String addedBy, DateTime addedDate) throws TagDefinitionApiException;
+ public Tag createDescriptiveTag(String tagDefinitionName) throws TagDefinitionApiException;
}
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
new file mode 100644
index 0000000..da36f10
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util.callcontext;
+
+import org.joda.time.DateTime;
+
+public interface CallContext {
+ public String getUserName();
+ public CallOrigin getCallOrigin();
+ public UserType getUserType();
+ public DateTime getCreatedDate();
+ public DateTime getUpdatedDate();
+}
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/CallOrigin.java b/api/src/main/java/com/ning/billing/util/callcontext/CallOrigin.java
new file mode 100644
index 0000000..8806647
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/callcontext/CallOrigin.java
@@ -0,0 +1,23 @@
+/*
+ * 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.util.callcontext;
+
+public enum CallOrigin {
+ INTERNAL,
+ EXTERNAL,
+ TEST
+}
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/UserType.java b/api/src/main/java/com/ning/billing/util/callcontext/UserType.java
new file mode 100644
index 0000000..b10a314
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/callcontext/UserType.java
@@ -0,0 +1,25 @@
+/*
+ * 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.util.callcontext;
+
+public enum UserType {
+ SYSTEM,
+ ADMIN,
+ CUSTOMER,
+ MIGRATION,
+ TEST
+}
diff --git a/api/src/main/java/com/ning/billing/util/ChangeType.java b/api/src/main/java/com/ning/billing/util/ChangeType.java
new file mode 100644
index 0000000..d6db6d3
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/ChangeType.java
@@ -0,0 +1,23 @@
+/*
+ * 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.util;
+
+public enum ChangeType {
+ INSERT,
+ UPDATE,
+ DELETE
+}
diff --git a/api/src/main/java/com/ning/billing/util/entity/Entity.java b/api/src/main/java/com/ning/billing/util/entity/Entity.java
index f363534..3369538 100644
--- a/api/src/main/java/com/ning/billing/util/entity/Entity.java
+++ b/api/src/main/java/com/ning/billing/util/entity/Entity.java
@@ -16,8 +16,12 @@
package com.ning.billing.util.entity;
+import org.joda.time.DateTime;
+
import java.util.UUID;
-public interface Entity {
+public interface Entity<T> {
public UUID getId();
+ public String getCreatedBy();
+ public DateTime getCreatedDate();
}
diff --git a/api/src/main/java/com/ning/billing/util/entity/ExtendedEntity.java b/api/src/main/java/com/ning/billing/util/entity/ExtendedEntity.java
new file mode 100644
index 0000000..b64e9c3
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/entity/ExtendedEntity.java
@@ -0,0 +1,23 @@
+/*
+ * 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.util.entity;
+
+import com.ning.billing.util.customfield.Customizable;
+import com.ning.billing.util.tag.Taggable;
+
+public interface ExtendedEntity extends Entity, Taggable, Customizable {
+}
diff --git a/api/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java b/api/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java
index 758d7dc..c860ddb 100644
--- a/api/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java
+++ b/api/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java
@@ -16,5 +16,9 @@
package com.ning.billing.util.entity;
+import org.joda.time.DateTime;
+
public interface UpdatableEntity extends Entity {
+ public String getUpdatedBy();
+ public DateTime getUpdatedDate();
}
diff --git a/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java b/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
index ea09e84..9f4bb38 100644
--- a/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
+++ b/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
@@ -19,7 +19,8 @@ package com.ning.billing.util.tag;
public enum ControlTagType {
AUTO_PAY_OFF("Suspends payments until removed.", true, false),
AUTO_INVOICING_OFF("Suspends invoicing until removed.", false, true),
- OVERDUE_ENFORCEMENT_OFF("Suspends overdue enforcement behaviour until removed.", false, false);;
+ OVERDUE_ENFORCEMENT_OFF("Suspends overdue enforcement behaviour until removed.", false, false),
+ WRITTEN_OFF("Indicated that an invoice is written off. No billing or payment effect.", false, false);
private final String description;
private final boolean autoPaymentOff;
@@ -35,11 +36,11 @@ public enum ControlTagType {
return this.description;
}
- public boolean autoPaymentOff() {
+ public boolean getAutoPaymentOff() {
return this.autoPaymentOff;
}
- public boolean autoInvoicingOff() {
+ public boolean getAutoInvoicingOff() {
return this.autoInvoicingOff;
}
}
diff --git a/api/src/main/java/com/ning/billing/util/tag/Tag.java b/api/src/main/java/com/ning/billing/util/tag/Tag.java
index 5e9008b..0a592cf 100644
--- a/api/src/main/java/com/ning/billing/util/tag/Tag.java
+++ b/api/src/main/java/com/ning/billing/util/tag/Tag.java
@@ -16,14 +16,8 @@
package com.ning.billing.util.tag;
-import java.util.UUID;
-import org.joda.time.DateTime;
import com.ning.billing.util.entity.Entity;
public interface Tag extends Entity {
String getTagDefinitionName();
-
- String getAddedBy();
-
- DateTime getAddedDate();
}
diff --git a/api/src/main/java/com/ning/billing/util/tag/TagDefinition.java b/api/src/main/java/com/ning/billing/util/tag/TagDefinition.java
index f6c2388..408e09d 100644
--- a/api/src/main/java/com/ning/billing/util/tag/TagDefinition.java
+++ b/api/src/main/java/com/ning/billing/util/tag/TagDefinition.java
@@ -16,12 +16,10 @@
package com.ning.billing.util.tag;
-import com.ning.billing.util.entity.UpdatableEntity;
+import com.ning.billing.util.entity.Entity;
-public interface TagDefinition extends UpdatableEntity {
+public interface TagDefinition extends Entity {
String getName();
- String getCreatedBy();
-
String getDescription();
}
diff --git a/api/src/main/java/com/ning/billing/util/tag/Taggable.java b/api/src/main/java/com/ning/billing/util/tag/Taggable.java
index 5e2f425..3b2e8b0 100644
--- a/api/src/main/java/com/ning/billing/util/tag/Taggable.java
+++ b/api/src/main/java/com/ning/billing/util/tag/Taggable.java
@@ -22,7 +22,7 @@ import org.joda.time.DateTime;
public interface Taggable {
public List<Tag> getTagList();
public boolean hasTag(String tagName);
- public void addTag(TagDefinition definition, String addedBy, DateTime dateAdded);
+ public void addTag(TagDefinition definition);
public void addTags(List<Tag> tags);
public void clearTags();
public void removeTag(TagDefinition definition);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
index 58cc017..304cb0b 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/MockModule.java
@@ -22,6 +22,9 @@ import java.io.IOException;
import java.net.URL;
import java.util.Set;
+import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.glue.TagStoreModule;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
@@ -79,9 +82,12 @@ public class MockModule extends AbstractModule {
bind(IDBI.class).toInstance(dbi);
}
+ install(new CallContextModule());
install(new GlobalLockerModule());
install(new BusModule());
install(new NotificationQueueModule());
+ install(new TagStoreModule());
+ install(new FieldStoreModule());
install(new AccountModule());
install(new CatalogModule());
install(new EntitlementModule());
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index 3030fcb..44b76f0 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -33,6 +33,10 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.joda.time.DateTime;
@@ -53,7 +57,6 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
-
import com.google.inject.Inject;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountData;
@@ -96,6 +99,7 @@ public class TestIntegration {
@Inject
private ClockMock clock;
+ private CallContext context;
@Inject
private Lifecycle lifecycle;
@@ -125,8 +129,6 @@ public class TestIntegration {
private void setupMySQL() throws IOException
{
-
-
final String accountDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
final String entitlementDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
final String invoiceDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
@@ -147,6 +149,8 @@ public class TestIntegration {
setupMySQL();
+ context = new DefaultCallContextFactory(clock).createCallContext("Integration Test", CallOrigin.TEST, UserType.TEST);
+
/**
* Initialize lifecyle for subset of services
*/
@@ -304,7 +308,7 @@ public class TestIntegration {
int billingDay = 2;
log.info("Beginning test with BCD of " + billingDay);
- Account account = accountUserApi.createAccount(getAccountData(billingDay), null, null);
+ Account account = accountUserApi.createAccount(getAccountData(billingDay), null, null, context);
UUID accountId = account.getId();
assertNotNull(account);
@@ -370,7 +374,7 @@ public class TestIntegration {
boolean proRationExpected) throws Exception {
log.info("Beginning test with BCD of " + billingDay);
- Account account = accountUserApi.createAccount(getAccountData(billingDay), null, null);
+ Account account = accountUserApi.createAccount(getAccountData(billingDay), null, null, context);
UUID accountId = account.getId();
assertNotNull(account);
@@ -562,7 +566,7 @@ public class TestIntegration {
@Test(groups = "slow")
public void testHappyPath() throws AccountApiException, EntitlementUserApiException {
- Account account = accountUserApi.createAccount(getAccountData(3), null, null);
+ Account account = accountUserApi.createAccount(getAccountData(3), null, null, context);
assertNotNull(account);
SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever");
@@ -599,7 +603,7 @@ public class TestIntegration {
public void testForMultipleRecurringPhases() throws AccountApiException, EntitlementUserApiException, InterruptedException {
clock.setDeltaFromReality(new DateTime().getMillis() - clock.getUTCNow().getMillis());
- Account account = accountUserApi.createAccount(getAccountData(15), null, null);
+ Account account = accountUserApi.createAccount(getAccountData(15), null, null, context);
UUID accountId = account.getId();
String productName = "Blowdart";
@@ -638,7 +642,7 @@ public class TestIntegration {
protected AccountData getAccountData(final int billingDay) {
final String someRandomKey = RandomStringUtils.randomAlphanumeric(10);
- AccountData accountData = new AccountData() {
+ return new AccountData() {
@Override
public String getName() {
return "firstName lastName";
@@ -717,6 +721,5 @@ public class TestIntegration {
return null;
}
};
- return accountData;
}
}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
index 0bfd0d0..33aa238 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/overdue/TestCondition.java
@@ -129,13 +129,13 @@ public class TestCondition {
DateTime now = new DateTime();
- BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag(null, "Tag", "Martin", now)});
- BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
+ BillingState<Overdueable> state0 = new BillingState<Overdueable>(new UUID(0L,1L), 0, BigDecimal.ZERO, now, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag("Tag")});
+ BillingState<Overdueable> state1 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
BillingState<Overdueable> state2 = new BillingState<Overdueable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20),
PaymentResponse.DO_NOT_HONOR,
- new Tag[]{new DefaultControlTag("Martin", now, ControlTagType.OVERDUE_ENFORCEMENT_OFF),
- new DefaultControlTag("Martin", now, ControlTagType.AUTO_INVOICING_OFF),
- new DescriptiveTag(null, "Tag", "Martin", now)});
+ new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF),
+ new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),
+ new DescriptiveTag("Tag")});
Assert.assertTrue(!c.evaluate(state0, now));
Assert.assertTrue(c.evaluate(state1, now));
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
index d969434..b7c3e7d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
@@ -27,7 +27,6 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.inject.Inject;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.account.api.MutableAccountData;
@@ -39,25 +38,33 @@ import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBui
import com.ning.billing.entitlement.api.user.SubscriptionTransition;
import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.engine.dao.SubscriptionSqlDao;
-
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
private static final Logger log = LoggerFactory.getLogger(DefaultEntitlementBillingApi.class);
-
- private final AccountUserApi accountApi;
+ private static final String API_USER_NAME = "Entitlement Billing Api";
+ private final CallContextFactory factory;
private final EntitlementDao entitlementDao;
+ private final AccountUserApi accountApi;
private final BillCycleDayCalculator bcdCalculator;
- @Inject
- public DefaultEntitlementBillingApi(final EntitlementDao dao, final BillCycleDayCalculator bcdCalculator, final AccountUserApi accountApi) {
- this.accountApi = accountApi;
+
+ public DefaultEntitlementBillingApi(final CallContextFactory factory, final EntitlementDao dao, final AccountUserApi accountApi, final BillCycleDayCalculator bcdCalculator) {
+ super();
+ this.factory = factory;
this.entitlementDao = dao;
+ this.accountApi = accountApi;
this.bcdCalculator = bcdCalculator;
}
@Override
public SortedSet<BillingEvent> getBillingEventsForAccountAndUpdateAccountBCD(
final UUID accountId) {
+ Account account = accountApi.getAccountById(accountId);
+ CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
List<SubscriptionBundle> bundles = entitlementDao.getSubscriptionBundleForAccount(accountId);
SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
@@ -67,13 +74,12 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
for (final Subscription subscription: subscriptions) {
for (final SubscriptionTransition transition : ((SubscriptionData) subscription).getBillingTransitions()) {
try {
- Account account = accountApi.getAccountById(accountId);
int bcd = bcdCalculator.calculateBcd(bundle, subscription, transition, account);
if(account.getBillCycleDay() == 0) {
MutableAccountData modifiedData = account.toMutableAccountData();
modifiedData.setBillCycleDay(bcd);
- accountApi.updateAccount(account.getExternalKey(), modifiedData);
+ accountApi.updateAccount(account.getExternalKey(), modifiedData, context);
}
@@ -97,6 +103,7 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
return entitlementDao.getAccountIdFromSubscriptionId(subscriptionId);
}
+
@Override
public void setChargedThroughDate(final UUID subscriptionId, final DateTime ctd) {
SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionId);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
index 4c9b01e..096914c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
@@ -29,13 +29,13 @@ import com.ning.billing.entitlement.events.phase.PhaseEvent;
import com.ning.billing.entitlement.events.phase.PhaseEventData;
import com.ning.billing.entitlement.events.user.*;
import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.DefaultClock;
import org.joda.time.DateTime;
import java.util.ArrayList;
import java.util.List;
-import java.util.UUID;
public class SubscriptionApiService {
@@ -52,8 +52,6 @@ public class SubscriptionApiService {
this.dao = dao;
}
-
-
public SubscriptionData createPlan(SubscriptionBuilder builder, Plan plan, PhaseType initialPhase,
String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate)
throws EntitlementUserApiException {
@@ -281,8 +279,8 @@ public class SubscriptionApiService {
}
}
- public void commitCustomFields(SubscriptionData subscription) {
- dao.saveCustomFields(subscription);
+ public void commitCustomFields(SubscriptionData subscription, CallContext context) {
+ dao.saveCustomFields(subscription, context);
}
private void validateRequestedDate(SubscriptionData subscription, DateTime now, DateTime requestedDate)
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index a2ed14c..e8e1bb0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -22,6 +22,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
+import javax.annotation.Nullable;
+
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,11 +48,12 @@ import com.ning.billing.entitlement.events.phase.PhaseEvent;
import com.ning.billing.entitlement.events.user.ApiEvent;
import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.customfield.CustomizableEntityBase;
+import com.ning.billing.util.entity.ExtendedEntityBase;
-public class SubscriptionData extends CustomizableEntityBase implements Subscription {
+public class SubscriptionData extends ExtendedEntityBase implements Subscription {
private final static Logger log = LoggerFactory.getLogger(SubscriptionData.class);
@@ -83,8 +86,9 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
this(builder, null, null);
}
- public SubscriptionData(SubscriptionBuilder builder, SubscriptionApiService apiService, Clock clock) {
- super(builder.getId());
+ public SubscriptionData(SubscriptionBuilder builder, @Nullable SubscriptionApiService apiService,
+ @Nullable Clock clock) {
+ super(builder.getId(), null, null);
this.apiService = apiService;
this.clock = clock;
this.bundleId = builder.getBundleId();
@@ -101,57 +105,34 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
return "Subscription";
}
-
@Override
- public void setFieldValue(String fieldName, String fieldValue) {
- setFieldValueInternal(fieldName, fieldValue, true);
- }
-
- public void setFieldValueInternal(String fieldName, String fieldValue, boolean commit) {
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
super.setFieldValue(fieldName, fieldValue);
- if (commit) {
- apiService.commitCustomFields(this);
- }
+ apiService.commitCustomFields(this, context);
}
-
@Override
- public void addFields(List<CustomField> fields) {
- addFieldsInternal(fields, true);
- }
-
- public void addFieldsInternal(List<CustomField> fields, boolean commit) {
- super.addFields(fields);
- if (commit) {
- apiService.commitCustomFields(this);
- }
+ public void saveFields(List<CustomField> fields, CallContext context) {
+ super.setFields(fields);
+ apiService.commitCustomFields(this, context);
}
@Override
- public void clearFields() {
- clearFieldsInternal(true);
- }
-
- public void clearFieldsInternal(boolean commit) {
+ public void clearPersistedFields(CallContext context) {
super.clearFields();
- if (commit) {
- apiService.commitCustomFields(this);
- }
+ apiService.commitCustomFields(this, context);
}
-
@Override
public UUID getBundleId() {
return bundleId;
}
-
@Override
public DateTime getStartDate() {
return startDate;
}
-
@Override
public SubscriptionState getState() {
return (getPreviousTransition() == null) ? null : getPreviousTransition().getNextState();
@@ -311,7 +292,6 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
return false;
}
-
public DateTime getPlanChangeEffectiveDate(ActionPolicy policy, DateTime requestedDate) {
if (policy == ActionPolicy.IMMEDIATE) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
index d2b9f11..88123ca 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
@@ -18,8 +18,9 @@ package com.ning.billing.entitlement.engine.dao;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.Bind;
@@ -35,8 +36,6 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.Date;
import java.util.List;
import java.util.UUID;
@@ -61,12 +60,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, CloseMe, Tran
@Mapper(ISubscriptionBundleSqlMapper.class)
public List<SubscriptionBundle> getBundleFromAccount(@Bind("account_id") String accountId);
- public static class SubscriptionBundleBinder implements Binder<Bind, SubscriptionBundleData> {
-
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
+ public static class SubscriptionBundleBinder extends BinderBase implements Binder<Bind, SubscriptionBundleData> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, SubscriptionBundleData bundle) {
stmt.bind("id", bundle.getId().toString());
@@ -76,13 +70,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, CloseMe, Tran
}
}
- public static class ISubscriptionBundleSqlMapper implements ResultSetMapper<SubscriptionBundle> {
-
- private DateTime getDate(ResultSet r, String fieldName) throws SQLException {
- final Timestamp resultStamp = r.getTimestamp(fieldName);
- return r.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class ISubscriptionBundleSqlMapper extends MapperBase implements ResultSetMapper<SubscriptionBundle> {
@Override
public SubscriptionBundle map(int arg, ResultSet r,
StatementContext ctx) throws SQLException {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index b6ee805..6ca1c15 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -19,6 +19,8 @@ package com.ning.billing.entitlement.engine.dao;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+
import com.ning.billing.entitlement.api.migration.AccountMigrationData;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
@@ -27,8 +29,6 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.events.EntitlementEvent;
public interface EntitlementDao {
-
-
// Bundle apis
public List<SubscriptionBundle> getSubscriptionBundleForAccount(UUID accountId);
@@ -73,11 +73,11 @@ public interface EntitlementDao {
public void changePlan(UUID subscriptionId, List<EntitlementEvent> changeEvents);
- public void migrate(UUID acountId, AccountMigrationData data);
+ public void migrate(UUID accountId, AccountMigrationData data);
public void undoMigration(UUID accountId);
// Custom Fields
- public void saveCustomFields(SubscriptionData subscription);
+ public void saveCustomFields(SubscriptionData subscription, CallContext context);
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
index e2e9203..cd688d3 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -24,6 +24,8 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
@@ -59,7 +61,7 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.entitlement.exceptions.EntitlementError;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.customfield.dao.FieldStoreDao;
+import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
import com.ning.billing.util.notificationq.NotificationKey;
import com.ning.billing.util.notificationq.NotificationQueue;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -77,10 +79,12 @@ public class EntitlementSqlDao implements EntitlementDao {
private final SubscriptionFactory factory;
private final NotificationQueueService notificationQueueService;
private final AddonUtils addonUtils;
+ private final CustomFieldDao customFieldDao;
@Inject
public EntitlementSqlDao(final IDBI dbi, final Clock clock, final SubscriptionFactory factory,
- final AddonUtils addonUtils, final NotificationQueueService notificationQueueService) {
+ final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
+ final CustomFieldDao customFieldDao) {
this.clock = clock;
this.factory = factory;
this.subscriptionsDao = dbi.onDemand(SubscriptionSqlDao.class);
@@ -88,6 +92,7 @@ public class EntitlementSqlDao implements EntitlementDao {
this.bundlesDao = dbi.onDemand(BundleSqlDao.class);
this.notificationQueueService = notificationQueueService;
this.addonUtils = addonUtils;
+ this.customFieldDao = customFieldDao;
}
@Override
@@ -117,7 +122,6 @@ public class EntitlementSqlDao implements EntitlementDao {
});
}
-
@Override
public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
Subscription subscription = subscriptionsDao.getSubscriptionFromId(subscriptionId.toString());
@@ -146,7 +150,6 @@ public class EntitlementSqlDao implements EntitlementDao {
return getBaseSubscription(bundleId, true);
}
-
@Override
public Subscription getSubscriptionFromId(final UUID subscriptionId) {
return buildSubscription(subscriptionsDao.getSubscriptionFromId(subscriptionId.toString()));
@@ -405,18 +408,10 @@ public class EntitlementSqlDao implements EntitlementDao {
}
}
- private void updateCustomFieldsFromTransaction(SubscriptionSqlDao transactionalDao, final SubscriptionData subscription) {
-
- String subscriptionId = subscription.getId().toString();
- String objectType = subscription.getObjectName();
-
- FieldStoreDao fieldStoreDao = transactionalDao.become(FieldStoreDao.class);
- fieldStoreDao.clear(subscriptionId, objectType);
-
- List<CustomField> fieldList = subscription.getFieldList();
- if (fieldList != null) {
- fieldStoreDao.batchSaveFromTransaction(subscriptionId, objectType, fieldList);
- }
+ private void updateCustomFieldsFromTransaction(final SubscriptionSqlDao transactionalDao,
+ final SubscriptionData subscription,
+ final CallContext context) {
+ customFieldDao.saveFields(transactionalDao, subscription.getId(), subscription.getObjectName(), subscription.getFieldList(), context);
}
private Subscription buildSubscription(Subscription input) {
@@ -441,10 +436,7 @@ public class EntitlementSqlDao implements EntitlementDao {
throw new EntitlementError(String.format("Unexpected code path in buildSubscription"));
}
-
-
private List<Subscription> buildBundleSubscriptions(List<Subscription> input) {
-
// Make sure BasePlan -- if exists-- is first
Collections.sort(input, new Comparator<Subscription>() {
@Override
@@ -604,23 +596,23 @@ public class EntitlementSqlDao implements EntitlementDao {
}
@Override
- public void saveCustomFields(final SubscriptionData subscription) {
+ public void saveCustomFields(final SubscriptionData subscription, final CallContext context) {
subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
@Override
public Void inTransaction(SubscriptionSqlDao transactionalDao,
TransactionStatus status) throws Exception {
- updateCustomFieldsFromTransaction(transactionalDao, subscription);
+ updateCustomFieldsFromTransaction(transactionalDao, subscription, context);
return null;
}
});
}
private void loadCustomFields(final SubscriptionData subscription) {
- FieldStoreDao fieldStoreDao = subscriptionsDao.become(FieldStoreDao.class);
- List<CustomField> fields = fieldStoreDao.load(subscription.getId().toString(), subscription.getObjectName());
- subscription.clearFieldsInternal(false);
+ CustomFieldSqlDao customFieldSqlDao = subscriptionsDao.become(CustomFieldSqlDao.class);
+ List<CustomField> fields = customFieldSqlDao.load(subscription.getId().toString(), subscription.getObjectName());
+ subscription.clearFields();
if (fields != null) {
- subscription.addFieldsInternal(fields, false);
+ subscription.setFields(fields);
}
}
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
index a931e9a..adf007e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
@@ -24,8 +24,9 @@ import com.ning.billing.entitlement.events.phase.PhaseEventBuilder;
import com.ning.billing.entitlement.events.phase.PhaseEventData;
import com.ning.billing.entitlement.events.user.*;
import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.Bind;
@@ -40,7 +41,6 @@ import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTempla
import org.skife.jdbi.v2.tweak.ResultSetMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@@ -72,12 +72,7 @@ public interface EventSqlDao extends Transactional<EventSqlDao>, CloseMe, Transm
@Mapper(EventSqlMapper.class)
public List<EntitlementEvent> getEventsForSubscription(@Bind("subscription_id") String subscriptionId);
- public static class EventSqlDaoBinder implements Binder<Bind, EntitlementEvent> {
-
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
+ public static class EventSqlDaoBinder extends BinderBase implements Binder<Bind, EntitlementEvent> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, EntitlementEvent evt) {
stmt.bind("event_id", evt.getId().toString());
@@ -96,13 +91,7 @@ public interface EventSqlDao extends Transactional<EventSqlDao>, CloseMe, Transm
}
}
- public static class EventSqlMapper implements ResultSetMapper<EntitlementEvent> {
-
- private DateTime getDate(ResultSet r, String fieldName) throws SQLException {
- final Timestamp resultStamp = r.getTimestamp(fieldName);
- return r.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class EventSqlMapper extends MapperBase implements ResultSetMapper<EntitlementEvent> {
@Override
public EntitlementEvent map(int index, ResultSet r, StatementContext ctx)
throws SQLException {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
index 59fca2c..3f222ca 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
@@ -20,6 +20,8 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
@@ -63,13 +65,8 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, C
@SqlUpdate
public void updateSubscription(@Bind("id") String id, @Bind("active_version") long activeVersion, @Bind("ctd_dt") Date ctd, @Bind("ptd_dt") Date ptd);
-
- public static class ISubscriptionDaoBinder implements Binder<Bind, SubscriptionData> {
-
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
+
+ public static class ISubscriptionDaoBinder extends BinderBase implements Binder<Bind, SubscriptionData> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, SubscriptionData sub) {
stmt.bind("id", sub.getId().toString());
@@ -83,13 +80,7 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, C
}
}
- public static class ISubscriptionDaoSqlMapper implements ResultSetMapper<SubscriptionData> {
-
- private DateTime getDate(ResultSet r, String fieldName) throws SQLException {
- final Timestamp resultStamp = r.getTimestamp(fieldName);
- return r.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class ISubscriptionDaoSqlMapper extends MapperBase implements ResultSetMapper<SubscriptionData> {
@Override
public SubscriptionData map(int arg0, ResultSet r, StatementContext ctx)
throws SQLException {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
index 88b3045..8fc1eef 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
@@ -37,17 +37,12 @@ import com.ning.billing.entitlement.engine.core.Engine;
import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.engine.dao.EntitlementSqlDao;
-
-
public class EntitlementModule extends AbstractModule {
-
-
protected void installConfig() {
final EntitlementConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EntitlementConfig.class);
bind(EntitlementConfig.class).toInstance(config);
}
-
protected void installEntitlementDao() {
bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index 24294a4..f89db88 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -61,7 +61,10 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.lifecycle.KillbillService.ServiceException;
import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.ClockModule;
public class TestDefaultEntitlementBillingApi {
@@ -77,16 +80,17 @@ public class TestDefaultEntitlementBillingApi {
private Clock clock;
private SubscriptionData subscription;
+ private CallContextFactory factory;
private DateTime subscriptionStartDate;
@BeforeSuite(alwaysRun=true)
public void setup() throws ServiceException {
TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
- final Injector g = Guice.createInjector(Stage.PRODUCTION, new CatalogModule(), new ClockModule());
-
+ final Injector g = Guice.createInjector(Stage.PRODUCTION, new CatalogModule(), new ClockModule(), new CallContextModule());
catalogService = g.getInstance(CatalogService.class);
clock = g.getInstance(Clock.class);
+ factory = g.getInstance(CallContextFactory.class);
((DefaultCatalogService)catalogService).loadCatalog();
}
@@ -135,8 +139,9 @@ public class TestDefaultEntitlementBillingApi {
((ZombieControl) accountApi).addResult("getAccountById", account);
BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService);
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,bcdCalculator, accountApi);
- SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, bcdCalculator);
+ SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
Assert.assertEquals(events.size(), 0);
}
@@ -159,8 +164,10 @@ public class TestDefaultEntitlementBillingApi {
((ZombieControl)accountApi).addResult("getAccountById", account);
BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService);
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,bcdCalculator, accountApi);
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, bcdCalculator);
SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+
checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
}
@@ -182,10 +189,11 @@ public class TestDefaultEntitlementBillingApi {
AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
((ZombieControl)accountApi).addResult("getAccountById", account);
-
BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService);
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,bcdCalculator, accountApi);
- SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, bcdCalculator);
+ SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+
checkFirstEvent(events, nextPlan, subscription.getStartDate().getDayOfMonth(), oneId, now, nextPhase, ApiEventType.CREATE.toString());
}
@@ -207,8 +215,10 @@ public class TestDefaultEntitlementBillingApi {
((ZombieControl)accountApi).addResult("getAccountById", account);
BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService);
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,bcdCalculator, accountApi);
- SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, bcdCalculator);
+ SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+
checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
}
@@ -230,8 +240,10 @@ public class TestDefaultEntitlementBillingApi {
AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
((ZombieControl)accountApi).addResult("getAccountById", account);
BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService);
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,bcdCalculator, accountApi);
- SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, bcdCalculator);
+ SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+
checkFirstEvent(events, nextPlan, bundles.get(0).getStartDate().getDayOfMonth(), oneId, now, nextPhase, ApiEventType.CREATE.toString());
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index 6a5520d..59121c9 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
@@ -75,6 +75,8 @@ import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.bus.DefaultBusService;
import com.ning.billing.util.bus.BusService;
+import javax.annotation.Nullable;
+
public abstract class TestApiBase {
@@ -408,7 +410,9 @@ public abstract class TestApiBase {
return accountData;
}
- protected PlanPhaseSpecifier getProductSpecifier(final String productName, final String priceList, final BillingPeriod term, final PhaseType phaseType) {
+ protected PlanPhaseSpecifier getProductSpecifier(final String productName, final String priceList,
+ final BillingPeriod term,
+ @Nullable final PhaseType phaseType) {
return new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, priceList, phaseType);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
index 996306a..472e7c0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
@@ -136,7 +136,7 @@ public class TestUserApiDemos extends TestApiBase {
/* STEP 7. MOVE TO NEXT PHASE */
testListener.pushExpectedEvent(NextEvent.PHASE);
clock.addDeltaFromReality(currentPhase.getDuration());
- assertTrue(testListener.isCompleted(3000));
+ assertTrue(testListener.isCompleted(5000));
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
currentPlan = subscription.getCurrentPlan();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
index 788cf2d..f6881fd 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
@@ -21,6 +21,11 @@ import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.DefaultClock;
import org.joda.time.DateTime;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -37,14 +42,14 @@ import com.ning.billing.util.customfield.CustomField;
public class TestUserCustomFieldsSql extends TestApiBase {
+ private static final String USER_NAME = "Entitlement Test";
+ private final CallContext context = new DefaultCallContextFactory(new DefaultClock()).createCallContext(USER_NAME, CallOrigin.TEST, UserType.TEST);
@Override
protected Injector getInjector() {
return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
}
-
-
@Test(enabled=false, groups={"slow"})
public void stress() {
cleanupTest();
@@ -79,12 +84,12 @@ public class TestUserCustomFieldsSql extends TestApiBase {
assertEquals(subscription.getFieldValue("nonExistent"), null);
- subscription.setFieldValue("field1", "value1");
+ subscription.saveFieldValue("field1", "value1", context);
assertEquals(subscription.getFieldValue("field1"), "value1");
List<CustomField> allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
- subscription.setFieldValue("field1", "valueNew1");
+ subscription.saveFieldValue("field1", "valueNew1", context);
assertEquals(subscription.getFieldValue("field1"), "valueNew1");
allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
@@ -94,7 +99,7 @@ public class TestUserCustomFieldsSql extends TestApiBase {
allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
- subscription.setFieldValue("field1", "valueSuperNew1");
+ subscription.saveFieldValue("field1", "valueSuperNew1", context);
assertEquals(subscription.getFieldValue("field1"), "valueSuperNew1");
allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
@@ -104,14 +109,11 @@ public class TestUserCustomFieldsSql extends TestApiBase {
allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
- /*
- * BROKEN
- subscription.setFieldValue("field1", null);
+ subscription.saveFieldValue("field1", null, context);
subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
assertEquals(subscription.getFieldValue("field1"), null);
allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
- */
} catch (EntitlementUserApiException e) {
log.error("Unexpected exception",e);
Assert.fail(e.getMessage());
@@ -137,7 +139,7 @@ public class TestUserCustomFieldsSql extends TestApiBase {
assertNotNull(subscription);
- subscription.setFieldValue("field1", "value1");
+ subscription.saveFieldValue("field1", "value1", context);
assertEquals(subscription.getFieldValue("field1"), "value1");
List<CustomField> allFields = subscription.getFieldList();
assertEquals(allFields.size(), 1);
@@ -148,8 +150,8 @@ public class TestUserCustomFieldsSql extends TestApiBase {
subscription.clearFields();
- subscription.setFieldValue("field2", "value2");
- subscription.setFieldValue("field3", "value3");
+ subscription.saveFieldValue("field2", "value2", context);
+ subscription.saveFieldValue("field3", "value3", context);
assertEquals(subscription.getFieldValue("field2"), "value2");
assertEquals(subscription.getFieldValue("field3"), "value3");
allFields = subscription.getFieldList();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index 31879e0..f73e7e0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.TreeSet;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
import org.apache.commons.lang.NotImplementedException;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
@@ -441,17 +442,16 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
try {
- NotificationQueue subscritionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
+ NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
Engine.NOTIFICATION_QUEUE_NAME);
- subscritionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
+ subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
} catch (NoSuchNotificationQueue e) {
throw new RuntimeException(e);
}
}
@Override
- public void saveCustomFields(SubscriptionData subscription) {
+ public void saveCustomFields(SubscriptionData subscription, CallContext context) {
throw new NotImplementedException();
}
-
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
index cb87dc0..65d8495 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
@@ -16,6 +16,8 @@
package com.ning.billing.entitlement.engine.dao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.tag.dao.TagDao;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
@@ -34,8 +36,9 @@ public class MockEntitlementDaoSql extends EntitlementSqlDao implements MockEnti
private final ResetSqlDao resetDao;
@Inject
- public MockEntitlementDaoSql(IDBI dbi, Clock clock, SubscriptionFactory factory, AddonUtils addonUtils, NotificationQueueService notificationQueueService) {
- super(dbi, clock, factory, addonUtils, notificationQueueService);
+ public MockEntitlementDaoSql(IDBI dbi, Clock clock, SubscriptionFactory factory, AddonUtils addonUtils, NotificationQueueService notificationQueueService,
+ CustomFieldDao customFieldDao) {
+ super(dbi, clock, factory, addonUtils, notificationQueueService, customFieldDao);
this.resetDao = dbi.onDemand(ResetSqlDao.class);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
index 5c1d6b5..acb1a2a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
@@ -21,6 +21,7 @@ import com.ning.billing.catalog.glue.CatalogModule;
import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.util.clock.MockClockModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CallContextModule;
public class MockEngineModule extends EntitlementModule {
@@ -31,5 +32,6 @@ public class MockEngineModule extends EntitlementModule {
install(new CatalogModule());
bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
install(new MockClockModule());
+ install(new CallContextModule());
}
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
index 786f1e3..8b78c2d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
@@ -29,10 +29,10 @@ public class MockEngineModuleMemory extends MockEngineModule {
bind(EntitlementDao.class).to(MockEntitlementDaoMemory.class).asEagerSingleton();
}
-
private void installNotificationQueue() {
bind(NotificationQueueService.class).to(MockNotificationQueueService.class).asEagerSingleton();
}
+
@Override
protected void configure() {
super.configure();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
index c452c3b..f774e58 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
@@ -23,6 +23,7 @@ import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.engine.dao.MockEntitlementDaoSql;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.glue.FieldStoreModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import org.skife.config.ConfigurationObjectFactory;
@@ -53,6 +54,7 @@ public class MockEngineModuleSql extends MockEngineModule {
protected void configure() {
installDBI();
install(new NotificationQueueModule());
+ install(new FieldStoreModule());
super.configure();
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index 3a04c3f..11712d2 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -21,6 +21,7 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -40,8 +41,8 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
- dao.notifyOfPaymentAttempt(invoicePayment);
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context) {
+ dao.notifyOfPaymentAttempt(invoicePayment, context);
}
@Override
@@ -66,15 +67,15 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
- public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
- InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate, amount, currency, null);
- dao.notifyOfPaymentAttempt(invoicePayment);
+ public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context) {
+ InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate, amount, currency);
+ dao.notifyOfPaymentAttempt(invoicePayment, context);
}
@Override
- public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+ public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context) {
InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate);
- dao.notifyOfPaymentAttempt(invoicePayment);
+ dao.notifyOfPaymentAttempt(invoicePayment, context);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
index 6852b69..bea87a7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
@@ -19,6 +19,10 @@ package com.ning.billing.invoice.api.migration;
import java.math.BigDecimal;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -27,7 +31,6 @@ import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoiceMigrationApi;
import com.ning.billing.invoice.dao.DefaultInvoiceDao;
-import com.ning.billing.invoice.model.DefaultInvoice;
import com.ning.billing.invoice.model.MigrationInvoiceItem;
import com.ning.billing.util.clock.Clock;
@@ -44,10 +47,11 @@ public class DefaultInvoiceMigrationApi implements InvoiceMigrationApi {
@Override
public UUID createMigrationInvoice(UUID accountId, DateTime targetDate, BigDecimal balance, Currency currency) {
- Invoice migrationInvoice = new DefaultInvoice(accountId, targetDate, currency, clock, true);
- InvoiceItem migrationInvoiceItem = new MigrationInvoiceItem(migrationInvoice.getId(), targetDate, balance, currency, clock);
+ CallContext context = new DefaultCallContextFactory(clock).createMigrationCallContext("Migration", CallOrigin.INTERNAL, UserType.MIGRATION, clock.getUTCNow(), clock.getUTCNow());
+ Invoice migrationInvoice = new MigrationInvoice(accountId, clock.getUTCNow(), targetDate, currency);
+ InvoiceItem migrationInvoiceItem = new MigrationInvoiceItem(migrationInvoice.getId(), accountId, targetDate, balance, currency );
migrationInvoice.addInvoiceItem(migrationInvoiceItem);
- dao.create(migrationInvoice);
+ dao.create(migrationInvoice, context);
return migrationInvoice.getId();
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java
new file mode 100644
index 0000000..84877eb
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java
@@ -0,0 +1,29 @@
+/*
+ * 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.invoice.api.migration;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.model.DefaultInvoice;
+import org.joda.time.DateTime;
+
+import java.util.UUID;
+
+public class MigrationInvoice extends DefaultInvoice {
+ public MigrationInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
+ super(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, true, null, null);
+ }
+}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/test/DefaultInvoiceTestApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/test/DefaultInvoiceTestApi.java
index bbec57f..ec0ca88 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/test/DefaultInvoiceTestApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/test/DefaultInvoiceTestApi.java
@@ -19,6 +19,7 @@ package com.ning.billing.invoice.api.test;
import com.google.inject.Inject;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.util.callcontext.CallContext;
public class DefaultInvoiceTestApi implements InvoiceTestApi {
private final InvoiceDao invoiceDao;
@@ -29,7 +30,7 @@ public class DefaultInvoiceTestApi implements InvoiceTestApi {
}
@Override
- public void create(Invoice invoice) {
- invoiceDao.create(invoice);
+ public void create(final Invoice invoice, final CallContext context) {
+ invoiceDao.create(invoice, context);
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 8e34ec9..f556778 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -20,6 +20,8 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.ControlTagType;
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -51,8 +53,8 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
- dao.notifyOfPaymentAttempt(invoicePayment);
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context) {
+ dao.notifyOfPaymentAttempt(invoicePayment, context);
}
@Override
@@ -72,8 +74,19 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
}
@Override
- public Invoice triggerInvoiceGeneration(UUID accountId,
- DateTime targetDate, boolean dryrun) throws InvoiceApiException {
- return dispatcher.processAccount(accountId, targetDate, dryrun);
+ public Invoice triggerInvoiceGeneration(final UUID accountId,
+ final DateTime targetDate, final boolean dryRun,
+ final CallContext context) throws InvoiceApiException {
+ return dispatcher.processAccount(accountId, targetDate, dryRun, context);
}
+
+ @Override
+ public void tagInvoiceAsWrittenOff(final UUID invoiceId, final CallContext context) {
+ dao.addControlTag(ControlTagType.WRITTEN_OFF, invoiceId, context);
+ }
+
+ @Override
+ public void tagInvoiceAsNotWrittenOff(final UUID invoiceId, final CallContext context) {
+ dao.removeControlTag(ControlTagType.WRITTEN_OFF, invoiceId, context);
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index 03970d0..13272c4 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -17,16 +17,26 @@
package com.ning.billing.invoice.dao;
import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import com.ning.billing.util.ChangeType;
+import com.ning.billing.util.audit.dao.AuditSqlDao;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.dao.TagDao;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,20 +58,23 @@ public class DefaultInvoiceDao implements InvoiceDao {
private final InvoiceSqlDao invoiceSqlDao;
private final InvoicePaymentSqlDao invoicePaymentSqlDao;
private final EntitlementBillingApi entitlementBillingApi;
+ private final TagDao tagDao;
private final Bus eventBus;
- private NextBillingDatePoster nextBillingDatePoster;
+ private final NextBillingDatePoster nextBillingDatePoster;
@Inject
public DefaultInvoiceDao(final IDBI dbi, final Bus eventBus,
final EntitlementBillingApi entitlementBillingApi,
- NextBillingDatePoster nextBillingDatePoster) {
+ final NextBillingDatePoster nextBillingDatePoster,
+ final TagDao tagDao) {
this.invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
this.invoicePaymentSqlDao = dbi.onDemand(InvoicePaymentSqlDao.class);
this.eventBus = eventBus;
this.entitlementBillingApi = entitlementBillingApi;
this.nextBillingDatePoster = nextBillingDatePoster;
+ this.tagDao = tagDao;
}
@Override
@@ -71,8 +84,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId.toString());
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -86,8 +98,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId.toString());
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -101,8 +112,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceDao.getInvoicesByAccountAfterDate(accountId.toString(), fromDate.toDate());
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -116,8 +126,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceDao.get();
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -132,8 +141,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
Invoice invoice = invoiceDao.getById(invoiceId.toString());
if (invoice != null) {
- getInvoiceItemsWithinTransaction(invoice, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoice, invoiceDao);
+ populateChildren(invoice, invoiceDao);
}
return invoice;
@@ -142,7 +150,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
@Override
- public void create(final Invoice invoice) {
+ public void create(final Invoice invoice, final CallContext context) {
invoiceSqlDao.inTransaction(new Transaction<Void, InvoiceSqlDao>() {
@Override
public Void inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
@@ -151,24 +159,31 @@ public class DefaultInvoiceDao implements InvoiceDao {
Invoice currentInvoice = invoiceDao.getById(invoice.getId().toString());
if (currentInvoice == null) {
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
List<InvoiceItem> recurringInvoiceItems = invoice.getInvoiceItems(RecurringInvoiceItem.class);
RecurringInvoiceItemSqlDao recurringInvoiceItemDao = invoiceDao.become(RecurringInvoiceItemSqlDao.class);
- recurringInvoiceItemDao.batchCreateFromTransaction(recurringInvoiceItems);
+ recurringInvoiceItemDao.batchCreateFromTransaction(recurringInvoiceItems, context);
notifyOfFutureBillingEvents(invoiceSqlDao, recurringInvoiceItems);
List<InvoiceItem> fixedPriceInvoiceItems = invoice.getInvoiceItems(FixedPriceInvoiceItem.class);
FixedPriceInvoiceItemSqlDao fixedPriceInvoiceItemDao = invoiceDao.become(FixedPriceInvoiceItemSqlDao.class);
- fixedPriceInvoiceItemDao.batchCreateFromTransaction(fixedPriceInvoiceItems);
+ fixedPriceInvoiceItemDao.batchCreateFromTransaction(fixedPriceInvoiceItems, context);
setChargedThroughDates(invoiceSqlDao, fixedPriceInvoiceItems, recurringInvoiceItems);
// STEPH Why do we need that? Are the payments not always null at this point?
List<InvoicePayment> invoicePayments = invoice.getPayments();
InvoicePaymentSqlDao invoicePaymentSqlDao = invoiceDao.become(InvoicePaymentSqlDao.class);
- invoicePaymentSqlDao.batchCreateFromTransaction(invoicePayments);
+ invoicePaymentSqlDao.batchCreateFromTransaction(invoicePayments, context);
+
+ AuditSqlDao auditSqlDao = invoiceDao.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("invoices", invoice.getId().toString(), ChangeType.INSERT.toString(), context);
+ auditSqlDao.insertAuditFromTransaction("recurring_invoice_items", getIdsFromInvoiceItems(recurringInvoiceItems), ChangeType.INSERT.toString(), context);
+ auditSqlDao.insertAuditFromTransaction("fixed_invoice_items", getIdsFromInvoiceItems(fixedPriceInvoiceItems), ChangeType.INSERT.toString(), context);
+ auditSqlDao.insertAuditFromTransaction("invoice_payments", getIdsFromInvoicePayments(invoicePayments), ChangeType.INSERT.toString(), context);
+
}
return null;
@@ -187,6 +202,26 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
}
+ private List<String> getIdsFromInvoiceItems(List<InvoiceItem> invoiceItems) {
+ List<String> ids = new ArrayList<String>();
+
+ for (InvoiceItem item : invoiceItems) {
+ ids.add(item.getId().toString());
+ }
+
+ return ids;
+ }
+
+ private List<String> getIdsFromInvoicePayments(List<InvoicePayment> invoicePayments) {
+ List<String> ids = new ArrayList<String>();
+
+ for (InvoicePayment payment : invoicePayments) {
+ ids.add(payment.getId().toString());
+ }
+
+ return ids;
+ }
+
@Override
public List<Invoice> getInvoicesBySubscription(final UUID subscriptionId) {
return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
@@ -194,8 +229,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceDao.getInvoicesBySubscription(subscriptionId.toString());
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -208,8 +242,8 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
@Override
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
- invoicePaymentSqlDao.notifyOfPaymentAttempt(invoicePayment);
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context) {
+ invoicePaymentSqlDao.notifyOfPaymentAttempt(invoicePayment, context);
}
@Override
@@ -219,8 +253,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
List<Invoice> invoices = invoiceSqlDao.getUnpaidInvoicesByAccountId(accountId.toString(), upToDate.toDate());
- getInvoiceItemsWithinTransaction(invoices, invoiceDao);
- getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+ populateChildren(invoices, invoiceDao);
return invoices;
}
@@ -238,10 +271,34 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
@Override
+ public void addControlTag(ControlTagType controlTagType, UUID invoiceId, CallContext context) {
+ tagDao.addTag(controlTagType.toString(), invoiceId, Invoice.ObjectType, context);
+ }
+
+ @Override
+ public void removeControlTag(ControlTagType controlTagType, UUID invoiceId, CallContext context) {
+ tagDao.removeTag(controlTagType.toString(), invoiceId, Invoice.ObjectType, context);
+ }
+
+ @Override
public void test() {
invoiceSqlDao.test();
}
+ private void populateChildren(final Invoice invoice, InvoiceSqlDao invoiceSqlDao) {
+ getInvoiceItemsWithinTransaction(invoice, invoiceSqlDao);
+ getInvoicePaymentsWithinTransaction(invoice, invoiceSqlDao);
+ getTagsWithinTransaction(invoice, invoiceSqlDao);
+ getFieldsWithinTransaction(invoice, invoiceSqlDao);
+ }
+
+ private void populateChildren(List<Invoice> invoices, InvoiceSqlDao invoiceSqlDao) {
+ getInvoiceItemsWithinTransaction(invoices, invoiceSqlDao);
+ getInvoicePaymentsWithinTransaction(invoices, invoiceSqlDao);
+ getTagsWithinTransaction(invoices, invoiceSqlDao);
+ getFieldsWithinTransaction(invoices, invoiceSqlDao);
+ }
+
private void getInvoiceItemsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceDao) {
for (final Invoice invoice : invoices) {
getInvoiceItemsWithinTransaction(invoice, invoiceDao);
@@ -264,13 +321,37 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
}
- private void getInvoicePaymentsWithinTransaction(final Invoice invoice, final InvoiceSqlDao invoiceDao) {
- InvoicePaymentSqlDao invoicePaymentSqlDao = invoiceDao.become(InvoicePaymentSqlDao.class);
+ private void getInvoicePaymentsWithinTransaction(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao) {
+ InvoicePaymentSqlDao invoicePaymentSqlDao = invoiceSqlDao.become(InvoicePaymentSqlDao.class);
String invoiceId = invoice.getId().toString();
List<InvoicePayment> invoicePayments = invoicePaymentSqlDao.getPaymentsForInvoice(invoiceId);
invoice.addPayments(invoicePayments);
}
+ private void getTagsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceSqlDao) {
+ for (final Invoice invoice : invoices) {
+ getTagsWithinTransaction(invoice, invoiceSqlDao);
+ }
+ }
+
+ private void getTagsWithinTransaction(final Invoice invoice, final Transmogrifier dao) {
+ List<Tag> tags = tagDao.loadTagsFromTransaction(dao, invoice.getId(), Invoice.ObjectType);
+ invoice.addTags(tags);
+ }
+
+ private void getFieldsWithinTransaction(final List<Invoice> invoices, final InvoiceSqlDao invoiceSqlDao) {
+ for (final Invoice invoice : invoices) {
+ getFieldsWithinTransaction(invoice, invoiceSqlDao);
+ }
+ }
+
+ private void getFieldsWithinTransaction(final Invoice invoice, final InvoiceSqlDao invoiceSqlDao) {
+ CustomFieldSqlDao customFieldSqlDao = invoiceSqlDao.become(CustomFieldSqlDao.class);
+ String invoiceId = invoice.getId().toString();
+ List<CustomField> customFields = customFieldSqlDao.load(invoiceId, Invoice.ObjectType);
+ invoice.setFields(customFields);
+ }
+
private void notifyOfFutureBillingEvents(final InvoiceSqlDao dao, final List<InvoiceItem> invoiceItems) {
for (final InvoiceItem item : invoiceItems) {
if (item instanceof RecurringInvoiceItem) {
@@ -311,5 +392,4 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
}
}
-
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
index 27b41ba..a895102 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.java
@@ -44,6 +44,8 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
import com.ning.billing.util.entity.EntityDao;
@ExternalizedSqlViaStringTemplate3()
@@ -60,13 +62,13 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
@Override
@SqlUpdate
- void create(@FixedPriceInvoiceItemBinder final InvoiceItem invoiceItem);
+ void create(@FixedPriceInvoiceItemBinder final InvoiceItem invoiceItem, @CallContextBinder final CallContext context);
@SqlBatch
- void create(@FixedPriceInvoiceItemBinder final List<InvoiceItem> items);
+ void create(@FixedPriceInvoiceItemBinder final List<InvoiceItem> items, @CallContextBinder final CallContext context);
@SqlBatch(transactional=false)
- void batchCreateFromTransaction(@FixedPriceInvoiceItemBinder final List<InvoiceItem> items);
+ void batchCreateFromTransaction(@FixedPriceInvoiceItemBinder final List<InvoiceItem> items, @CallContextBinder final CallContext context);
@BindingAnnotation(FixedPriceInvoiceItemBinder.FixedPriceInvoiceItemBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@@ -77,6 +79,7 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
return new Binder<FixedPriceInvoiceItemBinder, FixedPriceInvoiceItem>() {
public void bind(SQLStatement q, FixedPriceInvoiceItemBinder bind, FixedPriceInvoiceItem item) {
q.bind("id", item.getId().toString());
+ q.bind("accountId", item.getAccountId().toString());
q.bind("invoiceId", item.getInvoiceId().toString());
q.bind("bundleId", item.getBundleId().toString());
q.bind("subscriptionId", item.getSubscriptionId().toString());
@@ -86,7 +89,6 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
q.bind("endDate", item.getEndDate().toDate());
q.bind("amount", item.getAmount());
q.bind("currency", item.getCurrency().toString());
- q.bind("createdDate", item.getCreatedDate().toDate());
}
};
}
@@ -98,6 +100,8 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
public FixedPriceInvoiceItem map(int index, ResultSet result, StatementContext context) throws SQLException {
UUID id = UUID.fromString(result.getString("id"));
UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
+ UUID accountId = UUID.fromString(result.getString("account_id"));
+ UUID bundleId = UUID.fromString(result.getString("bundle_id"));
UUID subscriptionId = UUID.fromString(result.getString("subscription_id"));
String planName = result.getString("plan_name");
String phaseName = result.getString("phase_name");
@@ -105,10 +109,11 @@ public interface FixedPriceInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
DateTime endDate = new DateTime(result.getTimestamp("end_date"));
BigDecimal amount = result.getBigDecimal("amount");
Currency currency = Currency.valueOf(result.getString("currency"));
+ String createdBy = result.getString("created_by");
DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
- return new FixedPriceInvoiceItem(id, invoiceId, subscriptionId, planName, phaseName,
- startDate, endDate, amount, currency, createdDate);
+ return new FixedPriceInvoiceItem(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName,
+ startDate, endDate, amount, currency, createdBy, createdDate);
}
}
}
\ No newline at end of file
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index e09b9d2..2b22c90 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -17,16 +17,18 @@
package com.ning.billing.invoice.dao;
import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.Taggable;
+import com.ning.billing.util.tag.dao.TaggableDao;
import org.joda.time.DateTime;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
-public interface InvoiceDao {
- void create(Invoice invoice);
+public interface InvoiceDao extends TaggableDao {
+ void create(Invoice invoice, CallContext context);
Invoice getById(final UUID id);
@@ -42,7 +44,7 @@ public interface InvoiceDao {
InvoicePayment getInvoicePayment(final UUID paymentAttemptId);
- void notifyOfPaymentAttempt(final InvoicePayment invoicePayment);
+ void notifyOfPaymentAttempt(final InvoicePayment invoicePayment, final CallContext context);
BigDecimal getAccountBalance(final UUID accountId);
@@ -50,5 +52,5 @@ public interface InvoiceDao {
void test();
- List<Invoice> getAllInvoicesByAccount(UUID accountId);
+ List<Invoice> getAllInvoicesByAccount(final UUID accountId);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
index b8c9438..eed9680 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -24,13 +24,14 @@ import java.lang.annotation.Target;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Timestamp;
import java.util.List;
import java.util.UUID;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.Bind;
@@ -56,38 +57,42 @@ public interface InvoicePaymentSqlDao {
public List<InvoicePayment> get();
@SqlUpdate
- public void create(@InvoicePaymentBinder InvoicePayment invoicePayment);
+ public void create(@InvoicePaymentBinder final InvoicePayment invoicePayment,
+ @CallContextBinder final CallContext context);
@SqlBatch(transactional=false)
- void batchCreateFromTransaction(@InvoicePaymentBinder List<InvoicePayment> items);
+ void batchCreateFromTransaction(@InvoicePaymentBinder final List<InvoicePayment> items,
+ @CallContextBinder final CallContext context);
@SqlQuery
- public List<InvoicePayment> getPaymentsForInvoice(@Bind("invoiceId") String invoiceId);
+ public List<InvoicePayment> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId);
@SqlQuery
- InvoicePayment getInvoicePayment(@Bind("paymentAttemptId") UUID paymentAttemptId);
+ InvoicePayment getInvoicePayment(@Bind("paymentAttemptId") final UUID paymentAttemptId);
@SqlUpdate
- void notifyOfPaymentAttempt(@InvoicePaymentBinder InvoicePayment invoicePayment);
-
- public static class InvoicePaymentMapper implements ResultSetMapper<InvoicePayment> {
- private DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
- final Timestamp resultStamp = rs.getTimestamp(fieldName);
- return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
+ void notifyOfPaymentAttempt(@InvoicePaymentBinder final InvoicePayment invoicePayment,
+ @CallContextBinder final CallContext context);
+ public static class InvoicePaymentMapper extends MapperBase implements ResultSetMapper<InvoicePayment> {
@Override
public InvoicePayment map(int index, ResultSet result, StatementContext context) throws SQLException {
+ final UUID id = UUID.fromString(result.getString("id"));
final UUID paymentAttemptId = UUID.fromString(result.getString("payment_attempt_id"));
final UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
final DateTime paymentAttemptDate = getDate(result, "payment_attempt_date");
final BigDecimal amount = result.getBigDecimal("amount");
final String currencyString = result.getString("currency");
final Currency currency = (currencyString == null) ? null : Currency.valueOf(currencyString);
+ final String createdBy = result.getString("created_by");
final DateTime createdDate = getDate(result, "created_date");
return new InvoicePayment() {
@Override
+ public UUID getId() {
+ return id;
+ }
+ @Override
public UUID getPaymentAttemptId() {
return paymentAttemptId;
}
@@ -108,6 +113,10 @@ public interface InvoicePaymentSqlDao {
return currency;
}
@Override
+ public String getCreatedBy() {
+ return createdBy;
+ }
+ @Override
public DateTime getCreatedDate() {
return createdDate ;
}
@@ -125,14 +134,13 @@ public interface InvoicePaymentSqlDao {
return new Binder<InvoicePaymentBinder, InvoicePayment>() {
@Override
public void bind(SQLStatement q, InvoicePaymentBinder bind, InvoicePayment payment) {
+ q.bind("id", payment.getId().toString());
q.bind("invoiceId", payment.getInvoiceId().toString());
q.bind("paymentAttemptId", payment.getPaymentAttemptId().toString());
q.bind("paymentAttemptDate", payment.getPaymentAttemptDate().toDate());
q.bind("amount", payment.getAmount());
Currency currency = payment.getCurrency();
q.bind("currency", (currency == null) ? null : currency.toString());
- DateTime createdDate = payment.getCreatedDate();
- q.bind("createdDate", (createdDate == null) ? new DateTime().toDate() : createdDate.toDate());
}
};
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
index 61c3644..dc8e303 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
@@ -19,7 +19,9 @@ package com.ning.billing.invoice.dao;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.UuidMapper;
+import com.ning.billing.util.callcontext.CallContextBinder;
import com.ning.billing.util.entity.EntityDao;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.SQLStatement;
@@ -54,7 +56,7 @@ import java.util.UUID;
public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<InvoiceSqlDao>, Transmogrifier, CloseMe {
@Override
@SqlUpdate
- void create(@InvoiceBinder Invoice invoice);
+ void create(@InvoiceBinder Invoice invoice, @CallContextBinder final CallContext context);
@SqlQuery
List<Invoice> getInvoicesByAccount(@Bind("accountId") final String accountId);
@@ -74,11 +76,6 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
UUID getInvoiceIdByPaymentAttemptId(@Bind("paymentAttemptId") final String paymentAttemptId);
@SqlQuery
- @RegisterMapper(UuidMapper.class)
- List<UUID> getInvoicesForPayment(@Bind("targetDate") final Date targetDate,
- @Bind("numberOfDays") final int numberOfDays);
-
- @SqlQuery
@RegisterMapper(BalanceMapper.class)
BigDecimal getAccountBalance(@Bind("accountId") final String accountId);
@@ -120,8 +117,10 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
DateTime targetDate = new DateTime(result.getTimestamp("target_date"));
Currency currency = Currency.valueOf(result.getString("currency"));
boolean isMigrationInvoice = result.getBoolean("migrated");
+ String createdBy = result.getString("created_by");
+ DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
- return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency, isMigrationInvoice);
+ return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency, isMigrationInvoice, createdBy, createdDate);
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
index 1b38769..c00d613 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.java
@@ -16,10 +16,17 @@
package com.ning.billing.invoice.dao;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.model.RecurringInvoiceItem;
-import com.ning.billing.util.entity.EntityDao;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.UUID;
+
import org.joda.time.DateTime;
import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.StatementContext;
@@ -34,16 +41,12 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.math.BigDecimal;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.entity.EntityDao;
@ExternalizedSqlViaStringTemplate3()
@RegisterMapper(RecurringInvoiceItemSqlDao.RecurringInvoiceItemMapper.class)
@@ -59,10 +62,10 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
@Override
@SqlUpdate
- void create(@RecurringInvoiceItemBinder final InvoiceItem invoiceItem);
+ void create(@RecurringInvoiceItemBinder final InvoiceItem invoiceItem, @CallContextBinder final CallContext context);
@SqlBatch(transactional = false)
- void batchCreateFromTransaction(@RecurringInvoiceItemBinder final List<InvoiceItem> items);
+ void batchCreateFromTransaction(@RecurringInvoiceItemBinder final List<InvoiceItem> items, @CallContextBinder final CallContext context);
@BindingAnnotation(RecurringInvoiceItemBinder.InvoiceItemBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@@ -76,8 +79,9 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
public void bind(SQLStatement q, RecurringInvoiceItemBinder bind, RecurringInvoiceItem item) {
q.bind("id", item.getId().toString());
q.bind("invoiceId", item.getInvoiceId().toString());
- q.bind("subscriptionId", item.getSubscriptionId().toString());
+ q.bind("accountId", item.getAccountId().toString());
q.bind("bundleId", item.getBundleId().toString());
+ q.bind("subscriptionId", item.getSubscriptionId().toString());
q.bind("planName", item.getPlanName());
q.bind("phaseName", item.getPhaseName());
q.bind("startDate", item.getStartDate().toDate());
@@ -86,7 +90,6 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
q.bind("rate", item.getRate());
q.bind("currency", item.getCurrency().toString());
q.bind("reversedItemId", (item.getReversedItemId() == null) ? null : item.getReversedItemId().toString());
- q.bind("createdDate", item.getCreatedDate().toDate());
}
};
}
@@ -98,6 +101,7 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
public InvoiceItem map(int index, ResultSet result, StatementContext context) throws SQLException {
UUID id = UUID.fromString(result.getString("id"));
UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
+ UUID accountId = UUID.fromString(result.getString("account_id"));
UUID subscriptionId = UUID.fromString(result.getString("subscription_id"));
UUID bundleId = UUID.fromString(result.getString("bundle_id"));
String planName = result.getString("plan_name");
@@ -109,10 +113,12 @@ public interface RecurringInvoiceItemSqlDao extends EntityDao<InvoiceItem> {
Currency currency = Currency.valueOf(result.getString("currency"));
String reversedItemString = result.getString("reversed_item_id");
UUID reversedItemId = (reversedItemString == null) ? null : UUID.fromString(reversedItemString);
+ String createdBy = result.getString("created_by");
DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
- return new RecurringInvoiceItem(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
- amount, rate, currency, reversedItemId, createdDate);
+ return new RecurringInvoiceItem(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate,
+ amount, rate, currency, reversedItemId, createdBy, createdDate);
+
}
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
index c5e55cc..ba63bf1 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
@@ -76,7 +76,6 @@ public class InvoiceModule extends AbstractModule {
}
protected void installInvoiceListener() {
-
bind(InvoiceListener.class).asEagerSingleton();
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index 04a55ca..bb8d957 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.SortedSet;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,18 +69,20 @@ public class InvoiceDispatcher {
this.locker = locker;
String verboseOutputValue = System.getProperty("VERBOSE_OUTPUT");
- VERBOSE_OUTPUT = (verboseOutputValue == null) ? false : Boolean.parseBoolean(verboseOutputValue);
+ VERBOSE_OUTPUT = (verboseOutputValue != null) && Boolean.parseBoolean(verboseOutputValue);
}
- public void processSubscription(final SubscriptionTransition transition) throws InvoiceApiException {
+ public void processSubscription(final SubscriptionTransition transition,
+ final CallContext context) throws InvoiceApiException {
UUID subscriptionId = transition.getSubscriptionId();
DateTime targetDate = transition.getEffectiveTransitionTime();
log.info("Got subscription transition from InvoiceListener. id: " + subscriptionId.toString() + "; targetDate: " + targetDate.toString());
log.info("Transition type: " + transition.getTransitionType().toString());
- processSubscription(subscriptionId, targetDate);
+ processSubscription(subscriptionId, targetDate, context);
}
- public void processSubscription(final UUID subscriptionId, final DateTime targetDate) throws InvoiceApiException {
+ public void processSubscription(final UUID subscriptionId, final DateTime targetDate,
+ final CallContext context) throws InvoiceApiException {
if (subscriptionId == null) {
log.error("Failed handling entitlement change.", new InvoiceApiException(ErrorCode.INVOICE_INVALID_TRANSITION));
return;
@@ -92,15 +95,16 @@ public class InvoiceDispatcher {
return;
}
- processAccount(accountId, targetDate, false);
+ processAccount(accountId, targetDate, false, context);
}
- public Invoice processAccount(UUID accountId, DateTime targetDate, boolean dryrun) throws InvoiceApiException {
+ public Invoice processAccount(final UUID accountId, final DateTime targetDate,
+ final boolean dryRun, final CallContext context) throws InvoiceApiException {
GlobalLock lock = null;
try {
lock = locker.lockWithNumberOfTries(LockerService.INVOICE, accountId.toString(), NB_LOCK_TRY);
- return processAccountWithLock(accountId, targetDate, dryrun);
+ return processAccountWithLock(accountId, targetDate, dryRun, context);
} catch (LockFailedException e) {
// Not good!
@@ -114,7 +118,8 @@ public class InvoiceDispatcher {
return null;
}
- private Invoice processAccountWithLock(final UUID accountId, final DateTime targetDate, boolean dryrun) throws InvoiceApiException {
+ private Invoice processAccountWithLock(final UUID accountId, final DateTime targetDate,
+ final boolean dryRun, final CallContext context) throws InvoiceApiException {
Account account = accountUserApi.getAccountById(accountId);
if (account == null) {
@@ -145,8 +150,8 @@ public class InvoiceDispatcher {
}
outputDebugData(events, invoices);
- if (invoice.getNumberOfItems() > 0 && !dryrun) {
- invoiceDao.create(invoice);
+ if (invoice.getNumberOfItems() > 0 && !dryRun) {
+ invoiceDao.create(invoice, context);
}
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
index d31e98b..ff23965 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -18,6 +18,10 @@ package com.ning.billing.invoice;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.CallContextFactory;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,16 +34,19 @@ import com.ning.billing.invoice.api.InvoiceApiException;
public class InvoiceListener {
private final static Logger log = LoggerFactory.getLogger(InvoiceListener.class);
private final InvoiceDispatcher dispatcher;
+ private final CallContextFactory factory;
@Inject
- public InvoiceListener(InvoiceDispatcher dispatcher) {
+ public InvoiceListener(CallContextFactory factory, InvoiceDispatcher dispatcher) {
this.dispatcher = dispatcher;
+ this.factory = factory;
}
@Subscribe
public void handleSubscriptionTransition(final SubscriptionTransition transition) {
try {
- dispatcher.processSubscription(transition);
+ CallContext context = factory.createCallContext("Transition", CallOrigin.INTERNAL, UserType.SYSTEM);
+ dispatcher.processSubscription(transition, context);
} catch (InvoiceApiException e) {
log.error(e.getMessage());
}
@@ -47,7 +54,8 @@ public class InvoiceListener {
public void handleNextBillingDateEvent(final UUID subscriptionId, final DateTime eventDateTime) {
try {
- dispatcher.processSubscription(subscriptionId, eventDateTime);
+ CallContext context = factory.createCallContext("Next Billing Date", CallOrigin.INTERNAL, UserType.SYSTEM);
+ dispatcher.processSubscription(subscriptionId, eventDateTime, context);
} catch (InvoiceApiException e) {
log.error(e.getMessage());
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
index ed8f42d..1467415 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
@@ -23,19 +23,19 @@ import java.util.UUID;
import javax.annotation.Nullable;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.entity.ExtendedEntityBase;
import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePayment;
-import com.ning.billing.util.clock.Clock;
-
-public class DefaultInvoice implements Invoice {
+public class DefaultInvoice extends ExtendedEntityBase implements Invoice {
private final InvoiceItemList invoiceItems = new InvoiceItemList();
private final List<InvoicePayment> payments = new ArrayList<InvoicePayment>();
- private final UUID id;
private final UUID accountId;
private final Integer invoiceNumber;
private final DateTime invoiceDate;
@@ -43,28 +43,21 @@ public class DefaultInvoice implements Invoice {
private final Currency currency;
private final boolean migrationInvoice;
- public DefaultInvoice(UUID accountId, DateTime targetDate, Currency currency, Clock clock) {
- this(UUID.randomUUID(), accountId, null, clock.getUTCNow(), targetDate, currency);
- }
-
- public DefaultInvoice(UUID accountId, DateTime targetDate, Currency currency, Clock clock, boolean migrationInvoice) {
- this(UUID.randomUUID(), accountId, null, clock.getUTCNow(), targetDate, currency, migrationInvoice);
+ // used to create a new invoice
+ public DefaultInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
+ this(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, false, null, null);
}
- public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate, DateTime targetDate,
- Currency currency) {
- this(invoiceId, accountId, invoiceNumber, invoiceDate, targetDate, currency, false);
- }
-
- public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber,DateTime invoiceDate, DateTime targetDate,
- Currency currency, boolean migrationInvoice) {
- this.id = invoiceId;
+ // used to hydrate invoice from persistence layer
+ public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate,
+ DateTime targetDate, Currency currency, boolean isMigrationInvoice, @Nullable String createdBy, @Nullable DateTime createdDate) {
+ super(invoiceId, createdBy, createdDate);
this.accountId = accountId;
this.invoiceNumber = invoiceNumber;
this.invoiceDate = invoiceDate;
this.targetDate = targetDate;
this.currency = currency;
- this.migrationInvoice = migrationInvoice;
+ this.migrationInvoice = isMigrationInvoice;
}
@Override
@@ -215,5 +208,24 @@ public class DefaultInvoice implements Invoice {
return "DefaultInvoice [items=" + invoiceItems + ", payments=" + payments + ", id=" + id + ", accountId=" + accountId + ", invoiceDate=" + invoiceDate + ", targetDate=" + targetDate + ", currency=" + currency + ", amountPaid=" + getAmountPaid() + ", lastPaymentAttempt=" + getLastPaymentAttempt() + "]";
}
+ @Override
+ public String getObjectName() {
+ return Invoice.ObjectType;
+ }
+
+ @Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveFields(List<CustomField> fields, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearPersistedFields(CallContext context) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 9b9a83f..627a7be 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -16,38 +16,42 @@
package com.ning.billing.invoice.model;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.joda.time.Months;
+
import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.Duration;
+import com.ning.billing.config.InvoiceConfig;
import com.ning.billing.entitlement.api.billing.BillingEvent;
import com.ning.billing.entitlement.api.billing.BillingModeType;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.util.clock.Clock;
-import org.joda.time.DateTime;
-import org.joda.time.Months;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.UUID;
-import javax.annotation.Nullable;
public class DefaultInvoiceGenerator implements InvoiceGenerator {
private static final int ROUNDING_MODE = InvoicingConfiguration.getRoundingMode();
private static final int NUMBER_OF_DECIMALS = InvoicingConfiguration.getNumberOfDecimals();
- public static final String NUMBER_OF_MONTHS = "killbill.invoice.maxNumberOfMonthsInFuture";
private final Clock clock;
+ private final InvoiceConfig config;
@Inject
- public DefaultInvoiceGenerator(Clock clock) {
+ public DefaultInvoiceGenerator(Clock clock, InvoiceConfig config) {
this.clock = clock;
+ this.config = config;
}
/*
@@ -77,9 +81,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
targetDate = adjustTargetDate(existingInvoices, targetDate);
- DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, targetCurrency, clock);
+ DefaultInvoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, targetCurrency);
UUID invoiceId = invoice.getId();
- List<InvoiceItem> proposedItems = generateInvoiceItems(invoiceId, events, targetDate, targetCurrency);
+ List<InvoiceItem> proposedItems = generateInvoiceItems(invoiceId, accountId, events, targetDate, targetCurrency);
removeCancellingInvoiceItems(existingItems);
removeDuplicatedInvoiceItems(proposedItems, existingItems);
@@ -100,8 +104,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
private void validateTargetDate(DateTime targetDate) throws InvoiceApiException {
- String maximumNumberOfMonthsValue = System.getProperty(NUMBER_OF_MONTHS);
- int maximumNumberOfMonths= (maximumNumberOfMonthsValue == null) ? 36 : Integer.parseInt(maximumNumberOfMonthsValue);
+ int maximumNumberOfMonths = config.getNumberOfMonthsInFuture();
if (Months.monthsBetween(clock.getUTCNow(), targetDate).getMonths() > maximumNumberOfMonths) {
throw new InvoiceApiException(ErrorCode.INVOICE_TARGET_DATE_TOO_FAR_IN_THE_FUTURE, targetDate.toString());
@@ -164,7 +167,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- private List<InvoiceItem> generateInvoiceItems(final UUID invoiceId, final BillingEventSet events,
+ private List<InvoiceItem> generateInvoiceItems(final UUID invoiceId, final UUID accountId, final BillingEventSet events,
final DateTime targetDate, final Currency currency) throws InvoiceApiException {
List<InvoiceItem> items = new ArrayList<InvoiceItem>();
@@ -175,16 +178,16 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
nextEvent = (thisEvent.getSubscription().getId() == nextEvent.getSubscription().getId()) ? nextEvent : null;
}
- items.addAll(processEvents(invoiceId, thisEvent, nextEvent, targetDate, currency));
+ items.addAll(processEvents(invoiceId, accountId, thisEvent, nextEvent, targetDate, currency));
}
return items;
}
- private List<InvoiceItem> processEvents(final UUID invoiceId, final BillingEvent thisEvent, final BillingEvent nextEvent,
+ private List<InvoiceItem> processEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, final BillingEvent nextEvent,
final DateTime targetDate, final Currency currency) throws InvoiceApiException {
List<InvoiceItem> items = new ArrayList<InvoiceItem>();
- InvoiceItem fixedPriceInvoiceItem = generateFixedPriceItem(invoiceId, thisEvent, targetDate, currency);
+ InvoiceItem fixedPriceInvoiceItem = generateFixedPriceItem(invoiceId, accountId, thisEvent, targetDate, currency);
if (fixedPriceInvoiceItem != null) {
items.add(fixedPriceInvoiceItem);
}
@@ -211,12 +214,13 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
BigDecimal amount = itemDatum.getNumberOfCycles().multiply(rate).setScale(NUMBER_OF_DECIMALS, ROUNDING_MODE);
RecurringInvoiceItem recurringItem = new RecurringInvoiceItem(invoiceId,
- thisEvent.getSubscription().getId(),
+ accountId,
thisEvent.getSubscription().getBundleId(),
+ thisEvent.getSubscription().getId(),
thisEvent.getPlan().getName(),
thisEvent.getPlanPhase().getName(),
itemDatum.getStartDate(), itemDatum.getEndDate(),
- amount, rate, currency, clock.getUTCNow());
+ amount, rate, currency);
items.add(recurringItem);
}
}
@@ -235,7 +239,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- private InvoiceItem generateFixedPriceItem(final UUID invoiceId, final BillingEvent thisEvent,
+ private InvoiceItem generateFixedPriceItem(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent,
final DateTime targetDate, final Currency currency) throws InvoiceApiException {
if (thisEvent.getEffectiveDate().isAfter(targetDate)) {
return null;
@@ -246,11 +250,10 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
Duration duration = thisEvent.getPlanPhase().getDuration();
DateTime endDate = duration.addToDateTime(thisEvent.getEffectiveDate());
- return new FixedPriceInvoiceItem(invoiceId, thisEvent.getSubscription().getId(),
- thisEvent.getSubscription().getBundleId(),
+ return new FixedPriceInvoiceItem(invoiceId, accountId, thisEvent.getSubscription().getBundleId(),
+ thisEvent.getSubscription().getId(),
thisEvent.getPlan().getName(), thisEvent.getPlanPhase().getName(),
- thisEvent.getEffectiveDate(), endDate, fixedPrice, currency,
- clock.getUTCNow());
+ thisEvent.getEffectiveDate(), endDate, fixedPrice, currency);
} else {
return null;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
index a0f518a..22eb5e6 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
@@ -18,47 +18,38 @@ package com.ning.billing.invoice.model;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.util.entity.EntityBase;
import org.joda.time.DateTime;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.UUID;
-public class DefaultInvoicePayment implements InvoicePayment {
+public class DefaultInvoicePayment extends EntityBase implements InvoicePayment {
private final UUID paymentAttemptId;
private final UUID invoiceId;
private final DateTime paymentDate;
private final BigDecimal amount;
private final Currency currency;
- private final DateTime createdDate;
-
- public DefaultInvoicePayment(final UUID invoiceId, final DateTime paymentDate) {
- this(UUID.randomUUID(), invoiceId, paymentDate, null, null, null);
- }
public DefaultInvoicePayment(final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate) {
- this(paymentAttemptId, invoiceId, paymentDate, null, null, null);
- }
-
- public DefaultInvoicePayment(final UUID invoiceId, final DateTime paymentDate,
- final BigDecimal amount, final Currency currency) {
- this(UUID.randomUUID(), invoiceId, paymentDate, amount, currency, null);
+ this(UUID.randomUUID(), paymentAttemptId, invoiceId, paymentDate, null, null, null, null);
}
public DefaultInvoicePayment(final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate,
final BigDecimal amount, final Currency currency) {
- this(paymentAttemptId, invoiceId, paymentDate, amount, currency, null);
+ this(UUID.randomUUID(), paymentAttemptId, invoiceId, paymentDate, amount, currency, null, null);
}
- public DefaultInvoicePayment(final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate,
+ public DefaultInvoicePayment(final UUID id, final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate,
@Nullable final BigDecimal amount, @Nullable final Currency currency,
- @Nullable final DateTime createdDate) {
+ @Nullable final String createdBy, @Nullable final DateTime createdDate) {
+ super(id, createdBy, createdDate);
this.paymentAttemptId = paymentAttemptId;
this.amount = amount;
this.invoiceId = invoiceId;
this.paymentDate = paymentDate;
this.currency = currency;
- this.createdDate = (createdDate == null) ? new DateTime() : createdDate;
}
@Override
@@ -85,9 +76,4 @@ public class DefaultInvoicePayment implements InvoicePayment {
public Currency getCurrency() {
return currency;
}
-
- @Override
- public DateTime getCreatedDate() {
- return createdDate;
- }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
index 492e69c..643e2b4 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/FixedPriceInvoiceItem.java
@@ -24,16 +24,16 @@ import java.math.BigDecimal;
import java.util.UUID;
public class FixedPriceInvoiceItem extends InvoiceItemBase {
- public FixedPriceInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
- DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
- DateTime createdDate) {
- super(invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+
+ public FixedPriceInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency) {
+ super(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency);
}
- public FixedPriceInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
+ public FixedPriceInvoiceItem(UUID id, UUID invoiceId, UUID bundleId, UUID accountId, UUID subscriptionId, String planName, String phaseName,
DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
- DateTime createdDate) {
- super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
+ String createdBy, DateTime createdDate) {
+ super(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdBy, createdDate);
}
@Override
@@ -48,13 +48,14 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
@Override
public int hashCode() {
- int result = subscriptionId != null ? subscriptionId.hashCode() : 0;
+ int result = accountId.hashCode();
+ result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
result = 31 * result + (planName != null ? planName.hashCode() : 0);
result = 31 * result + (phaseName != null ? phaseName.hashCode() : 0);
result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
- result = 31 * result + (amount != null ? amount.hashCode() : 0);
- result = 31 * result + (currency != null ? currency.hashCode() : 0);
+ result = 31 * result + amount.hashCode();
+ result = 31 * result + currency.hashCode();
return result;
}
@@ -65,12 +66,16 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
}
FixedPriceInvoiceItem that = (FixedPriceInvoiceItem) item;
- int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
-
- if (compareSubscriptions == 0) {
- return getStartDate().compareTo(that.getStartDate());
+ int compareAccounts = getAccountId().compareTo(that.getAccountId());
+ if (compareAccounts == 0) {
+ int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
+ if (compareSubscriptions == 0) {
+ return getStartDate().compareTo(that.getStartDate());
+ } else {
+ return compareSubscriptions;
+ }
} else {
- return compareSubscriptions;
+ return compareAccounts;
}
}
@@ -79,6 +84,7 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
StringBuilder sb = new StringBuilder();
sb.append("InvoiceItem = {").append("id = ").append(id.toString()).append(", ");
sb.append("invoiceId = ").append(invoiceId.toString()).append(", ");
+ sb.append("accountId = ").append(accountId.toString()).append(", ");
sb.append("subscriptionId = ").append(subscriptionId.toString()).append(", ");
sb.append("planName = ").append(planName).append(", ");
sb.append("phaseName = ").append(phaseName).append(", ");
@@ -102,15 +108,15 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
if (o == null || getClass() != o.getClass()) return false;
FixedPriceInvoiceItem that = (FixedPriceInvoiceItem) o;
-
+ if (accountId.compareTo(that.accountId) != 0) return false;
+ if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null)
+ return false;
if (amount != null ? amount.compareTo(that.amount) != 0 : that.amount != null) return false;
if (currency != that.currency) return false;
if (startDate != null ? startDate.compareTo(that.startDate) != 0 : that.startDate != null) return false;
if (endDate != null ? endDate.compareTo(that.endDate) != 0 : that.endDate != null) return false;
if (phaseName != null ? !phaseName.equals(that.phaseName) : that.phaseName != null) return false;
if (planName != null ? !planName.equals(that.planName) : that.planName != null) return false;
- if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null)
- return false;
return true;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
index 71d8a0b..175a08e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemBase.java
@@ -18,14 +18,16 @@ package com.ning.billing.invoice.model;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.util.entity.EntityBase;
import org.joda.time.DateTime;
+import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.UUID;
-public abstract class InvoiceItemBase implements InvoiceItem {
- protected final UUID id;
+public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem {
protected final UUID invoiceId;
+ protected final UUID accountId;
protected final UUID subscriptionId;
protected final UUID bundleId;
protected final String planName;
@@ -34,20 +36,20 @@ public abstract class InvoiceItemBase implements InvoiceItem {
protected final DateTime endDate;
protected final BigDecimal amount;
protected final Currency currency;
- protected final DateTime createdDate;
- public InvoiceItemBase(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
- DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
- DateTime createdDate) {
- this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName,
- startDate, endDate, amount, currency, createdDate);
+ public InvoiceItemBase(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency) {
+ this(UUID.randomUUID(), invoiceId, accountId, bundleId, subscriptionId, planName, phaseName,
+ startDate, endDate, amount, currency, null, null);
}
- public InvoiceItemBase(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
- DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
- DateTime createdDate) {
- this.id = id;
+
+ public InvoiceItemBase(UUID id, UUID invoiceId, UUID accountId, @Nullable UUID bundleId, @Nullable UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
+ @Nullable String createdBy, @Nullable DateTime createdDate) {
+ super(id, createdBy, createdDate);
this.invoiceId = invoiceId;
+ this.accountId = accountId;
this.subscriptionId = subscriptionId;
this.bundleId = bundleId;
this.planName = planName;
@@ -56,7 +58,6 @@ public abstract class InvoiceItemBase implements InvoiceItem {
this.endDate = endDate;
this.amount = amount;
this.currency = currency;
- this.createdDate = createdDate;
}
public DateTime getCreatedDate() {
@@ -77,6 +78,10 @@ public abstract class InvoiceItemBase implements InvoiceItem {
public UUID getBundleId() {
return bundleId;
}
+
+ public UUID getAccountId() {
+ return accountId;
+ }
@Override
public UUID getSubscriptionId() {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
index 0feb08d..ec0962b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
@@ -23,16 +23,11 @@ import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.MigrationPlan;
-import com.ning.billing.util.clock.Clock;
public class MigrationInvoiceItem extends FixedPriceInvoiceItem {
- private final static UUID MIGRATION_SUBSCRIPTION_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257c");
- private final static UUID MIGRATION_BUNDLE_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257d"); // Going away anyway
- public MigrationInvoiceItem(UUID invoiceId, DateTime startDate, BigDecimal amount, Currency currency, Clock clock) {
- super(invoiceId, MIGRATION_SUBSCRIPTION_ID, MIGRATION_BUNDLE_ID, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME, startDate, startDate,
- amount, currency, clock.getUTCNow());
+ public MigrationInvoiceItem(UUID invoiceId, UUID accountId, DateTime startDate, BigDecimal amount, Currency currency) {
+ super(invoiceId, accountId, null, null, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME,
+ startDate, startDate, amount, currency);
}
-
-
-}
+}
\ No newline at end of file
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
index 3e32f09..b3c47fc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
@@ -27,42 +27,41 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
private final BigDecimal rate;
private final UUID reversedItemId;
- public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
+ public RecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
DateTime startDate, DateTime endDate,
BigDecimal amount, BigDecimal rate,
- Currency currency,
- DateTime createdDate) {
- this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
- amount, rate, currency, createdDate);
+ Currency currency) {
+ super(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency);
+ this.rate = rate;
+ this.reversedItemId = null;
}
- public RecurringInvoiceItem(UUID invoiceId, UUID subscriptionId, UUID bundleId, String planName, String phaseName,
+ public RecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
DateTime startDate, DateTime endDate,
BigDecimal amount, BigDecimal rate,
- Currency currency, UUID reversedItemId,
- DateTime createdDate) {
- this(UUID.randomUUID(), invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
- amount, rate, currency, reversedItemId, createdDate);
+ Currency currency, UUID reversedItemId) {
+ super(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate,
+ amount, currency);
+ this.rate = rate;
+ this.reversedItemId = reversedItemId;
}
- public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
+ public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
DateTime startDate, DateTime endDate,
BigDecimal amount, BigDecimal rate,
Currency currency,
- DateTime createdDate) {
- super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
-
+ String createdBy, DateTime createdDate) {
+ super(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdBy, createdDate);
this.rate = rate;
this.reversedItemId = null;
}
- public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID subscriptionId, UUID bundleId,String planName, String phaseName,
+ public RecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
DateTime startDate, DateTime endDate,
BigDecimal amount, BigDecimal rate,
Currency currency, UUID reversedItemId,
- DateTime createdDate) {
- super(id, invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate, amount, currency, createdDate);
-
+ String createdBy, DateTime createdDate) {
+ super(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdBy, createdDate);
this.rate = rate;
this.reversedItemId = reversedItemId;
}
@@ -70,8 +69,9 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
@Override
public InvoiceItem asCredit() {
BigDecimal amountNegated = amount == null ? null : amount.negate();
- return new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, planName, phaseName, startDate, endDate,
- amountNegated, rate, currency, id, createdDate);
+
+ return new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate,
+ amountNegated, rate, currency, id);
}
@Override
@@ -101,17 +101,21 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
}
RecurringInvoiceItem that = (RecurringInvoiceItem) item;
-
- int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
- if (compareSubscriptions == 0) {
- int compareStartDates = getStartDate().compareTo(that.getStartDate());
- if (compareStartDates == 0) {
- return getEndDate().compareTo(that.getEndDate());
+ int compareAccounts = getAccountId().compareTo(that.getAccountId());
+ if (compareAccounts == 0) {
+ int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
+ if (compareSubscriptions == 0) {
+ int compareStartDates = getStartDate().compareTo(that.getStartDate());
+ if (compareStartDates == 0) {
+ return getEndDate().compareTo(that.getEndDate());
+ } else {
+ return compareStartDates;
+ }
} else {
- return compareStartDates;
+ return compareSubscriptions;
}
} else {
- return compareSubscriptions;
+ return compareAccounts;
}
}
@@ -122,6 +126,7 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
RecurringInvoiceItem that = (RecurringInvoiceItem) o;
+ if (accountId.compareTo(that.accountId) != 0) return false;
if (amount.compareTo(that.amount) != 0) return false;
if (currency != that.currency) return false;
if (startDate.compareTo(that.startDate) != 0) return false;
@@ -138,8 +143,8 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
@Override
public int hashCode() {
- int result = invoiceId.hashCode();
- result = 31 * result + subscriptionId.hashCode();
+ int result = accountId.hashCode();
+ result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
result = 31 * result + planName.hashCode();
result = 31 * result + phaseName.hashCode();
result = 31 * result + startDate.hashCode();
@@ -161,36 +166,5 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
sb.append(amount.toString()).append(", ");
return sb.toString();
-
-// StringBuilder sb = new StringBuilder();
-// sb.append("InvoiceItem = {").append("id = ").append(id.toString()).append(", ");
-// sb.append("invoiceId = ").append(invoiceId.toString()).append(", ");
-// sb.append("subscriptionId = ").append(subscriptionId.toString()).append(", ");
-// sb.append("planName = ").append(planName).append(", ");
-// sb.append("phaseName = ").append(phaseName).append(", ");
-// sb.append("startDate = ").append(startDate.toString()).append(", ");
-// if (endDate != null) {
-// sb.append("endDate = ").append(endDate.toString()).append(", ");
-// } else {
-// sb.append("endDate = null");
-// }
-// sb.append("recurringAmount = ");
-// if (amount == null) {
-// sb.append("null");
-// } else {
-// sb.append(amount.toString());
-// }
-// sb.append(", ");
-//
-// sb.append("recurringRate = ");
-// if (rate == null) {
-// sb.append("null");
-// } else {
-// sb.append(rate.toString());
-// }
-// sb.append(", ");
-//
-// sb.append("}");
-// return sb.toString();
}
}
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
index 0b5d43a..f0a06a7 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/FixedPriceInvoiceItemSqlDao.sql.stg
@@ -3,6 +3,7 @@ group FixedPriceInvoiceItemSqlDao;
fields(prefix) ::= <<
<prefix>id,
<prefix>invoice_id,
+ <prefix>account_id,
<prefix>subscription_id,
<prefix>bundle_id,
<prefix>plan_name,
@@ -11,6 +12,7 @@ fields(prefix) ::= <<
<prefix>end_date,
<prefix>amount,
<prefix>currency,
+ <prefix>created_by,
<prefix>created_date
>>
@@ -41,14 +43,14 @@ getInvoiceItemsBySubscription() ::= <<
create() ::= <<
INSERT INTO fixed_invoice_items(<fields()>)
- VALUES(:id, :invoiceId, :subscriptionId, :planName, :phaseName,
- :startDate, :endDate, :amount, :currency, :createdDate);
+ VALUES(:id, :invoiceId, :accountId, :subscriptionId, :planName, :phaseName,
+ :startDate, :endDate, :amount, :currency, :userName, :createdDate);
>>
batchCreateFromTransaction() ::= <<
INSERT INTO fixed_invoice_items(<fields()>)
- VALUES(:id, :invoiceId, :subscriptionId, :planName, :phaseName,
- :startDate, :endDate, :amount, :currency, :createdDate);
+ VALUES(:id, :invoiceId, :accountId, :subscriptionId, :planName, :phaseName,
+ :startDate, :endDate, :amount, :currency, :userName, :createdDate);
>>
test() ::= <<
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 5e1586e..a673b81 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -1,22 +1,24 @@
group InvoicePayment;
invoicePaymentFields(prefix) ::= <<
+ <prefix>id,
<prefix>invoice_id,
<prefix>payment_attempt_id,
<prefix>payment_attempt_date,
<prefix>amount,
<prefix>currency,
+ <prefix>created_by,
<prefix>created_date
>>
create() ::= <<
INSERT INTO invoice_payments(<invoicePaymentFields()>)
- VALUES(:invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, :createdDate);
+ VALUES(:id, :invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, :userName, :createdDate);
>>
batchCreateFromTransaction() ::= <<
INSERT INTO invoice_payments(<invoicePaymentFields()>)
- VALUES(:invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, :createdDate);
+ VALUES(:id, :invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, :userName, :createdDate);
>>
getByPaymentAttemptId() ::= <<
@@ -38,7 +40,7 @@ getPaymentsForInvoice() ::= <<
notifyOfPaymentAttempt() ::= <<
INSERT INTO invoice_payments(<invoicePaymentFields()>)
- VALUES(:invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, NOW());
+ VALUES(:id, :invoiceId, :paymentAttemptId, :paymentAttemptDate, :amount, :currency, :userName, :createdDate);
>>
getInvoicePayment() ::= <<
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 51347fb..b83dc82 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -7,7 +7,9 @@ invoiceFetchFields(prefix) ::= <<
<prefix>invoice_date,
<prefix>target_date,
<prefix>currency,
- <prefix>migrated
+ <prefix>migrated,
+ <prefix>created_by,
+ <prefix>created_date
>>
invoiceSetFields(prefix) ::= <<
@@ -16,7 +18,9 @@ invoiceSetFields(prefix) ::= <<
<prefix>invoice_date,
<prefix>target_date,
<prefix>currency,
- <prefix>migrated
+ <prefix>migrated,
+ <prefix>created_by,
+ <prefix>created_date
>>
get() ::= <<
@@ -72,7 +76,7 @@ getAccountBalance() ::= <<
create() ::= <<
INSERT INTO invoices(<invoiceSetFields()>)
- VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated);
+ VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated, :userName, :createdDate);
>>
getInvoiceIdByPaymentAttemptId() ::= <<
@@ -93,7 +97,6 @@ getUnpaidInvoicesByAccountId() ::= <<
ORDER BY i.target_date ASC;
>>
-
test() ::= <<
SELECT 1
FROM invoices;
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
index 45dbc9d..fbc610b 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/RecurringInvoiceItemSqlDao.sql.stg
@@ -3,6 +3,7 @@ group RecurringInvoiceItemSqlDao;
fields(prefix) ::= <<
<prefix>id,
<prefix>invoice_id,
+ <prefix>account_id,
<prefix>subscription_id,
<prefix>bundle_id,
<prefix>plan_name,
@@ -13,6 +14,7 @@ fields(prefix) ::= <<
<prefix>rate,
<prefix>currency,
<prefix>reversed_item_id,
+ <prefix>created_by,
<prefix>created_date
>>
@@ -43,14 +45,14 @@ getInvoiceItemsBySubscription() ::= <<
create() ::= <<
INSERT INTO recurring_invoice_items(<fields()>)
- VALUES(:id, :invoiceId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
- :amount, :rate, :currency, :reversedItemId, :createdDate);
+ VALUES(:id, :invoiceId, :accountId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
+ :amount, :rate, :currency, :reversedItemId, :userName, :createdDate);
>>
batchCreateFromTransaction() ::= <<
INSERT INTO recurring_invoice_items(<fields()>)
- VALUES(:id, :invoiceId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
- :amount, :rate, :currency, :reversedItemId, :createdDate);
+ VALUES(:id, :invoiceId, :accountId, :subscriptionId, :planName, :phaseName, :startDate, :endDate,
+ :amount, :rate, :currency, :reversedItemId, :userName, :createdDate);
>>
test() ::= <<
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index 51087db..1df70c8 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -3,6 +3,7 @@ DROP TABLE IF EXISTS recurring_invoice_items;
CREATE TABLE recurring_invoice_items (
id char(36) NOT NULL,
invoice_id char(36) NOT NULL,
+ account_id char(36) NOT NULL,
subscription_id char(36) NOT NULL,
bundle_id char(36) NOT NULL,
plan_name varchar(50) NOT NULL,
@@ -13,6 +14,7 @@ CREATE TABLE recurring_invoice_items (
rate numeric(10,4) NULL,
currency char(3) NOT NULL,
reversed_item_id char(36),
+ created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
@@ -23,6 +25,7 @@ DROP TABLE IF EXISTS fixed_invoice_items;
CREATE TABLE fixed_invoice_items (
id char(36) NOT NULL,
invoice_id char(36) NOT NULL,
+ account_id char(36) NOT NULL,
subscription_id char(36) NOT NULL,
bundle_id char(36) NOT NULL,
plan_name varchar(50) NOT NULL,
@@ -31,6 +34,7 @@ CREATE TABLE fixed_invoice_items (
end_date datetime NOT NULL,
amount numeric(10,4) NULL,
currency char(3) NOT NULL,
+ created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
@@ -48,6 +52,8 @@ CREATE TABLE invoices (
target_date datetime NOT NULL,
currency char(3) NOT NULL,
migrated bool NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
PRIMARY KEY(invoice_number)
) ENGINE=innodb;
CREATE INDEX invoices_invoice_number ON invoices(invoice_number ASC);
@@ -56,11 +62,13 @@ CREATE INDEX invoices_account_id ON invoices(account_id ASC);
DROP TABLE IF EXISTS invoice_payments;
CREATE TABLE invoice_payments (
+ id char(36) NOT NULL,
invoice_id char(36) NOT NULL,
payment_attempt_id char(36) COLLATE utf8_bin NOT NULL,
payment_attempt_date datetime,
amount numeric(10,4),
currency char(3),
+ created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
PRIMARY KEY(invoice_id, payment_attempt_id)
) ENGINE=innodb;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index 5f24072..212ff58 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -23,6 +23,11 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
@@ -103,7 +108,7 @@ public class TestDefaultInvoiceMigrationApi {
private static final BigDecimal MIGRATION_INVOICE_AMOUNT = new BigDecimal("100.00");
private static final Currency MIGRATION_INVOICE_CURRENCY = Currency.USD;
-
+ private final Clock clock = new ClockMock();
@BeforeClass(alwaysRun = true)
public void setup() throws Exception
@@ -111,8 +116,8 @@ public class TestDefaultInvoiceMigrationApi {
log.info("Starting set up");
accountId = UUID.randomUUID();
subscriptionId = UUID.randomUUID();
- date_migrated = new ClockMock().getUTCNow().minusYears(1);
- date_regular = new ClockMock().getUTCNow();
+ date_migrated = clock.getUTCNow().minusYears(1);
+ date_regular = clock.getUTCNow();
final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
@@ -182,13 +187,14 @@ public class TestDefaultInvoiceMigrationApi {
InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
- Invoice invoice = dispatcher.processAccount(accountId, date_regular, true);
+ CallContext context = new DefaultCallContextFactory(clock).createCallContext("Migration test", CallOrigin.TEST, UserType.TEST);
+ Invoice invoice = dispatcher.processAccount(accountId, date_regular, true, context);
Assert.assertNotNull(invoice);
List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
Assert.assertEquals(invoices.size(),0);
- invoice = dispatcher.processAccount(accountId, date_regular, false);
+ invoice = dispatcher.processAccount(accountId, date_regular, false, context);
Assert.assertNotNull(invoice);
invoices = invoiceDao.getInvoicesByAccount(accountId);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index 3384274..3a00c1b 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
+import com.ning.billing.util.callcontext.CallContext;
import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
@@ -37,7 +38,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
}
@Override
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context) {
for (InvoicePayment existingInvoicePayment : invoicePayments) {
if (existingInvoicePayment.getInvoiceId().equals(invoicePayment.getInvoiceId()) && existingInvoicePayment.getPaymentAttemptId().equals(invoicePayment.getPaymentAttemptId())) {
invoicePayments.remove(existingInvoicePayment);
@@ -89,15 +90,15 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
}
@Override
- public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+ public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context) {
InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate, amountOutstanding, currency);
- notifyOfPaymentAttempt(invoicePayment);
+ notifyOfPaymentAttempt(invoicePayment, context);
}
@Override
- public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+ public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context) {
InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate);
- notifyOfPaymentAttempt(invoicePayment);
+ notifyOfPaymentAttempt(invoicePayment, context);
}
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 2224ede..10f3bef 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -17,37 +17,58 @@
package com.ning.billing.invoice.dao;
import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
import java.io.IOException;
-import com.ning.billing.invoice.tests.InvoicingTestBase;
import org.apache.commons.io.IOUtils;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.TransactionCallback;
import org.skife.jdbi.v2.TransactionStatus;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
+import com.ning.billing.config.InvoiceConfig;
import com.ning.billing.invoice.glue.InvoiceModuleWithEmbeddedDb;
+import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
+import com.ning.billing.invoice.model.InvoiceGenerator;
+import com.ning.billing.invoice.tests.InvoicingTestBase;
import com.ning.billing.util.bus.BusService;
import com.ning.billing.util.bus.DefaultBusService;
-import org.testng.annotations.BeforeMethod;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
protected InvoiceDao invoiceDao;
protected RecurringInvoiceItemSqlDao recurringInvoiceItemDao;
protected InvoicePaymentSqlDao invoicePaymentDao;
protected InvoiceModuleWithEmbeddedDb module;
+ protected Clock clock;
+ protected CallContext context;
+ protected InvoiceGenerator generator;
private BusService busService;
+ private final InvoiceConfig invoiceConfig = new InvoiceConfig() {
+ @Override
+ public long getDaoClaimTimeMs() {throw new UnsupportedOperationException();}
+ @Override
+ public int getDaoMaxReadyEvents() {throw new UnsupportedOperationException();}
+ @Override
+ public long getNotificationSleepTimeMs() {throw new UnsupportedOperationException();}
+ @Override
+ public boolean isEventProcessingOff() {throw new UnsupportedOperationException();}
+ @Override
+ public int getNumberOfMonthsInFuture() {return 36;}
+ };
+
@BeforeClass(alwaysRun = true)
protected void setup() throws IOException {
- // Health check test to make sure MySQL is setup properly
-
module = new InvoiceModuleWithEmbeddedDb();
final String accountDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
final String invoiceDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
@@ -66,8 +87,11 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
recurringInvoiceItemDao = module.getInvoiceItemSqlDao();
invoicePaymentDao = module.getInvoicePaymentSqlDao();
-
- busService = injector.getInstance(BusService.class);
+ clock = injector.getInstance(Clock.class);
+ context = new DefaultCallContextFactory(clock).createCallContext("Count Rogan", CallOrigin.TEST, UserType.TEST);
+ generator = new DefaultInvoiceGenerator(clock, invoiceConfig);
+
+ BusService busService = injector.getInstance(BusService.class);
((DefaultBusService) busService).startBus();
assertTrue(true);
@@ -103,7 +127,9 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
@AfterClass(alwaysRun = true)
protected void tearDown() {
- ((DefaultBusService) busService).stopBus();
+ if (busService != null) {
+ ((DefaultBusService) busService).stopBus();
+ }
module.stopDb();
assertTrue(true);
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index 1408656..33a1c6a 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -37,14 +37,11 @@ import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.api.InvoicePayment;
import com.ning.billing.invoice.model.BillingEventSet;
import com.ning.billing.invoice.model.DefaultInvoice;
-import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
import com.ning.billing.invoice.model.DefaultInvoicePayment;
-import com.ning.billing.invoice.model.InvoiceGenerator;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.tag.ControlTagType;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
@@ -55,23 +52,20 @@ import java.util.List;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
@Test(groups = {"invoicing", "invoicing-invoiceDao"})
public class InvoiceDaoTests extends InvoiceDaoTestBase {
- private final int NUMBER_OF_DAY_BETWEEN_RETRIES = 8;
- private final Clock clock = new DefaultClock();
- private final InvoiceGenerator generator = new DefaultInvoiceGenerator(clock);
-
@Test
public void testCreationAndRetrievalByAccount() {
UUID accountId = UUID.randomUUID();
- Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), Currency.USD, clock);
+ Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), clock.getUTCNow(), Currency.USD);
DateTime invoiceDate = invoice.getInvoiceDate();
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
assertNotNull(invoices);
@@ -87,16 +81,17 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
@Test
public void testInvoicePayment() {
UUID accountId = UUID.randomUUID();
- Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), Currency.USD, clock);
+ Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), clock.getUTCNow(), Currency.USD);
UUID invoiceId = invoice.getId();
UUID subscriptionId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime startDate = new DateTime(2010, 1, 1, 0, 0, 0, 0);
DateTime endDate = new DateTime(2010, 4, 1, 0, 0, 0, 0);
- InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId,"test plan", "test phase", startDate, endDate,
- new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD, clock.getUTCNow());
+ InvoiceItem invoiceItem = new RecurringInvoiceItem(invoiceId, accountId, bundleId,subscriptionId, "test plan", "test phase", startDate, endDate,
+ new BigDecimal("21.00"), new BigDecimal("7.00"), Currency.USD);
+
invoice.addInvoiceItem(invoiceItem);
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
Invoice savedInvoice = invoiceDao.getById(invoiceId);
assertNotNull(savedInvoice);
@@ -108,7 +103,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal paymentAmount = new BigDecimal("11.00");
UUID paymentAttemptId = UUID.randomUUID();
- invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(paymentAttemptId, invoiceId, clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD));
+ invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(paymentAttemptId, invoiceId, clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD), context);
Invoice retrievedInvoice = invoiceDao.getById(invoiceId);
assertNotNull(retrievedInvoice);
@@ -128,14 +123,14 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
public void testAddPayment() {
UUID accountId = UUID.randomUUID();
DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
+ Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
UUID paymentAttemptId = UUID.randomUUID();
DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
BigDecimal paymentAmount = new BigDecimal("14.0");
- invoiceDao.create(invoice);
- invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(paymentAttemptId, invoice.getId(), paymentAttemptDate, paymentAmount, Currency.USD));
+ invoiceDao.create(invoice, context);
+ invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(paymentAttemptId, invoice.getId(), paymentAttemptDate, paymentAmount, Currency.USD), context);
invoice = invoiceDao.getById(invoice.getId());
assertEquals(invoice.getAmountPaid().compareTo(paymentAmount), 0);
@@ -147,30 +142,17 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
public void testAddPaymentAttempt() {
UUID accountId = UUID.randomUUID();
DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
+ Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
- invoiceDao.create(invoice);
- invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(invoice.getId(), paymentAttemptDate));
+ invoiceDao.create(invoice, context);
+ invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(UUID.randomUUID(), invoice.getId(), paymentAttemptDate), context);
invoice = invoiceDao.getById(invoice.getId());
assertEquals(invoice.getLastPaymentAttempt().compareTo(paymentAttemptDate), 0);
}
-
- private List<Invoice> getInvoicesDueForPaymentAttempt(final List<Invoice> invoices, final DateTime date) {
- List<Invoice> invoicesDue = new ArrayList<Invoice>();
-
- for (final Invoice invoice : invoices) {
- if (invoice.isDueForPayment(date, NUMBER_OF_DAY_BETWEEN_RETRIES)) {
- invoicesDue.add(invoice);
- }
- }
-
- return invoicesDue;
- }
-
@Test
public void testGetInvoicesBySubscription() {
UUID accountId = UUID.randomUUID();
@@ -189,50 +171,52 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
// create invoice 1 (subscriptions 1-4)
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
+ invoiceDao.create(invoice1, context);
UUID invoiceId1 = invoice1.getId();
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
DateTime endDate = startDate.plusMonths(1);
- RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, subscriptionId1, bundleId,"test plan", "test A", startDate, endDate,
- rate1, rate1, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item1);
- RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, subscriptionId2, bundleId,"test plan", "test B", startDate, endDate,
- rate2, rate2, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item2);
+ RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId,subscriptionId1, "test plan", "test A", startDate, endDate,
+ rate1, rate1, Currency.USD);
+ recurringInvoiceItemDao.create(item1, context);
- RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, subscriptionId3, bundleId,"test plan", "test C", startDate, endDate,
- rate3, rate3, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item3);
+ RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId,subscriptionId2, "test plan", "test B", startDate, endDate,
+ rate2, rate2, Currency.USD);
+ recurringInvoiceItemDao.create(item2, context);
- RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, subscriptionId4, bundleId, "test plan", "test D", startDate, endDate,
- rate4, rate4, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item4);
+ RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId,subscriptionId3, "test plan", "test C", startDate, endDate,
+ rate3, rate3, Currency.USD);
+ recurringInvoiceItemDao.create(item3, context);
+
+ RecurringInvoiceItem item4 = new RecurringInvoiceItem(invoiceId1, accountId, bundleId,subscriptionId4, "test plan", "test D", startDate, endDate,
+ rate4, rate4, Currency.USD);
+ recurringInvoiceItemDao.create(item4, context);
// create invoice 2 (subscriptions 1-3)
- DefaultInvoice invoice2 = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
- invoiceDao.create(invoice2);
+ DefaultInvoice invoice2 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
+ invoiceDao.create(invoice2, context);
UUID invoiceId2 = invoice2.getId();
startDate = endDate;
endDate = startDate.plusMonths(1);
- RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, subscriptionId1, bundleId,"test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item5);
- RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, subscriptionId2, bundleId,"test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item6);
+ RecurringInvoiceItem item5 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId,subscriptionId1, "test plan", "test phase A", startDate, endDate,
+ rate1, rate1, Currency.USD);
+ recurringInvoiceItemDao.create(item5, context);
+
+ RecurringInvoiceItem item6 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId,subscriptionId2, "test plan", "test phase B", startDate, endDate,
+ rate2, rate2, Currency.USD);
+ recurringInvoiceItemDao.create(item6, context);
- RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, subscriptionId3, bundleId, "test plan", "test phase C", startDate, endDate,
- rate3, rate3, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item7);
+ RecurringInvoiceItem item7 = new RecurringInvoiceItem(invoiceId2, accountId, bundleId,subscriptionId3, "test plan", "test phase C", startDate, endDate,
+ rate3, rate3, Currency.USD);
+ recurringInvoiceItemDao.create(item7, context);
// check that each subscription returns the correct number of invoices
List<Invoice> items1 = invoiceDao.getInvoicesBySubscription(subscriptionId1);
@@ -252,12 +236,12 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
public void testGetInvoicesForAccountAfterDate() {
UUID accountId = UUID.randomUUID();
DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
DateTime targetDate2 = new DateTime(2011, 12, 6, 0, 0, 0, 0);
- Invoice invoice2 = new DefaultInvoice(accountId, targetDate2, Currency.USD, clock);
- invoiceDao.create(invoice2);
+ Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate2, Currency.USD);
+ invoiceDao.create(invoice2, context);
List<Invoice> invoices;
@@ -282,8 +266,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
UUID accountId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
DateTime endDate = startDate.plusMonths(1);
@@ -291,17 +275,17 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase A", startDate,
- endDate, rate1, rate1, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item1);
+ RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId,UUID.randomUUID(), "test plan", "test phase A", startDate,
+ endDate, rate1, rate1, Currency.USD);
+ recurringInvoiceItemDao.create(item1, context);
- RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate,
- endDate, rate2, rate2, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item2);
+ RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId,UUID.randomUUID(), "test plan", "test phase B", startDate,
+ endDate, rate2, rate2, Currency.USD);
+ recurringInvoiceItemDao.create(item2, context);
BigDecimal payment1 = new BigDecimal("48.0");
- InvoicePayment payment = new DefaultInvoicePayment(invoice1.getId(), new DateTime(), payment1, Currency.USD);
- invoicePaymentDao.create(payment);
+ InvoicePayment payment = new DefaultInvoicePayment(UUID.randomUUID(), invoice1.getId(), new DateTime(), payment1, Currency.USD);
+ invoicePaymentDao.create(payment, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(rate1.add(rate2).subtract(payment1)), 0);
@@ -312,8 +296,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
UUID accountId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
DateTime endDate = startDate.plusMonths(1);
@@ -321,13 +305,13 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item1);
+ RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
+ rate1, rate1, Currency.USD);
+ recurringInvoiceItemDao.create(item1, context);
- RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item2);
+ RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
+ rate2, rate2, Currency.USD);
+ recurringInvoiceItemDao.create(item2, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(rate1.add(rate2)), 0);
@@ -337,12 +321,12 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
public void testAccountBalanceWithNoInvoiceItems() {
UUID accountId = UUID.randomUUID();
DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
BigDecimal payment1 = new BigDecimal("48.0");
- InvoicePayment payment = new DefaultInvoicePayment(invoice1.getId(), new DateTime(), payment1, Currency.USD);
- invoicePaymentDao.create(payment);
+ InvoicePayment payment = new DefaultInvoicePayment(UUID.randomUUID(), invoice1.getId(), new DateTime(), payment1, Currency.USD);
+ invoicePaymentDao.create(payment, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId);
assertEquals(balance.compareTo(BigDecimal.ZERO.subtract(payment1)), 0);
@@ -353,8 +337,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
UUID accountId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
- Invoice invoice1 = new DefaultInvoice(accountId, targetDate1, Currency.USD, clock);
- invoiceDao.create(invoice1);
+ Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
DateTime endDate = startDate.plusMonths(1);
@@ -362,13 +346,14 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BigDecimal rate1 = new BigDecimal("17.0");
BigDecimal rate2 = new BigDecimal("42.0");
- RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId, "test plan", "test phase A", startDate, endDate,
- rate1, rate1, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item1);
- RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase B", startDate, endDate,
- rate2, rate2, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item2);
+ RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate,
+ rate1, rate1, Currency.USD);
+ recurringInvoiceItemDao.create(item1, context);
+
+ RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate,
+ rate2, rate2, Currency.USD);
+ recurringInvoiceItemDao.create(item2, context);
DateTime upToDate;
Collection<Invoice> invoices;
@@ -382,17 +367,17 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(invoices.size(), 1);
DateTime targetDate2 = new DateTime(2011, 7, 1, 0, 0, 0, 0);
- Invoice invoice2 = new DefaultInvoice(accountId, targetDate2, Currency.USD, clock);
- invoiceDao.create(invoice2);
+ Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate2, Currency.USD);
+ invoiceDao.create(invoice2, context);
DateTime startDate2 = new DateTime(2011, 6, 1, 0, 0, 0, 0);
DateTime endDate2 = startDate2.plusMonths(3);
BigDecimal rate3 = new BigDecimal("21.0");
- RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), UUID.randomUUID(), bundleId,"test plan", "test phase C", startDate2, endDate2,
- rate3, rate3, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item3);
+ RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2,
+ rate3, rate3, Currency.USD);
+ recurringInvoiceItemDao.create(item3, context);
upToDate = new DateTime(2011, 1, 1, 0, 0, 0, 0);
invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
@@ -454,8 +439,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(invoice2.getBalance(), FIVE);
invoiceList.add(invoice2);
- invoiceDao.create(invoice1);
- invoiceDao.create(invoice2);
+ invoiceDao.create(invoice1, context);
+ invoiceDao.create(invoice2, context);
Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId());
assertEquals(savedInvoice1.getTotalAmount(), ZERO);
@@ -515,7 +500,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
BillingEventSet events = new BillingEventSet();
events.add(event1);
- Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, null, effectiveDate1, Currency.USD);
+ UUID accountId = UUID.randomUUID();
+ Invoice invoice1 = generator.generateInvoice(accountId, events, null, effectiveDate1, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
assertEquals(invoice1.getTotalAmount().compareTo(ZERO), 0);
@@ -529,7 +515,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
"testEvent2", 2L, SubscriptionTransitionType.CHANGE);
events.add(event2);
- Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoiceList, effectiveDate2, Currency.USD);
+ Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, effectiveDate2, Currency.USD);
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
assertEquals(invoice2.getTotalAmount().compareTo(cheapAmount), 0);
@@ -537,7 +523,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
invoiceList.add(invoice2);
DateTime effectiveDate3 = effectiveDate2.plusMonths(1);
- Invoice invoice3 = generator.generateInvoice(UUID.randomUUID(), events, invoiceList, effectiveDate3, Currency.USD);
+ Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, effectiveDate3, Currency.USD);
assertNotNull(invoice3);
assertEquals(invoice3.getNumberOfItems(), 1);
assertEquals(invoice3.getTotalAmount().compareTo(cheapAmount), 0);
@@ -586,7 +572,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(invoice.getNumberOfItems(), 2);
assertEquals(invoice.getTotalAmount().compareTo(cheapAmount), 0);
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
Invoice savedInvoice = invoiceDao.getById(invoice.getId());
assertNotNull(savedInvoice);
@@ -623,7 +609,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate1, Currency.USD);
invoices.add(invoice1);
- invoiceDao.create(invoice1);
+ invoiceDao.create(invoice1, context);
invoice1 = invoiceDao.getById(invoice1.getId());
assertNotNull(invoice1.getInvoiceNumber());
@@ -633,8 +619,74 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
"testEvent2", 2L, SubscriptionTransitionType.CHANGE);
events.add(event2);
Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate2, Currency.USD);
- invoiceDao.create(invoice2);
+ invoiceDao.create(invoice2, context);
invoice2 = invoiceDao.getById(invoice2.getId());
assertNotNull(invoice2.getInvoiceNumber());
}
+
+ @Test
+ public void testAddingWrittenOffTag() throws InvoiceApiException {
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
+
+ Plan plan = BrainDeadProxyFactory.createBrainDeadProxyFor(Plan.class);
+ ((ZombieControl) plan).addResult("getName", "plan");
+
+ PlanPhase phase1 = BrainDeadProxyFactory.createBrainDeadProxyFor(PlanPhase.class);
+ ((ZombieControl) phase1).addResult("getName", "plan-phase1");
+
+ DateTime targetDate1 = clock.getUTCNow();
+ Currency currency = Currency.USD;
+
+ // create pseudo-random invoice
+ BillingEvent event1 = new DefaultBillingEvent(subscription, targetDate1, plan, phase1, null,
+ TEN, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+ BillingEventSet events = new BillingEventSet();
+ events.add(event1);
+
+ Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate1, Currency.USD);
+ invoiceDao.create(invoice, context);
+
+ invoiceDao.addControlTag(ControlTagType.WRITTEN_OFF, invoice.getId(), context);
+
+ Invoice savedInvoice = invoiceDao.getById(invoice.getId());
+ assertTrue(savedInvoice.hasTag(ControlTagType.WRITTEN_OFF.toString()));
+ }
+
+ @Test
+ public void testRemoveWrittenOffTag() throws InvoiceApiException {
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
+
+ Plan plan = BrainDeadProxyFactory.createBrainDeadProxyFor(Plan.class);
+ ((ZombieControl) plan).addResult("getName", "plan");
+
+ PlanPhase phase1 = BrainDeadProxyFactory.createBrainDeadProxyFor(PlanPhase.class);
+ ((ZombieControl) phase1).addResult("getName", "plan-phase1");
+
+ DateTime targetDate1 = clock.getUTCNow();
+ Currency currency = Currency.USD;
+
+ // create pseudo-random invoice
+ BillingEvent event1 = new DefaultBillingEvent(subscription, targetDate1, plan, phase1, null,
+ TEN, currency,
+ BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+ "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
+ BillingEventSet events = new BillingEventSet();
+ events.add(event1);
+
+ Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate1, Currency.USD);
+ invoiceDao.create(invoice, context);
+
+ invoiceDao.addControlTag(ControlTagType.WRITTEN_OFF, invoice.getId(), context);
+
+ Invoice savedInvoice = invoiceDao.getById(invoice.getId());
+ assertTrue(savedInvoice.hasTag(ControlTagType.WRITTEN_OFF.toString()));
+
+ invoiceDao.removeControlTag(ControlTagType.WRITTEN_OFF, invoice.getId(), context);
+ savedInvoice = invoiceDao.getById(invoice.getId());
+ assertFalse(savedInvoice.hasTag(ControlTagType.WRITTEN_OFF.toString()));
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
index 9d625bd..7ada46c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
@@ -20,8 +20,6 @@ import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.InvoiceItem;
import com.ning.billing.invoice.model.DefaultInvoice;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.DefaultClock;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
@@ -34,10 +32,9 @@ import static org.testng.Assert.assertNotNull;
@Test(groups = {"invoicing", "invoicing-invoiceDao"})
public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
- private final Clock clock = new DefaultClock();
-
@Test(groups = "slow")
public void testInvoiceItemCreation() {
+ UUID accountId = UUID.randomUUID();
UUID invoiceId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
UUID subscriptionId = UUID.randomUUID();
@@ -45,10 +42,9 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
DateTime endDate = new DateTime(2011, 11, 1, 0, 0, 0, 0);
BigDecimal rate = new BigDecimal("20.00");
- final DateTime expectedCreatedDate = clock.getUTCNow();
- RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, endDate,
- rate, rate, Currency.USD, expectedCreatedDate);
- recurringInvoiceItemDao.create(item);
+ RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId, "test plan", "test phase", startDate, endDate,
+ rate, rate, Currency.USD);
+ recurringInvoiceItemDao.create(item, context);
RecurringInvoiceItem thisItem = (RecurringInvoiceItem) recurringInvoiceItemDao.getById(item.getId().toString());
assertNotNull(thisItem);
@@ -60,11 +56,13 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
assertEquals(thisItem.getAmount().compareTo(item.getRate()), 0);
assertEquals(thisItem.getRate().compareTo(item.getRate()), 0);
assertEquals(thisItem.getCurrency(), item.getCurrency());
- assertEquals(thisItem.getCreatedDate().compareTo(item.getCreatedDate()), 0);
+ // created date is no longer set before persistence layer call
+ // assertEquals(thisItem.getCreatedDate().compareTo(item.getCreatedDate()), 0);
}
@Test(groups = "slow")
public void testGetInvoiceItemsBySubscriptionId() {
+ UUID accountId = UUID.randomUUID();
UUID subscriptionId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
@@ -72,9 +70,11 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
for (int i = 0; i < 3; i++) {
UUID invoiceId = UUID.randomUUID();
- RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1),
- rate, rate, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item);
+
+ RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
+ "test plan", "test phase", startDate.plusMonths(i), startDate.plusMonths(i + 1),
+ rate, rate, Currency.USD);
+ recurringInvoiceItemDao.create(item, context);
}
List<InvoiceItem> items = recurringInvoiceItemDao.getInvoiceItemsBySubscription(subscriptionId.toString());
@@ -83,6 +83,7 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
@Test(groups = "slow")
public void testGetInvoiceItemsByInvoiceId() {
+ UUID accountId = UUID.randomUUID();
UUID invoiceId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
@@ -91,9 +92,11 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
for (int i = 0; i < 5; i++) {
UUID subscriptionId = UUID.randomUUID();
BigDecimal amount = rate.multiply(new BigDecimal(i + 1));
- RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, startDate.plusMonths(1),
- amount, amount, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item);
+
+ RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
+ "test plan", "test phase", startDate, startDate.plusMonths(1),
+ amount, amount, Currency.USD);
+ recurringInvoiceItemDao.create(item, context);
}
List<InvoiceItem> items = recurringInvoiceItemDao.getInvoiceItemsByInvoice(invoiceId.toString());
@@ -105,18 +108,20 @@ public class InvoiceItemDaoTests extends InvoiceDaoTestBase {
UUID accountId = UUID.randomUUID();
UUID bundleId = UUID.randomUUID();
DateTime targetDate = new DateTime(2011, 5, 23, 0, 0, 0, 0);
- DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD, clock);
+ DefaultInvoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
UUID invoiceId = invoice.getId();
DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
BigDecimal rate = new BigDecimal("20.00");
UUID subscriptionId = UUID.randomUUID();
- RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, bundleId, "test plan", "test phase", startDate, startDate.plusMonths(1),
- rate, rate, Currency.USD, clock.getUTCNow());
- recurringInvoiceItemDao.create(item);
+
+ RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, accountId, bundleId, subscriptionId,
+ "test plan", "test phase", startDate, startDate.plusMonths(1),
+ rate, rate, Currency.USD);
+ recurringInvoiceItemDao.create(item, context);
List<InvoiceItem> items = recurringInvoiceItemDao.getInvoiceItemsByAccount(accountId.toString());
assertEquals(items.size(), 1);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index 031e02a..dec7697 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -24,7 +24,9 @@ import java.util.Map;
import java.util.UUID;
import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.tag.ControlTagType;
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -43,7 +45,7 @@ public class MockInvoiceDao implements InvoiceDao {
}
@Override
- public void create(Invoice invoice) {
+ public void create(final Invoice invoice, final CallContext context) {
synchronized (monitor) {
invoices.put(invoice.getId(), invoice);
}
@@ -151,7 +153,7 @@ public class MockInvoiceDao implements InvoiceDao {
}
@Override
- public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+ public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context) {
synchronized (monitor) {
Invoice invoice = invoices.get(invoicePayment.getInvoiceId());
if (invoice != null) {
@@ -199,4 +201,14 @@ public class MockInvoiceDao implements InvoiceDao {
}
return result;
}
+
+ @Override
+ public void addControlTag(ControlTagType controlTagType, UUID objectId, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeControlTag(ControlTagType controlTagType, UUID objectId, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
index 22fec14..fd15171 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithEmbeddedDb.java
@@ -23,8 +23,16 @@ import com.ning.billing.invoice.api.test.InvoiceTestApi;
import com.ning.billing.invoice.api.test.DefaultInvoiceTestApi;
import com.ning.billing.invoice.dao.InvoicePaymentSqlDao;
import com.ning.billing.invoice.dao.RecurringInvoiceItemSqlDao;
+import com.ning.billing.invoice.notification.MockNextBillingDateNotifier;
+import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
+import com.ning.billing.invoice.notification.NextBillingDateNotifier;
+import com.ning.billing.invoice.notification.NextBillingDatePoster;
import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.glue.FieldStoreModule;
import com.ning.billing.util.glue.GlobalLockerModule;
+import com.ning.billing.util.glue.TagStoreModule;
import org.skife.jdbi.v2.IDBI;
import com.ning.billing.account.api.AccountUserApi;
@@ -72,6 +80,12 @@ public class InvoiceModuleWithEmbeddedDb extends InvoiceModule {
}
@Override
+ protected void installNotifier() {
+ bind(NextBillingDateNotifier.class).to(MockNextBillingDateNotifier.class).asEagerSingleton();
+ bind(NextBillingDatePoster.class).to(MockNextBillingDatePoster.class).asEagerSingleton();
+ }
+
+ @Override
public void configure() {
loadSystemPropertiesFromClasspath("/resource.properties");
@@ -79,9 +93,13 @@ public class InvoiceModuleWithEmbeddedDb extends InvoiceModule {
bind(IDBI.class).toInstance(dbi);
bind(Clock.class).to(DefaultClock.class).asEagerSingleton();
+ bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+ install(new FieldStoreModule());
+ install(new TagStoreModule());
+
installNotificationQueue();
// install(new AccountModule());
- bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
+ bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
install(new CatalogModule());
install(new EntitlementModule());
install(new GlobalLockerModule());
@@ -89,7 +107,6 @@ public class InvoiceModuleWithEmbeddedDb extends InvoiceModule {
super.configure();
bind(InvoiceTestApi.class).to(DefaultInvoiceTestApi.class).asEagerSingleton();
-
install(new BusModule());
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
index 4be12cc..fe4feb4 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
@@ -20,6 +20,10 @@ import com.ning.billing.invoice.dao.InvoiceDao;
import com.ning.billing.invoice.dao.MockInvoiceDao;
import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.globallocker.MockGlobalLocker;
+import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.glue.TagStoreModule;
+import org.skife.jdbi.v2.Call;
public class InvoiceModuleWithMocks extends InvoiceModule {
@@ -49,8 +53,17 @@ public class InvoiceModuleWithMocks extends InvoiceModule {
protected void installInvoiceService() {
}
-
+
+ @Override
protected void installInvoiceMigrationApi() {
}
+
+ @Override
+ public void configure() {
+ super.configure();
+
+ install(new FieldStoreModule());
+ //install(new TagStoreModule());
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
index a06808e..99f12b4 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
@@ -16,6 +16,10 @@
package com.ning.billing.invoice;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.glue.FieldStoreModule;
+import com.ning.billing.util.glue.TagStoreModule;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
@@ -36,15 +40,15 @@ import com.ning.billing.util.glue.NotificationQueueModule;
public class MockModule extends AbstractModule {
-
-
public static final String PLUGIN_NAME = "yoyo";
@Override
protected void configure() {
-
bind(Clock.class).to(ClockMock.class).asEagerSingleton();
bind(ClockMock.class).asEagerSingleton();
+ bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+ install(new TagStoreModule());
+ install(new FieldStoreModule());
final MysqlTestingHelper helper = new MysqlTestingHelper();
bind(MysqlTestingHelper.class).toInstance(helper);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/MockNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/MockNextBillingDateNotifier.java
new file mode 100644
index 0000000..727d9d7
--- /dev/null
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/MockNextBillingDateNotifier.java
@@ -0,0 +1,34 @@
+/*
+ * 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.invoice.notification;
+
+public class MockNextBillingDateNotifier implements NextBillingDateNotifier {
+ @Override
+ public void initialize() {
+ // do nothing
+ }
+
+ @Override
+ public void start() {
+ // do nothing
+ }
+
+ @Override
+ public void stop() {
+ // do nothing
+ }
+}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index 0b2a456..adc78b7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -21,18 +21,32 @@ import static java.util.concurrent.TimeUnit.MINUTES;
import java.io.IOException;
import java.sql.SQLException;
-import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.MockAccountUserApi;
+import com.ning.billing.entitlement.api.billing.DefaultEntitlementBillingApi;
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
+import com.ning.billing.invoice.InvoiceDispatcher;
+import com.ning.billing.invoice.dao.DefaultInvoiceDao;
+import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
+import com.ning.billing.invoice.model.InvoiceGenerator;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.globallocker.MySqlGlobalLocker;
+import com.ning.billing.util.tag.dao.AuditedTagDao;
+import com.ning.billing.util.tag.dao.TagDao;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -47,16 +61,10 @@ import com.ning.billing.catalog.api.CatalogService;
import com.ning.billing.config.CatalogConfig;
import com.ning.billing.config.InvoiceConfig;
import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.entitlement.api.migration.AccountMigrationData;
import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
-import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.engine.dao.EntitlementSqlDao;
-import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.invoice.InvoiceListener;
-import com.ning.billing.invoice.dao.DefaultInvoiceDao;
import com.ning.billing.lifecycle.KillbillService.ServiceException;
import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
@@ -70,24 +78,22 @@ import com.ning.billing.util.notificationq.NotificationQueueService;
import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
public class TestNextBillingDateNotifier {
- private static Logger log = LoggerFactory.getLogger(TestNextBillingDateNotifier.class);
private Clock clock;
private DefaultNextBillingDateNotifier notifier;
private DummySqlTest dao;
private Bus eventBus;
private MysqlTestingHelper helper;
- private final InvoiceListenerMock listener = new InvoiceListenerMock();
+ private InvoiceListenerMock listener;
private NotificationQueueService notificationQueueService;
private static final class InvoiceListenerMock extends InvoiceListener {
int eventCount = 0;
UUID latestSubscriptionId = null;
- public InvoiceListenerMock() {
- super(null);
+ public InvoiceListenerMock(CallContextFactory factory, InvoiceDispatcher dispatcher) {
+ super(factory, dispatcher);
}
-
@Override
public void handleNextBillingDateEvent(UUID subscriptionId,
DateTime eventDateTime) {
@@ -112,19 +118,28 @@ public class TestNextBillingDateNotifier {
final Injector g = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
@Override
protected void configure() {
- bind(Clock.class).to(ClockMock.class).asEagerSingleton();
- bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
- bind(NotificationQueueService.class).to(DefaultNotificationQueueService.class).asEagerSingleton();
- final InvoiceConfig invoiceConfig = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
- bind(InvoiceConfig.class).toInstance(invoiceConfig);
- final CatalogConfig catalogConfig = new ConfigurationObjectFactory(System.getProperties()).build(CatalogConfig.class);
- bind(CatalogConfig.class).toInstance(catalogConfig);
- bind(CatalogService.class).to(DefaultCatalogService.class).asEagerSingleton();
- final MysqlTestingHelper helper = new MysqlTestingHelper();
- bind(MysqlTestingHelper.class).toInstance(helper);
- IDBI dbi = helper.getDBI();
- bind(IDBI.class).toInstance(dbi);
- bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
+ bind(Clock.class).to(ClockMock.class).asEagerSingleton();
+ bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+ bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
+ bind(NotificationQueueService.class).to(DefaultNotificationQueueService.class).asEagerSingleton();
+ final InvoiceConfig invoiceConfig = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
+ bind(InvoiceConfig.class).toInstance(invoiceConfig);
+ final CatalogConfig catalogConfig = new ConfigurationObjectFactory(System.getProperties()).build(CatalogConfig.class);
+ bind(CatalogConfig.class).toInstance(catalogConfig);
+ bind(CatalogService.class).to(DefaultCatalogService.class).asEagerSingleton();
+ final MysqlTestingHelper helper = new MysqlTestingHelper();
+ bind(MysqlTestingHelper.class).toInstance(helper);
+ IDBI dbi = helper.getDBI();
+ bind(IDBI.class).toInstance(dbi);
+ bind(TagDao.class).to(AuditedTagDao.class).asEagerSingleton();
+ bind(CustomFieldDao.class).to(AuditedCustomFieldDao.class).asEagerSingleton();
+ bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
+ bind(GlobalLocker.class).to(MySqlGlobalLocker.class).asEagerSingleton();
+ bind(InvoiceGenerator.class).to(DefaultInvoiceGenerator.class).asEagerSingleton();
+ bind(InvoiceDao.class).to(DefaultInvoiceDao.class);
+ bind(NextBillingDatePoster.class).to(DefaultNextBillingDatePoster.class).asEagerSingleton();
+ bind(AccountUserApi.class).to(MockAccountUserApi.class).asEagerSingleton();
+ bind(EntitlementBillingApi.class).to(DefaultEntitlementBillingApi.class).asEagerSingleton();
}
});
@@ -134,12 +149,14 @@ public class TestNextBillingDateNotifier {
eventBus = g.getInstance(Bus.class);
helper = g.getInstance(MysqlTestingHelper.class);
notificationQueueService = g.getInstance(NotificationQueueService.class);
-
+ InvoiceDispatcher dispatcher = g.getInstance(InvoiceDispatcher.class);
Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
EntitlementDao entitlementDao = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementDao.class);
((ZombieControl) entitlementDao).addResult("getSubscriptionFromId", subscription);
+ CallContextFactory factory = new DefaultCallContextFactory(clock);
+ listener = new InvoiceListenerMock(factory, dispatcher);
notifier = new DefaultNextBillingDateNotifier(notificationQueueService,g.getInstance(InvoiceConfig.class), entitlementDao, listener);
startMysql();
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index ed35ef7..eeeea97 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -23,6 +23,11 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
@@ -64,14 +69,17 @@ import com.ning.billing.util.globallocker.GlobalLocker;
@Test(groups = "slow")
@Guice(modules = {MockModule.class})
public class TestInvoiceDispatcher {
- Logger log = LoggerFactory.getLogger(TestInvoiceDispatcher.class);
+ private Logger log = LoggerFactory.getLogger(TestInvoiceDispatcher.class);
@Inject
- InvoiceUserApi invoiceUserApi;
+ private InvoiceUserApi invoiceUserApi;
+
@Inject
private InvoiceGenerator generator;
+
@Inject
private InvoiceDao invoiceDao;
+
@Inject
private GlobalLocker locker;
@@ -79,18 +87,19 @@ public class TestInvoiceDispatcher {
private MysqlTestingHelper helper;
@Inject
- NextBillingDateNotifier notifier;
+ private NextBillingDateNotifier notifier;
@Inject
private BusService busService;
+ @Inject
+ private Clock clock;
+ private CallContext context;
@BeforeSuite(groups = "slow")
public void setup() throws IOException
{
-
-
final String entitlementDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
@@ -103,6 +112,8 @@ public class TestInvoiceDispatcher {
notifier.initialize();
notifier.start();
+ context = new DefaultCallContextFactory(clock).createCallContext("Miracle Max", CallOrigin.TEST, UserType.TEST);
+
busService.getBus().start();
}
@@ -115,11 +126,12 @@ public class TestInvoiceDispatcher {
} catch (Exception e) {
log.warn("Failed to tearDown test properly ", e);
}
- }
- @Test(groups={"slow"}, enabled=true)
- public void testDryrunInvoice() throws InvoiceApiException {
- UUID accountId = UUID.randomUUID();
- UUID subscriptionId = UUID.randomUUID();
+ }
+
+ @Test(groups={"slow"}, enabled=true)
+ public void testDryRunInvoice() throws InvoiceApiException {
+ UUID accountId = UUID.randomUUID();
+ UUID subscriptionId = UUID.randomUUID();
AccountUserApi accountUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
@@ -147,21 +159,21 @@ public class TestInvoiceDispatcher {
InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
- Invoice invoice = dispatcher.processAccount(accountId, target, true);
+ Invoice invoice = dispatcher.processAccount(accountId, target, true, context);
Assert.assertNotNull(invoice);
List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
- Assert.assertEquals(invoices.size(),0);
+ Assert.assertEquals(invoices.size(), 0);
// Try it again to double check
- invoice = dispatcher.processAccount(accountId, target, true);
+ invoice = dispatcher.processAccount(accountId, target, true, context);
Assert.assertNotNull(invoice);
invoices = invoiceDao.getInvoicesByAccount(accountId);
- Assert.assertEquals(invoices.size(),0);
+ Assert.assertEquals(invoices.size(), 0);
// This time no dry run
- invoice = dispatcher.processAccount(accountId, target, false);
+ invoice = dispatcher.processAccount(accountId, target, false, context);
Assert.assertNotNull(invoice);
invoices = invoiceDao.getInvoicesByAccount(accountId);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index 838375e..6e6b9b3 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -16,7 +16,6 @@
package com.ning.billing.invoice.tests;
-import com.google.inject.Inject;
import com.ning.billing.catalog.DefaultPrice;
import com.ning.billing.catalog.MockInternationalPrice;
import com.ning.billing.catalog.MockPlan;
@@ -27,6 +26,7 @@ import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.PhaseType;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.config.InvoiceConfig;
import com.ning.billing.entitlement.api.billing.BillingEvent;
import com.ning.billing.entitlement.api.billing.BillingModeType;
import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
@@ -62,11 +62,38 @@ import static org.testng.Assert.assertNull;
@Test(groups = {"fast", "invoicing", "invoiceGenerator"})
public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
private final Clock clock = new DefaultClock();
+ private final InvoiceConfig invoiceConfig = new InvoiceConfig() {
+ @Override
+ public long getDaoClaimTimeMs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getDaoMaxReadyEvents() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getNotificationSleepTimeMs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEventProcessingOff() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getNumberOfMonthsInFuture() {
+ return 36;
+ }
+ };
+
private final InvoiceGenerator generator;
public DefaultInvoiceGeneratorTests() {
super();
- this.generator = new DefaultInvoiceGenerator(clock);
+ this.generator = new DefaultInvoiceGenerator(clock, invoiceConfig);
}
@Test
@@ -267,7 +294,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// plan 3: change of term from monthly (BCD = 20) to annual (BCD = 31; immediate)
// plan 4: change of plan, effective EOT, BCD = 7 (covers change of plan)
// plan 5: addon to plan 2, with bill cycle alignment to plan; immediate cancellation
-
+ UUID accountId = UUID.randomUUID();
UUID subscriptionId1 = UUID.randomUUID();
UUID subscriptionId2 = UUID.randomUUID();
UUID subscriptionId3 = UUID.randomUUID();
@@ -317,108 +344,108 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// on 1/5/2011, create subscription 1 (trial)
events.add(createBillingEvent(subscriptionId1, plan1StartDate, plan1, plan1Phase1, 5));
expectedAmount = EIGHT;
- testInvoiceGeneration(events, invoices, plan1StartDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan1StartDate, 1, expectedAmount);
// on 2/5/2011, invoice subscription 1 (trial)
expectedAmount = EIGHT;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 2, 5) , 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 2, 5) , 1, expectedAmount);
// on 3/5/2011, invoice subscription 1 (trial)
expectedAmount = EIGHT;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 3, 5), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 3, 5), 1, expectedAmount);
// on 3/10/2011, create subscription 2 (trial)
events.add(createBillingEvent(subscriptionId2, plan2StartDate, plan2, plan2Phase1, 10));
expectedAmount = TWENTY;
- testInvoiceGeneration(events, invoices, plan2StartDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan2StartDate, 1, expectedAmount);
// on 4/5/2011, invoice subscription 1 (discount)
events.add(createBillingEvent(subscriptionId1, plan1PhaseChangeDate, plan1, plan1Phase2, 5));
expectedAmount = TWELVE;
- testInvoiceGeneration(events, invoices, plan1PhaseChangeDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan1PhaseChangeDate, 1, expectedAmount);
// on 4/10/2011, invoice subscription 2 (trial)
expectedAmount = TWENTY;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 4, 10), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 4, 10), 1, expectedAmount);
// on 4/29/2011, cancel subscription 1
events.add(createBillingEvent(subscriptionId1, plan1CancelDate, plan1, plan1Phase3, 5));
expectedAmount = TWELVE.multiply(SIX.divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD)).negate().setScale(NUMBER_OF_DECIMALS);
- testInvoiceGeneration(events, invoices, plan1CancelDate, 2, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan1CancelDate, 2, expectedAmount);
// on 5/10/2011, invoice subscription 2 (trial)
expectedAmount = TWENTY;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 5, 10), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 5, 10), 1, expectedAmount);
// on 5/20/2011, create subscription 3 (monthly)
events.add(createBillingEvent(subscriptionId3, plan3StartDate, plan3, plan3Phase1, 20));
expectedAmount = TEN;
- testInvoiceGeneration(events, invoices, plan3StartDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan3StartDate, 1, expectedAmount);
// on 6/7/2011, create subscription 4
events.add(createBillingEvent(subscriptionId4, plan4StartDate, plan4a, plan4aPhase1, 7));
expectedAmount = FIFTEEN;
- testInvoiceGeneration(events, invoices, plan4StartDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan4StartDate, 1, expectedAmount);
// on 6/10/2011, invoice subscription 2 (discount)
events.add(createBillingEvent(subscriptionId2, plan2PhaseChangeToDiscountDate, plan2, plan2Phase2, 10));
expectedAmount = THIRTY;
- testInvoiceGeneration(events, invoices, plan2PhaseChangeToDiscountDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan2PhaseChangeToDiscountDate, 1, expectedAmount);
// on 6/20/2011, invoice subscription 3 (monthly)
expectedAmount = TEN;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 6, 20), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 6, 20), 1, expectedAmount);
// on 6/21/2011, create add-on (subscription 5)
events.add(createBillingEvent(subscriptionId5, plan5StartDate, plan5, plan5Phase1, 10));
expectedAmount = TWENTY.multiply(NINETEEN).divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD);
- testInvoiceGeneration(events, invoices, plan5StartDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan5StartDate, 1, expectedAmount);
// on 7/7/2011, invoice subscription 4 (plan 1)
expectedAmount = FIFTEEN;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 7, 7), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 7, 7), 1, expectedAmount);
// on 7/10/2011, invoice subscription 2 (discount), invoice subscription 5
expectedAmount = THIRTY.add(TWENTY);
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 7, 10), 2, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 7, 10), 2, expectedAmount);
// on 7/20/2011, invoice subscription 3 (monthly)
expectedAmount = TEN;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 7, 20), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 7, 20), 1, expectedAmount);
// on 7/31/2011, convert subscription 3 to annual
events.add(createBillingEvent(subscriptionId3, plan3UpgradeToAnnualDate, plan3, plan3Phase2, 31));
expectedAmount = ONE_HUNDRED.subtract(TEN);
expectedAmount = expectedAmount.add(TEN.multiply(ELEVEN.divide(THIRTY_ONE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD)));
expectedAmount = expectedAmount.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
- testInvoiceGeneration(events, invoices, plan3UpgradeToAnnualDate, 3, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan3UpgradeToAnnualDate, 3, expectedAmount);
// on 8/7/2011, invoice subscription 4 (plan 2)
events.add(createBillingEvent(subscriptionId4, plan4ChangeOfPlanDate, plan4b, plan4bPhase1, 7));
expectedAmount = TWENTY_FOUR;
- testInvoiceGeneration(events, invoices, plan4ChangeOfPlanDate, 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan4ChangeOfPlanDate, 1, expectedAmount);
// on 8/10/2011, invoice plan 2 (discount), invoice subscription 5
expectedAmount = THIRTY.add(TWENTY);
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 8, 10), 2, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 8, 10), 2, expectedAmount);
// on 9/7/2011, invoice subscription 4 (plan 2)
expectedAmount = TWENTY_FOUR;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 9, 7), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 9, 7), 1, expectedAmount);
// on 9/10/2011, invoice plan 2 (evergreen), invoice subscription 5
events.add(createBillingEvent(subscriptionId2, plan2PhaseChangeToEvergreenDate, plan2, plan2Phase3, 10));
expectedAmount = FORTY.add(TWENTY);
- testInvoiceGeneration(events, invoices, plan2PhaseChangeToEvergreenDate, 2, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan2PhaseChangeToEvergreenDate, 2, expectedAmount);
// on 10/7/2011, invoice subscription 4 (plan 2), cancel subscription 5
events.add(createBillingEvent(subscriptionId5, plan5CancelDate, plan5, plan5Phase2, 10));
expectedAmount = TWENTY_FOUR.add(TWENTY.multiply(THREE.divide(THIRTY)).negate().setScale(NUMBER_OF_DECIMALS));
- testInvoiceGeneration(events, invoices, plan5CancelDate, 3, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, plan5CancelDate, 3, expectedAmount);
// on 10/10/2011, invoice plan 2 (evergreen)
expectedAmount = FORTY ;
- testInvoiceGeneration(events, invoices, buildDateTime(2011, 10, 10), 1, expectedAmount);
+ testInvoiceGeneration(accountId, events, invoices, buildDateTime(2011, 10, 10), 1, expectedAmount);
}
@Test
@@ -671,11 +698,10 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
billCycleDay, BillingModeType.IN_ADVANCE, "Test", 1L, SubscriptionTransitionType.CREATE);
}
- private void testInvoiceGeneration(final BillingEventSet events, final List<Invoice> existingInvoices,
+ private void testInvoiceGeneration(final UUID accountId, final BillingEventSet events, final List<Invoice> existingInvoices,
final DateTime targetDate, final int expectedNumberOfItems,
final BigDecimal expectedAmount) throws InvoiceApiException {
Currency currency = Currency.USD;
- UUID accountId = UUID.randomUUID();
Invoice invoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, currency);
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
index c90bf69..4b47237 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
@@ -16,7 +16,6 @@
package com.ning.billing.invoice.tests;
-
import com.ning.billing.invoice.model.InvoicingConfiguration;
import org.joda.time.DateTime;
@@ -32,7 +31,7 @@ public abstract class InvoicingTestBase {
protected static final BigDecimal ONE_AND_A_HALF = new BigDecimal("1.5").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal TWO = new BigDecimal("2.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal THREE = new BigDecimal("3.0").setScale(NUMBER_OF_DECIMALS);
- protected static final BigDecimal FOUR = new BigDecimal("4.0").setScale(NUMBER_OF_DECIMALS);
+ //protected static final BigDecimal FOUR = new BigDecimal("4.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal FIVE = new BigDecimal("5.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal SIX = new BigDecimal("6.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal SEVEN = new BigDecimal("7.0").setScale(NUMBER_OF_DECIMALS);
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 63bc87e..c014b45 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -23,6 +23,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
+import com.ning.billing.util.callcontext.CallContext;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
@@ -48,6 +49,7 @@ public class DefaultPaymentApi implements PaymentApi {
private final PaymentDao paymentDao;
private final PaymentConfig config;
+
private static final Logger log = LoggerFactory.getLogger(DefaultPaymentApi.class);
@Inject
@@ -101,7 +103,7 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public Either<PaymentError, Void> updatePaymentGateway(String accountKey) {
+ public Either<PaymentError, Void> updatePaymentGateway(String accountKey, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
return plugin.updatePaymentGateway(accountKey);
}
@@ -113,31 +115,31 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public Either<PaymentError, String> addPaymentMethod(@Nullable String accountKey, PaymentMethodInfo paymentMethod) {
+ public Either<PaymentError, String> addPaymentMethod(@Nullable String accountKey, PaymentMethodInfo paymentMethod, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
return plugin.addPaymentMethod(accountKey, paymentMethod);
}
@Override
- public Either<PaymentError, Void> deletePaymentMethod(String accountKey, String paymentMethodId) {
+ public Either<PaymentError, Void> deletePaymentMethod(String accountKey, String paymentMethodId, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
return plugin.deletePaymentMethod(accountKey, paymentMethodId);
}
@Override
- public Either<PaymentError, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo) {
+ public Either<PaymentError, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
return plugin.updatePaymentMethod(accountKey, paymentMethodInfo);
}
@Override
- public List<Either<PaymentError, PaymentInfo>> createPayment(String accountKey, List<String> invoiceIds) {
+ public List<Either<PaymentError, PaymentInfo>> createPayment(String accountKey, List<String> invoiceIds, CallContext context) {
final Account account = accountUserApi.getAccountByKey(accountKey);
- return createPayment(account, invoiceIds);
+ return createPayment(account, invoiceIds, context);
}
@Override
- public Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId) {
+ public Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId, CallContext context) {
PaymentAttempt paymentAttempt = paymentDao.getPaymentAttemptById(paymentAttemptId);
if (paymentAttempt != null) {
@@ -159,8 +161,8 @@ public class DefaultPaymentApi implements PaymentApi {
.setPaymentAttemptId(UUID.randomUUID())
.build();
- paymentDao.createPaymentAttempt(newPaymentAttempt);
- return processPayment(getPaymentProviderPlugin(account), account, invoice, newPaymentAttempt);
+ paymentDao.createPaymentAttempt(newPaymentAttempt, context);
+ return processPayment(getPaymentProviderPlugin(account), account, invoice, newPaymentAttempt, context);
}
}
}
@@ -171,7 +173,7 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds) {
+ public List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
List<Either<PaymentError, PaymentInfo>> processedPaymentsOrErrors = new ArrayList<Either<PaymentError, PaymentInfo>>(invoiceIds.size());
@@ -197,16 +199,17 @@ public class DefaultPaymentApi implements PaymentApi {
processedPaymentsOrErrors.add(result);
}
else {
- PaymentAttempt paymentAttempt = paymentDao.createPaymentAttempt(invoice);
+ PaymentAttempt paymentAttempt = paymentDao.createPaymentAttempt(invoice, context);
- processedPaymentsOrErrors.add(processPayment(plugin, account, invoice, paymentAttempt));
+ processedPaymentsOrErrors.add(processPayment(plugin, account, invoice, paymentAttempt, context));
}
}
return processedPaymentsOrErrors;
}
- private Either<PaymentError, PaymentInfo> processPayment(PaymentProviderPlugin plugin, Account account, Invoice invoice, PaymentAttempt paymentAttempt) {
+ private Either<PaymentError, PaymentInfo> processPayment(PaymentProviderPlugin plugin, Account account, Invoice invoice,
+ PaymentAttempt paymentAttempt, CallContext context) {
Either<PaymentError, PaymentInfo> paymentOrError = plugin.processInvoice(account, invoice);
PaymentInfo paymentInfo = null;
@@ -218,7 +221,7 @@ public class DefaultPaymentApi implements PaymentApi {
}
else {
paymentInfo = paymentOrError.getRight();
- paymentDao.savePaymentInfo(paymentInfo);
+ paymentDao.savePaymentInfo(paymentInfo, context);
final String paymentMethodId = paymentInfo.getPaymentMethodId();
log.debug("Fetching payment method info for payment method id " + ((paymentMethodId == null) ? "null" : paymentMethodId));
@@ -229,18 +232,18 @@ public class DefaultPaymentApi implements PaymentApi {
if (paymentMethodInfo instanceof CreditCardPaymentMethodInfo) {
CreditCardPaymentMethodInfo ccPaymentMethod = (CreditCardPaymentMethodInfo)paymentMethodInfo;
- paymentDao.updatePaymentInfo(ccPaymentMethod.getType(), paymentInfo.getPaymentId(), ccPaymentMethod.getCardType(), ccPaymentMethod.getCardCountry());
+ paymentDao.updatePaymentInfo(ccPaymentMethod.getType(), paymentInfo.getPaymentId(), ccPaymentMethod.getCardType(), ccPaymentMethod.getCardCountry(), context);
}
else if (paymentMethodInfo instanceof PaypalPaymentMethodInfo) {
PaypalPaymentMethodInfo paypalPaymentMethodInfo = (PaypalPaymentMethodInfo)paymentMethodInfo;
- paymentDao.updatePaymentInfo(paypalPaymentMethodInfo.getType(), paymentInfo.getPaymentId(), null, null);
+ paymentDao.updatePaymentInfo(paypalPaymentMethodInfo.getType(), paymentInfo.getPaymentId(), null, null, context);
}
} else {
log.info(paymentMethodInfoOrError.getLeft().getMessage());
}
if (paymentInfo.getPaymentId() != null) {
- paymentDao.updatePaymentAttemptWithPaymentId(paymentAttempt.getPaymentAttemptId(), paymentInfo.getPaymentId());
+ paymentDao.updatePaymentAttemptWithPaymentId(paymentAttempt.getPaymentAttemptId(), paymentInfo.getPaymentId(), context);
}
}
@@ -249,7 +252,8 @@ public class DefaultPaymentApi implements PaymentApi {
paymentAttempt.getPaymentAttemptDate(),
paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : paymentInfo.getAmount(),
// paymentInfo.getRefundAmount(), TODO
- paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : invoice.getCurrency()));
+ paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : invoice.getCurrency()),
+ context);
return paymentOrError;
}
@@ -286,13 +290,13 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public Either<PaymentError, String> createPaymentProviderAccount(Account account) {
+ public Either<PaymentError, String> createPaymentProviderAccount(Account account, CallContext context) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin((Account)null);
return plugin.createPaymentProviderAccount(account);
}
@Override
- public Either<PaymentError, Void> updatePaymentProviderAccountContact(String externalKey) {
+ public Either<PaymentError, Void> updatePaymentProviderAccountContact(String externalKey, CallContext context) {
Account account = accountUserApi.getAccountByKey(externalKey);
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
return plugin.updatePaymentProviderAccountExistingContact(account);
@@ -304,7 +308,7 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public List<Either<PaymentError, PaymentInfo>> createRefund(Account account, List<String> invoiceIds) {
+ public List<Either<PaymentError, PaymentInfo>> createRefund(Account account, List<String> invoiceIds, CallContext context) {
//TODO
throw new UnsupportedOperationException();
}
@@ -315,8 +319,8 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
- return paymentDao.getPaymentAttemptForInvoiceId(invoiceId);
+ public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId) {
+ return paymentDao.getPaymentAttemptsForInvoiceId(invoiceId);
}
@Override
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
new file mode 100644
index 0000000..38e95d6
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
@@ -0,0 +1,171 @@
+/*
+ * 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.payment.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import com.ning.billing.util.ChangeType;
+import com.ning.billing.util.audit.dao.AuditSqlDao;
+import com.ning.billing.util.callcontext.CallContext;
+import org.apache.commons.lang.Validate;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentInfo;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+
+public class AuditedPaymentDao implements PaymentDao {
+ private final PaymentSqlDao sqlDao;
+
+ @Inject
+ public AuditedPaymentDao(IDBI dbi) {
+ this.sqlDao = dbi.onDemand(PaymentSqlDao.class);
+ }
+
+ @Override
+ public PaymentAttempt getPaymentAttemptForPaymentId(String paymentId) {
+ return sqlDao.getPaymentAttemptForPaymentId(paymentId);
+ }
+
+ @Override
+ public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId) {
+ return sqlDao.getPaymentAttemptsForInvoiceId(invoiceId);
+ }
+
+ @Override
+ public PaymentAttempt createPaymentAttempt(final PaymentAttempt paymentAttempt, final CallContext context) {
+ return sqlDao.inTransaction(new Transaction<PaymentAttempt, PaymentSqlDao>() {
+ @Override
+ public PaymentAttempt inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
+ transactional.insertPaymentAttempt(paymentAttempt, context);
+ PaymentAttempt savedPaymentAttempt = transactional.getPaymentAttemptById(paymentAttempt.getPaymentAttemptId().toString());
+ UUID historyRecordId = UUID.randomUUID();
+ transactional.insertPaymentAttemptHistory(historyRecordId.toString(), paymentAttempt, context);
+ AuditSqlDao auditSqlDao = transactional.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("payment_attempt", historyRecordId.toString(),
+ ChangeType.INSERT.toString(), context);
+ return savedPaymentAttempt;
+ }
+ });
+ }
+
+ @Override
+ public PaymentAttempt createPaymentAttempt(final Invoice invoice, final CallContext context) {
+ return sqlDao.inTransaction(new Transaction<PaymentAttempt, PaymentSqlDao>() {
+ @Override
+ public PaymentAttempt inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
+ final PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+ transactional.insertPaymentAttempt(paymentAttempt, context);
+ UUID historyRecordId = UUID.randomUUID();
+ transactional.insertPaymentAttemptHistory(historyRecordId.toString(), paymentAttempt, context);
+ AuditSqlDao auditSqlDao = transactional.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("payment_attempt", historyRecordId.toString(),
+ ChangeType.INSERT.toString(), context);
+
+ return paymentAttempt;
+ }
+ });
+ }
+
+ @Override
+ public void savePaymentInfo(final PaymentInfo info, final CallContext context) {
+ sqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
+ @Override
+ public Void inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
+ transactional.insertPaymentInfo(info, context);
+ UUID historyRecordId = UUID.randomUUID();
+ transactional.insertPaymentInfoHistory(historyRecordId.toString(), info, context);
+ AuditSqlDao auditSqlDao = transactional.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("payment", historyRecordId.toString(),
+ ChangeType.INSERT.toString(), context);
+
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void updatePaymentAttemptWithPaymentId(final UUID paymentAttemptId, final String paymentId, final CallContext context) {
+ sqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
+ @Override
+ public Void inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
+ transactional.updatePaymentAttemptWithPaymentId(paymentAttemptId.toString(), paymentId, context);
+ PaymentAttempt paymentAttempt = transactional.getPaymentAttemptById(paymentAttemptId.toString());
+ UUID historyRecordId = UUID.randomUUID();
+ transactional.insertPaymentAttemptHistory(historyRecordId.toString(), paymentAttempt, context);
+ AuditSqlDao auditSqlDao = transactional.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("payment_attempt", historyRecordId.toString(),
+ ChangeType.UPDATE.toString(), context);
+
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void updatePaymentInfo(final String type, final String paymentId, final String cardType,
+ final String cardCountry, final CallContext context) {
+ sqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
+ @Override
+ public Void inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
+ transactional.updatePaymentInfo(type, paymentId, cardType, cardCountry, context);
+ PaymentInfo paymentInfo = transactional.getPaymentInfo(paymentId.toString());
+ UUID historyRecordId = UUID.randomUUID();
+ transactional.insertPaymentInfoHistory(historyRecordId.toString(), paymentInfo, context);
+ AuditSqlDao auditSqlDao = transactional.become(AuditSqlDao.class);
+ auditSqlDao.insertAuditFromTransaction("payments", historyRecordId.toString(),
+ ChangeType.UPDATE.toString(), context);
+
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public List<PaymentInfo> getPaymentInfo(List<String> invoiceIds) {
+ if (invoiceIds == null || invoiceIds.size() == 0) {
+ return ImmutableList.<PaymentInfo>of();
+ } else {
+ return sqlDao.getPaymentInfos(invoiceIds);
+ }
+ }
+
+ @Override
+ public List<PaymentAttempt> getPaymentAttemptsForInvoiceIds(List<String> invoiceIds) {
+ if (invoiceIds == null || invoiceIds.size() == 0) {
+ return ImmutableList.<PaymentAttempt>of();
+ } else {
+ return sqlDao.getPaymentAttemptsForInvoiceIds(invoiceIds);
+ }
+ }
+
+ @Override
+ public PaymentAttempt getPaymentAttemptById(UUID paymentAttemptId) {
+ return sqlDao.getPaymentAttemptById(paymentAttemptId.toString());
+ }
+
+ @Override
+ public PaymentInfo getPaymentInfoForPaymentAttemptId(String paymentAttemptIdStr) {
+ return sqlDao.getPaymentInfoForPaymentAttemptId(paymentAttemptIdStr);
+ }
+
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
index 2c9ee06..ce6adf6 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
@@ -22,22 +22,23 @@ import java.util.UUID;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfo;
+import com.ning.billing.util.callcontext.CallContext;
public interface PaymentDao {
- PaymentAttempt createPaymentAttempt(Invoice invoice);
- PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt);
+ PaymentAttempt createPaymentAttempt(Invoice invoice, CallContext context);
+ PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, CallContext context);
- void savePaymentInfo(PaymentInfo right);
+ void savePaymentInfo(PaymentInfo right, CallContext context);
PaymentAttempt getPaymentAttemptForPaymentId(String paymentId);
List<PaymentAttempt> getPaymentAttemptsForInvoiceIds(List<String> invoiceIds);
- void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId);
+ void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId, CallContext context);
- PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId);
+ List<PaymentAttempt> getPaymentAttemptsForInvoiceId(String invoiceId);
- void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry);
+ void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry, CallContext context);
List<PaymentInfo> getPaymentInfo(List<String> invoiceIds);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index 69117fb..245a971 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -24,6 +24,10 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
@@ -33,6 +37,7 @@ import org.skife.jdbi.v2.sqlobject.Binder;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
@@ -45,60 +50,65 @@ import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfo;
@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper({PaymentSqlDao.PaymentAttemptMapper.class, PaymentSqlDao.PaymentInfoMapper.class})
public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Transmogrifier {
@SqlUpdate
- void insertPaymentAttempt(@Bind(binder = PaymentAttemptBinder.class) PaymentAttempt paymentAttempt);
+ void insertPaymentAttempt(@Bind(binder = PaymentAttemptBinder.class) PaymentAttempt paymentAttempt,
+ @CallContextBinder CallContext context);
+
+ @SqlUpdate
+ void insertPaymentAttemptHistory(@Bind("historyRecordId") final String historyRecordId,
+ @Bind(binder = PaymentAttemptBinder.class) final PaymentAttempt paymentAttempt,
+ @CallContextBinder final CallContext context);
@SqlQuery
- @Mapper(PaymentAttemptMapper.class)
PaymentAttempt getPaymentAttemptForPaymentId(@Bind("payment_id") String paymentId);
@SqlQuery
- @Mapper(PaymentAttemptMapper.class)
PaymentAttempt getPaymentAttemptById(@Bind("payment_attempt_id") String paymentAttemptId);
@SqlQuery
- @Mapper(PaymentAttemptMapper.class)
- PaymentAttempt getPaymentAttemptForInvoiceId(@Bind("invoice_id") String invoiceId);
+ List<PaymentAttempt> getPaymentAttemptsForInvoiceId(@Bind("invoice_id") String invoiceId);
@SqlQuery
- @Mapper(PaymentAttemptMapper.class)
List<PaymentAttempt> getPaymentAttemptsForInvoiceIds(@BindIn("invoiceIds") List<String> invoiceIds);
@SqlQuery
- @Mapper(PaymentInfoMapper.class)
PaymentInfo getPaymentInfoForPaymentAttemptId(@Bind("payment_attempt_id") String paymentAttemptId);
@SqlUpdate
void updatePaymentAttemptWithPaymentId(@Bind("payment_attempt_id") String paymentAttemptId,
@Bind("payment_id") String paymentId,
- @Bind("updated_dt") Date updatedDate);
+ @CallContextBinder CallContext context);
@SqlUpdate
void updatePaymentAttemptWithRetryInfo(@Bind("payment_attempt_id") String paymentAttemptId,
@Bind("retry_count") int retryCount,
- @Bind("updated_dt") Date updatedDate);
+ @CallContextBinder CallContext context);
@SqlUpdate
void updatePaymentInfo(@Bind("payment_method") String paymentMethod,
@Bind("payment_id") String paymentId,
@Bind("card_type") String cardType,
@Bind("card_country") String cardCountry,
- @Bind("updated_dt") Date updatedDate);
+ @CallContextBinder CallContext context);
@SqlQuery
- @Mapper(PaymentInfoMapper.class)
- List<PaymentInfo> getPaymentInfos(@BindIn("invoiceIds") List<String> invoiceIds);
+ List<PaymentInfo> getPaymentInfos(@BindIn("invoiceIds") final List<String> invoiceIds);
@SqlUpdate
- void insertPaymentInfo(@Bind(binder = PaymentInfoBinder.class) PaymentInfo paymentInfo);
+ void insertPaymentInfo(@Bind(binder = PaymentInfoBinder.class) final PaymentInfo paymentInfo,
+ @CallContextBinder final CallContext context);
- public static final class PaymentAttemptBinder implements Binder<Bind, PaymentAttempt> {
+ @SqlUpdate
+ void insertPaymentInfoHistory(@Bind("historyRecordId") final String historyRecordId,
+ @Bind(binder = PaymentInfoBinder.class) final PaymentInfo paymentInfo,
+ @CallContextBinder final CallContext context);
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
+ @SqlQuery
+ PaymentInfo getPaymentInfo(@Bind("paymentId") final String paymentId);
+ public static final class PaymentAttemptBinder extends BinderBase implements Binder<Bind, PaymentAttempt> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentAttempt paymentAttempt) {
stmt.bind("payment_attempt_id", paymentAttempt.getPaymentAttemptId().toString());
@@ -115,13 +125,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
}
}
- public static class PaymentAttemptMapper implements ResultSetMapper<PaymentAttempt> {
-
- private DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
- final Timestamp resultStamp = rs.getTimestamp(fieldName);
- return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class PaymentAttemptMapper extends MapperBase implements ResultSetMapper<PaymentAttempt> {
@Override
public PaymentAttempt map(int index, ResultSet rs, StatementContext ctx) throws SQLException {
@@ -151,12 +155,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
}
}
- public static final class PaymentInfoBinder implements Binder<Bind, PaymentInfo> {
-
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
+ public static final class PaymentInfoBinder extends BinderBase implements Binder<Bind, PaymentInfo> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentInfo paymentInfo) {
stmt.bind("payment_id", paymentInfo.getPaymentId().toString());
@@ -177,13 +176,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
}
}
- public static class PaymentInfoMapper implements ResultSetMapper<PaymentInfo> {
-
- private DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
- final Timestamp resultStamp = rs.getTimestamp(fieldName);
- return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class PaymentInfoMapper extends MapperBase implements ResultSetMapper<PaymentInfo> {
@Override
public PaymentInfo map(int index, ResultSet rs, StatementContext ctx) throws SQLException {
diff --git a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
index d53c236..e8034a1 100644
--- a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
@@ -19,6 +19,11 @@ package com.ning.billing.payment;
import java.util.Arrays;
import java.util.List;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,14 +45,17 @@ public class RequestProcessor {
private final AccountUserApi accountUserApi;
private final PaymentApi paymentApi;
private final Bus eventBus;
+ private final Clock clock;
private static final Logger log = LoggerFactory.getLogger(RequestProcessor.class);
@Inject
- public RequestProcessor(AccountUserApi accountUserApi,
+ public RequestProcessor(Clock clock,
+ AccountUserApi accountUserApi,
PaymentApi paymentApi,
PaymentProviderPluginRegistry pluginRegistry,
Bus eventBus) {
+ this.clock = clock;
this.accountUserApi = accountUserApi;
this.paymentApi = paymentApi;
this.eventBus = eventBus;
@@ -63,7 +71,8 @@ public class RequestProcessor {
log.info("could not process invoice payment: could not find a valid account for event {}", event);
}
else {
- List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account, Arrays.asList(event.getInvoiceId().toString()));
+ CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
+ List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account, Arrays.asList(event.getInvoiceId().toString()), context);
if (!results.isEmpty()) {
Either<PaymentError, PaymentInfo> result = results.get(0);
eventBus.post(result.isLeft() ? result.getLeft() : result.getRight());
diff --git a/payment/src/main/java/com/ning/billing/payment/RetryService.java b/payment/src/main/java/com/ning/billing/payment/RetryService.java
index 927df3f..d03b241 100644
--- a/payment/src/main/java/com/ning/billing/payment/RetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/RetryService.java
@@ -18,6 +18,11 @@ package com.ning.billing.payment;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
import org.joda.time.DateTime;
import com.google.inject.Inject;
@@ -39,15 +44,18 @@ public class RetryService implements KillbillService {
public static final String SERVICE_NAME = "retry-service";
public static final String QUEUE_NAME = "retry-events";
+ private final Clock clock;
private final NotificationQueueService notificationQueueService;
private final PaymentConfig config;
private final PaymentApi paymentApi;
private NotificationQueue retryQueue;
@Inject
- public RetryService(NotificationQueueService notificationQueueService,
+ public RetryService(Clock clock,
+ NotificationQueueService notificationQueueService,
PaymentConfig config,
PaymentApi paymentApi) {
+ this.clock = clock;
this.notificationQueueService = notificationQueueService;
this.paymentApi = paymentApi;
this.config = config;
@@ -63,7 +71,8 @@ public class RetryService implements KillbillService {
retryQueue = notificationQueueService.createNotificationQueue(SERVICE_NAME, QUEUE_NAME, new NotificationQueueHandler() {
@Override
public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
- retry(notificationKey);
+ CallContext context = new DefaultCallContext("RetryService", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
+ retry(notificationKey, context);
}
},
config);
@@ -93,7 +102,7 @@ public class RetryService implements KillbillService {
retryQueue.recordFutureNotification(timeOfRetry, key);
}
- private void retry(String paymentAttemptId) {
+ private void retry(String paymentAttemptId, CallContext context) {
PaymentInfo paymentInfo = paymentApi.getPaymentInfoForPaymentAttemptId(paymentAttemptId);
if (paymentInfo != null && PaymentStatus.Processed.equals(PaymentStatus.valueOf(paymentInfo.getStatus()))) {
@@ -102,7 +111,7 @@ public class RetryService implements KillbillService {
}
else {
System.out.println("Creating payment for payment attempt " + paymentAttemptId);
- paymentApi.createPaymentForPaymentAttempt(UUID.fromString(paymentAttemptId));
+ paymentApi.createPaymentForPaymentAttempt(UUID.fromString(paymentAttemptId), context);
}
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
index d3d9320..0c769fd 100644
--- a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
@@ -26,7 +26,7 @@ import com.ning.billing.payment.RetryService;
import com.ning.billing.payment.api.DefaultPaymentApi;
import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentService;
-import com.ning.billing.payment.dao.DefaultPaymentDao;
+import com.ning.billing.payment.dao.AuditedPaymentDao;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
@@ -42,7 +42,7 @@ public class PaymentModule extends AbstractModule {
}
protected void installPaymentDao() {
- bind(PaymentDao.class).to(DefaultPaymentDao.class).asEagerSingleton();
+ bind(PaymentDao.class).to(AuditedPaymentDao.class).asEagerSingleton();
}
protected void installPaymentProviderPlugins(PaymentConfig config) {
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
index 91eeb22..87c8d8f 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -10,7 +10,9 @@ paymentAttemptFields(prefix) ::= <<
<prefix>payment_attempt_dt,
<prefix>invoice_dt,
<prefix>retry_count,
+ <prefix>created_by,
<prefix>created_dt,
+ <prefix>updated_by,
<prefix>updated_dt
>>
@@ -28,13 +30,22 @@ paymentInfoFields(prefix) ::= <<
<prefix>card_type,
<prefix>card_country,
<prefix>effective_dt,
+ <prefix>created_by,
<prefix>created_dt,
+ <prefix>updated_by,
<prefix>updated_dt
>>
insertPaymentAttempt() ::= <<
INSERT INTO payment_attempts (<paymentAttemptFields()>)
- VALUES (:payment_attempt_id, :invoice_id, :account_id, :amount, :currency, :payment_id, :payment_attempt_dt, :invoice_dt, :retry_count, :created_dt, :updated_dt);
+ VALUES (:payment_attempt_id, :invoice_id, :account_id, :amount, :currency, :payment_id,
+ :payment_attempt_dt, :invoice_dt, :retry_count, :userName, :createdDate, :userName, :createdDate);
+>>
+
+insertPaymentAttemptHistory() ::= <<
+ INSERT INTO payment_attempt_history (history_record_id, <paymentAttemptFields()>)
+ VALUES (:historyRecordId, :payment_attempt_id, :invoice_id, :account_id, :amount, :currency, :payment_id,
+ :payment_attempt_dt, :invoice_dt, :retry_count, :userName, :createdDate, :userName, :createdDate);
>>
getPaymentAttemptForPaymentId() ::= <<
@@ -55,7 +66,7 @@ getPaymentAttemptsForInvoiceIds(invoiceIds) ::= <<
WHERE invoice_id in (<invoiceIds>)
>>
-getPaymentAttemptForInvoiceId() ::= <<
+getPaymentAttemptsForInvoiceId() ::= <<
SELECT <paymentAttemptFields()>
FROM payment_attempts
WHERE invoice_id = :invoice_id
@@ -64,13 +75,23 @@ getPaymentAttemptForInvoiceId() ::= <<
updatePaymentAttemptWithPaymentId() ::= <<
UPDATE payment_attempts
SET payment_id = :payment_id,
- updated_dt = :updated_dt
+ updated_by = :userName,
+ updated_dt = :updatedDate
WHERE payment_attempt_id = :payment_attempt_id
>>
insertPaymentInfo() ::= <<
INSERT INTO payments (<paymentInfoFields()>)
- VALUES (:payment_id, :amount, :refund_amount, :bank_identification_number, :payment_number, :payment_type, :status, :reference_id, :payment_method_id, :payment_method, :card_type, :card_country, :effective_dt, :created_dt, :updated_dt);
+ VALUES (:payment_id, :amount, :refund_amount, :bank_identification_number, :payment_number,
+ :payment_type, :status, :reference_id, :payment_method_id, :payment_method, :card_type,
+ :card_country, :effective_dt, :userName, :createdDate, :userName, :createdDate);
+>>
+
+insertPaymentInfoHistory() ::= <<
+ INSERT INTO payment_history (history_record_id, <paymentInfoFields()>)
+ VALUES (:historyRecordId, :payment_id, :amount, :refund_amount, :bank_identification_number, :payment_number,
+ :payment_type, :status, :reference_id, :payment_method_id, :payment_method, :card_type,
+ :card_country, :effective_dt, :userName, :createdDate, :userName, :createdDate);
>>
updatePaymentInfo() ::= <<
@@ -78,7 +99,8 @@ updatePaymentInfo() ::= <<
SET payment_method = :payment_method,
card_type = :card_type,
card_country = :card_country,
- updated_dt = :updated_dt
+ updated_by = :userName,
+ updated_dt = :updatedDate
WHERE payment_id = :payment_id
>>
@@ -95,3 +117,9 @@ getPaymentInfoForPaymentAttemptId() ::= <<
WHERE pa.payment_attempt_id = :payment_attempt_id
AND pa.payment_id = p.payment_id
>>
+
+getPaymentInfo() ::= <<
+ SELECT <paymentInfoFields()>
+ FROM payments
+ WHERE payment_id = :paymentId
+>>
diff --git a/payment/src/main/resources/com/ning/billing/payment/ddl.sql b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
index 3d0cc1a..3a344f9 100644
--- a/payment/src/main/resources/com/ning/billing/payment/ddl.sql
+++ b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
@@ -9,11 +9,32 @@ CREATE TABLE payment_attempts (
payment_id varchar(36) COLLATE utf8_bin,
retry_count tinyint,
invoice_dt datetime NOT NULL,
+ created_by varchar(50) NOT NULL,
created_dt datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
updated_dt datetime NOT NULL,
PRIMARY KEY (payment_attempt_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+DROP TABLE IF EXISTS payment_attempt_history;
+CREATE TABLE payment_attempt_history (
+ history_record_id char(36) NOT NULL,
+ payment_attempt_id char(36) COLLATE utf8_bin NOT NULL,
+ account_id char(36) COLLATE utf8_bin NOT NULL,
+ invoice_id char(36) COLLATE utf8_bin NOT NULL,
+ amount decimal(8,2),
+ currency char(3),
+ payment_attempt_dt datetime NOT NULL,
+ payment_id varchar(36) COLLATE utf8_bin,
+ retry_count tinyint,
+ invoice_dt datetime NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_dt datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_dt datetime NOT NULL,
+ PRIMARY KEY (history_record_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
DROP TABLE IF EXISTS payments;
CREATE TABLE payments (
payment_id varchar(36) COLLATE utf8_bin NOT NULL,
@@ -29,7 +50,32 @@ CREATE TABLE payments (
card_type varchar(20) COLLATE utf8_bin,
card_country varchar(50) COLLATE utf8_bin,
effective_dt datetime,
+ created_by varchar(50) NOT NULL,
created_dt datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
updated_dt datetime NOT NULL,
PRIMARY KEY (payment_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+DROP TABLE IF EXISTS payment_history;
+CREATE TABLE payment_history (
+ history_record_id char(36) NOT NULL,
+ payment_id varchar(36) COLLATE utf8_bin NOT NULL,
+ amount decimal(8,2),
+ refund_amount decimal(8,2),
+ payment_number varchar(36) COLLATE utf8_bin,
+ bank_identification_number varchar(36) COLLATE utf8_bin,
+ status varchar(20) COLLATE utf8_bin,
+ reference_id varchar(36) COLLATE utf8_bin,
+ payment_type varchar(20) COLLATE utf8_bin,
+ payment_method_id varchar(36) COLLATE utf8_bin,
+ payment_method varchar(20) COLLATE utf8_bin,
+ card_type varchar(20) COLLATE utf8_bin,
+ card_country varchar(50) COLLATE utf8_bin,
+ effective_dt datetime,
+ created_by varchar(50) NOT NULL,
+ created_dt datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_dt datetime NOT NULL,
+ PRIMARY KEY (history_record_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestMockPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestMockPaymentApi.java
index b9f761a..7c005ee 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestMockPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestMockPaymentApi.java
@@ -16,6 +16,8 @@
package com.ning.billing.payment.api;
+import com.google.inject.Inject;
+import com.ning.billing.util.clock.Clock;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -26,5 +28,8 @@ import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
@Guice(modules = { PaymentTestModuleWithMocks.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class })
@Test(groups = "fast")
public class TestMockPaymentApi extends TestPaymentApi {
-
+ @Inject
+ public TestMockPaymentApi(Clock clock) {
+ super(clock);
+ }
}
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index ad42504..d85589b 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -43,6 +43,11 @@ import com.ning.billing.invoice.model.RecurringInvoiceItem;
import com.ning.billing.payment.TestHelper;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.entity.EntityPersistenceException;
public abstract class TestPaymentApi {
@@ -53,6 +58,13 @@ public abstract class TestPaymentApi {
@Inject
protected TestHelper testHelper;
+ protected CallContext context;
+
+ @Inject
+ public TestPaymentApi(Clock clock) {
+ context = new DefaultCallContext("Payment Tests", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
+ }
+
@BeforeMethod(alwaysRun = true)
public void setUp() throws EventBusException {
eventBus.start();
@@ -72,7 +84,7 @@ public abstract class TestPaymentApi {
final UUID subscriptionId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
- invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(), account.getId(),
subscriptionId,
bundleId,
"test plan", "test phase",
@@ -80,10 +92,9 @@ public abstract class TestPaymentApi {
now.plusMonths(1),
amount,
new BigDecimal("1.0"),
- Currency.USD,
- now));
+ Currency.USD));
- List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()));
+ List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()), context);
assertEquals(results.size(), 1);
assertTrue(results.get(0).isRight());
@@ -121,14 +132,14 @@ public abstract class TestPaymentApi {
assertEquals(paymentInfo.getPaymentMethodId(), paymentInfoFromGet.getPaymentMethodId());
assertEquals(paymentInfo.getEffectiveDate(), paymentInfoFromGet.getEffectiveDate());
- PaymentAttempt paymentAttemptFromGet = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
- assertEquals(paymentAttempt, paymentAttemptFromGet);
+ List<PaymentAttempt> paymentAttemptsFromGet = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
+ assertEquals(paymentAttempt, paymentAttemptsFromGet.get(0));
}
private PaymentProviderAccount setupAccountWithPaypalPaymentMethod() throws AccountApiException, EntityPersistenceException {
final Account account = testHelper.createTestPayPalAccount();
- paymentApi.createPaymentProviderAccount(account);
+ paymentApi.createPaymentProviderAccount(account, context);
String accountKey = account.getExternalKey();
@@ -137,7 +148,7 @@ public abstract class TestPaymentApi {
.setEmail(account.getEmail())
.setDefaultMethod(true)
.build();
- Either<PaymentError, String> paymentMethodIdOrError = paymentApi.addPaymentMethod(accountKey, paymentMethod);
+ Either<PaymentError, String> paymentMethodIdOrError = paymentApi.addPaymentMethod(accountKey, paymentMethod, context);
assertTrue(paymentMethodIdOrError.isRight());
assertNotNull(paymentMethodIdOrError.getRight());
@@ -164,7 +175,7 @@ public abstract class TestPaymentApi {
@Test(enabled=true)
public void testUpdatePaymentProviderAccountContact() throws AccountApiException, EntityPersistenceException {
final Account account = testHelper.createTestPayPalAccount();
- paymentApi.createPaymentProviderAccount(account);
+ paymentApi.createPaymentProviderAccount(account, context);
String newName = "Tester " + RandomStringUtils.randomAlphanumeric(10);
String newNumber = "888-888-" + RandomStringUtils.randomNumeric(4);
@@ -179,7 +190,7 @@ public abstract class TestPaymentApi {
.billingCycleDay(account.getBillCycleDay())
.build();
- Either<PaymentError, Void> voidOrError = paymentApi.updatePaymentProviderAccountContact(accountToUpdate.getExternalKey());
+ Either<PaymentError, Void> voidOrError = paymentApi.updatePaymentProviderAccountContact(accountToUpdate.getExternalKey(), context);
assertTrue(voidOrError.isRight());
}
@@ -187,7 +198,7 @@ public abstract class TestPaymentApi {
public void testCannotDeleteDefaultPaymentMethod() throws AccountApiException, EntityPersistenceException {
PaymentProviderAccount account = setupAccountWithPaypalPaymentMethod();
- Either<PaymentError, Void> errorOrVoid = paymentApi.deletePaymentMethod(account.getAccountKey(), account.getDefaultPaymentMethodId());
+ Either<PaymentError, Void> errorOrVoid = paymentApi.deletePaymentMethod(account.getAccountKey(), account.getDefaultPaymentMethodId(), context);
assertTrue(errorOrVoid.isLeft());
}
@@ -195,19 +206,19 @@ public abstract class TestPaymentApi {
@Test(enabled=true)
public void testDeleteNonDefaultPaymentMethod() throws AccountApiException, EntityPersistenceException {
final Account account = testHelper.createTestPayPalAccount();
- paymentApi.createPaymentProviderAccount(account);
+ paymentApi.createPaymentProviderAccount(account, context);
String accountKey = account.getExternalKey();
PaypalPaymentMethodInfo paymentMethod1 = new PaypalPaymentMethodInfo.Builder().setDefaultMethod(false).setBaid("12345").setEmail(account.getEmail()).build();
- Either<PaymentError, String> paymentMethodIdOrError1 = paymentApi.addPaymentMethod(accountKey, paymentMethod1);
+ Either<PaymentError, String> paymentMethodIdOrError1 = paymentApi.addPaymentMethod(accountKey, paymentMethod1, context);
assertTrue(paymentMethodIdOrError1.isRight());
assertNotNull(paymentMethodIdOrError1.getRight());
PaypalPaymentMethodInfo paymentMethod2 = new PaypalPaymentMethodInfo.Builder().setDefaultMethod(true).setBaid("12345").setEmail(account.getEmail()).build();
- Either<PaymentError, String> paymentMethodIdOrError2 = paymentApi.addPaymentMethod(accountKey, paymentMethod2);
+ Either<PaymentError, String> paymentMethodIdOrError2 = paymentApi.addPaymentMethod(accountKey, paymentMethod2, context);
assertTrue(paymentMethodIdOrError2.isRight());
assertNotNull(paymentMethodIdOrError2.getRight());
@@ -216,8 +227,8 @@ public abstract class TestPaymentApi {
assertTrue(paymentMethodsOrError.isRight());
- Either<PaymentError, Void> errorOrVoid1 = paymentApi.deletePaymentMethod(accountKey, paymentMethodIdOrError1.getRight());
- Either<PaymentError, Void> errorOrVoid2 = paymentApi.deletePaymentMethod(accountKey, paymentMethodIdOrError2.getRight());
+ Either<PaymentError, Void> errorOrVoid1 = paymentApi.deletePaymentMethod(accountKey, paymentMethodIdOrError1.getRight(), context);
+ Either<PaymentError, Void> errorOrVoid2 = paymentApi.deletePaymentMethod(accountKey, paymentMethodIdOrError2.getRight(), context);
assertTrue(errorOrVoid1.isRight());
assertTrue(errorOrVoid2.isLeft());
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
index b4bfb51..7c8239f 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
@@ -17,13 +17,14 @@
package com.ning.billing.payment.dao;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
+import com.ning.billing.util.callcontext.CallContext;
+import org.apache.commons.collections.CollectionUtils;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
@@ -46,25 +47,35 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttempt createPaymentAttempt(Invoice invoice) {
- PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
- paymentAttempts.put(paymentAttempt.getPaymentAttemptId(), paymentAttempt);
- return paymentAttempt;
+ public PaymentAttempt createPaymentAttempt(Invoice invoice, CallContext context) {
+ PaymentAttempt updatedPaymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice.getId(), invoice.getAccountId(),
+ invoice.getBalance(), invoice.getCurrency(), invoice.getInvoiceDate(),
+ null, null, null, context.getCreatedDate(), context.getUpdatedDate());
+
+ paymentAttempts.put(updatedPaymentAttempt.getPaymentAttemptId(), updatedPaymentAttempt);
+ return updatedPaymentAttempt;
}
@Override
- public PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt) {
- paymentAttempts.put(paymentAttempt.getPaymentAttemptId(), paymentAttempt);
- return paymentAttempt;
+ public PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, CallContext context) {
+ PaymentAttempt updatedPaymentAttempt = new PaymentAttempt(paymentAttempt.getPaymentAttemptId(),
+ paymentAttempt.getInvoiceId(),
+ paymentAttempt.getAccountId(), paymentAttempt.getAmount(), paymentAttempt.getCurrency(),
+ paymentAttempt.getInvoiceDate(), paymentAttempt.getPaymentAttemptDate(),
+ paymentAttempt.getPaymentId(), paymentAttempt.getRetryCount(),
+ context.getCreatedDate(), context.getUpdatedDate());
+
+ paymentAttempts.put(updatedPaymentAttempt.getPaymentAttemptId(), updatedPaymentAttempt);
+ return updatedPaymentAttempt;
}
@Override
- public void savePaymentInfo(PaymentInfo paymentInfo) {
+ public void savePaymentInfo(PaymentInfo paymentInfo, CallContext context) {
payments.put(paymentInfo.getPaymentId(), paymentInfo);
}
@Override
- public void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId) {
+ public void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId, CallContext context) {
PaymentAttempt existingPaymentAttempt = paymentAttempts.get(paymentAttemptId);
if (existingPaymentAttempt != null) {
@@ -74,25 +85,25 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
- for (PaymentAttempt paymentAttempt : paymentAttempts.values()) {
- if (invoiceId.equals(paymentAttempt.getInvoiceId().toString())) {
- return paymentAttempt;
- }
- }
- return null;
+ public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(final String invoiceId) {
+ Collection<PaymentAttempt> attempts = Collections2.filter(paymentAttempts.values(), new Predicate<PaymentAttempt>() {
+ @Override
+ public boolean apply(PaymentAttempt input) {
+ return invoiceId.equals(input.getInvoiceId().toString());
+ }
+ });
+ return new ArrayList<PaymentAttempt>(attempts);
}
@Override
- public void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry) {
+ public void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry, CallContext context) {
PaymentInfo existingPayment = payments.get(paymentId);
if (existingPayment != null) {
PaymentInfo payment = existingPayment.cloner()
.setPaymentMethod(paymentMethodType)
.setCardType(cardType)
.setCardCountry(cardCountry)
- // TODO pass the clock?
- .setUpdatedDate(new DateTime(DateTimeZone.UTC))
+ .setUpdatedDate(context.getUpdatedDate())
.build();
payments.put(paymentId, payment);
}
@@ -118,9 +129,9 @@ public class MockPaymentDao implements PaymentDao {
public List<PaymentAttempt> getPaymentAttemptsForInvoiceIds(List<String> invoiceIds) {
List<PaymentAttempt> paymentAttempts = new ArrayList<PaymentAttempt>(invoiceIds.size());
for (String invoiceId : invoiceIds) {
- PaymentAttempt attempt = getPaymentAttemptForInvoiceId(invoiceId);
- if (attempt != null) {
- paymentAttempts.add(attempt);
+ List<PaymentAttempt> attempts = getPaymentAttemptsForInvoiceId(invoiceId);
+ if (CollectionUtils.isNotEmpty(attempts)) {
+ paymentAttempts.addAll(attempts);
}
}
return paymentAttempts;
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index 70708eb..472fc2f 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -18,10 +18,17 @@ package com.ning.billing.payment.dao;
import java.math.BigDecimal;
import java.util.Arrays;
+import java.util.List;
import java.util.UUID;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.TestCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.clock.DefaultClock;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -31,8 +38,8 @@ import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfo;
public abstract class TestPaymentDao {
-
protected PaymentDao paymentDao;
+ protected CallContext context = new TestCallContext("PaymentTests");
@Test
public void testCreatePayment() {
@@ -44,16 +51,14 @@ public abstract class TestPaymentDao {
.setPaymentMethodId("12345")
.setReferenceId("12345")
.setType("Electronic")
- .setCreatedDate(new DateTime(DateTimeZone.UTC))
- .setUpdatedDate(new DateTime(DateTimeZone.UTC))
- .setEffectiveDate(new DateTime(DateTimeZone.UTC))
+ .setEffectiveDate(new DefaultClock().getUTCNow())
.build();
- paymentDao.savePaymentInfo(paymentInfo);
+ paymentDao.savePaymentInfo(paymentInfo, context);
}
@Test
- public void testUpdatePaymenInfo() {
+ public void testUpdatePaymentInfo() {
PaymentInfo paymentInfo = new PaymentInfo.Builder().setPaymentId(UUID.randomUUID().toString())
.setAmount(BigDecimal.TEN)
.setStatus("Processed")
@@ -62,14 +67,14 @@ public abstract class TestPaymentDao {
.setPaymentMethodId("12345")
.setReferenceId("12345")
.setType("Electronic")
- .setCreatedDate(new DateTime(DateTimeZone.UTC))
- .setUpdatedDate(new DateTime(DateTimeZone.UTC))
- .setEffectiveDate(new DateTime(DateTimeZone.UTC))
+ .setCreatedDate(new DefaultClock().getUTCNow())
+ .setUpdatedDate(new DefaultClock().getUTCNow())
+ .setEffectiveDate(new DefaultClock().getUTCNow())
.build();
- paymentDao.savePaymentInfo(paymentInfo);
-
- paymentDao.updatePaymentInfo("CreditCard", paymentInfo.getPaymentId(), "Visa", "US");
+ CallContext context = new TestCallContext("PaymentTests");
+ paymentDao.savePaymentInfo(paymentInfo, context);
+ paymentDao.updatePaymentInfo("CreditCard", paymentInfo.getPaymentId(), "Visa", "US", context);
}
@Test
@@ -80,12 +85,10 @@ public abstract class TestPaymentDao {
.setAccountId(UUID.randomUUID())
.setAmount(BigDecimal.TEN)
.setCurrency(Currency.USD)
- .setInvoiceDate(new DateTime(DateTimeZone.UTC))
- .setCreatedDate(new DateTime(DateTimeZone.UTC))
- .setUpdatedDate(new DateTime(DateTimeZone.UTC))
+ .setInvoiceDate(context.getCreatedDate())
.build();
- paymentDao.createPaymentAttempt(paymentAttempt);
+ paymentDao.createPaymentAttempt(paymentAttempt, context);
}
@Test
@@ -97,15 +100,15 @@ public abstract class TestPaymentDao {
final BigDecimal invoiceAmount = BigDecimal.TEN;
// Move the clock backwards to test the updated_date field (see below)
- final DateTime now = new DateTime(DateTimeZone.UTC).minusDays(1);
-
- PaymentAttempt originalPaymenAttempt = new PaymentAttempt(paymentAttemptId, invoiceId, accountId, invoiceAmount, Currency.USD, now, now, paymentId, 0);
+ ClockMock clock = new ClockMock();
+ CallContext thisContext = new DefaultCallContext("Payment Tests", CallOrigin.TEST, UserType.TEST, clock);
- PaymentAttempt attempt = paymentDao.createPaymentAttempt(originalPaymenAttempt);
+ PaymentAttempt originalPaymentAttempt = new PaymentAttempt(paymentAttemptId, invoiceId, accountId, invoiceAmount, Currency.USD, clock.getUTCNow(), clock.getUTCNow(), paymentId, 0);
+ PaymentAttempt attempt = paymentDao.createPaymentAttempt(originalPaymentAttempt, thisContext);
- PaymentAttempt attempt2 = paymentDao.getPaymentAttemptForInvoiceId(invoiceId.toString());
+ List<PaymentAttempt> attemptsFromGet = paymentDao.getPaymentAttemptsForInvoiceId(invoiceId.toString());
- Assert.assertEquals(attempt, attempt2);
+ Assert.assertEquals(attempt, attemptsFromGet.get(0));
PaymentAttempt attempt3 = paymentDao.getPaymentAttemptsForInvoiceIds(Arrays.asList(invoiceId.toString())).get(0);
@@ -123,18 +126,19 @@ public abstract class TestPaymentDao {
.setPaymentMethodId("12345")
.setReferenceId("12345")
.setType("Electronic")
- .setCreatedDate(now)
- .setUpdatedDate(now)
- .setEffectiveDate(now)
+ .setCreatedDate(clock.getUTCNow())
+ .setUpdatedDate(clock.getUTCNow())
+ .setEffectiveDate(clock.getUTCNow())
.build();
- paymentDao.savePaymentInfo(originalPaymentInfo);
+ paymentDao.savePaymentInfo(originalPaymentInfo, thisContext);
PaymentInfo paymentInfo = paymentDao.getPaymentInfo(Arrays.asList(invoiceId.toString())).get(0);
Assert.assertEquals(paymentInfo, originalPaymentInfo);
- paymentDao.updatePaymentInfo(originalPaymentInfo.getPaymentMethod(), originalPaymentInfo.getPaymentId(), originalPaymentInfo.getCardType(), originalPaymentInfo.getCardCountry());
+ clock.setDeltaFromReality(60 * 60 * 1000); // move clock forward one hour
+ paymentDao.updatePaymentInfo(originalPaymentInfo.getPaymentMethod(), originalPaymentInfo.getPaymentId(), originalPaymentInfo.getCardType(), originalPaymentInfo.getCardCountry(), thisContext);
paymentInfo = paymentDao.getPaymentInfo(Arrays.asList(invoiceId.toString())).get(0);
- Assert.assertEquals(paymentInfo.getCreatedDate().getMillis() / 1000, originalPaymentInfo.getCreatedDate().getMillis() / 1000);
+ Assert.assertEquals(paymentInfo.getCreatedDate().compareTo(attempt.getCreatedDate()), 0);
Assert.assertTrue(paymentInfo.getUpdatedDate().isAfter(originalPaymentInfo.getUpdatedDate()));
}
}
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithEmbeddedDb.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithEmbeddedDb.java
index a5da11b..84e3e5a 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithEmbeddedDb.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithEmbeddedDb.java
@@ -18,7 +18,6 @@ package com.ning.billing.payment.dao;
import java.io.IOException;
-import com.ning.billing.util.clock.DefaultClock;
import org.apache.commons.io.IOUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -31,7 +30,7 @@ import com.ning.billing.dbi.MysqlTestingHelper;
public class TestPaymentDaoWithEmbeddedDb extends TestPaymentDao {
private final MysqlTestingHelper helper = new MysqlTestingHelper();
- @BeforeClass(alwaysRun = true)
+ @BeforeClass(groups = { "slow", "database" })
public void startMysql() throws IOException {
final String paymentddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
@@ -39,13 +38,13 @@ public class TestPaymentDaoWithEmbeddedDb extends TestPaymentDao {
helper.initDb(paymentddl);
}
- @AfterClass(alwaysRun = true)
+ @AfterClass(groups = { "slow", "database" })
public void stopMysql() {
helper.stopMysql();
}
- @BeforeMethod(alwaysRun = true)
+ @BeforeMethod(groups = { "slow", "database" })
public void setUp() throws IOException {
- paymentDao = new DefaultPaymentDao(helper.getDBI(), new DefaultClock());
+ paymentDao = new AuditedPaymentDao(helper.getDBI());
}
}
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithMock.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithMock.java
index 6e31f90..d540955 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithMock.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDaoWithMock.java
@@ -23,7 +23,7 @@ import org.testng.annotations.Test;
@Test(groups = { "fast" })
public class TestPaymentDaoWithMock extends TestPaymentDao {
- @BeforeMethod(alwaysRun = true)
+ @BeforeMethod(groups = { "fast" })
public void setUp() throws IOException {
paymentDao = new MockPaymentDao();
}
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index da5d4b4..39115db 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -19,6 +19,10 @@ package com.ning.billing.payment;
import java.math.BigDecimal;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.entity.EntityPersistenceException;
import org.apache.commons.lang.RandomStringUtils;
import org.joda.time.DateTime;
@@ -38,11 +42,13 @@ import com.ning.billing.invoice.model.RecurringInvoiceItem;
public class TestHelper {
protected final AccountDao accountDao;
protected final InvoiceDao invoiceDao;
+ private final CallContext context;
@Inject
- public TestHelper(AccountDao accountDao, InvoiceDao invoiceDao) {
+ public TestHelper(CallContextFactory factory, AccountDao accountDao, InvoiceDao invoiceDao) {
this.accountDao = accountDao;
this.invoiceDao = invoiceDao;
+ context = factory.createCallContext("Princess Buttercup", CallOrigin.TEST, UserType.TEST);
}
// These helper methods can be overridden in a plugin implementation
@@ -57,7 +63,7 @@ public class TestHelper {
.currency(Currency.USD)
.billingCycleDay(1)
.build();
- accountDao.create(account);
+ accountDao.create(account, context);
return account;
}
@@ -72,7 +78,7 @@ public class TestHelper {
.currency(Currency.USD)
.billingCycleDay(1)
.build();
- accountDao.create(account);
+ accountDao.create(account, context);
return account;
}
@@ -80,25 +86,25 @@ public class TestHelper {
DateTime targetDate,
Currency currency,
InvoiceItem... items) {
- Invoice invoice = new DefaultInvoice(UUID.randomUUID(), account.getId(), 1, new DateTime(), targetDate, currency);
+ Invoice invoice = new DefaultInvoice(account.getId(), new DateTime(), targetDate, currency);
for (InvoiceItem item : items) {
if (item instanceof RecurringInvoiceItem) {
RecurringInvoiceItem recurringInvoiceItem = (RecurringInvoiceItem) item;
invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
- recurringInvoiceItem.getSubscriptionId(),
- recurringInvoiceItem.getBundleId(),
+ account.getId(),
+ recurringInvoiceItem.getBundleId(),
+ recurringInvoiceItem.getSubscriptionId(),
recurringInvoiceItem.getPlanName(),
recurringInvoiceItem.getPhaseName(),
recurringInvoiceItem.getStartDate(),
recurringInvoiceItem.getEndDate(),
recurringInvoiceItem.getAmount(),
recurringInvoiceItem.getRate(),
- recurringInvoiceItem.getCurrency(),
- recurringInvoiceItem.getCreatedDate()));
+ recurringInvoiceItem.getCurrency()));
}
}
- invoiceDao.create(invoice);
+ invoiceDao.create(invoice, context);
return invoice;
}
@@ -107,8 +113,10 @@ public class TestHelper {
final UUID subscriptionId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
final BigDecimal amount = new BigDecimal("10.00");
- final InvoiceItem item = new RecurringInvoiceItem(null, subscriptionId, bundleId, "test plan", "test phase", now, now.plusMonths(1),
- amount, new BigDecimal("1.0"), Currency.USD, now);
+
+ final InvoiceItem item = new RecurringInvoiceItem(null, account.getId(), bundleId, subscriptionId, "test plan", "test phase", now, now.plusMonths(1),
+ amount, new BigDecimal("1.0"), Currency.USD);
+
return createTestInvoice(account, now, Currency.USD, item);
}
diff --git a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
index e38f14f..80bdd82 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
@@ -20,6 +20,8 @@ import static org.testng.Assert.assertNotNull;
import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TestCallContext;
import com.ning.billing.util.entity.EntityPersistenceException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
@@ -51,6 +53,8 @@ public class TestNotifyInvoicePaymentApi {
@Inject
private TestHelper testHelper;
+ private CallContext context = new TestCallContext("Payment Api Tests");
+
@BeforeMethod(alwaysRun = true)
public void setUp() throws EventBusException {
eventBus.start();
@@ -74,7 +78,8 @@ public class TestNotifyInvoicePaymentApi {
invoice.getBalance(),
invoice.getCurrency(),
paymentAttempt.getPaymentAttemptId(),
- paymentAttempt.getPaymentAttemptDate());
+ paymentAttempt.getPaymentAttemptDate(),
+ context);
InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttempt.getPaymentAttemptId());
@@ -89,7 +94,8 @@ public class TestNotifyInvoicePaymentApi {
PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
paymentAttempt.getPaymentAttemptId(),
- paymentAttempt.getPaymentAttemptDate());
+ paymentAttempt.getPaymentAttemptDate(),
+ context);
InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttempt.getPaymentAttemptId());
diff --git a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
index 888e017..8b71c10 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
@@ -26,6 +26,8 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.Callable;
+import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.util.glue.CallContextModule;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
@@ -99,8 +101,9 @@ public class TestPaymentInvoiceIntegration {
@BeforeMethod(alwaysRun = true)
public void setUp() throws EventBusException {
Injector injector = Guice.createInjector(new PaymentTestModuleWithEmbeddedDb(),
- new AccountModule(),
+ new AccountModuleWithMocks(),
new InvoiceModuleWithMocks(),
+ new CallContextModule(),
new MockClockModule(),
new AbstractModule() {
@Override
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index c71915c..16d21e6 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -25,11 +25,12 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
import org.joda.time.DateTime;
import org.joda.time.Days;
-import org.joda.time.Months;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
@@ -55,6 +56,8 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
import com.ning.billing.payment.setup.PaymentConfig;
import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.notificationq.MockNotificationQueue;
import com.ning.billing.util.notificationq.Notification;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -84,6 +87,7 @@ public class TestRetryService {
private MockPaymentProviderPlugin mockPaymentProviderPlugin;
private MockNotificationQueue mockNotificationQueue;
+ private CallContext context;
@BeforeClass(alwaysRun = true)
public void initialize() throws Exception {
@@ -97,6 +101,7 @@ public class TestRetryService {
mockPaymentProviderPlugin = (MockPaymentProviderPlugin)registry.getPlugin(null);
mockNotificationQueue = (MockNotificationQueue)notificationQueueService.getNotificationQueue(RetryService.SERVICE_NAME, RetryService.QUEUE_NAME);
+ context = new DefaultCallContext("RetryServiceTests", CallOrigin.INTERNAL, UserType.TEST, clock);
}
@AfterMethod(alwaysRun = true)
@@ -116,6 +121,7 @@ public class TestRetryService {
final DateTime startDate = clock.getUTCNow();
final DateTime endDate = startDate.plusMonths(1);
invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ account.getId(),
subscriptionId,
bundleId,
"test plan", "test phase",
@@ -123,12 +129,11 @@ public class TestRetryService {
endDate,
amount,
new BigDecimal("1.0"),
- Currency.USD,
- clock.getUTCNow()));
+ Currency.USD));
mockPaymentProviderPlugin.makeNextInvoiceFail();
- List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()));
+ List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()), context);
assertEquals(results.size(), 1);
assertTrue(results.get(0).isLeft());
@@ -138,12 +143,12 @@ public class TestRetryService {
assertEquals(pendingNotifications.size(), 1);
Notification notification = pendingNotifications.get(0);
- PaymentAttempt paymentAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
+ List<PaymentAttempt> paymentAttempts = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
- assertNotNull(paymentAttempt);
- assertEquals(notification.getNotificationKey(), paymentAttempt.getPaymentAttemptId().toString());
+ assertNotNull(paymentAttempts);
+ assertEquals(notification.getNotificationKey(), paymentAttempts.get(0).getPaymentAttemptId().toString());
- DateTime expectedRetryDate = paymentAttempt.getPaymentAttemptDate().plusDays(paymentConfig.getPaymentRetryDays().get(0));
+ DateTime expectedRetryDate = paymentAttempts.get(0).getPaymentAttemptDate().plusDays(paymentConfig.getPaymentRetryDays().get(0));
assertEquals(notification.getEffectiveDate(), expectedRetryDate);
}
@@ -159,6 +164,7 @@ public class TestRetryService {
final DateTime now = clock.getUTCNow();
invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ account.getId(),
subscriptionId,
bundleId,
"test plan", "test phase",
@@ -166,8 +172,7 @@ public class TestRetryService {
now.plusMonths(1),
amount,
new BigDecimal("1.0"),
- Currency.USD,
- now));
+ Currency.USD));
int numberOfDays = paymentConfig.getPaymentRetryDays().get(0);
DateTime nextRetryDate = now.plusDays(numberOfDays);
@@ -176,7 +181,7 @@ public class TestRetryService {
.setPaymentAttemptDate(now)
.build();
- PaymentAttempt attempt = paymentDao.createPaymentAttempt(paymentAttempt);
+ paymentDao.createPaymentAttempt(paymentAttempt, context);
retryService.scheduleRetry(paymentAttempt, nextRetryDate);
((ClockMock)clock).setDeltaFromReality(Days.days(numberOfDays).toStandardSeconds().getSeconds() * 1000);
Thread.sleep(2000);
@@ -184,14 +189,14 @@ public class TestRetryService {
List<Notification> pendingNotifications = mockNotificationQueue.getPendingEvents();
assertEquals(pendingNotifications.size(), 0);
- List<PaymentInfo> paymentInfos = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId().toString()));
- assertEquals(paymentInfos.size(), 1);
+ List<PaymentInfo> paymentInfoList = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId().toString()));
+ assertEquals(paymentInfoList.size(), 1);
- PaymentInfo paymentInfo = paymentInfos.get(0);
+ PaymentInfo paymentInfo = paymentInfoList.get(0);
assertEquals(paymentInfo.getStatus(), PaymentStatus.Processed.toString());
- PaymentAttempt updatedAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
- assertEquals(paymentInfo.getPaymentId(), updatedAttempt.getPaymentId());
+ List<PaymentAttempt> updatedAttempts = paymentApi.getPaymentAttemptsForInvoiceId(invoice.getId().toString());
+ assertEquals(paymentInfo.getPaymentId(), updatedAttempts.get(0).getPaymentId());
}
}
diff --git a/util/src/main/java/com/ning/billing/util/audit/dao/AuditSqlDao.java b/util/src/main/java/com/ning/billing/util/audit/dao/AuditSqlDao.java
new file mode 100644
index 0000000..f3f96f4
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/audit/dao/AuditSqlDao.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.util.audit.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import java.util.List;
+
+@ExternalizedSqlViaStringTemplate3
+public interface AuditSqlDao {
+ @SqlUpdate
+ public void insertAuditFromTransaction(@Bind("tableName") final String tableName,
+ @Bind("recordId") final String recordId,
+ @Bind("changeType") String changeType,
+ @CallContextBinder CallContext context);
+
+ @SqlBatch(transactional = false)
+ public void insertAuditFromTransaction(@Bind("tableName") final String tableName,
+ @Bind("recordId") final List<String> recordIds,
+ @Bind("changeType") String changeType,
+ @CallContextBinder CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
new file mode 100644
index 0000000..8164f76
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
@@ -0,0 +1,44 @@
+/*
+ * 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.util.callcontext;
+
+public abstract class CallContextBase implements CallContext {
+ private final String userName;
+ private final CallOrigin callOrigin;
+ private final UserType userType;
+
+ public CallContextBase(String userName, CallOrigin callOrigin, UserType userType) {
+ this.userName = userName;
+ this.callOrigin = callOrigin;
+ this.userType = userType;
+ }
+
+ @Override
+ public String getUserName() {
+ return userName;
+ }
+
+ @Override
+ public CallOrigin getCallOrigin() {
+ return callOrigin;
+ }
+
+ @Override
+ public UserType getUserType() {
+ return userType;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java
new file mode 100644
index 0000000..3ac8a98
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.util.callcontext;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@BindingAnnotation(CallContextBinder.CallContextBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface CallContextBinder {
+ public static class CallContextBinderFactory implements BinderFactory {
+ @Override
+ public Binder build(Annotation annotation) {
+ return new Binder<CallContextBinder, CallContext>() {
+ @Override
+ public void bind(SQLStatement q, CallContextBinder bind, CallContext callContext) {
+ q.bind("userName", callContext.getUserName());
+ q.bind("createdDate", callContext.getCreatedDate().toDate());
+ q.bind("updatedDate", callContext.getUpdatedDate().toDate());
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
new file mode 100644
index 0000000..6ffc554
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util.callcontext;
+
+import org.joda.time.DateTime;
+
+public interface CallContextFactory {
+ CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType);
+
+ CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate);
+
+ CallContext toMigrationCallContext(CallContext callContext, DateTime createdDate, DateTime updatedDate);
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
new file mode 100644
index 0000000..57dc682
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.callcontext;
+
+import com.ning.billing.util.clock.Clock;
+import org.joda.time.DateTime;
+
+public class DefaultCallContext extends CallContextBase {
+ private final Clock clock;
+
+ public DefaultCallContext(String userName, CallOrigin callOrigin, UserType userType, Clock clock) {
+ super(userName, callOrigin, userType);
+ this.clock = clock;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return clock.getUTCNow();
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return clock.getUTCNow();
+ }
+}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
new file mode 100644
index 0000000..f75574c
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.util.callcontext;
+
+import com.google.inject.Inject;
+import com.ning.billing.util.clock.Clock;
+import org.joda.time.DateTime;
+
+public class DefaultCallContextFactory implements CallContextFactory {
+ private final Clock clock;
+
+ @Inject
+ public DefaultCallContextFactory(Clock clock) {
+ this.clock = clock;
+ }
+
+ @Override
+ public CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType) {
+ return new DefaultCallContext(userName, callOrigin, userType, clock);
+ }
+
+ @Override
+ public CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate) {
+ return new MigrationCallContext(userName, callOrigin, userType, createdDate, updatedDate);
+ }
+
+ @Override
+ public CallContext toMigrationCallContext(CallContext callContext, DateTime createdDate, DateTime updatedDate) {
+ return new MigrationCallContext(callContext, createdDate, updatedDate);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
new file mode 100644
index 0000000..9d7fc58
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
@@ -0,0 +1,46 @@
+/*
+ * 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.util.callcontext;
+
+import org.joda.time.DateTime;
+
+public class MigrationCallContext extends CallContextBase {
+ private final DateTime createdDate;
+ private final DateTime updatedDate;
+
+ public MigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate) {
+ super(userName, callOrigin, userType);
+ this.createdDate = createdDate;
+ this.updatedDate = updatedDate;
+ }
+
+ public MigrationCallContext(CallContext context, DateTime createdDate, DateTime updatedDate) {
+ super(context.getUserName(), context.getCallOrigin(), context.getUserType());
+ this.createdDate = createdDate;
+ this.updatedDate = updatedDate;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return updatedDate;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistory.java b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistory.java
new file mode 100644
index 0000000..b4bb413
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistory.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.util.customfield;
+
+import com.ning.billing.util.ChangeType;
+import org.joda.time.DateTime;
+
+import java.util.UUID;
+
+public class CustomFieldHistory implements CustomField {
+ private final UUID historyId = UUID.randomUUID();
+ private final CustomField field;
+ private final ChangeType changeType;
+
+ public CustomFieldHistory(CustomField field, ChangeType changeType) {
+ this.field = field;
+ this.changeType = changeType;
+ }
+
+ public UUID getHistoryId() {
+ return historyId;
+ }
+
+ public ChangeType getChangeType() {
+ return changeType;
+ }
+
+ @Override
+ public String getName() {
+ return field.getName();
+ }
+
+ @Override
+ public String getValue() {
+ return field.getValue();
+ }
+
+ @Override
+ public void setValue(String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public UUID getId() {
+ return field.getId();
+ }
+
+ @Override
+ public String getCreatedBy() {
+ return field.getCreatedBy();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return field.getCreatedDate();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistoryBinder.java b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistoryBinder.java
new file mode 100644
index 0000000..51e3621
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldHistoryBinder.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util.customfield;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@BindingAnnotation(CustomFieldHistoryBinder.CustomFieldBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface CustomFieldHistoryBinder {
+ public static class CustomFieldBinderFactory implements BinderFactory {
+ @Override
+ public Binder build(Annotation annotation) {
+ return new Binder<CustomFieldHistoryBinder, CustomFieldHistory>() {
+ @Override
+ public void bind(SQLStatement q, CustomFieldHistoryBinder bind, CustomFieldHistory customFieldHistory) {
+ q.bind("historyId", customFieldHistory.getHistoryId().toString());
+ q.bind("changeType", customFieldHistory.getChangeType().toString());
+ q.bind("id", customFieldHistory.getId().toString());
+ q.bind("fieldName", customFieldHistory.getName());
+ q.bind("fieldValue", customFieldHistory.getValue());
+ }
+ };
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/CustomFieldMapper.java b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldMapper.java
new file mode 100644
index 0000000..97d469d
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/CustomFieldMapper.java
@@ -0,0 +1,40 @@
+/*
+ * 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.util.customfield;
+
+import com.ning.billing.util.entity.MapperBase;
+import org.joda.time.DateTime;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+public class CustomFieldMapper extends MapperBase implements ResultSetMapper<CustomField> {
+ @Override
+ public CustomField map(int index, ResultSet result, StatementContext context) throws SQLException {
+ UUID id = UUID.fromString(result.getString("id"));
+ String fieldName = result.getString("field_name");
+ String fieldValue = result.getString("field_value");
+ String createdBy = result.getString("created_by");
+ DateTime createdDate = getDate(result, "created_date");
+ String updatedBy = result.getString("updated_by");
+ DateTime updatedDate = getDate(result, "updated_date");
+ return new StringCustomField(id, createdBy, createdDate, updatedBy, updatedDate, fieldName, fieldValue);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/CustomizableEntityBase.java b/util/src/main/java/com/ning/billing/util/customfield/CustomizableEntityBase.java
index ac184be..88fcffa 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/CustomizableEntityBase.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/CustomizableEntityBase.java
@@ -19,12 +19,18 @@ package com.ning.billing.util.customfield;
import java.util.List;
import java.util.UUID;
import com.ning.billing.util.entity.EntityBase;
+import org.joda.time.DateTime;
-public abstract class CustomizableEntityBase extends EntityBase implements CustomizableEntity {
+public abstract class CustomizableEntityBase extends EntityBase implements Customizable {
protected final FieldStore fields;
- public CustomizableEntityBase(final UUID id) {
- super(id);
+ public CustomizableEntityBase() {
+ super();
+ fields = DefaultFieldStore.create(getId(), getObjectName());
+ }
+
+ public CustomizableEntityBase(final UUID id, String createdBy, DateTime createdDate) {
+ super(id, createdBy, createdDate);
fields = DefaultFieldStore.create(getId(), getObjectName());
}
@@ -44,7 +50,7 @@ public abstract class CustomizableEntityBase extends EntityBase implements Custo
}
@Override
- public void addFields(final List<CustomField> fields) {
+ public void setFields(final List<CustomField> fields) {
if (fields != null) {
this.fields.add(fields);
}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
new file mode 100644
index 0000000..b7d2de0
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
@@ -0,0 +1,81 @@
+/*
+ * 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.util.customfield.dao;
+
+import com.ning.billing.util.ChangeType;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.CustomFieldHistory;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+public class AuditedCustomFieldDao implements CustomFieldDao {
+ @Override
+ public void saveFields(Transmogrifier dao, UUID objectId, String objectType, List<CustomField> fields, CallContext context) {
+ CustomFieldSqlDao customFieldSqlDao = dao.become(CustomFieldSqlDao.class);
+
+ // get list of existing fields
+ List<CustomField> existingFields = customFieldSqlDao.load(objectId.toString(), objectType);
+ List<CustomField> fieldsToUpdate = new ArrayList<CustomField>();
+
+ // sort into fields to update (fieldsToUpdate), fields to add (fields), and fields to delete (existingFields)
+ Iterator<CustomField> fieldIterator = fields.iterator();
+ while (fieldIterator.hasNext()) {
+ CustomField field = fieldIterator.next();
+
+ Iterator<CustomField> existingFieldIterator = existingFields.iterator();
+ while (existingFieldIterator.hasNext()) {
+ CustomField existingField = existingFieldIterator.next();
+ if (field.getName().equals(existingField.getName())) {
+ // if the tags match, remove from both lists
+ fieldsToUpdate.add(field);
+ fieldIterator.remove();
+ existingFieldIterator.remove();
+ }
+ }
+ }
+
+ customFieldSqlDao.batchInsertFromTransaction(objectId.toString(), objectType, fields, context);
+ customFieldSqlDao.batchUpdateFromTransaction(objectId.toString(), objectType, fieldsToUpdate, context);
+ customFieldSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingFields, context);
+
+ List<CustomFieldHistory> fieldHistories = new ArrayList<CustomFieldHistory>();
+ fieldHistories.addAll(convertToHistoryEntry(fields, ChangeType.INSERT));
+ fieldHistories.addAll(convertToHistoryEntry(fieldsToUpdate, ChangeType.UPDATE));
+ fieldHistories.addAll(convertToHistoryEntry(existingFields, ChangeType.DELETE));
+
+ CustomFieldHistorySqlDao historyDao = dao.become(CustomFieldHistorySqlDao.class);
+ historyDao.batchAddHistoryFromTransaction(objectId.toString(), objectType, fieldHistories, context);
+
+ CustomFieldAuditSqlDao auditDao = dao.become(CustomFieldAuditSqlDao.class);
+ auditDao.batchInsertAuditLogFromTransaction(objectId.toString(), objectType, fieldHistories, context);
+ }
+
+ private List<CustomFieldHistory> convertToHistoryEntry(List<CustomField> fields, ChangeType changeType) {
+ List<CustomFieldHistory> result = new ArrayList<CustomFieldHistory>();
+
+ for (CustomField field : fields) {
+ result.add(new CustomFieldHistory(field, changeType));
+ }
+
+ return result;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.java
new file mode 100644
index 0000000..471cdca
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.java
@@ -0,0 +1,37 @@
+/*
+ * 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.util.customfield.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.customfield.CustomFieldHistory;
+import com.ning.billing.util.customfield.CustomFieldHistoryBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import java.util.List;
+
+@ExternalizedSqlViaStringTemplate3
+public interface CustomFieldAuditSqlDao extends Transactional<CustomFieldAuditSqlDao> {
+ @SqlBatch(transactional=false)
+ public void batchInsertAuditLogFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CustomFieldHistoryBinder final List<CustomFieldHistory> entities,
+ @CallContextBinder final CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldDao.java
new file mode 100644
index 0000000..a987c4d
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldDao.java
@@ -0,0 +1,28 @@
+/*
+ * 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.util.customfield.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import java.util.List;
+import java.util.UUID;
+
+public interface CustomFieldDao {
+ void saveFields(Transmogrifier dao, UUID objectId, String objectType, List<CustomField> fields, CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.java
new file mode 100644
index 0000000..6124ff4
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.java
@@ -0,0 +1,36 @@
+/*
+ * 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.util.customfield.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.customfield.CustomFieldHistory;
+import com.ning.billing.util.customfield.CustomFieldHistoryBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import java.util.List;
+
+@ExternalizedSqlViaStringTemplate3
+public interface CustomFieldHistorySqlDao {
+ @SqlBatch(transactional=false)
+ public void batchAddHistoryFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CustomFieldHistoryBinder final List<CustomFieldHistory> entities,
+ @CallContextBinder final CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
new file mode 100644
index 0000000..733bfeb
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -0,0 +1,57 @@
+/*
+ * 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.util.customfield.dao;
+
+import java.util.List;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.customfield.CustomFieldBinder;
+import com.ning.billing.util.customfield.CustomFieldMapper;
+import com.ning.billing.util.entity.UpdatableEntityCollectionDao;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+import com.ning.billing.util.customfield.CustomField;
+
+@ExternalizedSqlViaStringTemplate3
+@RegisterMapper(CustomFieldMapper.class)
+public interface CustomFieldSqlDao extends UpdatableEntityCollectionDao<CustomField>, Transactional<CustomFieldSqlDao>, Transmogrifier {
+ @Override
+ @SqlBatch(transactional=false)
+ public void batchInsertFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CustomFieldBinder final List<CustomField> entities,
+ @CallContextBinder final CallContext context);
+
+ @Override
+ @SqlBatch(transactional=false)
+ public void batchUpdateFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CustomFieldBinder final List<CustomField> entities,
+ @CallContextBinder final CallContext context);
+
+ @Override
+ @SqlBatch(transactional=false)
+ public void batchDeleteFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CustomFieldBinder final List<CustomField> entities,
+ @CallContextBinder final CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
index 4e04ff3..f60093c 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
@@ -17,18 +17,22 @@
package com.ning.billing.util.customfield;
import java.util.UUID;
-import com.ning.billing.util.entity.EntityBase;
+import com.ning.billing.util.entity.UpdatableEntityBase;
+import org.joda.time.DateTime;
-public class StringCustomField extends EntityBase<CustomField> implements CustomField {
+public class StringCustomField extends UpdatableEntityBase implements CustomField {
private String name;
private String value;
public StringCustomField(String name, String value) {
- this(UUID.randomUUID(), name, value);
+ super();
+ this.name = name;
+ this.value = value;
}
- public StringCustomField(UUID id, String name, String value) {
- super(id);
+ public StringCustomField(UUID id, String createdBy, DateTime createdDate,
+ String updatedBy, DateTime updatedDate, String name, String value) {
+ super(id, createdBy, createdDate, updatedBy, updatedDate);
this.name = name;
this.value = value;
}
diff --git a/util/src/main/java/com/ning/billing/util/entity/BinderBase.java b/util/src/main/java/com/ning/billing/util/entity/BinderBase.java
new file mode 100644
index 0000000..8839541
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/BinderBase.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util.entity;
+
+import org.joda.time.DateTime;
+
+import java.util.Date;
+
+public abstract class BinderBase {
+ protected Date getDate(DateTime dateTime) {
+ return dateTime == null ? null : dateTime.toDate();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
index 3cb71f8..4de0312 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
@@ -16,21 +16,41 @@
package com.ning.billing.util.entity;
+import org.joda.time.DateTime;
+
import java.util.UUID;
-public abstract class EntityBase<T> implements Entity {
+public abstract class EntityBase implements Entity {
protected final UUID id;
+ protected final String createdBy;
+ protected final DateTime createdDate;
- public EntityBase(UUID id) {
+ // used to hydrate objects
+ public EntityBase(UUID id, String createdBy, DateTime createdDate) {
this.id = id;
+ this.createdBy = createdBy;
+ this.createdDate = createdDate;
}
+ // used to create new objects
public EntityBase() {
- this(UUID.randomUUID());
+ this.id = UUID.randomUUID();
+ this.createdBy = null;
+ this.createdDate = null;
}
@Override
public UUID getId() {
return id;
}
+
+ @Override
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityCollectionBase.java b/util/src/main/java/com/ning/billing/util/entity/EntityCollectionBase.java
index 369f255..a240000 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityCollectionBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityCollectionBase.java
@@ -54,7 +54,7 @@ public abstract class EntityCollectionBase<T extends Entity> implements EntityCo
@Override
public void remove(T entity) {
- entities.remove(entity);
+ entities.remove(getEntityKey(entity));
}
@Override
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityCollectionDao.java b/util/src/main/java/com/ning/billing/util/entity/EntityCollectionDao.java
index 11d149c..9bb2d8e 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityCollectionDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityCollectionDao.java
@@ -16,6 +16,8 @@
package com.ning.billing.util.entity;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
import org.skife.jdbi.v2.sqlobject.*;
import java.util.List;
@@ -26,15 +28,17 @@ import java.util.List;
* @param <T>
*/
public interface EntityCollectionDao<T extends Entity> {
-
@SqlBatch(transactional=false)
- public void batchSaveFromTransaction(@Bind("objectId") final String objectId,
- @Bind("objectType") final String objectType,
- @BindBean final List<T> entities);
+ public void batchInsertFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @BindBean final List<T> entities,
+ @CallContextBinder final CallContext context);
- @SqlUpdate
- public void clear(@Bind("objectId") final String objectId,
- @Bind("objectType") final String objectType);
+ @SqlBatch(transactional=false)
+ public void batchDeleteFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @BindBean final List<T> entities,
+ @CallContextBinder final CallContext context);
@SqlQuery
public List<T> load(@Bind("objectId") final String objectId,
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityDao.java b/util/src/main/java/com/ning/billing/util/entity/EntityDao.java
index 1337950..d093492 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityDao.java
@@ -18,16 +18,16 @@ package com.ning.billing.util.entity;
import java.util.List;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-import com.ning.billing.account.api.AccountApiException;
-
public interface EntityDao<T extends Entity> {
@SqlUpdate
- public void create(@BindBean final T entity) throws EntityPersistenceException;
+ public void create(@BindBean final T entity, @CallContextBinder final CallContext context) throws EntityPersistenceException;
@SqlQuery
public T getById(@Bind("id") final String id);
diff --git a/util/src/main/java/com/ning/billing/util/entity/ExtendedEntityBase.java b/util/src/main/java/com/ning/billing/util/entity/ExtendedEntityBase.java
new file mode 100644
index 0000000..0017397
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/ExtendedEntityBase.java
@@ -0,0 +1,133 @@
+/*
+ * 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.util.entity;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.Customizable;
+import com.ning.billing.util.customfield.DefaultFieldStore;
+import com.ning.billing.util.customfield.FieldStore;
+import com.ning.billing.util.tag.DefaultTagStore;
+import com.ning.billing.util.tag.DescriptiveTag;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.TagStore;
+import com.ning.billing.util.tag.Taggable;
+import org.joda.time.DateTime;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.UUID;
+
+public abstract class ExtendedEntityBase extends EntityBase implements Customizable, Taggable {
+ protected final FieldStore fields;
+ protected final TagStore tags;
+
+ public ExtendedEntityBase() {
+ super();
+ this.fields = DefaultFieldStore.create(getId(), getObjectName());
+ this.tags = new DefaultTagStore(id, getObjectName());
+ }
+
+ public ExtendedEntityBase(final UUID id, @Nullable final String createdBy, @Nullable final DateTime createdDate) {
+ super(id, createdBy, createdDate);
+ this.fields = DefaultFieldStore.create(getId(), getObjectName());
+ this.tags = new DefaultTagStore(id, getObjectName());
+ }
+
+ @Override
+ public String getFieldValue(final String fieldName) {
+ return fields.getValue(fieldName);
+ }
+
+ @Override
+ public void setFieldValue(final String fieldName, final String fieldValue) {
+ fields.setValue(fieldName, fieldValue);
+ }
+
+ @Override
+ public List<CustomField> getFieldList() {
+ return fields.getEntityList();
+ }
+
+ @Override
+ public void setFields(final List<CustomField> fields) {
+ if (fields != null) {
+ this.fields.add(fields);
+ }
+ }
+
+ @Override
+ public void clearFields() {
+ fields.clear();
+ }
+
+ @Override
+ public List<Tag> getTagList() {
+ return tags.getEntityList();
+ }
+
+ @Override
+ public boolean hasTag(final String tagName) {
+ return tags.containsTag(tagName);
+ }
+
+ @Override
+ public void addTag(final TagDefinition definition) {
+ Tag tag = new DescriptiveTag(definition);
+ tags.add(tag) ;
+ }
+
+ @Override
+ public void addTags(final List<Tag> tags) {
+ if (tags != null) {
+ this.tags.add(tags);
+ }
+ }
+
+ @Override
+ public void clearTags() {
+ this.tags.clear();
+ }
+
+ @Override
+ public void removeTag(final TagDefinition definition) {
+ tags.remove(definition.getName());
+ }
+
+ @Override
+ public boolean generateInvoice() {
+ return tags.generateInvoice();
+ }
+
+ @Override
+ public boolean processPayment() {
+ return tags.processPayment();
+ }
+
+ @Override
+ public abstract String getObjectName();
+
+ @Override
+ public abstract void saveFieldValue(String fieldName, String fieldValue, CallContext context);
+
+ @Override
+ public abstract void saveFields(List<CustomField> fields, CallContext context);
+
+ @Override
+ public abstract void clearPersistedFields(CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/MapperBase.java b/util/src/main/java/com/ning/billing/util/entity/MapperBase.java
new file mode 100644
index 0000000..e2902d8
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/MapperBase.java
@@ -0,0 +1,32 @@
+/*
+ * 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.util.entity;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+
+public abstract class MapperBase {
+ protected DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
+ final Timestamp resultStamp = rs.getTimestamp(fieldName);
+ return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java
new file mode 100644
index 0000000..c860ddb
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java
@@ -0,0 +1,24 @@
+/*
+ * 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.util.entity;
+
+import org.joda.time.DateTime;
+
+public interface UpdatableEntity extends Entity {
+ public String getUpdatedBy();
+ public DateTime getUpdatedDate();
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java
new file mode 100644
index 0000000..3aaffbc
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util.entity;
+
+import org.joda.time.DateTime;
+
+import java.util.UUID;
+
+public abstract class UpdatableEntityBase extends EntityBase implements UpdatableEntity {
+ private final String updatedBy;
+ private final DateTime updatedDate;
+
+ public UpdatableEntityBase() {
+ super();
+ this.updatedBy = null;
+ this.updatedDate = null;
+ }
+
+ public UpdatableEntityBase(UUID id, String createdBy, DateTime createdDate, String updatedBy, DateTime updatedDate) {
+ super(id, createdBy, createdDate);
+ this.updatedBy = updatedBy;
+ this.updatedDate = updatedDate;
+ }
+
+ @Override
+ public String getUpdatedBy() {
+ return updatedBy;
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return updatedDate;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityCollectionDao.java b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityCollectionDao.java
new file mode 100644
index 0000000..ed27853
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityCollectionDao.java
@@ -0,0 +1,33 @@
+/*
+ * 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.util.entity;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+
+import java.util.List;
+
+public interface UpdatableEntityCollectionDao<T extends Entity> extends EntityCollectionDao<T> {
+ @SqlBatch(transactional=false)
+ public void batchUpdateFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @BindBean final List<T> entities,
+ @CallContextBinder final CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityDao.java b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityDao.java
index eb4adc1..4438625 100644
--- a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityDao.java
@@ -16,10 +16,13 @@
package com.ning.billing.util.entity;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
import org.skife.jdbi.v2.sqlobject.BindBean;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
public interface UpdatableEntityDao<T extends UpdatableEntity> extends EntityDao<T> {
@SqlUpdate
- public void update(@BindBean final T entity) throws EntityPersistenceException;
+ public void update(@BindBean final T entity, @CallContextBinder final CallContext context)
+ throws EntityPersistenceException;
}
diff --git a/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
new file mode 100644
index 0000000..6c0cca0
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
@@ -0,0 +1,28 @@
+/*
+ * 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.util.glue;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+
+public class CallContextModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/FieldStoreModule.java b/util/src/main/java/com/ning/billing/util/glue/FieldStoreModule.java
new file mode 100644
index 0000000..2d579fc
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/FieldStoreModule.java
@@ -0,0 +1,28 @@
+/*
+ * 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.util.glue;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
+
+public class FieldStoreModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ bind(CustomFieldDao.class).to(AuditedCustomFieldDao.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java b/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java
index 560a09f..c05ca29 100644
--- a/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java
+++ b/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java
@@ -1,39 +1,39 @@
-/*
- * 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.util.glue;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
-import org.skife.jdbi.v2.IDBI;
-
-public class TagDescriptionDaoProvider implements Provider<TagDefinitionSqlDao>
-{
- private final IDBI dbi;
-
- @Inject
- public TagDescriptionDaoProvider(final IDBI dbi)
- {
- this.dbi = dbi;
- }
-
- @Override
- public TagDefinitionSqlDao get()
- {
- return dbi.onDemand(TagDefinitionSqlDao.class);
- }
-}
+///*
+// * 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.util.glue;
+//
+//import com.google.inject.Inject;
+//import com.google.inject.Provider;
+//import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
+//import org.skife.jdbi.v2.IDBI;
+//
+//public class TagDescriptionDaoProvider implements Provider<TagDefinitionSqlDao>
+//{
+// private final IDBI dbi;
+//
+// @Inject
+// public TagDescriptionDaoProvider(final IDBI dbi)
+// {
+// this.dbi = dbi;
+// }
+//
+// @Override
+// public TagDefinitionSqlDao get()
+// {
+// return dbi.onDemand(TagDefinitionSqlDao.class);
+// }
+//}
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java
index aa0f080..1f97f7e 100644
--- a/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java
@@ -1,39 +1,39 @@
-/*
- * 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.util.glue;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.ning.billing.util.tag.dao.TagStoreSqlDao;
-import org.skife.jdbi.v2.IDBI;
-
-public class TagStoreDaoProvider implements Provider<TagStoreSqlDao>
-{
- private final IDBI dbi;
-
- @Inject
- public TagStoreDaoProvider(final IDBI dbi)
- {
- this.dbi = dbi;
- }
-
- @Override
- public TagStoreSqlDao get()
- {
- return dbi.onDemand(TagStoreSqlDao.class);
- }
-}
+///*
+// * 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.util.glue;
+//
+//import com.google.inject.Inject;
+//import com.google.inject.Provider;
+//import com.ning.billing.util.tag.dao.TagSqlDao;
+//import org.skife.jdbi.v2.IDBI;
+//
+//public class TagStoreDaoProvider implements Provider<TagSqlDao>
+//{
+// private final IDBI dbi;
+//
+// @Inject
+// public TagStoreDaoProvider(final IDBI dbi)
+// {
+// this.dbi = dbi;
+// }
+//
+// @Override
+// public TagSqlDao get()
+// {
+// return dbi.onDemand(TagSqlDao.class);
+// }
+//}
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
index 5f87a6a..47e5412 100644
--- a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
@@ -19,17 +19,17 @@ package com.ning.billing.util.glue;
import com.google.inject.AbstractModule;
import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.tag.api.DefaultTagDefinitionUserApi;
+import com.ning.billing.util.tag.dao.AuditedTagDao;
import com.ning.billing.util.tag.dao.DefaultTagDefinitionDao;
+import com.ning.billing.util.tag.dao.TagDao;
import com.ning.billing.util.tag.dao.TagDefinitionDao;
import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
-import com.ning.billing.util.tag.dao.TagStoreSqlDao;
public class TagStoreModule extends AbstractModule
{
protected void installDaos() {
- bind(TagDefinitionSqlDao.class).toProvider(TagDescriptionDaoProvider.class).asEagerSingleton();
bind(TagDefinitionDao.class).to(DefaultTagDefinitionDao.class).asEagerSingleton();
- bind(TagStoreSqlDao.class).toProvider(TagStoreDaoProvider.class).asEagerSingleton();
+ bind(TagDao.class).to(AuditedTagDao.class).asEagerSingleton();
}
@Override
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
index 2f511ec..9253e2d 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
@@ -23,6 +23,8 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
+import com.ning.billing.util.entity.BinderBase;
+import com.ning.billing.util.entity.MapperBase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.SQLStatement;
@@ -63,12 +65,7 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
@SqlUpdate
public void insertClaimedHistory(@Bind("sequence_id") int sequenceId, @Bind("owner") String owner, @Bind("claimed_dt") Date clainedDate, @Bind("notification_id") String notificationId);
- public static class NotificationSqlDaoBinder implements Binder<Bind, Notification> {
-
- private Date getDate(DateTime dateTime) {
- return dateTime == null ? null : dateTime.toDate();
- }
-
+ public static class NotificationSqlDaoBinder extends BinderBase implements Binder<Bind, Notification> {
@Override
public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Notification evt) {
stmt.bind("notification_id", evt.getUUID().toString());
@@ -83,13 +80,7 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
}
- public static class NotificationSqlMapper implements ResultSetMapper<Notification> {
-
- private DateTime getDate(ResultSet r, String fieldName) throws SQLException {
- final Timestamp resultStamp = r.getTimestamp(fieldName);
- return r.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
- }
-
+ public static class NotificationSqlMapper extends MapperBase implements ResultSetMapper<Notification> {
@Override
public Notification map(int index, ResultSet r, StatementContext ctx)
throws SQLException {
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
index 03e9740..53d8841 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
@@ -22,6 +22,7 @@ import org.joda.time.DateTime;
import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.api.TagUserApi;
import com.ning.billing.util.tag.ControlTagType;
@@ -45,18 +46,19 @@ public class DefaultTagDefinitionUserApi implements TagUserApi {
}
@Override
- public TagDefinition create(final String name, final String description, final String createdBy) throws TagDefinitionApiException {
- return dao.create(name, description, createdBy);
+ public TagDefinition create(final String name, final String description, final CallContext context) throws TagDefinitionApiException {
+ return dao.create(name, description, context);
}
@Override
- public void deleteAllTagsForDefinition(final String definitionName) throws TagDefinitionApiException {
- dao.deleteAllTagsForDefinition(definitionName);
+ public void deleteAllTagsForDefinition(final String definitionName, final CallContext context)
+ throws TagDefinitionApiException {
+ dao.deleteAllTagsForDefinition(definitionName, context);
}
@Override
- public void deleteTagDefinition(final String definitionName) throws TagDefinitionApiException {
- dao.deleteAllTagsForDefinition(definitionName);
+ public void deleteTagDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
+ dao.deleteAllTagsForDefinition(definitionName, context);
}
@Override
@@ -66,8 +68,7 @@ public class DefaultTagDefinitionUserApi implements TagUserApi {
}
@Override
- public Tag createControlTag(String controlTagName, String addedBy,
- DateTime addedDate) throws TagDefinitionApiException {
+ public Tag createControlTag(String controlTagName) throws TagDefinitionApiException {
ControlTagType type = null;
for(ControlTagType t : ControlTagType.values()) {
if(t.toString().equals(controlTagName)) {
@@ -78,14 +79,13 @@ public class DefaultTagDefinitionUserApi implements TagUserApi {
if(type == null) {
throw new TagDefinitionApiException(ErrorCode.CONTROL_TAG_DOES_NOT_EXIST, controlTagName);
}
- return new DefaultControlTag(addedBy, addedDate, type);
+ return new DefaultControlTag(type);
}
@Override
- public Tag createDescriptiveTag(String tagDefinitionName, String addedBy,
- DateTime addedDate) throws TagDefinitionApiException {
+ public Tag createDescriptiveTag(String tagDefinitionName) throws TagDefinitionApiException {
TagDefinition tagDefinition = getTagDefinition(tagDefinitionName);
- return new DescriptiveTag(tagDefinition, addedBy, addedDate);
+ return new DescriptiveTag(tagDefinition);
}
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java
new file mode 100644
index 0000000..6e361f9
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/AuditedTagDao.java
@@ -0,0 +1,153 @@
+/*
+ * 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.util.tag.dao;
+
+import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.Tag;
+import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+public class AuditedTagDao implements TagDao {
+ private final TagSqlDao tagSqlDao;
+ private final TagAuditSqlDao tagAuditSqlDao;
+
+ @Inject
+ public AuditedTagDao(final IDBI dbi) {
+ this.tagSqlDao = dbi.onDemand(TagSqlDao.class);
+ this.tagAuditSqlDao = dbi.onDemand(TagAuditSqlDao.class);
+ }
+
+ @Override
+ public void saveTags(final UUID objectId, final String objectType,
+ final List<Tag> tags, final CallContext context) {
+ // get list of existing tags
+ List<Tag> existingTags = tagSqlDao.load(objectId.toString(), objectType);
+
+ // sort into tags to update (tagsToUpdate), tags to add (tags), and tags to delete (existingTags)
+ Iterator<Tag> tagIterator = tags.iterator();
+ while (tagIterator.hasNext()) {
+ Tag tag = tagIterator.next();
+
+ Iterator<Tag> existingTagIterator = existingTags.iterator();
+ while (existingTagIterator.hasNext()) {
+ Tag existingTag = existingTagIterator.next();
+ if (tag.getTagDefinitionName().equals(existingTag.getTagDefinitionName())) {
+ // if the tags match, remove from both lists
+ // in the case of tag, this just means the tag remains associated
+ tagIterator.remove();
+ existingTagIterator.remove();
+ }
+ }
+ }
+
+ tagSqlDao.batchInsertFromTransaction(objectId.toString(), objectType, tags, context);
+ tagSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingTags, context);
+
+ tagAuditSqlDao.batchInsertFromTransaction(tags, context);
+ tagAuditSqlDao.batchDeleteFromTransaction(existingTags, context);
+ }
+
+ @Override
+ public void saveTagsFromTransaction(final Transmogrifier dao, final UUID objectId, final String objectType,
+ final List<Tag> tags, final CallContext context) {
+ TagSqlDao tagSqlDao = dao.become(TagSqlDao.class);
+
+ // get list of existing tags
+ List<Tag> existingTags = tagSqlDao.load(objectId.toString(), objectType);
+
+ // sort into tags to update (tagsToUpdate), tags to add (tags), and tags to delete (existingTags)
+ Iterator<Tag> tagIterator = tags.iterator();
+ while (tagIterator.hasNext()) {
+ Tag tag = tagIterator.next();
+
+ Iterator<Tag> existingTagIterator = existingTags.iterator();
+ while (existingTagIterator.hasNext()) {
+ Tag existingTag = existingTagIterator.next();
+ if (tag.getTagDefinitionName().equals(existingTag.getTagDefinitionName())) {
+ // if the tags match, remove from both lists
+ // in the case of tag, this just means the tag remains associated
+ tagIterator.remove();
+ existingTagIterator.remove();
+ }
+ }
+ }
+
+ tagSqlDao.batchInsertFromTransaction(objectId.toString(), objectType, tags, context);
+ tagSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingTags, context);
+
+ TagAuditSqlDao auditDao = dao.become(TagAuditSqlDao.class);
+ auditDao.batchInsertFromTransaction(tags, context);
+ auditDao.batchDeleteFromTransaction(existingTags, context);
+ }
+
+ @Override
+ public List<Tag> loadTags(final UUID objectId, final String objectType) {
+ return tagSqlDao.load(objectId.toString(), objectType);
+ }
+
+ @Override
+ public List<Tag> loadTagsFromTransaction(final Transmogrifier dao, final UUID objectId, final String objectType) {
+ TagSqlDao tagSqlDao = dao.become(TagSqlDao.class);
+ return tagSqlDao.load(objectId.toString(), objectType);
+ }
+
+ @Override
+ public void addTag(final String tagName, final UUID objectId, final String objectType, final CallContext context) {
+ tagSqlDao.inTransaction(new Transaction<Void, TagSqlDao>() {
+ @Override
+ public Void inTransaction(final TagSqlDao tagSqlDao, final TransactionStatus status) throws Exception {
+ String tagId = UUID.randomUUID().toString();
+ tagSqlDao.addTagFromTransaction(tagId, tagName, objectId.toString(), objectType, context);
+
+ TagAuditSqlDao auditDao = tagSqlDao.become(TagAuditSqlDao.class);
+ auditDao.addTagFromTransaction(tagId, context);
+
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void removeTag(final String tagName, final UUID objectId, final String objectType, final CallContext context) {
+ tagSqlDao.inTransaction(new Transaction<Void, TagSqlDao>() {
+ @Override
+ public Void inTransaction(final TagSqlDao tagSqlDao, final TransactionStatus status) throws Exception {
+ Tag tag = tagSqlDao.findTag(tagName, objectId.toString(), objectType);
+
+ if (tag == null) {
+ throw new InvoiceApiException(ErrorCode.TAG_DOES_NOT_EXIST, tagName);
+ }
+
+ tagSqlDao.removeTagFromTransaction(tagName, objectId.toString(), objectType, context);
+
+ TagAuditSqlDao auditDao = tagSqlDao.become(TagAuditSqlDao.class);
+ auditDao.removeTagFromTransaction(tag.getId().toString(), context);
+
+ return null;
+ }
+ });
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
index dddb14f..884dacd 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
@@ -18,24 +18,22 @@ package com.ning.billing.util.tag.dao;
import java.util.ArrayList;
import java.util.List;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.ControlTagType;
import org.skife.jdbi.v2.IDBI;
import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.tag.ControlTagType;
import com.ning.billing.util.tag.DefaultTagDefinition;
-import com.ning.billing.util.tag.Tag;
import com.ning.billing.util.tag.TagDefinition;
public class DefaultTagDefinitionDao implements TagDefinitionDao {
private final TagDefinitionSqlDao dao;
- private final Clock clock;
@Inject
- public DefaultTagDefinitionDao(IDBI dbi, Clock clock) {
+ public DefaultTagDefinitionDao(IDBI dbi) {
this.dao = dbi.onDemand(TagDefinitionSqlDao.class);
- this.clock = clock;
}
@Override
@@ -46,7 +44,7 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
// add control tag definitions
for (ControlTagType controlTag : ControlTagType.values()) {
- definitionList.add(new DefaultTagDefinition(controlTag.toString(), controlTag.getDescription(), null));
+ definitionList.add(new DefaultTagDefinition(controlTag.toString(), controlTag.getDescription()));
}
return definitionList;
@@ -58,7 +56,8 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
}
@Override
- public TagDefinition create(final String definitionName, final String description, final String createdBy) throws TagDefinitionApiException {
+ public TagDefinition create(final String definitionName, final String description,
+ final CallContext context) throws TagDefinitionApiException {
if (isControlTagName(definitionName)) {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_CONFLICTS_WITH_CONTROL_TAG, definitionName);
}
@@ -69,8 +68,8 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_ALREADY_EXISTS, definitionName);
}
- TagDefinition definition = new DefaultTagDefinition(definitionName, description, createdBy);
- dao.create(definition);
+ TagDefinition definition = new DefaultTagDefinition(definitionName, description);
+ dao.create(definition, context);
return definition;
}
@@ -85,17 +84,17 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
}
@Override
- public void deleteAllTagsForDefinition(final String definitionName) throws TagDefinitionApiException {
+ public void deleteAllTagsForDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
TagDefinition existingDefinition = dao.getByName(definitionName);
if (existingDefinition == null) {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionName);
}
- dao.deleteAllTagsForDefinition(definitionName);
+ dao.deleteAllTagsForDefinition(definitionName, context);
}
@Override
- public void deleteTagDefinition(final String definitionName) throws TagDefinitionApiException {
+ public void deleteTagDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
if (dao.tagDefinitionUsageCount(definitionName) > 0) {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_IN_USE, definitionName);
}
@@ -106,6 +105,6 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionName);
}
- dao.deleteTagDefinition(definitionName);
+ dao.deleteTagDefinition(definitionName, context);
}
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagBinder.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagBinder.java
index d56257d..2416b21 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagBinder.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagBinder.java
@@ -21,6 +21,9 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+
+import com.google.inject.Inject;
+import com.ning.billing.util.clock.Clock;
import org.skife.jdbi.v2.SQLStatement;
import org.skife.jdbi.v2.sqlobject.Binder;
import org.skife.jdbi.v2.sqlobject.BinderFactory;
@@ -37,8 +40,6 @@ public @interface TagBinder {
public void bind(SQLStatement q, TagBinder bind, Tag tag) {
q.bind("id", tag.getId().toString());
q.bind("tagDefinitionName", tag.getTagDefinitionName());
- q.bind("addedDate", tag.getAddedDate().toDate());
- q.bind("addedBy", tag.getAddedBy());
}
};
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
new file mode 100644
index 0000000..11594ac
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.tag.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import java.util.List;
+import java.util.UUID;
+
+public interface TagDao {
+ void saveTagsFromTransaction(Transmogrifier dao, UUID objectId, String objectType, List<Tag> tags, CallContext context);
+
+ void saveTags(UUID objectId, String objectType, List<Tag> tags, CallContext context);
+
+ List<Tag> loadTags(UUID objectId, String objectType);
+
+ List<Tag> loadTagsFromTransaction(Transmogrifier dao, UUID objectId, String objectType);
+
+ void addTag(String tagName, UUID objectId, String objectType, CallContext context);
+
+ void removeTag(String tagName, UUID objectId, String objectType, CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
index 3164518..112ff75 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionDao.java
@@ -17,6 +17,8 @@
package com.ning.billing.util.tag.dao;
import java.util.List;
+
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.tag.TagDefinition;
@@ -25,9 +27,9 @@ public interface TagDefinitionDao {
public TagDefinition getByName(String definitionName);
- public TagDefinition create(String definitionName, String description, String createdBy) throws TagDefinitionApiException;
+ public TagDefinition create(String definitionName, String description, CallContext context) throws TagDefinitionApiException;
- public void deleteAllTagsForDefinition(String definitionName) throws TagDefinitionApiException;
+ public void deleteAllTagsForDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
- public void deleteTagDefinition(String definitionName) throws TagDefinitionApiException;
+ public void deleteTagDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
index 86e1b5b..1308ae1 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.java
@@ -24,8 +24,10 @@ import java.lang.annotation.Target;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
import com.ning.billing.util.entity.EntityDao;
-import com.ning.billing.util.entity.UpdatableEntityDao;
import com.ning.billing.util.tag.DefaultTagDefinition;
import com.ning.billing.util.tag.TagDefinition;
import org.joda.time.DateTime;
@@ -43,20 +45,16 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
@ExternalizedSqlViaStringTemplate3
@RegisterMapper(TagDefinitionSqlDao.TagDefinitionMapper.class)
-public interface TagDefinitionSqlDao extends UpdatableEntityDao<TagDefinition> {
- @Override
- @SqlUpdate
- public void create(@TagDefinitionBinder final TagDefinition entity);
-
+public interface TagDefinitionSqlDao extends EntityDao<TagDefinition> {
@Override
@SqlUpdate
- public void update(@TagDefinitionBinder final TagDefinition entity);
+ public void create(@TagDefinitionBinder final TagDefinition entity, @CallContextBinder final CallContext context);
@SqlUpdate
- public void deleteAllTagsForDefinition(@Bind("name") final String definitionName);
+ public void deleteAllTagsForDefinition(@Bind("name") final String definitionName, @CallContextBinder final CallContext context);
@SqlUpdate
- public void deleteTagDefinition(@Bind("name") final String definitionName);
+ public void deleteTagDefinition(@Bind("name") final String definitionName, @CallContextBinder final CallContext context);
@SqlQuery
public int tagDefinitionUsageCount(@Bind("name") final String definitionName);
@@ -71,7 +69,8 @@ public interface TagDefinitionSqlDao extends UpdatableEntityDao<TagDefinition> {
String name = result.getString("name");
String description = result.getString("description");
String createdBy = result.getString("created_by");
- return new DefaultTagDefinition(id, name, description, createdBy);
+ DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
+ return new DefaultTagDefinition(id, createdBy, createdDate, name, description);
}
}
@@ -85,7 +84,6 @@ public interface TagDefinitionSqlDao extends UpdatableEntityDao<TagDefinition> {
public void bind(final SQLStatement q, final TagDefinitionBinder bind, final TagDefinition tagDefinition) {
q.bind("id", tagDefinition.getId().toString());
q.bind("name", tagDefinition.getName());
- q.bind("createdBy", tagDefinition.getCreatedBy());
q.bind("description", tagDefinition.getDescription());
}
};
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TaggableDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TaggableDao.java
new file mode 100644
index 0000000..de45f87
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TaggableDao.java
@@ -0,0 +1,28 @@
+/*
+ * 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.util.tag.dao;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.ControlTagType;
+
+import java.util.UUID;
+
+public interface TaggableDao {
+ public void addControlTag(ControlTagType controlTagType, UUID objectId, CallContext context);
+
+ public void removeControlTag(ControlTagType controlTagType, UUID objectId, CallContext context);
+}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
index 4e3804f..74e6f04 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
@@ -18,40 +18,42 @@ package com.ning.billing.util.tag.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
import java.util.UUID;
+
+import com.ning.billing.util.entity.MapperBase;
+import com.ning.billing.util.tag.ControlTag;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
import com.ning.billing.util.tag.ControlTagType;
import com.ning.billing.util.tag.DefaultControlTag;
-import com.ning.billing.util.tag.DefaultTagDefinition;
import com.ning.billing.util.tag.DescriptiveTag;
import com.ning.billing.util.tag.Tag;
-import com.ning.billing.util.tag.TagDefinition;
-public class TagMapper implements ResultSetMapper<Tag> {
+public class TagMapper extends MapperBase implements ResultSetMapper<Tag> {
@Override
public Tag map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
String name = result.getString("tag_definition_name");
- UUID id = UUID.fromString(result.getString("id"));
- String addedBy = result.getString("added_by");
- DateTime addedDate = new DateTime(result.getTimestamp("added_date"));
+ ControlTagType thisTagType = null;
+ for (ControlTagType controlTagType : ControlTagType.values()) {
+ if (name.equals(controlTagType.toString())) {
+ thisTagType = controlTagType;
+ }
+ }
- Tag tag;
- try {
- ControlTagType controlTagType = ControlTagType.valueOf(name);
- tag = new DefaultControlTag(id, addedBy, addedDate, controlTagType);
- } catch (Throwable t) {
- String description = result.getString("tag_description");
+ if (thisTagType == null) {
+ UUID id = UUID.fromString(result.getString("id"));
String createdBy = result.getString("created_by");
+ DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
- UUID tagDefinitionId = UUID.fromString(result.getString("tag_definition_id"));
- TagDefinition tagDefinition = new DefaultTagDefinition(tagDefinitionId, name, description, createdBy);
- tag = new DescriptiveTag(id, tagDefinition, addedBy, addedDate);
+ return new DescriptiveTag(id, createdBy, createdDate, name);
+ } else {
+ return new DefaultControlTag(thisTagType);
}
-
- return tag;
}
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java
new file mode 100644
index 0000000..79b68b0
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagSqlDao.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.tag.dao;
+
+import java.util.List;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlBatch;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+import com.ning.billing.util.entity.EntityCollectionDao;
+import com.ning.billing.util.tag.Tag;
+
+@ExternalizedSqlViaStringTemplate3
+@RegisterMapper(TagMapper.class)
+public interface TagSqlDao extends EntityCollectionDao<Tag>, Transactional<TagSqlDao>, Transmogrifier {
+ @Override
+ @SqlBatch(transactional=false)
+ public void batchInsertFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @TagBinder final List<Tag> entities,
+ @CallContextBinder final CallContext context);
+
+ @Override
+ @SqlBatch(transactional=false)
+ public void batchDeleteFromTransaction(@Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @TagBinder final List<Tag> entities,
+ @CallContextBinder final CallContext context);
+
+ @SqlUpdate
+ public void addTagFromTransaction(@Bind("id") final String tagId,
+ @Bind("tagDefinitionName") final String tagName,
+ @Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CallContextBinder final CallContext context);
+
+ @SqlUpdate
+ public void removeTagFromTransaction(@Bind("tagDefinitionName") final String tagName,
+ @Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType,
+ @CallContextBinder final CallContext context);
+
+ @SqlQuery
+ public Tag findTag(@Bind("tagDefinitionName") final String tagName,
+ @Bind("objectId") final String objectId,
+ @Bind("objectType") final String objectType);
+}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java b/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
index 588beb7..662de60 100644
--- a/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
+++ b/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
@@ -22,15 +22,16 @@ import org.joda.time.DateTime;
public class DefaultControlTag extends DescriptiveTag implements ControlTag {
private final ControlTagType controlTagType;
- public DefaultControlTag(final String addedBy,
- final DateTime addedDate, final ControlTagType controlTagType) {
- this(UUID.randomUUID(), addedBy, addedDate, controlTagType);
+ // use to create new objects
+ public DefaultControlTag(final ControlTagType controlTagType) {
+ super(controlTagType.toString());
+ this.controlTagType = controlTagType;
}
- public DefaultControlTag(final UUID id, final String addedBy,
- final DateTime addedDate, final ControlTagType controlTagType) {
-
- super(id, controlTagType.toString(), addedBy, addedDate);
+ // use to hydrate objects when loaded from the persistence layer
+ public DefaultControlTag(final UUID id, final String createdBy,
+ final DateTime createdDate, final ControlTagType controlTagType) {
+ super(id, createdBy, createdDate, controlTagType.toString());
this.controlTagType = controlTagType;
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/DefaultTagDefinition.java b/util/src/main/java/com/ning/billing/util/tag/DefaultTagDefinition.java
index 482e56d..0eb0ac9 100644
--- a/util/src/main/java/com/ning/billing/util/tag/DefaultTagDefinition.java
+++ b/util/src/main/java/com/ning/billing/util/tag/DefaultTagDefinition.java
@@ -18,23 +18,22 @@ package com.ning.billing.util.tag;
import java.util.UUID;
import com.ning.billing.util.entity.EntityBase;
+import org.joda.time.DateTime;
public class DefaultTagDefinition extends EntityBase implements TagDefinition {
private String name;
private String description;
- private String createdBy;
- public DefaultTagDefinition(String name, String description,
- String createdBy) {
- this(UUID.randomUUID(), name, description, createdBy);
+ public DefaultTagDefinition(String name, String description) {
+ super();
+ this.name = name;
+ this.description = description;
}
- public DefaultTagDefinition(UUID id, String name, String description,
- String createdBy) {
- super(id);
+ public DefaultTagDefinition(UUID id, String createdBy, DateTime createdDate, String name, String description) {
+ super(id, createdBy, createdDate);
this.name = name;
this.description = description;
- this.createdBy = createdBy;
}
@Override
@@ -43,11 +42,6 @@ public class DefaultTagDefinition extends EntityBase implements TagDefinition {
}
@Override
- public String getCreatedBy() {
- return createdBy;
- }
-
- @Override
public String getDescription() {
return description;
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/DescriptiveTag.java b/util/src/main/java/com/ning/billing/util/tag/DescriptiveTag.java
index ced1938..1ad70fe 100644
--- a/util/src/main/java/com/ning/billing/util/tag/DescriptiveTag.java
+++ b/util/src/main/java/com/ning/billing/util/tag/DescriptiveTag.java
@@ -17,41 +17,39 @@
package com.ning.billing.util.tag;
import java.util.UUID;
-import org.joda.time.DateTime;
+
+import com.google.inject.Inject;
+import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.entity.EntityBase;
+import com.ning.billing.util.entity.UpdatableEntityBase;
+import org.joda.time.DateTime;
public class DescriptiveTag extends EntityBase implements Tag {
private final String tagDefinitionName;
- private final String addedBy;
- private final DateTime addedDate;
- public DescriptiveTag(UUID id, String tagDefinitionName, String addedBy, DateTime addedDate) {
- super(id);
+ @Inject
+ private Clock clock;
+
+ // use to hydrate objects from the persistence layer
+ public DescriptiveTag(UUID id, String createdBy, DateTime createdDate, String tagDefinitionName) {
+ super(id, createdBy, createdDate);
this.tagDefinitionName = tagDefinitionName;
- this.addedBy = addedBy;
- this.addedDate = addedDate;
}
- public DescriptiveTag(UUID id, TagDefinition tagDefinition, String addedBy, DateTime addedDate) {
- this(id, tagDefinition.getName(), addedBy, addedDate);
+ // use to create new objects
+ public DescriptiveTag(TagDefinition tagDefinition) {
+ super();
+ this.tagDefinitionName = tagDefinition.getName();
}
- public DescriptiveTag(TagDefinition tagDefinition, String addedBy, DateTime addedDate) {
- this(UUID.randomUUID(), tagDefinition.getName(), addedBy, addedDate);
+ // use to create new objects
+ public DescriptiveTag(String tagDefinitionName) {
+ super();
+ this.tagDefinitionName = tagDefinitionName;
}
@Override
public String getTagDefinitionName() {
return tagDefinitionName;
}
-
- @Override
- public String getAddedBy() {
- return addedBy;
- }
-
- @Override
- public DateTime getAddedDate() {
- return addedDate;
- }
}
diff --git a/util/src/main/resources/com/ning/billing/util/audit/dao/AuditSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/audit/dao/AuditSqlDao.sql.stg
new file mode 100644
index 0000000..25cc9d4
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/audit/dao/AuditSqlDao.sql.stg
@@ -0,0 +1,16 @@
+group AuditSqlDao;
+
+fields(prefix) ::= <<
+ <prefix>table_name,
+ <prefix>record_id,
+ <prefix>change_type,
+ <prefix>change_date,
+ <prefix>changed_by,
+ <prefix>reason_code,
+ <prefix>comments
+>>
+
+insertAuditFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES(:tableName, :recordId, :changeType, :createdDate, :userName, NULL, NULL);
+>>
\ No newline at end of file
diff --git a/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.sql.stg
new file mode 100644
index 0000000..99a2830
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldAuditSqlDao.sql.stg
@@ -0,0 +1,17 @@
+group CustomFieldAuditSqlDao;
+
+fields(prefix) ::= <<
+ <prefix>table_name,
+ <prefix>record_id,
+ <prefix>change_type,
+ <prefix>change_date,
+ <prefix>changed_by,
+ <prefix>reason_code,
+ <prefix>comments
+>>
+
+batchInsertAuditLogFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES('custom_field_history', :id, :changeType, :createdDate, :userName, NULL, NULL);
+>>
+;
\ No newline at end of file
diff --git a/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.sql.stg
new file mode 100644
index 0000000..c9e2ab0
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldHistorySqlDao.sql.stg
@@ -0,0 +1,18 @@
+group CustomFieldHistorySqlDao;
+
+fields(prefix) ::= <<
+ <prefix>history_id,
+ <prefix>id,
+ <prefix>object_id,
+ <prefix>object_type,
+ <prefix>field_name,
+ <prefix>field_value,
+ <prefix>updated_by,
+ <prefix>date,
+ <prefix>change_type
+>>
+
+batchAddHistoryFromTransaction() ::= <<
+ INSERT INTO custom_field_history(<fields()>)
+ VALUES(:historyId, :id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :updatedDate, :changeType);
+>>
\ No newline at end of file
diff --git a/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
new file mode 100644
index 0000000..1fbf994
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
@@ -0,0 +1,29 @@
+group CustomFieldSqlDao;
+
+batchInsertFromTransaction() ::= <<
+ INSERT INTO custom_fields(id, object_id, object_type, field_name, field_value, created_by, created_date, updated_by, updated_date)
+ VALUES (:id, :objectId, :objectType, :fieldName, :fieldValue, :userName, :createdDate, :userName, :updatedDate);
+>>
+
+batchUpdateFromTransaction() ::= <<
+ UPDATE custom_fields
+ SET field_value = :fieldValue, updated_by = :userName, updated_date = :updatedDate
+ WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName;
+>>
+
+batchDeleteFromTransaction() ::= <<
+ DELETE FROM custom_fields
+ WHERE object_id = :objectId AND object_type = :objectType AND field_name = :fieldName;
+>>
+
+load() ::= <<
+ SELECT id, object_id, object_type, field_name, field_value, created_by, created_date, updated_by, updated_date
+ FROM custom_fields
+ WHERE object_id = :objectId AND object_type = :objectType;
+>>
+
+test() ::= <<
+ SELECT 1 FROM custom_fields;
+>>
+;
+
diff --git a/util/src/main/resources/com/ning/billing/util/ddl.sql b/util/src/main/resources/com/ning/billing/util/ddl.sql
index f7db1db..17442c1 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -5,8 +5,10 @@ CREATE TABLE custom_fields (
object_type varchar(30) NOT NULL,
field_name varchar(30) NOT NULL,
field_value varchar(255),
+ created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
- updated_date datetime NOT NULL,
+ updated_by varchar(50) DEFAULT NULL,
+ updated_date datetime DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
CREATE INDEX custom_fields_object_id_object_type ON custom_fields(object_id, object_type);
@@ -14,40 +16,26 @@ CREATE UNIQUE INDEX custom_fields_unique ON custom_fields(object_id, object_type
DROP TABLE IF EXISTS custom_field_history;
CREATE TABLE custom_field_history (
+ history_id char(36) NOT NULL,
id char(36) NOT NULL,
object_id char(36) NOT NULL,
object_type varchar(30) NOT NULL,
field_name varchar(30),
field_value varchar(255),
+ updated_by varchar(50) NOT NULL,
date datetime NOT NULL,
change_type char(6) NOT NULL
) ENGINE=innodb;
CREATE INDEX custom_field_history_object_id_object_type ON custom_fields(object_id, object_type);
-CREATE TRIGGER store_custom_field_history_on_insert AFTER INSERT ON custom_fields
- FOR EACH ROW
- INSERT INTO custom_field_history (id, object_id, object_type, field_name, field_value, date, change_type)
- VALUES (NEW.id, NEW.object_id, NEW.object_type, NEW.field_name, NEW.field_value, NOW(), 'CREATE');
-
-CREATE TRIGGER store_custom_field_history_on_update AFTER UPDATE ON custom_fields
- FOR EACH ROW
- INSERT INTO custom_field_history (id, object_id, object_type, field_name, field_value, date, change_type)
- VALUES (NEW.id, NEW.object_id, NEW.object_type, NEW.field_name, NEW.field_value, NOW(), 'UPDATE');
-
-CREATE TRIGGER store_custom_field_history_on_delete BEFORE DELETE ON custom_fields
- FOR EACH ROW
- INSERT INTO custom_field_history (id, object_id, object_type, field_name, field_value, date, change_type)
- VALUES (OLD.id, OLD.object_id, OLD.object_type, NULL, NULL, NOW(), 'DELETE');
-
DROP TABLE IF EXISTS tag_descriptions;
DROP TABLE IF EXISTS tag_definitions;
CREATE TABLE tag_definitions (
id char(36) NOT NULL,
name varchar(20) NOT NULL,
- created_by varchar(50) NOT NULL,
description varchar(200) NOT NULL,
+ created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
- updated_date datetime NOT NULL,
PRIMARY KEY(id)
) ENGINE=innodb;
CREATE UNIQUE INDEX tag_definitions_name ON tag_definitions(name);
@@ -58,35 +46,21 @@ CREATE TABLE tag_definition_history (
name varchar(30) NOT NULL,
created_by varchar(50),
description varchar(200),
- date datetime NOT NULL,
- change_type char(6) NOT NULL
+ change_type char(6) NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ date datetime NOT NULL
) ENGINE=innodb;
CREATE INDEX tag_definition_history_id ON tag_definition_history(id);
CREATE INDEX tag_definition_history_name ON tag_definition_history(name);
-CREATE TRIGGER tag_definition_history_after_insert AFTER INSERT ON tag_definition_history
- FOR EACH ROW
- INSERT INTO tag_definition_history (id, name, created_by, description, date, change_type)
- VALUES (NEW.id, NEW.name, NEW.created_by, NEW.description, NOW(), 'CREATE');
-
-CREATE TRIGGER tag_definition_history_after_update AFTER UPDATE ON tag_definition_history
- FOR EACH ROW
- INSERT INTO tag_definition_history (id, name, created_by, description, date, change_type)
- VALUES (NEW.id, NEW.name, NEW.created_by, NEW.description, NOW(), 'UPDATE');
-
-CREATE TRIGGER tag_definition_history_before_delete BEFORE DELETE ON tag_definition_history
- FOR EACH ROW
- INSERT INTO tag_definition_history (id, name, created_by, description, date, change_type)
- VALUES (OLD.id, OLD.name, NULL, NULL, NOW(), 'DELETE');
-
DROP TABLE IF EXISTS tags;
CREATE TABLE tags (
id char(36) NOT NULL,
tag_definition_name varchar(20) NOT NULL,
object_id char(36) NOT NULL,
object_type varchar(30) NOT NULL,
- added_date datetime NOT NULL,
- added_by varchar(50) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
PRIMARY KEY(id)
) ENGINE = innodb;
CREATE INDEX tags_by_object ON tags(object_id);
@@ -98,26 +72,12 @@ CREATE TABLE tag_history (
tag_definition_name varchar(20) NOT NULL,
object_id char(36) NOT NULL,
object_type varchar(30) NOT NULL,
- date datetime NOT NULL,
- change_type char(6) NOT NULL
+ change_type char(6) NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ date datetime NOT NULL
) ENGINE = innodb;
CREATE INDEX tag_history_by_object ON tags(object_id);
-CREATE TRIGGER tag_history_after_insert AFTER INSERT ON tag_history
- FOR EACH ROW
- INSERT INTO tag_history (id, tag_definition_name, object_id, object_type, date, change_type)
- VALUES (NEW.id, NEW.tag_definition_name, NEW.object_id, NEW.object_type, NOW(), 'CREATE');
-
-CREATE TRIGGER tag_history_after_update AFTER UPDATE ON tag_history
- FOR EACH ROW
- INSERT INTO tag_history (id, tag_definition_name, object_id, object_type, date, change_type)
- VALUES (NEW.id, NEW.tag_definition_name, NEW.object_id, NEW.object_type, NOW(), 'UPDATE');
-
-CREATE TRIGGER tag_history_before_delete BEFORE DELETE ON tag_history
- FOR EACH ROW
- INSERT INTO tag_history (id, tag_definition_name, object_id, object_type, date, change_type)
- VALUES (OLD.id, OLD.tag_definition_name, OLD.object_id, OLD.object_type, NOW(), 'DELETE');
-
DROP TABLE IF EXISTS notifications;
CREATE TABLE notifications (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -137,10 +97,23 @@ CREATE INDEX `idx_get_ready` ON notifications (`effective_dt`,`created_dt`,`id`
DROP TABLE IF EXISTS claimed_notifications;
CREATE TABLE claimed_notifications (
- id int(11) unsigned NOT NULL AUTO_INCREMENT,
- sequence_id int(11) unsigned NOT NULL,
+ id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ sequence_id int(11) unsigned NOT NULL,
owner_id varchar(64) NOT NULL,
claimed_dt datetime NOT NULL,
notification_id char(36) NOT NULL,
PRIMARY KEY(id)
-) ENGINE=innodb;
\ No newline at end of file
+) ENGINE=innodb;
+
+DROP TABLE IF EXISTS audit_log;
+CREATE TABLE audit_log (
+ id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ table_name varchar(50) NOT NULL,
+ record_id char(36) NOT NULL,
+ change_type char(6) NOT NULL,
+ change_date datetime NOT NULL,
+ changed_by varchar(50) NOT NULL,
+ reason_code varchar(20) DEFAULT NULL,
+ comments varchar(255) DEFAULT NULL,
+ PRIMARY KEY(id)
+) ENGINE=innodb;
diff --git a/util/src/main/resources/com/ning/billing/util/tag/dao/TagAuditSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/tag/dao/TagAuditSqlDao.sql.stg
new file mode 100644
index 0000000..c591fba
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/tag/dao/TagAuditSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group TagAuditSqlDao;
+
+fields(prefix) ::= <<
+ <prefix>table_name,
+ <prefix>record_id,
+ <prefix>change_type,
+ <prefix>change_date,
+ <prefix>changed_by,
+ <prefix>reason_code,
+ <prefix>comments
+>>
+
+batchInsertFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES('tag', :id, 'INSERT', :createdDate, :userName, NULL, NULL);
+>>
+
+batchDeleteFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES('tag', :id, 'DELETE', :updatedDate, :userName, NULL, NULL);
+>>
+
+addTagFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES('tag', :id, 'INSERT', :createdDate, :userName, NULL, NULL);
+>>
+
+removeTagFromTransaction() ::= <<
+ INSERT INTO audit_log(<fields()>)
+ VALUES('tag', :id, 'DELETE', :updatedDate, :userName, NULL, NULL);
+>>
\ No newline at end of file
diff --git a/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
index 333da26..54bdfa9 100644
--- a/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
@@ -3,10 +3,9 @@ group TagDefinitionDao;
fields(prefix) ::= <<
<prefix>id,
<prefix>name,
- <prefix>created_by,
<prefix>description,
- <prefix>created_date,
- <prefix>updated_date
+ <prefix>created_by,
+ <prefix>created_date
>>
get() ::= <<
@@ -16,13 +15,7 @@ get() ::= <<
create() ::= <<
INSERT INTO tag_definitions(<fields()>)
- VALUES(:id, :name, :createdBy, :description, NOW(), NOW());
->>
-
-update() ::= <<
- UPDATE tag_definitions
- SET name = :name, created_by = :createdBy, description = :description, updated_date = NOW())
- WHERE id = :id;
+ VALUES(:id, :name, :description, :userName, :createdDate);
>>
load() ::= <<
diff --git a/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg
new file mode 100644
index 0000000..e950d75
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/tag/dao/TagSqlDao.sql.stg
@@ -0,0 +1,54 @@
+group TagDao;
+
+fields(prefix) ::= <<
+ <prefix>id,
+ <prefix>tag_definition_name,
+ <prefix>object_id,
+ <prefix>object_type,
+ <prefix>created_by,
+ <prefix>created_date
+>>
+
+batchInsertFromTransaction() ::= <<
+ INSERT INTO tags(<fields()>)
+ VALUES (:id, :tagDefinitionName, :objectId, :objectType, :userName, :createdDate);
+>>
+
+batchDeleteFromTransaction() ::= <<
+ DELETE FROM tags
+ WHERE tag_definition_name = :tagDefinitionName
+ AND object_id = :objectId AND object_type = :objectType;
+>>
+
+addTagFromTransaction() ::= <<
+ INSERT INTO tags(<fields()>)
+ VALUES (:id, :tagDefinitionName, :objectId, :objectType, :userName, :createdDate);
+>>
+
+removeTagFromTransaction() ::= <<
+ DELETE FROM tags
+ WHERE tag_definition_name = :tagDefinitionName
+ AND object_id = :objectId AND object_type = :objectType;
+>>
+
+findTag() ::= <<
+ SELECT <fields()> FROM tags
+ WHERE tag_definition_name = :tagDefinitionName
+ AND object_id = :objectId AND object_type = :objectType;
+>>
+
+load() ::= <<
+ SELECT t.id, t.object_id, t.object_type, t.created_by, t.created_date,
+ td.id AS tag_definition_id,
+ t.tag_definition_name AS tag_definition_name,
+ td.description AS tag_description,
+ td.created_by
+ FROM tags t
+ LEFT JOIN tag_definitions td ON t.tag_definition_name = td.name
+ WHERE t.object_id = :objectId AND t.object_type = :objectType;
+>>
+
+test() ::= <<
+ SELECT 1 FROM tags;
+>>
+;
\ No newline at end of file
diff --git a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
index 98d498c..866289e 100644
--- a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
+++ b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
@@ -134,7 +134,7 @@ public class MysqlTestingHelper
public IDBI getDBI()
{
- final String dbiString = "jdbc:mysql://localhost:" + port + "/" + DB_NAME + "?createDatabaseIfNotExist=true";
+ final String dbiString = "jdbc:mysql://localhost:" + port + "/" + DB_NAME + "?createDatabaseIfNotExist=true&allowMultiQueries=true";
return new DBI(dbiString, USERNAME, PASSWORD);
}
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
new file mode 100644
index 0000000..b632f2e
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.util.callcontext;
+
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+
+public class TestCallContext implements CallContext {
+ private final String userName;
+ private final DateTime updatedDate;
+ private final DateTime createdDate;
+
+ public TestCallContext(String userName) {
+ this.userName = userName;
+ DateTime now = new DefaultClock().getUTCNow();
+ this.updatedDate = now;
+ this.createdDate = now;
+ }
+
+ public TestCallContext(String userName, DateTime createdDate, DateTime updatedDate) {
+ this.userName = userName;
+ this.createdDate = createdDate;
+ this.updatedDate = updatedDate;
+ }
+
+ @Override
+ public String getUserName() {
+ return userName;
+ }
+
+ @Override
+ public CallOrigin getCallOrigin() {
+ return CallOrigin.TEST;
+ }
+
+ @Override
+ public UserType getUserType() {
+ return UserType.TEST;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return updatedDate;
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
index 9bc67dd..8a2385b 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
@@ -17,19 +17,29 @@
package com.ning.billing.util.customfield;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.UUID;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.MockClockModule;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.glue.FieldStoreModule;
import org.apache.commons.io.IOUtils;
import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.Transaction;
-import org.skife.jdbi.v2.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.util.customfield.dao.FieldStoreDao;
+import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
@@ -38,7 +48,9 @@ import static org.testng.Assert.fail;
public class TestFieldStore {
Logger log = LoggerFactory.getLogger(TestFieldStore.class);
private final MysqlTestingHelper helper = new MysqlTestingHelper();
+ private CallContext context;
private IDBI dbi;
+ private CustomFieldDao customFieldDao;
@BeforeClass(groups = {"util", "slow"})
protected void setup() throws IOException {
@@ -50,6 +62,13 @@ public class TestFieldStore {
helper.initDb(utilDdl);
dbi = helper.getDBI();
+ customFieldDao = new AuditedCustomFieldDao();
+
+ FieldStoreModule module = new FieldStoreModule();
+ final Injector injector = Guice.createInjector(Stage.DEVELOPMENT, module, new MockClockModule());
+ Clock clock = injector.getInstance(Clock.class);
+ context = new DefaultCallContextFactory(clock).createCallContext("Fezzik", CallOrigin.TEST, UserType.TEST);
+
}
catch (Throwable t) {
log.error("Setup failed", t);
@@ -74,38 +93,22 @@ public class TestFieldStore {
String fieldValue = "Kitty Hawk";
fieldStore1.setValue(fieldName, fieldValue);
- FieldStoreDao fieldStoreDao = dbi.onDemand(FieldStoreDao.class);
- fieldStoreDao.inTransaction(new Transaction<Void, FieldStoreDao>() {
- @Override
- public Void inTransaction(FieldStoreDao transactional,
- TransactionStatus status) throws Exception {
- transactional.batchSaveFromTransaction(id.toString(), objectType, fieldStore1.getEntityList());
- return null;
- }
- });
-
+ CustomFieldSqlDao customFieldSqlDao = dbi.onDemand(CustomFieldSqlDao.class);
+ customFieldDao.saveFields(customFieldSqlDao, id, objectType, fieldStore1.getEntityList(), context);
final FieldStore fieldStore2 = DefaultFieldStore.create(id, objectType);
- fieldStore2.add(fieldStoreDao.load(id.toString(), objectType));
+ fieldStore2.add(customFieldSqlDao.load(id.toString(), objectType));
assertEquals(fieldStore2.getValue(fieldName), fieldValue);
fieldValue = "Cape Canaveral";
fieldStore2.setValue(fieldName, fieldValue);
assertEquals(fieldStore2.getValue(fieldName), fieldValue);
- fieldStoreDao.inTransaction(new Transaction<Void, FieldStoreDao>() {
- @Override
- public Void inTransaction(FieldStoreDao transactional,
- TransactionStatus status) throws Exception {
- transactional.batchSaveFromTransaction(id.toString(), objectType, fieldStore2.getEntityList());
- return null;
- }
- });
-
+ customFieldDao.saveFields(customFieldSqlDao, id, objectType, fieldStore2.getEntityList(), context);
final FieldStore fieldStore3 = DefaultFieldStore.create(id, objectType);
assertEquals(fieldStore3.getValue(fieldName), null);
- fieldStore3.add(fieldStoreDao.load(id.toString(), objectType));
+ fieldStore3.add(customFieldSqlDao.load(id.toString(), objectType));
assertEquals(fieldStore3.getValue(fieldName), fieldValue);
}
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index f9e874e..fefbcdb 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -178,9 +178,9 @@ public class TestNotificationQueue {
}
});
- Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
queue.stopQueue();
- }
+ Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
+ }
@Test(groups="slow")
public void testManyNotifications() throws InterruptedException {
@@ -252,18 +252,18 @@ public class TestNotificationQueue {
}
});
- if (completed.size() == MAX_NOTIFICATIONS) {
- success = true;
- break;
- }
- //log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
- expectedNotifications.wait(1000);
- }
- } while (nbTry-- > 0);
- assertEquals(success, true);
- queue.stopQueue();
+ if (completed.size() == MAX_NOTIFICATIONS) {
+ success = true;
+ break;
+ }
+ //log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
+ expectedNotifications.wait(1000);
+ }
+ } while (nbTry-- > 0);
- }
+ queue.stopQueue();
+ assertEquals(success, true);
+ }
/**
* Test that we can post a notification in the future from a transaction and get the notification
@@ -380,10 +380,10 @@ public class TestNotificationQueue {
// expected behavior
}
- Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
- Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
queueFred.stopQueue();
- }
+ Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
+ Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
+ }
NotificationConfig getNotificationConfig(final boolean off,
final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java
new file mode 100644
index 0000000..553bc3c
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDao.java
@@ -0,0 +1,106 @@
+/*
+ * 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.util.tag.dao;
+
+import com.google.inject.Inject;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.tag.Tag;
+import org.joda.time.DateTime;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class MockTagDao implements TagDao {
+ private Map<UUID, List<Tag>> tagStore = new HashMap<UUID, List<Tag>>();
+ private final Clock clock;
+
+ @Inject
+ public MockTagDao(Clock clock) {
+ this.clock = clock;
+ }
+
+ @Override
+ public void saveTagsFromTransaction(final Transmogrifier dao, final UUID objectId, final String objectType,
+ final List<Tag> tags, final CallContext context) {
+ tagStore.put(objectId, tags);
+ }
+
+ @Override
+ public void saveTags(UUID objectId, String objectType, List<Tag> tags, CallContext context) {
+ tagStore.put(objectId, tags);
+ }
+
+ @Override
+ public List<Tag> loadTags(UUID objectId, String objectType) {
+ return tagStore.get(objectId);
+ }
+
+ @Override
+ public List<Tag> loadTagsFromTransaction(Transmogrifier dao, UUID objectId, String objectType) {
+ return tagStore.get(objectId);
+ }
+
+ @Override
+ public void addTag(final String tagName, final UUID objectId, final String objectType, final CallContext context) {
+ Tag tag = new Tag() {
+ private UUID id = UUID.randomUUID();
+ private DateTime createdDate = clock.getUTCNow();
+
+ @Override
+ public String getTagDefinitionName() {
+ return tagName;
+ }
+
+ @Override
+ public UUID getId() {
+ return id;
+ }
+
+ @Override
+ public String getCreatedBy() {
+ return context.getUserName();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+ };
+
+
+ tagStore.get(objectId).add(tag);
+ }
+
+ @Override
+ public void removeTag(String tagName, UUID objectId, String objectType, CallContext context) {
+ List<Tag> tags = tagStore.get(objectId);
+ if (tags != null) {
+ Iterator<Tag> tagIterator = tags.iterator();
+ while (tagIterator.hasNext()) {
+ Tag tag = tagIterator.next();
+ if (tag.getTagDefinitionName().equals(tagName)) {
+ tagIterator.remove();
+ }
+ }
+ }
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
index 425020e..adcb848 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/MockTagDefinitionDao.java
@@ -19,9 +19,9 @@ package com.ning.billing.util.tag.dao;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.tag.DefaultTagDefinition;
import com.ning.billing.util.tag.TagDefinition;
@@ -35,25 +35,26 @@ public class MockTagDefinitionDao implements TagDefinitionDao {
}
@Override
- public TagDefinition getByName(String definitionName) {
+ public TagDefinition getByName(final String definitionName) {
return tags.get(definitionName);
}
@Override
- public TagDefinition create(String definitionName, String description, String createdBy) throws TagDefinitionApiException {
- TagDefinition tag = new DefaultTagDefinition(UUID.randomUUID(), definitionName, description, createdBy);
+ public TagDefinition create(final String definitionName, final String description,
+ final CallContext context) throws TagDefinitionApiException {
+ TagDefinition tag = new DefaultTagDefinition(definitionName, description);
tags.put(definitionName, tag);
return tag;
}
@Override
- public void deleteAllTagsForDefinition(String definitionName) throws TagDefinitionApiException {
+ public void deleteAllTagsForDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
tags.remove(definitionName);
}
@Override
- public void deleteTagDefinition(String definitionName) throws TagDefinitionApiException {
+ public void deleteTagDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
tags.remove(definitionName);
}
}
diff --git a/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleMemory.java b/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleMemory.java
new file mode 100644
index 0000000..3acc3a1
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/tag/MockTagStoreModuleMemory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.util.tag;
+
+import com.ning.billing.util.glue.TagStoreModule;
+import com.ning.billing.util.tag.dao.MockTagDao;
+import com.ning.billing.util.tag.dao.MockTagDefinitionDao;
+import com.ning.billing.util.tag.dao.TagDao;
+import com.ning.billing.util.tag.dao.TagDefinitionDao;
+
+public class MockTagStoreModuleMemory extends TagStoreModule {
+ @Override
+ protected void installDaos() {
+ bind(TagDefinitionDao.class).to(MockTagDefinitionDao.class).asEagerSingleton();
+ bind(TagDao.class).to(MockTagDao.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
index 90ccaea..1e51e57 100644
--- a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
+++ b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
@@ -18,12 +18,22 @@ package com.ning.billing.util.tag;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.tag.dao.TagDao;
import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.joda.time.Seconds;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.Transaction;
-import org.skife.jdbi.v2.TransactionStatus;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import org.skife.jdbi.v2.tweak.HandleCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,10 +46,7 @@ import com.google.inject.Inject;
import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.tag.dao.TagDefinitionDao;
-import com.ning.billing.util.tag.dao.TagStoreSqlDao;
-
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -48,10 +55,8 @@ import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test(groups={"slow"})
-@Guice(modules = TagStoreModuleMock.class)
+@Guice(modules = MockTagStoreModuleSql.class)
public class TestTagStore {
- private final static String ACCOUNT_TYPE = "ACCOUNT";
-
@Inject
private MysqlTestingHelper helper;
@@ -59,19 +64,19 @@ public class TestTagStore {
private IDBI dbi;
@Inject
- private TagStoreSqlDao tagStoreSqlDao;
-
+ private TagDao tagDao;
+
@Inject
private TagDefinitionDao tagDefinitionDao;
@Inject
private Clock clock;
- private TagDefinition tag1;
- private TagDefinition tag2;
-
+ private TagDefinition testTag;
+ private TestSqlDao dao;
private final Logger log = LoggerFactory.getLogger(TestTagStore.class);
+ private CallContext context;
@BeforeClass(groups="slow")
protected void setup() throws IOException {
@@ -81,12 +86,13 @@ public class TestTagStore {
helper.startMysql();
helper.initDb(utilDdl);
- tagStoreSqlDao.test();
+ context = new DefaultCallContextFactory(clock).createCallContext("Tag store test", CallOrigin.TEST, UserType.TEST);
+ dao = dbi.onDemand(TestSqlDao.class);
+
cleanupTags();
- tag1 = tagDefinitionDao.create("tag1", "First tag", "test");
- tag2 = tagDefinitionDao.create("tag2", "Second tag", "test");
-
+ tagDefinitionDao.create("tag1", "First tag", context);
+ testTag = tagDefinitionDao.create("testTag", "Second tag", context);
}
catch (Throwable t) {
log.error("Failed to start tag store tests", t);
@@ -100,18 +106,6 @@ public class TestTagStore {
helper.stopMysql();
}
- private void saveTags(final TagStoreSqlDao dao, final String objectType, final String accountId, final List<Tag> tagList) {
- dao.inTransaction(new Transaction<Void, TagStoreSqlDao>() {
- @Override
- public Void inTransaction(TagStoreSqlDao transactional,
- TransactionStatus status) throws Exception {
- dao.batchSaveFromTransaction(accountId.toString(), objectType, tagList);
- return null;
- }
- });
- }
-
-
private void cleanupTags() {
try {
helper.getDBI().withHandle(new HandleCallback<Void>() {
@@ -131,19 +125,16 @@ public class TestTagStore {
public void testTagCreationAndRetrieval() {
UUID accountId = UUID.randomUUID();
- TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
- Tag tag = new DescriptiveTag(tag2, "test", clock.getUTCNow());
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
+ Tag tag = new DescriptiveTag(testTag);
tagStore.add(tag);
- TagStoreSqlDao dao = dbi.onDemand(TagStoreSqlDao.class);
- saveTags(dao, ACCOUNT_TYPE, accountId.toString(), tagStore.getEntityList());
+ tagDao.saveTagsFromTransaction(dao, accountId, Account.ObjectType, tagStore.getEntityList(), context);
- List<Tag> savedTags = dao.load(accountId.toString(), ACCOUNT_TYPE);
+ List<Tag> savedTags = tagDao.loadTags(accountId, Account.ObjectType);
assertEquals(savedTags.size(), 1);
Tag savedTag = savedTags.get(0);
- assertEquals(savedTag.getAddedBy(), tag.getAddedBy());
- assertEquals(savedTag.getAddedDate().compareTo(tag.getAddedDate()), 0);
assertEquals(savedTag.getTagDefinitionName(), tag.getTagDefinitionName());
assertEquals(savedTag.getId(), tag.getId());
}
@@ -152,19 +143,19 @@ public class TestTagStore {
@Test(groups="slow")
public void testControlTagCreation() {
UUID accountId = UUID.randomUUID();
- TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
- ControlTag tag = new DefaultControlTag("testUser", clock.getUTCNow(), ControlTagType.AUTO_INVOICING_OFF);
+ ControlTag tag = new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF);
tagStore.add(tag);
assertEquals(tagStore.generateInvoice(), false);
List<Tag> tagList = tagStore.getEntityList();
- saveTags(tagStoreSqlDao, ACCOUNT_TYPE, accountId.toString(), tagList);
+ tagDao.saveTagsFromTransaction(dao, accountId, Account.ObjectType, tagList, context);
tagStore.clear();
assertEquals(tagStore.getEntityList().size(), 0);
- tagList = tagStoreSqlDao.load(accountId.toString(), ACCOUNT_TYPE);
+ tagList = tagDao.loadTags(accountId, Account.ObjectType);
tagStore.add(tagList);
assertEquals(tagList.size(), 1);
@@ -174,27 +165,26 @@ public class TestTagStore {
@Test(groups="slow")
public void testDescriptiveTagCreation() {
UUID accountId = UUID.randomUUID();
- TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
String definitionName = "SomeTestTag";
TagDefinition tagDefinition = null;
try {
- tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", "testUser");
+ tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", context);
} catch (TagDefinitionApiException e) {
fail("Tag definition creation failed.", e);
}
- DescriptiveTag tag = new DescriptiveTag(tagDefinition, "testUser", clock.getUTCNow());
+ DescriptiveTag tag = new DescriptiveTag(tagDefinition);
tagStore.add(tag);
assertEquals(tagStore.generateInvoice(), true);
- List<Tag> tagList = tagStore.getEntityList();
- saveTags(tagStoreSqlDao, ACCOUNT_TYPE, accountId.toString(), tagList);
+ tagDao.saveTagsFromTransaction(dao, accountId, Account.ObjectType, tagStore.getEntityList(), context);
tagStore.clear();
assertEquals(tagStore.getEntityList().size(), 0);
- tagList = tagStoreSqlDao.load(accountId.toString(), ACCOUNT_TYPE);
+ List<Tag> tagList = tagDao.loadTags(accountId, Account.ObjectType);
tagStore.add(tagList);
assertEquals(tagList.size(), 1);
@@ -204,31 +194,30 @@ public class TestTagStore {
@Test(groups="slow")
public void testMixedTagCreation() {
UUID accountId = UUID.randomUUID();
- TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
String definitionName = "MixedTagTest";
TagDefinition tagDefinition = null;
try {
- tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", "testUser");
+ tagDefinition = tagDefinitionDao.create(definitionName, "Test tag for some test purpose", context);
} catch (TagDefinitionApiException e) {
fail("Tag definition creation failed.", e);
}
- DescriptiveTag descriptiveTag = new DescriptiveTag(tagDefinition, "testUser", clock.getUTCNow());
+ DescriptiveTag descriptiveTag = new DescriptiveTag(tagDefinition);
tagStore.add(descriptiveTag);
assertEquals(tagStore.generateInvoice(), true);
- ControlTag controlTag = new DefaultControlTag("testUser", clock.getUTCNow(), ControlTagType.AUTO_INVOICING_OFF);
+ ControlTag controlTag = new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF);
tagStore.add(controlTag);
assertEquals(tagStore.generateInvoice(), false);
- List<Tag> tagList = tagStore.getEntityList();
- saveTags(tagStoreSqlDao, ACCOUNT_TYPE, accountId.toString(), tagList);
+ tagDao.saveTagsFromTransaction(dao, accountId, Account.ObjectType, tagStore.getEntityList(), context);
tagStore.clear();
assertEquals(tagStore.getEntityList().size(), 0);
- tagList = tagStoreSqlDao.load(accountId.toString(), ACCOUNT_TYPE);
+ List<Tag> tagList = tagDao.loadTags(accountId, Account.ObjectType);
tagStore.add(tagList);
assertEquals(tagList.size(), 2);
@@ -238,16 +227,16 @@ public class TestTagStore {
@Test(groups="slow")
public void testControlTags() {
UUID accountId = UUID.randomUUID();
- TagStore tagStore = new DefaultTagStore(accountId, ACCOUNT_TYPE);
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
assertEquals(tagStore.generateInvoice(), true);
assertEquals(tagStore.processPayment(), true);
- ControlTag invoiceTag = new DefaultControlTag("testUser", clock.getUTCNow(), ControlTagType.AUTO_INVOICING_OFF);
+ ControlTag invoiceTag = new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF);
tagStore.add(invoiceTag);
assertEquals(tagStore.generateInvoice(), false);
assertEquals(tagStore.processPayment(), true);
- ControlTag paymentTag = new DefaultControlTag("testUser", clock.getUTCNow(), ControlTagType.AUTO_PAY_OFF);
+ ControlTag paymentTag = new DefaultControlTag(ControlTagType.AUTO_PAY_OFF);
tagStore.add(paymentTag);
assertEquals(tagStore.generateInvoice(), false);
assertEquals(tagStore.processPayment(), false);
@@ -256,18 +245,18 @@ public class TestTagStore {
@Test(groups="slow", expectedExceptions = TagDefinitionApiException.class)
public void testTagDefinitionCreationWithControlTagName() throws TagDefinitionApiException {
String definitionName = ControlTagType.AUTO_PAY_OFF.toString();
- tagDefinitionDao.create(definitionName, "This should break", "test");
+ tagDefinitionDao.create(definitionName, "This should break", context);
}
@Test(groups="slow")
public void testTagDefinitionDeletionForUnusedDefinition() throws TagDefinitionApiException {
String definitionName = "TestTag1234";
- tagDefinitionDao.create(definitionName, "Some test tag", "test");
+ tagDefinitionDao.create(definitionName, "Some test tag", context);
TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
assertNotNull(tagDefinition);
- tagDefinitionDao.deleteTagDefinition(definitionName);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
tagDefinition = tagDefinitionDao.getByName(definitionName);
assertNull(tagDefinition);
}
@@ -275,30 +264,29 @@ public class TestTagStore {
@Test(groups="slow", expectedExceptions = TagDefinitionApiException.class)
public void testTagDefinitionDeletionForDefinitionInUse() throws TagDefinitionApiException {
String definitionName = "TestTag12345";
- tagDefinitionDao.create(definitionName, "Some test tag", "test");
+ tagDefinitionDao.create(definitionName, "Some test tag", context);
TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
assertNotNull(tagDefinition);
UUID objectId = UUID.randomUUID();
- String objectType = "TestType";
- TagStore tagStore = new DefaultTagStore(objectId, objectType);
- Tag tag = new DescriptiveTag(tagDefinition, "test", clock.getUTCNow());
+ TagStore tagStore = new DefaultTagStore(objectId, Account.ObjectType);
+ Tag tag = new DescriptiveTag(tagDefinition);
tagStore.add(tag);
- saveTags(tagStoreSqlDao, objectType, objectId.toString(), tagStore.getEntityList());
+ tagDao.saveTags(objectId, Account.ObjectType, tagStore.getEntityList(), context);
- List<Tag> tags = tagStoreSqlDao.load(objectId.toString(), objectType);
+ List<Tag> tags = tagDao.loadTags(objectId, Account.ObjectType);
assertEquals(tags.size(), 1);
- tagDefinitionDao.deleteTagDefinition(definitionName);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
}
@Test(groups="slow")
public void testDeleteAllTagsForDefinitionInUse() {
String definitionName = "TestTag1234567";
try {
- tagDefinitionDao.create(definitionName, "Some test tag", "test");
+ tagDefinitionDao.create(definitionName, "Some test tag", context);
} catch (TagDefinitionApiException e) {
fail("Could not create tag definition", e);
}
@@ -307,24 +295,23 @@ public class TestTagStore {
assertNotNull(tagDefinition);
UUID objectId = UUID.randomUUID();
- String objectType = "TestType";
- TagStore tagStore = new DefaultTagStore(objectId, objectType);
- Tag tag = new DescriptiveTag(tagDefinition, "test", clock.getUTCNow());
+ TagStore tagStore = new DefaultTagStore(objectId, Account.ObjectType);
+ Tag tag = new DescriptiveTag(tagDefinition);
tagStore.add(tag);
- saveTags(tagStoreSqlDao, objectType, objectId.toString(), tagStore.getEntityList());
+ tagDao.saveTags(objectId, Account.ObjectType, tagStore.getEntityList(), context);
- List<Tag> tags = tagStoreSqlDao.load(objectId.toString(), objectType);
+ List<Tag> tags = tagDao.loadTags(objectId, Account.ObjectType);
assertEquals(tags.size(), 1);
try {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName);
+ tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
} catch (TagDefinitionApiException e) {
fail("Could not delete tags for tag definition", e);
}
try {
- tagDefinitionDao.deleteTagDefinition(definitionName);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
} catch (TagDefinitionApiException e) {
fail("Could not delete tag definition", e);
}
@@ -334,7 +321,7 @@ public class TestTagStore {
public void testDeleteAllTagsForDefinitionNotInUse() {
String definitionName = "TestTag4321";
try {
- tagDefinitionDao.create(definitionName, "Some test tag", "test");
+ tagDefinitionDao.create(definitionName, "Some test tag", context);
} catch (TagDefinitionApiException e) {
fail("Could not create tag definition", e);
}
@@ -343,13 +330,13 @@ public class TestTagStore {
assertNotNull(tagDefinition);
try {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName);
+ tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
} catch (TagDefinitionApiException e) {
fail("Could not delete tags for tag definition", e);
}
try {
- tagDefinitionDao.deleteTagDefinition(definitionName);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
} catch (TagDefinitionApiException e) {
fail("Could not delete tag definition", e);
}
@@ -360,7 +347,7 @@ public class TestTagStore {
String definitionName = "TestTag654321";
String wrongDefinitionName = "TestTag564321";
try {
- tagDefinitionDao.create(definitionName, "Some test tag", "test");
+ tagDefinitionDao.create(definitionName, "Some test tag", context);
} catch (TagDefinitionApiException e) {
fail("Could not create tag definition", e);
}
@@ -368,10 +355,10 @@ public class TestTagStore {
TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
assertNotNull(tagDefinition);
- tagDefinitionDao.deleteAllTagsForDefinition(wrongDefinitionName);
+ tagDefinitionDao.deleteAllTagsForDefinition(wrongDefinitionName, context);
try {
- tagDefinitionDao.deleteTagDefinition(definitionName);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
} catch (TagDefinitionApiException e) {
fail("Could not delete tag definition", e);
}
@@ -382,4 +369,64 @@ public class TestTagStore {
List<TagDefinition> definitionList = tagDefinitionDao.getTagDefinitions();
assertTrue(definitionList.size() >= ControlTagType.values().length);
}
+
+ @Test
+ public void testTagInsertAudit() {
+ UUID accountId = UUID.randomUUID();
+
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
+ Tag tag = new DescriptiveTag(testTag);
+ tagStore.add(tag);
+
+ tagDao.saveTagsFromTransaction(dao, accountId, Account.ObjectType, tagStore.getEntityList(), context);
+
+ List<Tag> savedTags = tagDao.loadTags(accountId, Account.ObjectType);
+ assertEquals(savedTags.size(), 1);
+
+ Tag savedTag = savedTags.get(0);
+ assertEquals(savedTag.getTagDefinitionName(), tag.getTagDefinitionName());
+ assertEquals(savedTag.getId(), tag.getId());
+
+ Handle handle = dbi.open();
+ String query = String.format("select * from audit_log where table_name = 'Tag' and record_id='%s'",
+ tag.getId().toString());
+ List<Map<String, Object>> result = handle.select(query);
+ assertNotNull(result);
+ assertEquals(result.size(), 1);
+ assertEquals(result.get(0).get("change_type"), "INSERT");
+ assertNotNull(result.get(0).get("change_date"));
+ DateTime changeDate = new DateTime(result.get(0).get("change_date"));
+ assertTrue(Seconds.secondsBetween(changeDate, context.getCreatedDate()).getSeconds() < 2);
+ assertEquals(result.get(0).get("changed_by"), context.getUserName());
+ }
+
+ @Test
+ public void testTagDeleteAudit() {
+ UUID accountId = UUID.randomUUID();
+
+ TagStore tagStore = new DefaultTagStore(accountId, Account.ObjectType);
+ Tag tag = new DescriptiveTag(testTag);
+ tagStore.add(tag);
+
+ tagDao.saveTags(accountId, Account.ObjectType, tagStore.getEntityList(), context);
+
+ tagStore.remove(tag);
+ tagDao.saveTags(accountId, Account.ObjectType, tagStore.getEntityList(), context);
+
+ List<Tag> savedTags = tagDao.loadTags(accountId, Account.ObjectType);
+ assertEquals(savedTags.size(), 0);
+
+ Handle handle = dbi.open();
+ String query = String.format("select * from audit_log where table_name = 'tag' and record_id='%s' and change_type='DELETE'",
+ tag.getId().toString());
+ List<Map<String, Object>> result = handle.select(query);
+ assertNotNull(result);
+ assertEquals(result.size(), 1);
+ assertNotNull(result.get(0).get("change_date"));
+ DateTime changeDate = new DateTime(result.get(0).get("change_date"));
+ assertTrue(Seconds.secondsBetween(changeDate, context.getUpdatedDate()).getSeconds() < 2);
+ assertEquals(result.get(0).get("changed_by"), context.getUserName());
+ }
+
+ public interface TestSqlDao extends Transmogrifier {}
}