killbill-memoizeit

Changes

account/pom.xml 50(+0 -50)

api/pom.xml 50(+0 -50)

blacklist 10(+0 -10)

catalog/pom.xml 46(+0 -46)

docker-compose.yml 10(+2 -8)

entitlement/pom.xml 50(+0 -50)

ignored 44(+0 -44)

invoice/pom.xml 50(+0 -50)

jaxrs/pom.xml 50(+0 -50)

junction/pom.xml 50(+0 -50)

overdue/pom.xml 46(+0 -46)

payment/pom.xml 50(+0 -50)

pom.xml 4(+2 -2)

tenant/pom.xml 50(+0 -50)

util/pom.xml 46(+0 -46)

whitelist 2(+0 -2)

Details

account/pom.xml 50(+0 -50)

diff --git a/account/pom.xml b/account/pom.xml
index f9f6da0..eec798b 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -191,54 +191,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
index 6adb006..d27b7bd 100644
--- a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
+++ b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultImmutableAccountInternalApi.java
@@ -48,6 +48,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultImmutableAccountInternalApi implements ImmutableAccountInternalApi {
 
     private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
@@ -75,12 +77,16 @@ public class DefaultImmutableAccountInternalApi implements ImmutableAccountInter
         return getImmutableAccountDataByRecordId(recordId, context);
     }
 
+public static SingleCache<Parameters, ImmutableAccountData> getImmutableAccountDataByRecordId = new SingleCache<>("DefaultImmutableAccountInternalApi.getImmutableAccountDataByRecordId");
+
     @Override
     public ImmutableAccountData getImmutableAccountDataByRecordId(final Long recordId, final InternalTenantContext context) throws AccountApiException {
+return getImmutableAccountDataByRecordId.computeIfAbsent(new Parameters(recordId, context), () -> {
         // final CacheLoaderArgument arg = createImmutableAccountCacheLoaderArgument(context);
         // return accountCacheController.get(recordId, arg);
         final Account account = getAccountByRecordIdInternal(recordId, context);
         return account != null ? new DefaultImmutableAccountData(account) : null;
+}, 20000);
     }
 
     // private CacheLoaderArgument createImmutableAccountCacheLoaderArgument(final InternalTenantContext context) {
@@ -96,16 +102,26 @@ public class DefaultImmutableAccountInternalApi implements ImmutableAccountInter
     //     return new CacheLoaderArgument(null, args, context);
     // }
 
+public static SingleCache<Parameters, AccountModelDao> inTransactionCache = new SingleCache<>("DefaultImmutableAccountInternalApi.inTransaction");
+public static SingleCache<Parameters, Account> getAccountByRecordIdInternal = new SingleCache<>("DefaultImmutableAccountInternalApi.getAccountByRecordIdInternal");
+
     private Account getAccountByRecordIdInternal(final Long recordId, final InternalTenantContext context) {
+return getAccountByRecordIdInternal.computeIfAbsent(new Parameters(recordId, context), () -> {
+
+
+
         final AccountModelDao accountModelDao = transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<AccountModelDao>() {
 
             @Override
             public AccountModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+return inTransactionCache.computeIfAbsent(new Parameters(entitySqlDaoWrapperFactory), () -> {
                 final EntitySqlDao<AccountModelDao, Account> transactional = entitySqlDaoWrapperFactory.become(AccountSqlDao.class);
                 return transactional.getByRecordId(recordId, context);
+}, 20000);
             }
         });
 
         return accountModelDao != null ? new DefaultAccount(accountModelDao) : null;
+}, 20000);
     }
 }
diff --git a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
index 1ab81f5..5ffbd02 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
@@ -68,6 +68,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, AccountApiException> implements AccountDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultAccountDao.class);
@@ -136,12 +138,16 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
         }
     }
 
+public static SingleCache<Parameters, AccountModelDao> inTransaction = new SingleCache<>("DefaultAccountDao.inTransaction"); 
+
     @Override
     public AccountModelDao getAccountByKey(final String key, final InternalTenantContext context) {
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<AccountModelDao>() {
             @Override
             public AccountModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+return inTransaction.computeIfAbsent(new Parameters(entitySqlDaoWrapperFactory),  () -> {
                 return entitySqlDaoWrapperFactory.become(AccountSqlDao.class).getAccountByKey(key, context);
+}, 20000);
             }
         });
     }

api/pom.xml 50(+0 -50)

