diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
index 2d494f5..d46a568 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestTag.java
@@ -168,6 +168,20 @@ public class TestTag extends TestJaxrsBase {
}
}
+ @Test(groups = "slow", description = "Cannot create a control tag against wrong object type")
+ public void testNotApplicableType() throws Exception {
+
+ final Account account = createAccount();
+ try {
+ accountApi.createAccountTags(account.getAccountId(), ImmutableList.<UUID>of(ControlTagType.WRITTEN_OFF.getId()), requestOptions);
+ Assert.fail("Creating a (control) tag against a wrong object type should fail");
+ } catch (final Exception e) {
+ Assert.assertTrue(true);
+ }
+ }
+
+
+
@Test(groups = "slow", description = "retrieve account logs")
public void testGetTagAuditLogsWithHistory() throws Exception {
final Account accountJson = createAccount();
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
index bb6c9f0..9cb4bdc 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/DefaultTagDao.java
@@ -201,9 +201,27 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
@Override
public void create(final TagModelDao entity, final InternalCallContext context) throws TagApiException {
+
+ validateApplicableObjectTypes(entity.getTagDefinitionId(), entity.getObjectType());
transactionalSqlDao.execute(false, TagApiException.class, getCreateEntitySqlDaoTransactionWrapper(entity, context));
}
+ private void validateApplicableObjectTypes(final UUID tagDefinitionId, final ObjectType objectType) throws TagApiException {
+
+ final ControlTagType controlTagType = Iterables.tryFind(ImmutableList.<ControlTagType>copyOf(ControlTagType.values()), new Predicate<ControlTagType>() {
+ @Override
+ public boolean apply(final ControlTagType input) {
+ return input.getId().equals(tagDefinitionId);
+ }
+ }).orNull();
+
+ if (controlTagType != null && !controlTagType.getApplicableObjectTypes().contains(objectType)) {
+ // TODO Add missing ErrorCode.TAG_NOT_APPLICABLE
+ // throw new TagApiException(ErrorCode.TAG_NOT_APPLICABLE);
+ throw new IllegalStateException(String.format("Invalid control tag '%s' for object type '%s'", controlTagType.name(), objectType));
+ }
+ }
+
@Override
public void deleteTag(final UUID objectId, final ObjectType objectType, final UUID tagDefinitionId, final InternalCallContext context) throws TagApiException {