AEM: Handling Page-Replication events with a custom Transport Handler

An usual approach to react to different events in AEM is the implementation of an Event Handler1. In your implementation you subscribe to one or more event topics which are then passed into the void handleEvent(Event event) method.

The interface for an Event Handler is quite simple, so this is a very lean approach. You can find an example in Adobe’s Knowledge Base

Although you can subscribe to the Replication Event2, there are some usecases where an EventHandler might not work for you.

This blogpost originates from the requirement to export Page Data into an external system upon replication.

Transport Handler

The Transport Handler3 interface allows applications to hook into the replication mechanism and implement a custom agent. The most common implementation is the Replication Agent which is responsible to transport AEM Pages and Resources from an author instance to the publisher instances.

Agents are created in /etc/replication/agents.author.html and the used page component can simply extend the cq/replication/components/agent ResourceType.

Implementation

Depending on the complexity you have to implement one or two interfaces. First of all TransportHandler which is responsible for the transport to your destination. The canHandle method should return true, if the passed AgentConfig matches your Handler. In deliver you need to handle the actual transaction.

As there are multiple possible ReplicationActionTypes4 you might want to check for them first. They are available by calling ReplicationTransaction.getAction().getType().

One advantage of TransportHandler compared to EventHandler is, that you don’t have to resolve the page or resource related to the event but that you can get a customizable ReplicationContent5 object with the relevant information (see below for further customizations).

Service(TransportHandler.class)
@Component(label = "My custom Agent", immediate = true)
public class MyTransportHandler implements TransportHandler {

  public boolean canHandle(AgentConfig config) {}

  public ReplicationResult deliver(TransportContext ctx, ReplicationTransaction tx) throws ReplicationException {}
}

Custom ContentBuilder

A ContentBuilder6 assembles the data for a replication into a single object that is passed to the Transport Handler.

Each ContentBuilder has to set the name property which is selectable as Serialization Type in the ReplicationAgent configuration afterwards.

@Property(name = "name", value = "my custom format")

Replication Agent

Conclusion

With the provided information, it is easy to implement a custom Transport Handler that is informed upon Replication and can then replicate the content into an external system. Depending on the requirement, you can also add a Content Builder and provide a adapted format for the ReplicationContent.

Other examples

If you want to look into more code, Nate Yolles published an indepth example how he implemented an Transport Handler which invalidates the Akamai Cache for certain pages upon replication.

Footnotes

Related Posts