diff --git a/api/pom.xml b/api/pom.xml
index a4164e5..af00cce 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -65,54 +65,4 @@
             <artifactId>config-magic</artifactId>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>

catalog/pom.xml 46(+0 -46)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 335e287..2b1772c 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -188,52 +188,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>
                 <executions>

docker-compose.yml 10(+2 -8)

diff --git a/docker-compose.yml b/docker-compose.yml
index cba3982..c61a5a8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,14 +17,8 @@ services:
       - KILLBILL_DAO_USER=root
       - KILLBILL_DAO_PASSWORD=killbill
       - JAVA_OPTS=${JAVA_OPTS:-"-Xms4096m -Xmx6124m"}
-      - TRACER_ENABLE=${TRACER_ENABLE:-true}
-      - TRACER_MINIMUM_EXECUTION_TIME=${TRACER_MINIMUM_EXECUTION_TIME:-1}
-      - TRACER_SERIALISE_INTERNALS=false
-      - TRACER_VERBOSE=true
-      - TRACER_TRACES=/caching-approaches-comparison/applications/traces/killbill
-      - TRACER_IGNORED_PACKAGES=/caching-approaches-comparison/applications/uncached/killbill/ignored
-      - TRACER_WHITELIST=/caching-approaches-comparison/applications/uncached/killbill/whitelist
-      - TRACER_LOG=/caching-approaches-comparison/applications/output/killbill-tracer.log
+      - CACHE_EVENTS=${CACHE_EVENTS:-/caching-approaches-comparison/applications/output/killbill-memoizeit-cache}
+      - CACHE_REGISTER_SIZE=false
     volumes:
       - application:/application
       - /root/.m2:/root/.m2

entitlement/pom.xml 50(+0 -50)

diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index bc36b0d..fce0269 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -214,54 +214,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
index 2a30b39..e459746 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
@@ -41,6 +41,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class EntitlementUtils {
 
     protected final NotificationQueueService notificationQueueService;
@@ -87,13 +89,15 @@ public class EntitlementUtils {
         dao.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableMap.<BlockingState, Optional<UUID>>of(state, Optional.<UUID>fromNullable(bundleId)), context);
     }
 
+public static SingleCache<Parameters, UUID> getFirstActiveSubscriptionIdForKeyOrNull = new SingleCache<>("EntitlementUtils.getFirstActiveSubscriptionIdForKeyOrNull"); 
+
     /**
      * @param externalKey   the bundle externalKey
      * @param tenantContext the context
      * @return the id of the first subscription (BASE or STANDALONE) that is still active for that key
      */
     public UUID getFirstActiveSubscriptionIdForKeyOrNull(final String externalKey, final InternalTenantContext tenantContext) {
-
+return getFirstActiveSubscriptionIdForKeyOrNull.computeIfAbsent(new Parameters(externalKey, tenantContext),  () -> {
         final Iterable<UUID> nonAddonUUIDs = subscriptionBaseInternalApi.getNonAOSubscriptionIdsForKey(externalKey, tenantContext);
         return Iterables.tryFind(nonAddonUUIDs, new Predicate<UUID>() {
             @Override
@@ -102,5 +106,6 @@ public class EntitlementUtils {
                 return (state == null || !state.getStateName().equals(DefaultEntitlementApi.ENT_STATE_CANCELLED));
             }
         }).orNull();
+}, 20000);
     }
 }

invoice/pom.xml 50(+0 -50)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index 37e9f4d..45a3262 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -232,54 +232,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 30aa18d..58f5022 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -91,6 +91,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPaginationNoException;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultInvoiceUserApi implements InvoiceUserApi {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultInvoiceUserApi.class);
@@ -194,16 +196,24 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                              );
     }
 
