killbill-memoizeit

Merge remote-tracking branch 'origin/analytics-as-osgi-plugin-support'

4/4/2013 7:37:26 PM

Details

diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index d58f6d7..0140d40 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -126,7 +126,7 @@ public class TestAccountDao extends AccountTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(tagDefinition.getId(), ObjectType.ACCOUNT, account.getId(), internalCallContext.getCreatedDate());
         tagDao.create(new TagModelDao(tag), internalCallContext);
 
-        final List<TagModelDao> tags = tagDao.getTags(account.getId(), ObjectType.ACCOUNT, internalCallContext);
+        final List<TagModelDao> tags = tagDao.getTagsForObject(account.getId(), ObjectType.ACCOUNT, internalCallContext);
         Assert.assertEquals(tags.size(), 1);
         Assert.assertEquals(tags.get(0).getTagDefinitionId(), tagDefinition.getId());
         Assert.assertEquals(tags.get(0).getObjectId(), account.getId());
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 f8760f8..38d9e48 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,7 +18,6 @@ package com.ning.billing.util.api;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 import com.ning.billing.ObjectType;
@@ -51,18 +50,65 @@ public interface TagUserApi {
      */
     public void deleteTagDefinition(UUID tagDefinitionId, CallContext context) throws TagDefinitionApiException;
 
+    /**
+     * @param tagDefinitionId The tag definition id
+     * @param context         The call context, for auditing purposes
+     * @return The Tag definition
+     * @throws TagDefinitionApiException
+     */
     public TagDefinition getTagDefinition(UUID tagDefinitionId, TenantContext context) throws TagDefinitionApiException;
 
+    /**
+     * @param tageDefinitionName The tag definition name
+     * @param context            The call context, for auditing purposes
+     * @return the tag definition
+     * @throws TagDefinitionApiException
+     */
     public TagDefinition getTagDefinitionForName(String tageDefinitionName, TenantContext context) throws TagDefinitionApiException;
 
+    /**
+     * @param tagDefinitionIds The collection of the defintion ids
+     * @param context          The call context, for auditing purposes
+     * @return the tag definition
+     * @throws TagDefinitionApiException
+     * @throws TagDefinitionApiException
+     */
     public List<TagDefinition> getTagDefinitions(Collection<UUID> tagDefinitionIds, TenantContext context) throws TagDefinitionApiException;
 
+    /**
+     * @param objectId         The id for the object on which to add tags
+     * @param objectType       The object type
+     * @param tagDefinitionIds The collection of tag definition ids
+     * @param context          The call context, for auditing purposes
+     * @throws TagApiException
+     */
     public void addTags(UUID objectId, ObjectType objectType, Collection<UUID> tagDefinitionIds, CallContext context) throws TagApiException;
 
+    /**
+     * @param objectId        The id for the object on which to add tags
+     * @param objectType      The object type
+     * @param tagDefinitionId The tag definition id
+     * @param context         The call context, for auditing purposes
+     * @throws TagApiException
+     */
     public void addTag(UUID objectId, ObjectType objectType, UUID tagDefinitionId, CallContext context) throws TagApiException;
 
+    /**
+     * @param objectId       The id for the object on which to add tags
+     * @param objectType     The object type
+     * @param tagDefinitions The collection of tag definition ids
+     * @param context        The call context, for auditing purposes
+     * @throws TagApiException
+     */
     public void removeTags(UUID objectId, ObjectType objectType, Collection<UUID> tagDefinitions, CallContext context) throws TagApiException;
 
+    /**
+     * @param objectId        The id for the object on which to add tags
+     * @param objectType      The object type
+     * @param tagDefinitionId The tage definition id
+     * @param context         The call context, for auditing purposes
+     * @throws TagApiException
+     */
     public void removeTag(UUID objectId, ObjectType objectType, UUID tagDefinitionId, CallContext context) throws TagApiException;
 
     /**
@@ -71,5 +117,22 @@ public interface TagUserApi {
      * @param context    The tenant context
      * @return A map of tag, key being the tagId, and value the tag
      */
-    public List<Tag> getTags(UUID objectId, ObjectType objectType, TenantContext context);
+    public List<Tag> getTagsForObject(UUID objectId, ObjectType objectType, TenantContext context);
+
+    /**
+     * @param accountId  The account id
+     * @param objectType The type of object on which to retrieve the tags
+     * @param context    The tenant context
+     * @return A list of tags for that object type and that given account
+     */
+    public List<Tag> getTagsForAccountType(UUID accountId, ObjectType objectType, TenantContext context);
+
+
+    /**
+     *
+     * @param accountId The account id
+     * @param context   The tenant context
+     * @return A list of tags for that given account
+     */
+    public List<Tag> getTagsForAccount(UUID accountId, TenantContext context);
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
index 3fe7604..aaca80d 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
@@ -174,7 +174,7 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
 
     private void add_AUTO_INVOICING_OFF_Tag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
         tagApi.addTag(id, type, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
-        final List<Tag> tags = tagApi.getTags(id, type, callContext);
+        final List<Tag> tags = tagApi.getTagsForObject(id, type, callContext);
         assertEquals(tags.size(), 1);
     }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
index ae23993..bb46d0c 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoPayOff.java
@@ -281,7 +281,7 @@ public class TestIntegrationWithAutoPayOff extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.TAG);
         tagApi.addTag(id, type, ControlTagType.AUTO_PAY_OFF.getId(), callContext);
         assertTrue(busHandler.isCompleted(DELAY));
