December 19, 2014
  |   Blog, WEM / WCM

Reverse Replication: Customize For Your Content

Replication, activation, and publishing are three terms interchangeably used to describe the process of transferring data from the author instance to the publish instance in AEM. Reverse replication is the same type of process except it transfers from the publish instance to the author instance. Reverse replication is typically used to replicate data, such as forum posts and user profiles, to the author instance. This post was inspired by some issues we ran into while trying to reverse replicate form submission data. In order to understand the difficulties regarding reverse replication, we must first understand how normal replication works.

One of the most common uses of the replication process occurs when an author activates a page to the publish instance. The action triggers the replication agent on the author instance to start the process. The replication agent contains configurations for transferring the data such as protocol options and replication triggers. This agent packages up the data and then puts it into the replication queue in order for it to be transferred over. On the publish instance there is a receiver servlet that pulls the data from the queue and installs it on that instance.

Reverse replication uses the same basic process as replication with a few modifications and limitations on what it can do. Transferring data from the publish to author using http protocol creates security risks. However, with anyone being able to transfer data if they want.  AEM reduces this security risk by taking the following precautions to prevent any issues from occurring:

  • Replication can be triggered by node addition, modification or deletion; while reverse replication can only occur after modification or deletion.
  • The out of the box method is difficult to implement on nodes that are not of the type cq:Page. This is due to the OOTB replication agent looking for a cq:PageContent node that has the cq:distribute, cq:lastModified and cq:lastModifiedBy properties.
  • The author instance has to initiate the transfer from the publish instance on a defined time interval.

For data to be reverse replicated properly it needs to be packaged and placed in a directory that will act similarly to the replication queue on the author instance. The default reverse replication agent is configured to use the folder /var/replication/outbox.

Figure A: Reverse replication process

Typically the reverse replication process is triggered by using a workflow instead of an author clicking activate from the previous example. The replication agent on the publish instance then creates the package and places it in the outbox folder to wait. On the author instance there needs to be a replication agent for reverse replication as well that polls the outbox folder at configurable time intervals, the default is set to 60000 milliseconds. Once the author’s agent has polled the outbox the packages are transferred to the author instance and installed.

 Customized reverse replication implementation

The reverse replication process doesn’t sound difficult, especially when compared to regular replication which is used frequently. Due to the security precautions mentioned earlier it can be a difficult task depending on the content you want to bring over. As previously stated the issues that inspired this post occurred when we tried to capture submissions from a form in a nt:unstructured node. The submission data nodes were saved in a tree of nt:unstructured nodes used to store the submission date that looks like the image below:

Figure B: Form data node structure

We tried to use workflows for triggering reverse replication whenever a form was submitted but due to this customized way of storing the submission data we ran into many difficulties. Not to say that the out of the box way of doing it is bad but it is very limited in what it can replicate correctly.

The solution that we ended up implementing for this problem used a few of the replication-related classes from the com.day.cq.replication package. We created a method in the back end class that handled the form submissions which triggered the process once it got to the end of the submission method. The main classes that were used to control this replication process included the Replicator, ReplicationOptions, and AgentFilter. It is the same as creating an agent using the interface within CQ5 except it allows more flexibility since you can fire off the replication from within your code instead of relying on workflows or some other triggering method.

We found that using the replication classes allowed us to easily perform the reverse replication process because the agent filter is what specifies which replication agent is going to be used. Instead of trying to configure a workflows parameters in just the right way to pick up the submissions we created an instance of the AgentFilter class that triggered on distribute and added it to the ReplicationOptions. This essentially bypasses some of the limitations on the publish agent and puts the data in the outbox folder whenever a user submission is accepted. The two code snippets below are examples of the solution we implemented:

private void replicateResource(final Resource resource, ReplicationActionType actionType){
final ReplicationOptions replicationOptions = new ReplicationOptions()
final Session adminSession = resource.resourceResolver.adaptTo(Session.class)
replicationOptions.setFilter(DISTRIBUTE_AGENT_FILTER)
replicationOptions.setSynchronous(true)
try{
replicator.replicate(adminSession, actionType, resource.path, replicationOptions)
}catch(Exception e){
throw new ReplicationException(“Unable to replicate ${resource.name}”)
}
}

Figure C: Replication method example

private static final AgentFilter DISTRIBUTE_AGENT_FILTER = new AgentFilter() {
public boolean isIncluded(Agent agent) {
return agent.configuration.isTriggeredOnDistribute()
}
};

Figure D: Reverse replication agent example

For a more customized reverse replication process, we recommend the class-based approach for flexibility. When the form’s submit button is clicked the code snippets from Figure:B&C were used to allow the reverse replication process to be started. The method in Figure: B was called after the submission completed some validation and was saved to the author’s JCR. Before the replicate method was used the agent filter option was set to use the distribution agent filter created in Figure:C that prompts the reverse replication process.

When we looked into this issue there were a lot of examples using the workflow option of implementing reverse replication, however not many other options of accomplishing this task. While using the replication classes we found that some of the other solutions could have probably been simplified by writing their own reverse replication trigger. We hope this clarifies the subject for others facing the same issue.

Ryan Cude
Ryan Cude is an AEM consultant with experience in both front and back end design and development. He has over a year of experience with Java and AEM development. Is certified in Adobe CQ5.5 Component Development and has worked on multiple projects. In his free time he enjoys concerts, cooking, and investigating different technologies for personal projects.
View All Posts By This Author

Subscribe to Our Newsletter

Get the latest insights from Blue Acorn iCi

Let's build something together.