+public static SingleCache<Parameters, BigDecimal> getAccountBalanceCache = new SingleCache<>("DefaultInvoiceUserApi.getAccountBalance");
+
     @Override
     public BigDecimal getAccountBalance(final UUID accountId, final TenantContext context) {
+return getAccountBalanceCache.computeIfAbsent(new Parameters(accountId, context), () -> {
         final BigDecimal result = dao.getAccountBalance(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
         return result == null ? BigDecimal.ZERO : result;
+}, 20000);
     }
 
+public static SingleCache<Parameters, BigDecimal> getAccountCBACache = new SingleCache<>("DefaultInvoiceUserApi.getAccountCBA");
+
     @Override
     public BigDecimal getAccountCBA(final UUID accountId, final TenantContext context) {
+return getAccountCBACache.computeIfAbsent(new Parameters(accountId, context), () -> {
         final BigDecimal result = dao.getAccountCBA(accountId, internalCallContextFactory.createInternalTenantContext(accountId, context));
         return result == null ? BigDecimal.ZERO : result;
+}, 20000);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
index a2a4cd6..26e1f12 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/CBADao.java
@@ -39,6 +39,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class CBADao {
 
     private final InvoiceDaoHelper invoiceDaoHelper;
@@ -48,10 +50,14 @@ public class CBADao {
         this.invoiceDaoHelper = invoiceDaoHelper;
     }
 
+public static SingleCache<Parameters, BigDecimal> getAccountCBAFromTransactionCache = new SingleCache<>("CBADao.getAccountCBAFromTransaction");
+
     // PERF: Compute the CBA directly in the database (faster than re-constructing all invoices)
     public BigDecimal getAccountCBAFromTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalTenantContext context) {
+return getAccountCBAFromTransactionCache.computeIfAbsent(new Parameters(entitySqlDaoWrapperFactory, context), () -> {
         final InvoiceItemSqlDao invoiceItemSqlDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class);
         return invoiceItemSqlDao.getAccountCBA(context);
+}, 20000);
     }
 
     // We expect a clean up to date invoice, with all the items except the cba, that we will compute in that method
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 0165e3b..56d16a4 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -94,6 +94,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, InvoiceApiException> implements InvoiceDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultInvoiceDao.class);
@@ -485,8 +487,11 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
 
     }
 
+public static SingleCache<Parameters, BigDecimal> getAccountBalanceCache = new SingleCache<>("DefaultInvoiceDao.getAccountBalance");
+
     @Override
     public BigDecimal getAccountBalance(final UUID accountId, final InternalTenantContext context) {
+return getAccountBalanceCache.computeIfAbsent(new Parameters(accountId, context), () -> {
         final List<Tag> invoicesTags = getInvoicesTags(context);
 
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<BigDecimal>() {
@@ -517,16 +522,21 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                 return accountBalance.subtract(cba);
             }
         });
+}, 20000);
     }
 
+public static SingleCache<Parameters, BigDecimal> getAccountCBA = new SingleCache<>("DefaultInvoiceDao.getAccountCBA");
+
     @Override
     public BigDecimal getAccountCBA(final UUID accountId, final InternalTenantContext context) {
+return getAccountCBA.computeIfAbsent(new Parameters(accountId, context), () -> {
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<BigDecimal>() {
             @Override
             public BigDecimal inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
                 return cbaDao.getAccountCBAFromTransaction(entitySqlDaoWrapperFactory, context);
             }
         });
+}, 20000);
     }
 
     @Override
@@ -541,22 +551,29 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
         });
     }
 
+public static SingleCache<Parameters, UUID> inTransaction13 = new SingleCache<>("DefaultInvoiceDao.inTransaction13");
     @Override
     public UUID getInvoiceIdByPaymentId(final UUID paymentId, final InternalTenantContext context) {
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<UUID>() {
             @Override
             public UUID inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+return inTransaction13.computeIfAbsent(new Parameters(entitySqlDaoWrapperFactory), () -> {
                 return entitySqlDaoWrapperFactory.become(InvoiceSqlDao.class).getInvoiceIdByPaymentId(paymentId.toString(), context);
+}, 20000);
             }
         });
     }
 
+public static SingleCache<Parameters, List<InvoicePaymentModelDao>> inTransaction14 = new SingleCache<>("DefaultInvoiceDao.inTransaction14");
+
     @Override
     public List<InvoicePaymentModelDao> getInvoicePaymentsByPaymentId(final UUID paymentId, final InternalTenantContext context) {
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<InvoicePaymentModelDao>>() {
             @Override
             public List<InvoicePaymentModelDao> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+return inTransaction14.computeIfAbsent(new Parameters(entitySqlDaoWrapperFactory), () -> {
                 return entitySqlDaoWrapperFactory.become(InvoicePaymentSqlDao.class).getInvoicePayments(paymentId.toString(), context);
+}, 20000);
             }
         });
     }
@@ -1382,9 +1399,13 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
         });
     }
 