-        final List<Tag> tags = tagApi.getTags(id, type, callContext);
+        final List<Tag> tags = tagApi.getTagsForObject(id, type, callContext);
         assertEquals(tags.size(), 1);
     }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestTagApi.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestTagApi.java
new file mode 100644
index 0000000..91249e5
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestTagApi.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010-2013 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.beatrix.integration;
+
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.api.TestApiListener.NextEvent;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBase;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+
+import com.google.inject.Inject;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+public class TestTagApi extends TestIntegrationBase {
+
+
+    private Account account;
+
+    @Inject
+    private TagUserApi tagApi;
+
+    @Override
+    @BeforeMethod(groups = {"slow"})
+    public void beforeMethod() throws Exception {
+        super.beforeMethod();
+        account = createAccountWithNonOsgiPaymentMethod(getAccountData(25));
+        assertNotNull(account);
+    }
+
+    @Test(groups = {"slow"}, enabled = true)
+    public void testApiTagOnAccount() throws Exception {
+
+        busHandler.pushExpectedEvents(NextEvent.TAG);
+        tagApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        busHandler.pushExpectedEvents(NextEvent.TAG);
+        tagApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.AUTO_PAY_OFF.getId(), callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        List<Tag> tags = tagApi.getTagsForAccount(account.getId(), callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+        tags = tagApi.getTagsForObject(account.getId(), ObjectType.ACCOUNT, callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+        tags = tagApi.getTagsForAccountType(account.getId(), ObjectType.ACCOUNT, callContext);
+        Assert.assertEquals(tags.size(), 2);
+    }
+
+
+    @Test(groups = {"slow"}, enabled = true)
+    public void testApiTagOnInvoice() throws Exception {
+
+        //
+        // Create necessary logic to end up with an Invoice object on that account.
+        //
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", callContext);
+
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.ANNUAL;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
+        final PlanPhaseSpecifier bpPlanPhaseSpecifier = new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null);
+        final SubscriptionData bpSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                       bpPlanPhaseSpecifier,
+                                                                                                                       null,
+                                                                                                                       callContext));
+        assertNotNull(bpSubscription);
+        assertTrue(busHandler.isCompleted(DELAY));
+        assertListenerStatus();
+
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), callContext);
+        Assert.assertEquals(invoices.size(), 1);
+
+        final Invoice invoice = invoices.get(0);
+        Assert.assertEquals(invoice.getAccountId(), account.getId());
+
+        //
+        // Create a new tag definition
+        //
+        busHandler.pushExpectedEvents(NextEvent.TAG_DEFINITION);
+        TagDefinition tagDefinition = tagApi.create("foo", "foo desc", callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        //
+        // Add 2 Tags on the invoice (1 control tag and 1 user tag)
+        //
+        busHandler.pushExpectedEvents(NextEvent.TAG);
+        tagApi.addTag(invoice.getId(), ObjectType.INVOICE, ControlTagType.WRITTEN_OFF.getId(), callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        busHandler.pushExpectedEvents(NextEvent.TAG);
+        tagApi.addTag(invoice.getId(), ObjectType.INVOICE, tagDefinition.getId(), callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        List<Tag> tags = tagApi.getTagsForAccount(account.getId(), callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+        tags = tagApi.getTagsForObject(invoice.getId(), ObjectType.INVOICE, callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+        tags = tagApi.getTagsForAccountType(account.getId(), ObjectType.INVOICE, callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+
+        //
+        // Add a tag on the account itself and retry
+        //
+        busHandler.pushExpectedEvents(NextEvent.TAG);
+        tagApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.AUTO_PAY_OFF.getId(), callContext);
+        assertTrue(busHandler.isCompleted(DELAY));
+
+        tags = tagApi.getTagsForAccount(account.getId(), callContext);
+        Assert.assertEquals(tags.size(), 3);
+
+        tags = tagApi.getTagsForObject(invoice.getId(), ObjectType.INVOICE, callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+        tags = tagApi.getTagsForAccountType(account.getId(), ObjectType.INVOICE, callContext);
+        Assert.assertEquals(tags.size(), 2);
+
+
+    }
+
+
+}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index d87d160..5edcfa7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -37,15 +37,11 @@ import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.model.InvoicingConfiguration;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBase;
 import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 
-import sun.management.ThreadInfoCompositeData;
-
 import static org.testng.Assert.assertEquals;
 
 public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
@@ -354,12 +350,12 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
     public void testAddRemoveWrittenOffTag() throws InvoiceApiException, TagApiException {
         invoiceUserApi.tagInvoiceAsWrittenOff(invoiceId, callContext);
 
-        List<Tag> tags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
+        List<Tag> tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, callContext);
         assertEquals(tags.size(), 1);
         assertEquals(tags.get(0).getTagDefinitionId(), ControlTagType.WRITTEN_OFF.getId());
 
         invoiceUserApi.tagInvoiceAsNotWrittenOff(invoiceId, callContext);
-        tags = tagUserApi.getTags(invoiceId, ObjectType.INVOICE, callContext);
+        tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, callContext);
         assertEquals(tags.size(), 0);
     }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
index cd88edc..5899f83 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -31,7 +31,6 @@ import org.joda.time.format.ISODateTimeFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
@@ -84,7 +83,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     }
 
     protected Response getTags(final UUID id, final boolean withAudit, final TenantContext context) throws TagDefinitionApiException {
-        final List<Tag> tags = tagUserApi.getTags(id, getObjectType(), context);
+        final List<Tag> tags = tagUserApi.getTagsForObject(id, getObjectType(), context);
         final Collection<UUID> tagIdList = (tags.size() == 0) ?
                                            Collections.<UUID>emptyList() :
                                            Collections2.transform(tags, new Function<Tag, UUID>() {
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
index 5a61f63..450d29b 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
@@ -73,14 +73,22 @@ public class InternalCallContextFactory {
         return new InternalTenantContext(tenantRecordId, accountRecordId);
     }
 
-    /**
-     * Crate an internal call context from a call context, and retrieving the account_record_id from another table
-     *
-     * @param objectId   the id of the row in the table pointed by object type where to look for account_record_id
-     * @param objectType the object type pointed by this objectId
-     * @param context    original call context
-     * @return internal call context from context, with a non null account_record_id (if found)
-     */
+    public InternalTenantContext createInternalTenantContext(final UUID accountId, final TenantContext context) {
+        final Long tenantRecordId = getTenantRecordId(context);
+        final Long accountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(accountId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
+        return new InternalTenantContext(tenantRecordId, accountRecordId);
+    }
+
+
+
+        /**
+         * Crate an internal call context from a call context, and retrieving the account_record_id from another table
+         *
+         * @param objectId   the id of the row in the table pointed by object type where to look for account_record_id
+         * @param objectType the object type pointed by this objectId
+         * @param context    original call context
+         * @return internal call context from context, with a non null account_record_id (if found)
+         */
     public InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final CallContext context) {
         // The context may come from a user API - for security, check we're not doing cross-tenants operations
         //final Long tenantRecordIdFromObject = retrieveTenantRecordIdFromObject(objectId, objectType);
@@ -194,6 +202,8 @@ public class InternalCallContextFactory {
         return new InternalCallContext(tenantRecordId, null, context);
     }
 
+
+
     // Used when we need to re-hydrate the context with the account_record_id (when creating the account)
     public InternalCallContext createInternalCallContext(final Long accountRecordId, final InternalCallContext context) {
         return new InternalCallContext(context.getTenantRecordId(), accountRecordId, context.getUserToken(), context.getCreatedBy(),
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
index 418dbee..25f8e6c 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
@@ -56,6 +56,10 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
                            @BindBean final InternalTenantContext context);
 
     @SqlQuery
+    public List<M> getByAccountRecordId(@BindBean final InternalTenantContext context);
+
+
+    @SqlQuery
     @Cachable(CacheType.RECORD_ID)
     public Long getRecordId(@Bind("id") final String id,
                             @BindBean final InternalTenantContext context);
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/tag/DefaultTagInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/tag/DefaultTagInternalApi.java
index 774e20c..f2eed5c 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/tag/DefaultTagInternalApi.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/tag/DefaultTagInternalApi.java
@@ -66,7 +66,7 @@ public class DefaultTagInternalApi implements TagInternalApi {
 
     @Override
     public List<Tag> getTags(final UUID objectId, final ObjectType objectType, final InternalTenantContext context) {
-        return ImmutableList.<Tag>copyOf(Collections2.transform(tagDao.getTags(objectId, objectType, context),
+        return ImmutableList.<Tag>copyOf(Collections2.transform(tagDao.getTagsForObject(objectId, objectType, context),
                                                                 new Function<TagModelDao, Tag>() {
                                                                     @Override
                                                                     public Tag apply(final TagModelDao input) {
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 ae12ebc..0e4c188 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
@@ -127,22 +127,35 @@ public class DefaultTagUserApi implements TagUserApi {
     }
 
     @Override
-    public List<Tag> getTags(final UUID objectId, final ObjectType objectType, final TenantContext context) {
-        return ImmutableList.<Tag>copyOf(Collections2.transform(tagDao.getTags(objectId, objectType, internalCallContextFactory.createInternalTenantContext(context)),
-                                                                new Function<TagModelDao, Tag>() {
-                                                                    @Override
-                                                                    public Tag apply(final TagModelDao input) {
-                                                                        return TagModelDaoHelper.isControlTag(input.getTagDefinitionId()) ?
-                                                                               new DefaultControlTag(ControlTagType.getTypeFromId(input.getTagDefinitionId()), objectType, objectId, input.getCreatedDate()) :
-                                                                               new DescriptiveTag(input.getTagDefinitionId(), objectType, objectId, input.getCreatedDate());
-                                                                    }
-                                                                }));
-    }
-
-    @Override
     public TagDefinition getTagDefinitionForName(final String tagDefinitionName, final TenantContext context)
             throws TagDefinitionApiException {
         return new DefaultTagDefinition(tagDefinitionDao.getByName(tagDefinitionName, internalCallContextFactory.createInternalTenantContext(context)),
                                         TagModelDaoHelper.isControlTag(tagDefinitionName));
     }
+
+    @Override
+    public List<Tag> getTagsForObject(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+        return withModelTransform(tagDao.getTagsForObject(objectId, objectType, internalCallContextFactory.createInternalTenantContext(context)));
+    }
+
+    @Override
+    public List<Tag> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final TenantContext context) {
+        return withModelTransform(tagDao.getTagsForAccountType(accountId, objectType, internalCallContextFactory.createInternalTenantContext(accountId, context)));
+    }
+
+    @Override
+    public List<Tag> getTagsForAccount(final UUID accountId, final TenantContext context) {
+        return withModelTransform(tagDao.getTagsForAccount(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context)));
+    }
+
+    private List<Tag> withModelTransform(final List<TagModelDao> input) {
+        return ImmutableList.<Tag>copyOf(Collections2.transform(input, new Function<TagModelDao, Tag>() {
+            @Override
+            public Tag apply(final TagModelDao input) {
+                return TagModelDaoHelper.isControlTag(input.getTagDefinitionId()) ?
+                       new DefaultControlTag(ControlTagType.getTypeFromId(input.getTagDefinitionId()), input.getObjectType(), input.getObjectId(), input.getCreatedDate()) :
+                       new DescriptiveTag(input.getTagDefinitionId(), input.getObjectType(), input.getObjectId(), input.getCreatedDate());
+            }
+        }));
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
index cd5a164..6ae85a9 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
@@ -19,6 +19,8 @@ package com.ning.billing.util.tag.dao;
 import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,6 +30,7 @@ import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.Cachable.CacheType;
 import com.ning.billing.util.cache.CacheControllerDispatcher;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
@@ -44,6 +47,9 @@ import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiException> implements TagDao {
@@ -62,7 +68,7 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
     }
 
     @Override
-    public List<TagModelDao> getTags(final UUID objectId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
+    public List<TagModelDao> getTagsForObject(final UUID objectId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
         return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<TagModelDao>>() {
             @Override
             public List<TagModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
@@ -72,6 +78,30 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
     }
 
     @Override
+    public List<TagModelDao> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
+
+        final List<TagModelDao> allTags = getTagsForAccount(accountId, internalTenantContext);
+        return ImmutableList.<TagModelDao>copyOf(Collections2.filter(allTags, new Predicate<TagModelDao>() {
+            @Override
+            public boolean apply(@Nullable final TagModelDao input) {
+                return input.getObjectType() == objectType;
+            }
+        }));
+    }
+
+    @Override
+    public List<TagModelDao> getTagsForAccount(final UUID accountId, final InternalTenantContext internalTenantContext) {
+
+        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<TagModelDao>>() {
+            @Override
+            public List<TagModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+                return entitySqlDaoWrapperFactory.become(TagSqlDao.class).getByAccountRecordId(internalTenantContext);
+            }
+        });
+    }
+
+
+    @Override
     protected void postBusEventFromTransaction(final TagModelDao tag, final TagModelDao savedTag, final ChangeType changeType,
                                                final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InternalCallContext context)
             throws BillingExceptionBase {
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
index 152dfbf..9fd3ed8 100644
--- 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
@@ -32,5 +32,9 @@ public interface TagDao {
 
     TagModelDao getById(UUID tagId, InternalTenantContext context);
 
-    List<TagModelDao> getTags(UUID objectId, ObjectType objectType, InternalTenantContext internalTenantContext);
+    List<TagModelDao> getTagsForObject(UUID objectId, ObjectType objectType, InternalTenantContext internalTenantContext);
+
+    List<TagModelDao> getTagsForAccountType(UUID accountId, ObjectType objectType, InternalTenantContext internalTenantContext);
+
+    List<TagModelDao> getTagsForAccount(UUID accountId, InternalTenantContext internalTenantContext);
 }
diff --git a/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
index 6610aa5..9a2c236 100644
--- a/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/entity/dao/EntitySqlDao.sql.stg
@@ -162,6 +162,16 @@ where <recordIdField("t.")> = :recordId
 ;
 >>
 
+getByAccountRecordId(accountRecordId) ::= <<
+select
+<allTableFields("t.")>
+from <tableName()> t
+where <accountRecordIdField("t.")> = :accountRecordId
+<AND_CHECK_TENANT("t.")>
+;
+>>
+
+
 getHistoryTargetRecordId(recordId) ::= <<
 select
 <targetRecordIdField("t.")>
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
index 111d8fe..8ed8aa5 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
@@ -78,7 +78,7 @@ public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
         final Tag tag = new DescriptiveTag(tagDefinition.getId(), ObjectType.ACCOUNT, objectId, clock.getUTCNow());
 
         tagDao.create(new TagModelDao(tag), internalCallContext);
-        final List<TagModelDao> tags = tagDao.getTags(objectId, ObjectType.ACCOUNT, internalCallContext);
+        final List<TagModelDao> tags = tagDao.getTagsForObject(objectId, ObjectType.ACCOUNT, internalCallContext);
         Assert.assertEquals(tags.size(), 1);
         final TagModelDao savedTag = tags.get(0);
         Assert.assertEquals(savedTag.getTagDefinitionId(), tagDefinition.getId());
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
index 053232f..f80d600 100644
--- 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
@@ -65,7 +65,7 @@ public class MockTagDao implements TagDao {
     }
 
     @Override
-    public List<TagModelDao> getTags(final UUID objectId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
+    public List<TagModelDao> getTagsForObject(final UUID objectId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
         if (tagStore.get(objectId) == null) {
             return ImmutableList.<TagModelDao>of();
         }
@@ -78,6 +78,16 @@ public class MockTagDao implements TagDao {
         }));
     }
 
+    @Override
+    public List<TagModelDao> getTagsForAccountType(final UUID accountId, final ObjectType objectType, final InternalTenantContext internalTenantContext) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<TagModelDao> getTagsForAccount(final UUID accountId, final InternalTenantContext internalTenantContext) {
+        throw new UnsupportedOperationException();
+    }
+
     public void clear() {
         tagStore.clear();
     }
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
index e1c95b0..90a84a4 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
@@ -16,42 +16,24 @@
 
 package com.ning.billing.util.tag.dao;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
 import org.testng.Assert;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
 import com.ning.billing.ObjectType;
 import com.ning.billing.api.TestApiListener;
 import com.ning.billing.api.TestApiListener.NextEvent;
-import com.ning.billing.api.TestListenerStatus;
-import com.ning.billing.mock.glue.MockDbHelperModule;
 import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
 import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.bus.InMemoryBusModule;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.events.BusInternalEvent;
-import com.ning.billing.util.events.TagInternalEvent;
-import com.ning.billing.util.glue.CacheModule;
-import com.ning.billing.util.glue.ClockModule;
-import com.ning.billing.util.glue.NonEntityDaoModule;
-import com.ning.billing.util.glue.TagStoreModule;
-import com.ning.billing.util.svcsapi.bus.InternalBus;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.DescriptiveTag;
 import com.ning.billing.util.tag.Tag;
 
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Inject;
-
 import static org.testng.Assert.assertEquals;
 
 public class TestDefaultTagDao extends UtilTestSuiteWithEmbeddedDB {
@@ -159,7 +141,7 @@ public class TestDefaultTagDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertTrue(eventsListener.isCompleted(2000));
 
         // Make sure we can retrieve it via the DAO
-        final List<TagModelDao> foundTags = tagDao.getTags(objectId, objectType, internalCallContext);
+        final List<TagModelDao> foundTags = tagDao.getTagsForObject(objectId, objectType, internalCallContext);
         Assert.assertEquals(foundTags.size(), 1);
         Assert.assertEquals(foundTags.get(0).getTagDefinitionId(), createdTagDefinition.getId());
 
@@ -179,7 +161,7 @@ public class TestDefaultTagDao extends UtilTestSuiteWithEmbeddedDB {
         Assert.assertTrue(eventsListener.isCompleted(2000));
 
         // Make sure the tag is deleted
-        Assert.assertEquals(tagDao.getTags(objectId, objectType, internalCallContext).size(), 0);
+        Assert.assertEquals(tagDao.getTagsForObject(objectId, objectType, internalCallContext).size(), 0);
 
         /*
         final TagInternalEvent tagSecondEventReceived = eventsListener.getTagEvents().get(1);