killbill-uncached
Changes
util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java 42(+9 -33)
Details
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java b/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
index 23acc3e..163eeea 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/api/DefaultCustomFieldUserApi.java
@@ -17,14 +17,11 @@
package org.killbill.billing.util.customfield.api;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
-import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
+import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.callcontext.CallContext;
@@ -34,6 +31,7 @@ import org.killbill.billing.util.customfield.CustomField;
import org.killbill.billing.util.customfield.StringCustomField;
import org.killbill.billing.util.customfield.dao.CustomFieldDao;
import org.killbill.billing.util.customfield.dao.CustomFieldModelDao;
+import org.killbill.billing.util.customfield.dao.DefaultCustomFieldDao;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
@@ -89,37 +87,15 @@ public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
@Override
public void addCustomFields(final List<CustomField> customFields, final CallContext context) throws CustomFieldApiException {
- // TODO make it transactional
-
- final Map<UUID, ObjectType> mapping = new HashMap<UUID, ObjectType>();
- for (final CustomField cur : customFields) {
- mapping.put(cur.getObjectId(), cur.getObjectType());
- }
-
- final List<CustomFieldModelDao> all = new LinkedList<CustomFieldModelDao>();
- for (UUID cur : mapping.keySet()) {
- final ObjectType type = mapping.get(cur);
- all.addAll(customFieldDao.getCustomFieldsForObject(cur, type, internalCallContextFactory.createInternalCallContext(cur, type, context)));
- }
- final List<CustomField> toBeInserted = new LinkedList<CustomField>();
- for (final CustomField cur : customFields) {
- final CustomFieldModelDao match = Iterables.tryFind(all, new com.google.common.base.Predicate<CustomFieldModelDao>() {
+ if (!customFields.isEmpty()) {
+ final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(customFields.get(0).getObjectId(), customFields.get(0).getObjectType(), context);
+ final Iterable<CustomFieldModelDao> transformed = Iterables.transform(customFields, new Function<CustomField, CustomFieldModelDao>() {
@Override
- public boolean apply(final CustomFieldModelDao input) {
- return input.getObjectId().equals(cur.getObjectId()) &&
- input.getObjectType() == cur.getObjectType() &&
- input.getFieldName().equals(cur.getFieldName());
-
+ public CustomFieldModelDao apply(final CustomField input) {
+ return new CustomFieldModelDao(context.getCreatedDate(), input.getFieldName(), input.getFieldValue(), input.getObjectId(), input.getObjectType());
}
- }).orNull();
- if (match != null) {
- throw new CustomFieldApiException(ErrorCode.CUSTOM_FIELD_ALREADY_EXISTS, match.getId());
- }
- toBeInserted.add(cur);
- }
-
- for (CustomField cur : toBeInserted) {
- customFieldDao.create(new CustomFieldModelDao(context.getCreatedDate(), cur.getFieldName(), cur.getFieldValue(), cur.getObjectId(), cur.getObjectType()), internalCallContextFactory.createInternalCallContext(cur.getObjectId(), cur.getObjectType(), context));
+ });
+ ((DefaultCustomFieldDao) customFieldDao).create(transformed, internalCallContext);
}
}
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldModelDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldModelDao.java
index 9f4371b..6147e25 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldModelDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldModelDao.java
@@ -25,6 +25,7 @@ import org.killbill.billing.util.customfield.CustomField;
import org.killbill.billing.util.dao.TableName;
import org.killbill.billing.util.entity.dao.EntityModelDao;
import org.killbill.billing.util.entity.dao.EntityModelDaoBase;
+import org.killbill.billing.util.tag.dao.TagModelDao;
public class CustomFieldModelDao extends EntityModelDaoBase implements EntityModelDao<CustomField> {
@@ -34,7 +35,6 @@ public class CustomFieldModelDao extends EntityModelDaoBase implements EntityMod
private ObjectType objectType;
private Boolean isActive;
-
public CustomFieldModelDao() { /* For the DAO mapper */ }
public CustomFieldModelDao(final UUID id, final DateTime createdDate, final DateTime updatedDate, final String fieldName,
@@ -137,6 +137,27 @@ public class CustomFieldModelDao extends EntityModelDaoBase implements EntityMod
return true;
}
+ public boolean isSame(final CustomFieldModelDao that) {
+ if (fieldName != null ? !fieldName.equals(that.fieldName) : that.fieldName != null) {
+ return false;
+ }
+ if (fieldValue != null ? !fieldValue.equals(that.fieldValue) : that.fieldValue != null) {
+ return false;
+ }
+ if (objectId != null ? !objectId.equals(that.objectId) : that.objectId != null) {
+ return false;
+ }
+ if (objectType != that.objectType) {
+ return false;
+ }
+ if (isActive != null ? !isActive.equals(that.isActive) : that.isActive != null) {
+ return false;
+ }
+ return true;
+ }
+
+
+
@Override
public int hashCode() {
int result = super.hashCode();
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
index 742bf5d..28677b9 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/DefaultCustomFieldDao.java
@@ -24,37 +24,38 @@ import java.util.UUID;
import javax.annotation.Nullable;
-import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.Ordering;
-import org.skife.jdbi.v2.IDBI;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.killbill.billing.BillingExceptionBase;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
-import org.killbill.bus.api.PersistentBus;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.clock.Clock;
import org.killbill.billing.events.BusInternalEvent;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.customfield.CustomField;
import org.killbill.billing.util.customfield.api.DefaultCustomFieldCreationEvent;
import org.killbill.billing.util.customfield.api.DefaultCustomFieldDeletionEvent;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.entity.Pagination;
+import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.Ordering;
import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.PaginationIteratorBuilder;
import org.killbill.billing.util.entity.dao.EntityDaoBase;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.clock.Clock;
+import org.skife.jdbi.v2.IDBI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.inject.Inject;
public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, CustomField, CustomFieldApiException> implements CustomFieldDao {
@@ -126,6 +127,18 @@ public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, Cu
}
@Override
+ protected boolean checkEntityAlreadyExists(final EntitySqlDao<CustomFieldModelDao, CustomField> transactional, final CustomFieldModelDao entity, final InternalCallContext context) {
+ return Iterables.find(transactional.getByAccountRecordId(context),
+ new Predicate<CustomFieldModelDao>() {
+ @Override
+ public boolean apply(final CustomFieldModelDao existingCustomField) {
+ return entity.isSame(existingCustomField);
+ }
+ },
+ null) != null;
+ }
+
+ @Override
protected void postBusEventFromTransaction(final CustomFieldModelDao customField, final CustomFieldModelDao savedCustomField, final ChangeType changeType,
final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalCallContext context)
throws BillingExceptionBase {
diff --git a/util/src/test/java/org/killbill/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java b/util/src/test/java/org/killbill/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
index fcddf41..4004e9a 100644
--- a/util/src/test/java/org/killbill/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
+++ b/util/src/test/java/org/killbill/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
@@ -23,11 +23,13 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.ImmutableAccountData;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.util.UtilTestSuiteWithEmbeddedDB;
+import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.customfield.CustomField;
import org.killbill.billing.util.customfield.StringCustomField;
import org.killbill.billing.util.entity.Pagination;
@@ -35,16 +37,20 @@ import org.mockito.Mockito;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.tweak.HandleCallback;
import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
- @Test(groups = "slow")
- public void testSaveCustomFieldWithAccountRecordId() throws Exception {
- final UUID accountId = UUID.randomUUID();
- final Long accountRecordId = 19384012L;
+ final UUID accountId = UUID.randomUUID();
+ final Long accountRecordId = 19384012L;
+
+ @Override
+ @BeforeMethod(groups = "slow")
+ public void beforeMethod() throws Exception {
+ super.beforeMethod();
final ImmutableAccountData immutableAccountData = Mockito.mock(ImmutableAccountData.class);
Mockito.when(immutableAccountInternalApi.getImmutableAccountDataByRecordId(Mockito.<Long>eq(accountRecordId), Mockito.<InternalTenantContext>any())).thenReturn(immutableAccountData);
@@ -59,6 +65,39 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
return null;
}
});
+ }
+
+ @Test(groups = "slow")
+ public void testCustomFieldBasic() throws Exception {
+
+ final CustomField customField1 = new StringCustomField("some123", "some 456", ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
+ final CustomField customField2 = new StringCustomField("other123", "other 456", ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
+ eventsListener.pushExpectedEvents(NextEvent.CUSTOM_FIELD, NextEvent.CUSTOM_FIELD);
+ customFieldUserApi.addCustomFields(ImmutableList.<CustomField>of(customField1, customField2), callContext);
+ assertListenerStatus();
+
+ // Verify operation is indeed transaction, and nothing was inserted
+ final CustomField customField3 = new StringCustomField("qrqrq123", "qrqrq 456", ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
+ try {
+ customFieldUserApi.addCustomFields(ImmutableList.<CustomField>of(customField3, customField1), callContext);
+ } catch (CustomFieldApiException e) {
+ Assert.assertEquals(e.getCode(), ErrorCode.CUSTOM_FIELD_ALREADY_EXISTS.getCode());
+ }
+
+ List<CustomField> all = customFieldUserApi.getCustomFieldsForAccount(accountId, callContext);
+ Assert.assertEquals(all.size(), 2);
+
+ eventsListener.pushExpectedEvent(NextEvent.CUSTOM_FIELD);
+ customFieldUserApi.addCustomFields(ImmutableList.<CustomField>of(customField3), callContext);
+ assertListenerStatus();
+
+ all = customFieldUserApi.getCustomFieldsForAccount(accountId, callContext);
+ Assert.assertEquals(all.size(), 3);
+ }
+
+
+ @Test(groups = "slow")
+ public void testSaveCustomFieldWithAccountRecordId() throws Exception {
checkPagination(0);
diff --git a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
index e2b016d..f3d5cf7 100644
--- a/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
+++ b/util/src/test/java/org/killbill/billing/util/customfield/dao/MockCustomFieldDao.java
@@ -52,6 +52,7 @@ public class MockCustomFieldDao extends MockEntityDaoBase<CustomFieldModelDao, C
throw new UnsupportedOperationException();
}
+
@Override
public Pagination<CustomFieldModelDao> searchCustomFields(final String searchKey, final Long offset, final Long limit, final InternalTenantContext context) {
throw new UnsupportedOperationException();