+public static SingleCache<Parameters, List<Tag>> getInvoicesTags = new SingleCache<>("DefaultInvoiceDao.getInvoicesTags");
+
     // PERF: fetch tags once. See also https://github.com/killbill/killbill/issues/720.
     private List<Tag> getInvoicesTags(final InternalTenantContext context) {
+return getInvoicesTags.computeIfAbsent(new Parameters(context), () -> {
         return tagInternalApi.getTagsForAccountType(ObjectType.INVOICE, false, context);
+}, 20000);
     }
 
     private static boolean checkAgainstExistingInvoiceItemState(final InvoiceItemModelDao existingInvoiceItem, final InvoiceItemModelDao inputInvoiceItem) {

jaxrs/pom.xml 50(+0 -50)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index e3bc326..4a269ca 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -201,54 +201,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 8e6df2e..b6af95e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -152,6 +152,8 @@ import io.swagger.annotations.ApiResponses;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 @Singleton
 @Path(JaxrsResource.ACCOUNTS_PATH)
 @Api(value = JaxrsResource.ACCOUNTS_PATH, description = "Operations on accounts", tags = "Account")
@@ -218,6 +220,8 @@ public class AccountResource extends JaxRsResourceBase {
         return Response.status(Status.OK).entity(accountJson).build();
     }
 
+public static SingleCache<Parameters, AccountJson> apply = new SingleCache<>("AccountResource.apply");
+
     @TimedResource
     @GET
     @Path("/" + PAGINATION)
@@ -239,14 +243,17 @@ public class AccountResource extends JaxRsResourceBase {
                                                 new Function<Account, AccountJson>() {
                                                     @Override
                                                     public AccountJson apply(final Account account) {
+                                                      return apply.computeIfAbsent(new Parameters(account), () -> {
                                                         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(account.getId(), auditMode.getLevel(), tenantContext);
                                                         return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, accountAuditLogs, tenantContext);
+                                                      }, 20000);
                                                     }
                                                 },
                                                 nextPageUri
                                                );
     }
 
+
     @TimedResource
     @GET
     @Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@@ -344,8 +351,11 @@ public class AccountResource extends JaxRsResourceBase {
         return Response.status(Status.OK).entity(accountJson).build();
     }
 
