Easily Integrate Akamai into your Adobe CQ/AEM Instance with Velir’s Akamai Connector

  • Sebastien Bernard
  • July 9, 2014

Akamai’s Dynamic Site Accelerator is a highly valuable Content Delivery Network (CDN) for reducing the load on your internal setups and ultimately, for diminishing infrastructure costs. This has been a useful tool for many of our clients, enabling them to offload the majority of incoming requests from their production servers during large traffic events. To take full advantage of Akamai’s caching capabilities Velir has created a connector that integrates your CMS with Akamai. This post provides details on what this connector is and how it can be put into use for your next CQ project.

The Need for an Akamai Connector

On a recent Adobe CQ/AEM project we tightly integrated Akamai into the AEM publishing process, which allowed us to take advantage of the CDN while ensuring that site visitors were presented with the latest content. This particular client was producing a series of successful marketing campaigns and promotions that would cause short spikes in traffic to the site and saturate the network. Investing in additional network infrastructure to respond to these short traffic spikes did not make sense. To avoid the cost of a heavily upgraded network Velir proposed Akamai and their CDN to absorb the traffic spikes and speed up the end-user browsing experience.

The first step was to help the client identify areas of the site that would benefit from being cached by Akamai. We analyzed the traffic and the different content types to build this caching strategy using an empirical approach - we first configured Akamai to cache all important static assets with a low time to live (TTL) value to avoid frustrating the editors and ensure the latest content was quickly available to end users.

However, to take full advantage of Akamai caching and avoid pointless requests to the servers we needed a more aggressive caching strategy with a higher TTL. This required automatic invalidation of the Akamai cache if a static file (especially a PDF) was edited by an author. To do this we needed to call the Akamai Content Control Utility (CCU) API to invalidate an object once it had been edited and published in AEM.

This is why we created the Akamai-CCU-Rest-API connector: to invalidate the Akamai cache when assets have been updated or deleted. This connector allows us to increase the TTL of PDFs and other content without having to worry about them getting stale.  Once an asset has been activated or deactivated the Akamai-CCU-Rest-API connector automatically detects this change and invalidates the Akamai cache.

The Akamai-CCU-Rest-API Connector

The connector is an independent OSGI bundle that can be installed on your AEM/Adobe CQ server and allows you to connect your CQ instance with the Akamai Content Control Utility REST API.

This bundles manager calls the Akamai CCU Rest API when content is replicated and also allows the call to be triggered manually. It is an easy configurable bundle that handles AEM replicate events and accordingly notifies Akamai to invalidate the caching of the modified resources.

Implementation

The bundle is coded using groovy and uses the http-builder framework to manage the connections. It has few dependencies to make it very light. It is composed of two main parts:

CCUManager

The CCUMANAGER encapsulates the calls to the Akamai REST API and is the interface of the connector itself that manages a pool of connections to request the Akamai CCU REST services. It offers simple method signatures with predefined default values to invalidate cached objects. You can perform the invalidation by CP code or URL depending on your strategy. This class doesn't do any processing on the URLs that you pass to it; it just makes sure that the list contains unique values and adds them to the purge request.

Only the ccuManager.purgeByUrls(absoluteUrls) is used as a default by the job but there are a number of other signatures that may be used such as:

  • PurgeResponse purgeByCpCode(String cpCode)
  • PurgeResponse purge(Collection<String> objects, PurgeType purgeType, PurgeAction purgeAction, PurgeDomain purgeDomain)
  • PurgeStatus getPurgeStatus(String progressUri)
  • QueueStatus getQueueStatus()

Akamai Event Handler/Flush Akamai Items Job

AkamaiEventHandler is an event handler that listens to the replication queue “com/day/cq/replication”. It is in charge of adding a job to a dedicated Akamai queue if the path to invalidate starts with one of the values specified in the list "pathsHandled" (by default it is “/content/dam”). If the handler validates the event it adds a job with the resource being invalidated to “com/velir/aem/akamai/ccu/impl/FlushAkamaiItemsJob”.

The FlushAkamaiItemsJob listens to the previous queue and sends Akamai a purge notification using the CCUManager. The job listens to "com/velir/aem/akamai/ccu/impl/FlushAkamaiItemsJob" and calls the CCuManager.purgeByUrls(...) with the list of paths to invalidate. These paths are prepended by the rootUrl that represents the scheme + the domain without “/” at the end.

Example: rootSiteUrl = "http://www.velir.com" and url = "/test" => The path to invalidate will be "http://www.velir.com/test"

The job logs all the paths that are invalidated in an Akamai.log file:

19.05.2014 15:55:12.073 *INFO* [pool-7-thread-20-Akamai Job Queue(com/velir/aem/akamai/ccu/impl/FlushAkamaiItemsJob)] com.velir.aem.akamai.ccu.impl.FlushAkamaiItemsJob Path(s) to purge:
19.05.2014 15:55:12.074 *INFO* [pool-7-thread-20-Akamai Job Queue(com/velir/aem/akamai/ccu/impl/FlushAkamaiItemsJob)] com.velir.aem.akamai.ccu.impl.FlushAkamaiItemsJob http://www.rwjf.org/content/dam/farm/reports/issue_briefs/2014/rwjf413404

Using the Akamai Connector

Download and Installation

The bundle can be downloaded on GitHub: https://github.com/Velir/akamai-ccu-rest-api-connector/releases.

The current version is 1.0 and it is our first production version.

Once you have the bundle you can just install it as a normal bundle using the Felix interface: http://localhost:4502/system/console/bundles

AEM Web Console Bundles

Select the jar you just downloaded. For example, akamai-ccu-rest-api-connector-1.1-SNAPSHOT.jar and click Install.

Akamai Connector Installation

Once Felix has installed the package you should see:

You might need to install additional bundles to make it work. The bundle is designed to be as light as possible but you will need:

  • groovy-all
  • httpcode-osgi
  • httpclient-osgi

Look at the pom.xml to see all the dependencies.

Configuration

Under OSGI > Configuration you can see the three classes that can be configured:

Akamai Connector Configuration

You need to setup the username and password for the CCUManager

Akamai Connector CCUManager Configuration

To use the automatic invalidation you also need to setup the handled paths. If an asset under that path is activated, it will automatically invalidate the Akamai cache for this specific asset.

Akamai Connector Cache Configuration

As part of the automatic invalidation you need to setup the root URL of the site you want to invalidate. Akamai only uses absolute URLs and CQ just provides a relative path to the current site. So you need to specify the web site that is cached by Akamai as http://www.mysite.com and the job will prepend that root URL to the CQ relative URL and call the CCUManager with the absolute URL.

Akamai Connector Cache Flush Configuration

Installation via Source Control

You can also clone the repository https://github.com/Velir/akamai-ccu-rest-api-connector and use Maven to compile and package the bundle: mvn clean install.

The current stable version is akamai-ccu-rest-api-connector-1.0 (https://github.com/Velir/akamai-ccu-rest-api-connector/tree/akamai-ccu-rest-api-connector-1.0).

The master branch is the development version 1.1-SNAPSHOT (https://github.com/Velir/akamai-ccu-rest-api-connector/).

More Information

Additional information on Velir’s Akamai connector can be found here: https://github.com/Velir/akamai-ccu-rest-api-connector.

Feel free to contact us or leave a comment below if you’d like to discuss it further.