APL Cache
=========

APL is an automated solution to application-level caching. APL can be incorporated into web applications so that it can monitor and choose content to be cached according to changing usage patterns. It consists of two complementary asynchronous parts: (a) a reactive model applying, responsible for monitoring traces of the application execution and caching method calls (previously identified as caching opportunities) at runtime; and (b) a proactive model building, which analyzes on the background the behavior of the application, taking into account application-specific information, and finds cacheable opportunities. Figure above presents an overview of the dynamics of our approach, indicating the activities that comprise its running cycle. These asynchronous parts involve performing three different activities: (1) data tracking, (2) data mining and (3) cache management.

![Overview](http://inf.ufrgs.br/~jmamertz/resources/images/ProposedSolution.png)

Features
------------
- Declarative configuration
- Enable and disable features by configuration or at runtime
- Automatic identification of cacheable methods
- Automated caching of cacheable methods

APL Cache is implemented in Java, thus can be used with Java web applications. We adopted a set of technologies that provide an appropriate infrastructure for the framework. Used technologies are highlighted in the above figure, which presents the APL Cache architecture, with its modules and communication among them.

![Architecture](http://inf.ufrgs.br/~jmamertz/resources/images/APLCacheArchitecture.png)

Required Tools
--------------
- AOP-enabled compilation
- Maven 3
- Java 8

###### Optional
- To store application traces: MongoDB or Redis or In-memory
- To cache data: Redis or Memcached or In-memory

Build and Dependency
--------------------

Go to the framework folder and build the `pom.xml` with Maven: `mvn clean install`

If your project is maven-based, in your `pom.xml`:
```xml
<dependencies>
    <dependency>
        <groupId>br.ufrgs.inf.prosoft.adaptivecaching</groupId>
        <artifactId>autonomicmanager</artifactId>
        <version>0.6.0-SNAPSHOT</version>
    </dependency>
</dependencies>
```

Otherwise, you can also get the `.jar` produced by maven can be just added to the classpath.

Usage
-----

###### Application example

In order to have a practice reference, consider the project `toyexample`. It should be found along with the source of the framework.

Create a file adaptivecaching.properties under the resources folder of your application to specify the configuration desired.

```
#Cache config
#Redis:
#adaptivecaching.cache.url=localhost
#adaptivecaching.cache.port=6379

#Logging
adaptivecaching.cache.logging=DEBUG
adaptivecaching.monitoring.logging=DEBUG

#Repository config:
##MongoDB:
adaptivecaching.monitoring.db.scheme=cachemonitoring
adaptivecaching.monitoring.db.name=petclinic
adaptivecaching.monitoring.db.port=27017
adaptivecaching.monitoring.db.address=localhost

##Redis:
#adaptivecaching.monitoring.db.scheme=yourdb

#adaptivecaching.monitoring.db.port=27017
#adaptivecaching.monitoring.db.address=localhost
```

Then, create a configuration class which consists of `@AdaptiveCaching` and `@ComponentScan` annotations, on the root package of the system:

```
//mongodb as log database
//ehcache as cache
@AdaptiveCaching(cacheProvider = CacheProviderType.EHCACHE, logRepository = RepositoryType.MONGODB,
    modelling = Modelling.ACCUMULATION, analyzerEnabled = false, enabled = true, disableMonitoringAfterAnalysis = true,
    clearMonitoringDataOnStart = true, traceAsync = false, tracerEnabled = true)
```
```
@ComponentScan(allowed = "my.package", denied = "my.package.not")
public class Configuration {
}
```

Available customizations are:
- Modelling: FULLEXPLORATION, ACCUMULATION, PARTIALEXPLORATION;
- RepositoryType: MONGODB, TEXTFILE, MEMORY, CONSOLE, REDIS;
- CacheProviderType: MEMCACHED, REDIS, EHCACHE, GUAVA, CAFFEINE;

###### Available annotations and default params

`@AdaptiveCaching`
- cacheProvider = CacheProviderType.EHCACHE
- logRepository = RepositoryType.MONGODB
- modelling = Modelling.ACCUMULATION
- analyzerEnabled = false
- enabled = true
- disableMonitoringAfterAnalysis = true
- clearMonitoringDataOnStart = true
- traceAsync = false
- tracerEnabled = true

`@ComponentScan`
- allowed = "my.package"
- denied = "my.package.model"

The framework also provides means for developers to make customizations using hints, indicating possible locations of cacheable methods, which can improve the set of caching candidates as well as exclude methods that should not be cached, thus saving the time of tracking them.
These indications are done by using the annotations: `@Uncacheable` and `@Cacheable`.
		
Inner workings
--------------

To collect data to be analyzed and manage cacheable methods, we intercept method executions using aspect-oriented programming (AOP), more specifically the AspectJ implementation. AOP provides an easy way to weave code at specified points, without changing the base code. APL Cache store method calls with a generic representation of application traces. To compare input and output data of method calls and ensure that structurally equivalent objects have the same representation, objects are loaded and compared by using implementations of the `equals` and `hashCode` methods. Saving actions are performed in an execution thread separate from the one that is processing the request, minimizing response delays.

Available solutions of caching components were also adopted. They provide APIs to manipulate data and access metadata information about the cache, such as statistics and configurations. Our framework is decoupled of particular caching components, and thus supports the most popular distributed cache systems and libraries, which can be configured through property files and annotations. APL Cache automates the decision of what to cache, but such caching components allow us to collect metadata about the cache and also easily manipulate cached content.

The collected data are analyzed offline, separately from the web application, to prevent impact in the application performance---it can even run on a dedicated machine. To evaluate shared execution traces (accessed by multiple users), we obtain the user session, which is an application-specific information thus taken into account only in application-level caching. Our framework provides a set of alternative implementations to obtain this information from the most popular web frameworks, such as Java EE and the Spring Framework. In case alternative ways of managing user sessions are adopted, developers should implement interfaces provided by our framework.