+public static SingleCache<Parameters, AccountJson> getAccount = new SingleCache<>("AccountResource.getAccount");
+
     private AccountJson getAccount(final Account account, final Boolean accountWithBalance, final Boolean accountWithBalanceAndCBA,
                                    final AccountAuditLogs auditLogs, final TenantContext tenantContext) {
+return getAccount.computeIfAbsent(new Parameters(account, accountWithBalance, accountWithBalanceAndCBA, auditLogs, tenantContext), () -> {
         if (accountWithBalanceAndCBA) {
             final BigDecimal accountBalance = invoiceApi.getAccountBalance(account.getId(), tenantContext);
             final BigDecimal accountCBA = invoiceApi.getAccountCBA(account.getId(), tenantContext);
@@ -356,6 +366,7 @@ public class AccountResource extends JaxRsResourceBase {
         } else {
             return new AccountJson(account, null, null, auditLogs);
         }
+}, 20000);
     }
 
     @TimedResource

junction/pom.xml 50(+0 -50)

diff --git a/junction/pom.xml b/junction/pom.xml
index afeb9d9..134d3d7 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -206,54 +206,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>

overdue/pom.xml 46(+0 -46)

diff --git a/overdue/pom.xml b/overdue/pom.xml
index d343e45..445b503 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -206,52 +206,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>
                 <executions>

payment/pom.xml 50(+0 -50)

diff --git a/payment/pom.xml b/payment/pom.xml
index 4e8f48d..1277f2c 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -249,54 +249,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
index b8bcf61..4106bb3 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
@@ -85,6 +85,8 @@ import static org.killbill.billing.payment.dispatcher.PaymentPluginDispatcher.di
 import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPagination;
 import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPaginationFromPlugins;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class PaymentMethodProcessor extends ProcessorBase {
 
     private static final Logger log = LoggerFactory.getLogger(PaymentMethodProcessor.class);
@@ -322,8 +324,16 @@ public class PaymentMethodProcessor extends ProcessorBase {
         }
     }
 
-    public List<PaymentMethod> getPaymentMethods(final boolean includedInactive, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
+public static MultiCache<Parameters, List<PaymentMethod>> getPaymentMethods = new MultiCache<>("PaymentMethodProcessor.getPaymentMethods");
+
+    public List<PaymentMethod> getPaymentMethods(final boolean includedInactive, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) {//throws PaymentApiException {
+return getPaymentMethods.computeIfAbsent(new Parameters(includedInactive, withPluginInfo, properties, context),  () -> {
+    try {
         return getPaymentMethods(includedInactive, withPluginInfo, properties, buildTenantContext(context), context);
+    } catch (PaymentApiException ex) {
+        throw new RuntimeException(ex);
+    }
+}, 20000);
     }
 
     public List<PaymentMethod> getPaymentMethods(final boolean includedInactive, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext context) throws PaymentApiException {

pom.xml 4(+2 -2)

diff --git a/pom.xml b/pom.xml
index 036d73e..7068082 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,8 +49,8 @@
     </modules>
     <dependencies>
         <dependency>
-            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-            <artifactId>ApplicationTracer</artifactId>
+            <groupId>br.ufrgs.inf.prosoft.cache</groupId>
+            <artifactId>Cache</artifactId>
             <version>1.0</version>
         </dependency>
     </dependencies>
diff --git a/profiles/killbill/pom.xml b/profiles/killbill/pom.xml
index e58a90c..5ac48b3 100644
--- a/profiles/killbill/pom.xml
+++ b/profiles/killbill/pom.xml
@@ -471,52 +471,6 @@
         </resources>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>2.4</version>
diff --git a/profiles/killpay/pom.xml b/profiles/killpay/pom.xml
index fab2ff6..2b4cdda 100644
--- a/profiles/killpay/pom.xml
+++ b/profiles/killpay/pom.xml
@@ -190,52 +190,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>2.4</version>
diff --git a/subscription/pom.xml b/subscription/pom.xml
index d46a8d6..f6ed771 100644
--- a/subscription/pom.xml
+++ b/subscription/pom.xml
@@ -202,54 +202,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>

tenant/pom.xml 50(+0 -50)

diff --git a/tenant/pom.xml b/tenant/pom.xml
index 93eab11..46646cb 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -183,54 +183,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
-    </build>
 </project>
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java b/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
index d15a8ab..9493ffb 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/api/user/DefaultTenantUserApi.java
@@ -52,6 +52,8 @@ import com.google.inject.Inject;
 
 import org.killbill.billing.tenant.api.TenantInternalApi;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultTenantUserApi implements TenantUserApi {
 
     //
@@ -133,14 +135,22 @@ public class DefaultTenantUserApi implements TenantUserApi {
         return tenant;
     }
 
+public static SingleCache<Parameters, Tenant> getTenantById = new SingleCache<>("DefaultTenantUserApi.getTenantById"); 
+
     @Override
-    public Tenant getTenantById(final UUID id) throws TenantApiException {
+    public Tenant getTenantById(final UUID id) {
+return getTenantById.computeIfAbsent(new Parameters(id),  () -> {
         // TODO - API cleanup?
+    try {
         TenantModelDao tenant = tenantDao.getById(id, new InternalTenantContext(null));
         if (tenant == null) {
             throw new TenantApiException(ErrorCode.TENANT_DOES_NOT_EXIST_FOR_ID, id);
         }
         return new DefaultTenant(tenant);
+    } catch (TenantApiException ex) {
+        throw new RuntimeException(ex);
+    }
+}, 20000);
     }
 
     @Override
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
index f0527ae..4c887f7 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/NoCachingTenantDao.java
@@ -43,6 +43,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * This is a special implementation of the TenantDao that does not rely on caching (CacheControllerDispatcher is not injected and passed
  * to the EntitySqlDaoWrapperInvocationHandler. It only implements the set of operations that does not require caching:
@@ -62,12 +64,16 @@ public class NoCachingTenantDao extends EntityDaoBase<TenantModelDao, Tenant, Te
              null, internalCallContextFactory), TenantSqlDao.class);
     }
 
+public static SingleCache<Parameters, TenantModelDao> inTransaction = new SingleCache<>("NoCachingTenantDao.inTransaction"); 
+
     @Override
     public TenantModelDao getTenantByApiKey(final String apiKey) {
         return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<TenantModelDao>() {
             @Override
             public TenantModelDao inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+return inTransaction.computeIfAbsent(new Parameters(apiKey),  () -> {
                 return entitySqlDaoWrapperFactory.become(TenantSqlDao.class).getByApiKey(apiKey);
+}, 20000);
             }
         });
     }

util/pom.xml 46(+0 -46)

diff --git a/util/pom.xml b/util/pom.xml
index 6b2334b..67df441 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -325,52 +325,6 @@
     <build>
         <plugins>
             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.11</version>
-                <configuration>
-                    <showWeaveInfo>false</showWeaveInfo>
-                    <complianceLevel>1.8</complianceLevel>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                    <Xlint>ignore</Xlint>
-                    <encoding>UTF-8</encoding>
-                    <verbose>false</verbose>
-                    <forceAjcCompile>true</forceAjcCompile>
-                    <sources/>
-                    <weaveDirectories>
-                        <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
-                    </weaveDirectories>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>br.ufrgs.inf.prosoft.applicationtracer</groupId>
-                            <artifactId>ApplicationTracer</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.9.1</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
diff --git a/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java b/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
index 782e4e0..0cf3903 100644
--- a/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
+++ b/util/src/main/java/org/killbill/billing/util/audit/dao/DefaultAuditDao.java
@@ -61,6 +61,8 @@ import com.google.common.collect.Lists;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultAuditDao implements AuditDao {
 
     private final DBRouter<NonEntitySqlDao> dbRouter;
@@ -109,6 +111,9 @@ public class DefaultAuditDao implements AuditDao {
         return new DefaultAccountAuditLogsForObjectType(auditLevel, allAuditLogs);
     }
 
+
+public static SingleCache<Parameters, AuditLog> apply = new SingleCache<>("DefaultAuditDao.apply");
+
     private Iterator<AuditLog> buildAuditLogsFromModelDao(final Iterator<AuditLogModelDao> auditLogsForAccountRecordId, final InternalTenantContext tenantContext) {
         // final Map<TableName, Map<Long, UUID>> recordIdIdsCache = new HashMap<TableName, Map<Long, UUID>>();
         // final Map<TableName, Map<Long, UUID>> historyRecordIdIdsCache = new HashMap<TableName, Map<Long, UUID>>();
@@ -116,6 +121,7 @@ public class DefaultAuditDao implements AuditDao {
                                                                new Function<AuditLogModelDao, AuditLog>() {
                                                                    @Override
                                                                    public AuditLog apply(final AuditLogModelDao input) {
+return apply.computeIfAbsent(new Parameters(input), () -> {
                                                                        // If input is for e.g. TAG_DEFINITION_HISTORY, retrieve TAG_DEFINITIONS
                                                                        // For tables without history, e.g. TENANT, originalTableNameForHistoryTableName will be null
                                                                        final TableName originalTableNameForHistoryTableName = findTableNameForHistoryTableName(input.getTableName());
@@ -167,6 +173,7 @@ Iterable<RecordIdIdMappings> mappings = null;
                                                                        }
 
                                                                        return new DefaultAuditLog(input, objectType, auditedEntityId);
+}, 20000);
                                                                    }
 
                                                                    private TableName findTableNameForHistoryTableName(final TableName historyTableName) {
@@ -190,6 +197,7 @@ Iterable<RecordIdIdMappings> mappings = null;
         }
     }
 
+
     @Override
     public List<AuditLogWithHistory> getAuditLogsWithHistoryForId(final HistorySqlDao transactional, final TableName tableName, final UUID objectId, final AuditLevel auditLevel, final InternalTenantContext context) {
         final TableName historyTableName = tableName.getHistoryTableName();
diff --git a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
index ed15ba1..ce4d922 100644
--- a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
@@ -43,6 +43,8 @@ import org.slf4j.MDC;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 // Internal contexts almost always expect accountRecordId and tenantRecordId to be populated
 public class InternalCallContextFactory {
 
@@ -318,7 +320,10 @@ public class InternalCallContextFactory {
                                        updatedDate != null ? createdDate : clock.getUTCNow());
     }
 
+public static SingleCache<Parameters, ImmutableAccountData> getImmutableAccountData = new SingleCache<>("InternalCallContextFactory.getImmutableAccountData"); 
+
     private ImmutableAccountData getImmutableAccountData(final Long accountRecordId, final Long tenantRecordId) {
+return getImmutableAccountData.computeIfAbsent(new Parameters(accountRecordId, tenantRecordId),  () -> {
         Preconditions.checkNotNull(accountRecordId, "Missing accountRecordId");
         final InternalTenantContext tmp = new InternalTenantContext(tenantRecordId, accountRecordId, null, null);
         try {
@@ -328,6 +333,7 @@ public class InternalCallContextFactory {
         } catch (final AccountApiException e) {
             throw new RuntimeException(e);
         }
+}, 20000);
     }
 
     private void populateMDCContext(@Nullable final UUID userToken, @Nullable final Long accountRecordId, final Long tenantRecordId) {
@@ -385,7 +391,10 @@ public class InternalCallContextFactory {
         }
     }
 
+public static SingleCache<Parameters, Long> getTenantRecordIdSafe = new SingleCache<>("InternalCallContextFactory.getTenantRecordIdSafe");
+
     private Long getTenantRecordIdSafe(final TenantContext context) {
+return getTenantRecordIdSafe.computeIfAbsent(new Parameters(context), () -> {
         // Default to single default tenant (e.g. single tenant mode)
         // TODO Extract this convention (e.g. BusinessAnalyticsBase needs to know about it)
         if (context.getTenantId() == null) {
@@ -394,6 +403,7 @@ public class InternalCallContextFactory {
             // This is always safe (the tenant context was created from the api key and secret)
             return getTenantRecordIdUnsafe(context.getTenantId(), ObjectType.TENANT);
         }
+}, 20000);
     }
 
     private UUID getTenantIdSafe(final InternalTenantContext context) {
@@ -408,20 +418,28 @@ public class InternalCallContextFactory {
     // In-code tenant checkers
     //
 
+public static MultiCache<Parameters, Boolean> objectBelongsToTheRightTenant1 = new MultiCache<>("Parser.objectBelongsToTheRightTenant1");
+
     private boolean objectBelongsToTheRightTenant(final UUID objectId, final ObjectType objectType, final TenantContext context) throws ObjectDoesNotExist {
+return objectBelongsToTheRightTenant1.computeIfAbsent(new Parameters(objectId, objectType, context), () -> {
         final Long realTenantRecordId = getTenantRecordIdSafe(context);
         if (realTenantRecordId == null) {
             throw new ObjectDoesNotExist(String.format("Tenant id=%s doesn't exist!", context.getTenantId()));
         }
         return objectBelongsToTheRightTenant(objectId, objectType, realTenantRecordId);
+}, 20000);
     }
 
+public static MultiCache<Parameters, Boolean> objectBelongsToTheRightTenant2 = new MultiCache<>("Parser.objectBelongsToTheRightTenant2");
+
     private boolean objectBelongsToTheRightTenant(final UUID objectId, final ObjectType objectType, final Long realTenantRecordId) throws ObjectDoesNotExist {
+return objectBelongsToTheRightTenant2.computeIfAbsent(new Parameters(objectId, objectType, realTenantRecordId), () -> {
         final Long objectTenantRecordId = getTenantRecordIdUnsafe(objectId, objectType);
         if (objectTenantRecordId == null) {
             throw new ObjectDoesNotExist(String.format("Object id=%s type=%s doesn't exist!", objectId, objectType));
         }
         return objectTenantRecordId.equals(realTenantRecordId);
+}, 20000);
     }
 
     //
@@ -432,8 +450,12 @@ public class InternalCallContextFactory {
         return nonEntityDao.retrieveAccountRecordIdFromObject(objectId, objectType, null);
     }
 
+public static MultiCache<Parameters, Long> getTenantRecordIdUnsafe = new MultiCache<>("InternalCallContextFactory.getTenantRecordIdUnsafe");
+
     private Long getTenantRecordIdUnsafe(final UUID objectId, final ObjectType objectType) {
+return getTenantRecordIdUnsafe.computeIfAbsent(new Parameters(objectId, objectType), () -> {
         return nonEntityDao.retrieveTenantRecordIdFromObject(objectId, objectType, null);
+}, 20000);
     }
 
     public static final class ObjectDoesNotExist extends IllegalStateException {
diff --git a/util/src/main/java/org/killbill/billing/util/dao/DefaultNonEntityDao.java b/util/src/main/java/org/killbill/billing/util/dao/DefaultNonEntityDao.java
index 7ebb1c4..c1d9c87 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/DefaultNonEntityDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/DefaultNonEntityDao.java
@@ -41,6 +41,8 @@ import com.google.common.base.Preconditions;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultNonEntityDao implements NonEntityDao {
 
     private final DBRouter<NonEntitySqlDao> dbRouter;
@@ -108,13 +110,21 @@ public class DefaultNonEntityDao implements NonEntityDao {
         }, objectIdOrNull, objectType, tableName, cache);
     }
 
+public static MultiCache<Parameters, Long> retrieveTenantRecordIdFromObject = new MultiCache<>("DefaultNonEntityDao.retrieveTenantRecordIdFromObject");
+
     @Override
     public Long retrieveTenantRecordIdFromObject(@Nullable final UUID objectId, final ObjectType objectType, @Nullable final Object cache) {
+return retrieveTenantRecordIdFromObject.computeIfAbsent(new Parameters(objectId, objectType, cache), () -> {
         return retrieveTenantRecordIdFromObjectInTransaction(objectId, objectType, cache, null);
+}, 20000);
     }
 
+public static SingleCache<Parameters, Long> doRetrieve = new SingleCache<>("DefaultNonEntityDao.doRetrieve");
+public static MultiCache<Parameters, Long> retrieveTenantRecordIdFromObjectInTransaction = new MultiCache<>("DefaultNonEntityDao.retrieveTenantRecordIdFromObjectInTransaction");
+
     @Override
     public Long retrieveTenantRecordIdFromObjectInTransaction(@Nullable final UUID objectId, final ObjectType objectType, @Nullable final Object cache, @Nullable final Handle handle) {
+return retrieveTenantRecordIdFromObjectInTransaction.computeIfAbsent(new Parameters(objectId, objectType, cache, handle), () -> {
         final TableName tableName = TableName.fromObjectType(objectType);
         Preconditions.checkNotNull(tableName, "%s is not a valid ObjectType", objectType);
 
@@ -122,6 +132,7 @@ public class DefaultNonEntityDao implements NonEntityDao {
         return withCachingObjectId.withCaching(new OperationRetrieval<Long>() {
             @Override
             public Long doRetrieve(final ObjectType objectType) {
+return doRetrieve.computeIfAbsent(new Parameters(objectType), () -> {
                 final NonEntitySqlDao inTransactionNonEntitySqlDao = handle == null ? dbRouter.onDemand(true) : SqlObjectBuilder.attach(handle, NonEntitySqlDao.class);
 
                 switch (tableName) {
@@ -133,8 +144,10 @@ public class DefaultNonEntityDao implements NonEntityDao {
                         return inTransactionNonEntitySqlDao.getTenantRecordIdFromObjectOtherThanTenant(objectIdOrNull, tableName.getTableName());
                 }
 
+}, 20000);
             }
         }, objectIdOrNull, objectType, tableName, cache);
+}, 20000);
     }
 
     @Override
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 9b9e4a4..adff3d4 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
@@ -64,6 +64,8 @@ import com.google.inject.Inject;
 
 import static org.killbill.billing.util.glue.IDBISetup.MAIN_RO_IDBI_NAMED;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiException> implements TagDao {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultTagDao.class);
@@ -99,8 +101,11 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
         });
     }
 
+public static SingleCache<Parameters, List<TagModelDao>> getTagsForAccountType = new SingleCache<>("DefaultTagDao.getTagsForAccountType");
+
     @Override
     public List<TagModelDao> getTagsForAccountType(final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
+return getTagsForAccountType.computeIfAbsent(new Parameters(objectType, includedDeleted, internalTenantContext), () -> {
         final List<TagModelDao> allTags = getTagsForAccount(includedDeleted, internalTenantContext);
         return ImmutableList.<TagModelDao>copyOf(Collections2.filter(allTags, new Predicate<TagModelDao>() {
             @Override
@@ -108,6 +113,7 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
                 return input.getObjectType() == objectType;
             }
         }));
+}, 20000);
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java b/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
index ac87b9f..b119267 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/DefaultTagInternalApi.java
@@ -38,6 +38,8 @@ import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 public class DefaultTagInternalApi implements TagInternalApi {
 
     private final TagDao tagDao;
@@ -71,9 +73,13 @@ public class DefaultTagInternalApi implements TagInternalApi {
         return toTagList(tagDao.getTagsForAccount(includedDeleted, context));
     }
 
+public static SingleCache<Parameters, List<Tag>> getTagsForAccountType = new SingleCache<>("DefaultTagInternalApi.getTagsForAccountType");
+
     @Override
     public List<Tag> getTagsForAccountType(final ObjectType objectType, final boolean includedDeleted, final InternalTenantContext internalTenantContext) {
+return getTagsForAccountType.computeIfAbsent(new Parameters(objectType, includedDeleted, internalTenantContext), () -> {
         return toTagList(tagDao.getTagsForAccountType(objectType, includedDeleted, internalTenantContext));
+}, 20000);
     }
 
     @Override