Details
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 422221a..2be6d6d 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
@@ -25,51 +25,41 @@ import com.ning.billing.util.dao.ObjectType;
import com.ning.billing.util.tag.Tag;
import com.ning.billing.util.tag.TagDefinition;
-// TODO: add ability to create, update and remove tags
public interface TagUserApi {
- /***
- *
+ /**
* @return the list of all available tag definitions
*/
public List<TagDefinition> getTagDefinitions();
- /***
- *
+ /**
* @param definitionName Identifies the definition.
- * @param description Describes the use of the definition.
- * @param context The call context, for auditing purposes
+ * @param description Describes the use of the definition.
+ * @param context The call context, for auditing purposes
* @return the newly created tag definition
* @throws TagDefinitionApiException
*/
public TagDefinition create(String definitionName, 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, CallContext context) throws TagDefinitionApiException;
-
- /***
- *
- * @param definitionName Identifies the definition.
- * @param context The call context, for auditing purposes
+ * @param context The call context, for auditing purposes
* @throws TagDefinitionApiException
*/
public void deleteTagDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
- /**
- *
- * @param name
- * @return the tag with this definition
+ /**
+ * @param name
+ * @return the tag with this definition
* @throws TagDefinitionApiException
- */
- public TagDefinition getTagDefinition(String name) throws TagDefinitionApiException;
+ */
+ public TagDefinition getTagDefinition(String name) throws TagDefinitionApiException;
public void addTags(UUID objectId, ObjectType objectType, List<TagDefinition> tagDefinitions, CallContext context);
+
public void addTag(UUID objectId, ObjectType objectType, TagDefinition tagDefinition, CallContext context);
+
public void removeTags(UUID objectId, ObjectType objectType, List<TagDefinition> tagDefinitions, CallContext context);
+
public void removeTag(UUID objectId, ObjectType objectType, TagDefinition tagDefinition, CallContext context);
public Map<String, Tag> getTags(UUID objectId, ObjectType objectType);
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
index c3edd34..93de7f8 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagUserApi.java
@@ -51,14 +51,8 @@ public class DefaultTagUserApi implements TagUserApi {
}
@Override
- public void deleteAllTagsForDefinition(final String definitionName, final CallContext context)
- throws TagDefinitionApiException {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
- }
-
- @Override
public void deleteTagDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
+ tagDefinitionDao.deleteTagDefinition(definitionName, context);
}
@Override
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 afad118..049c42d 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
@@ -20,6 +20,9 @@ import java.util.ArrayList;
import java.util.List;
import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.skife.jdbi.v2.exceptions.TransactionFailedException;
import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
@@ -32,7 +35,7 @@ import com.ning.billing.util.tag.TagDefinition;
import com.ning.billing.util.tag.api.user.TagEventBuilder;
public class DefaultTagDefinitionDao implements TagDefinitionDao {
- private final TagDefinitionSqlDao dao;
+ private final TagDefinitionSqlDao tagDefinitionSqlDao;
private final TagEventBuilder tagEventBuilder;
private final Bus bus;
@@ -40,16 +43,16 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
public DefaultTagDefinitionDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final Bus bus) {
this.tagEventBuilder = tagEventBuilder;
this.bus = bus;
- this.dao = dbi.onDemand(TagDefinitionSqlDao.class);
+ this.tagDefinitionSqlDao = dbi.onDemand(TagDefinitionSqlDao.class);
}
@Override
public List<TagDefinition> getTagDefinitions() {
- // get user definitions from the database
+ // Get user definitions from the database
final List<TagDefinition> definitionList = new ArrayList<TagDefinition>();
- definitionList.addAll(dao.get());
+ definitionList.addAll(tagDefinitionSqlDao.get());
- // add control tag definitions
+ // Add control tag definitions
for (final ControlTagType controlTag : ControlTagType.values()) {
definitionList.add(new DefaultTagDefinition(controlTag.toString(), controlTag.getDescription(), true));
}
@@ -59,31 +62,47 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
@Override
public TagDefinition getByName(final String definitionName) {
- // add control tag definitions
+ // Add control tag definitions
for (final ControlTagType controlTag : ControlTagType.values()) {
if (definitionName.equals(controlTag.name())) {
return new DefaultTagDefinition(controlTag.toString(), controlTag.getDescription(), true);
}
}
- return dao.getByName(definitionName);
+
+ return tagDefinitionSqlDao.getByName(definitionName);
}
@Override
public TagDefinition create(final String definitionName, final String description,
final CallContext context) throws TagDefinitionApiException {
+ // Make sure a control tag with this name don't already exist
if (isControlTagName(definitionName)) {
throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_CONFLICTS_WITH_CONTROL_TAG, definitionName);
}
- final TagDefinition existingDefinition = dao.getByName(definitionName);
-
- if (existingDefinition != null) {
- throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_ALREADY_EXISTS, definitionName);
+ try {
+ return tagDefinitionSqlDao.inTransaction(new Transaction<TagDefinition, TagDefinitionSqlDao>() {
+ @Override
+ public TagDefinition inTransaction(final TagDefinitionSqlDao transactional, final TransactionStatus status) throws Exception {
+ // Make sure the tag definition doesn't exist already
+ final TagDefinition existingDefinition = tagDefinitionSqlDao.getByName(definitionName);
+ if (existingDefinition != null) {
+ throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_ALREADY_EXISTS, definitionName);
+ }
+
+ final TagDefinition definition = new DefaultTagDefinition(definitionName, description, false);
+ tagDefinitionSqlDao.create(definition, context);
+
+ return definition;
+ }
+ });
+ } catch (TransactionFailedException exception) {
+ if (exception.getCause() instanceof TagDefinitionApiException) {
+ throw (TagDefinitionApiException) exception.getCause();
+ } else {
+ throw exception;
+ }
}
-
- final TagDefinition definition = new DefaultTagDefinition(definitionName, description, false);
- dao.create(definition, context);
- return definition;
}
private boolean isControlTagName(final String definitionName) {
@@ -97,27 +116,33 @@ public class DefaultTagDefinitionDao implements TagDefinitionDao {
}
@Override
- public void deleteAllTagsForDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
- final TagDefinition existingDefinition = dao.getByName(definitionName);
- if (existingDefinition == null) {
- throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionName);
- }
-
- dao.deleteAllTagsForDefinition(definitionName, context);
- }
-
- @Override
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);
- }
-
- final TagDefinition existingDefinition = dao.getByName(definitionName);
-
- if (existingDefinition == null) {
- throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionName);
+ try {
+ tagDefinitionSqlDao.inTransaction(new Transaction<Void, TagDefinitionSqlDao>() {
+ @Override
+ public Void inTransaction(final TagDefinitionSqlDao transactional, final TransactionStatus status) throws Exception {
+ // Make sure the tag definition exists
+ final TagDefinition existingDefinition = tagDefinitionSqlDao.getByName(definitionName);
+ if (existingDefinition == null) {
+ throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, definitionName);
+ }
+
+ // Make sure it is not used currently
+ if (tagDefinitionSqlDao.tagDefinitionUsageCount(definitionName) > 0) {
+ throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_IN_USE, definitionName);
+ }
+
+ tagDefinitionSqlDao.deleteTagDefinition(definitionName, context);
+
+ return null;
+ }
+ });
+ } catch (TransactionFailedException exception) {
+ if (exception.getCause() instanceof TagDefinitionApiException) {
+ throw (TagDefinitionApiException) exception.getCause();
+ } else {
+ throw exception;
+ }
}
-
- dao.deleteTagDefinition(definitionName, 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 cc10c93..ae645ea 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
@@ -29,7 +29,5 @@ public interface TagDefinitionDao {
public TagDefinition create(String definitionName, String description, CallContext context) throws TagDefinitionApiException;
- public void deleteAllTagsForDefinition(String definitionName, CallContext context) 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 8524c53..4a7dd1c 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
@@ -34,6 +34,7 @@ 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;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
@@ -45,7 +46,7 @@ import com.ning.billing.util.tag.TagDefinition;
@ExternalizedSqlViaStringTemplate3
@RegisterMapper(TagDefinitionSqlDao.TagDefinitionMapper.class)
-public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinition> {
+public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinition>, Transactional<TagDefinitionSqlDao> {
@Override
@SqlUpdate
public void create(@TagDefinitionBinder final TagDefinition entity, @CallContextBinder final CallContext context);
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 2d36936..d7a3e63 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
@@ -49,11 +49,6 @@ public class MockTagDefinitionDao implements TagDefinitionDao {
}
@Override
- public void deleteAllTagsForDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
- tags.remove(definitionName);
- }
-
- @Override
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/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
index bea5065..8dcd638 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
@@ -285,7 +285,7 @@ public class TestTagStore {
}
@Test(groups = "slow")
- public void testDeleteAllTagsForDefinitionInUse() {
+ public void testDeleteTagBeforeDeleteTagDefinition() {
final String definitionName = "TestTag1234567";
try {
tagDefinitionDao.create(definitionName, "Some test tag", context);
@@ -306,58 +306,9 @@ public class TestTagStore {
final Map<String, Tag> tagMap = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
assertEquals(tagMap.size(), 1);
- try {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
- } catch (TagDefinitionApiException e) {
- fail("Could not delete tagStore for tag definition", e);
- }
-
- try {
- tagDefinitionDao.deleteTagDefinition(definitionName, context);
- } catch (TagDefinitionApiException e) {
- fail("Could not delete tag definition", e);
- }
- }
-
- @Test(groups = "slow")
- public void testDeleteAllTagsForDefinitionNotInUse() {
- final String definitionName = "TestTag4321";
- try {
- tagDefinitionDao.create(definitionName, "Some test tag", context);
- } catch (TagDefinitionApiException e) {
- fail("Could not create tag definition", e);
- }
-
- final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
- assertNotNull(tagDefinition);
-
- try {
- tagDefinitionDao.deleteAllTagsForDefinition(definitionName, context);
- } catch (TagDefinitionApiException e) {
- fail("Could not delete tagStore for tag definition", e);
- }
-
- try {
- tagDefinitionDao.deleteTagDefinition(definitionName, context);
- } catch (TagDefinitionApiException e) {
- fail("Could not delete tag definition", e);
- }
- }
-
- @Test(groups = "slow", expectedExceptions = TagDefinitionApiException.class)
- public void testDeleteAllTagsForDefinitionWithWrongName() throws TagDefinitionApiException {
- final String definitionName = "TestTag654321";
- final String wrongDefinitionName = "TestTag564321";
- try {
- tagDefinitionDao.create(definitionName, "Some test tag", context);
- } catch (TagDefinitionApiException e) {
- fail("Could not create tag definition", e);
- }
-
- final TagDefinition tagDefinition = tagDefinitionDao.getByName(definitionName);
- assertNotNull(tagDefinition);
-
- tagDefinitionDao.deleteAllTagsForDefinition(wrongDefinitionName, context);
+ tagDao.deleteTag(objectId, ObjectType.ACCOUNT, tagDefinition, context);
+ final Map<String, Tag> tagMapAfterDeletion = tagDao.loadEntities(objectId, ObjectType.ACCOUNT);
+ assertEquals(tagMapAfterDeletion.size(), 0);
try {
tagDefinitionDao.deleteTagDefinition(definitionName, context);