Skip to content

Instantly share code, notes, and snippets.

AEM: Deploying replication agents as code

Include your replication agents in your git repository

Use case

Let's imagine you want to install AEM with a pretty standard, simple topology. You may have 4 environments (local, dev, uat, prod) and each environments consists of one author replicating to two publishers. 

That means you have 8 replication agents to set up, 12 if you add a dispatcher, 20 if you want reverse-replication, etc.

Configuring these replication agents can start to become a bit of a chore, especially if you are using custom replication and transport (receiver) users. You should btw, it's in the security checklist.

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:rep="internal"
jcr:mixinTypes="[rep:AccessControllable]"
jcr:primaryType="cq:Page">
<jcr:content
cq:template="/libs/cq/replication/templates/agent"
jcr:description="Agent that replicates to the default publish instance."
jcr:primaryType="nt:unstructured"
jcr:title="Publish"
sling:resourceType="cq/replication/components/agent"
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:rep="internal"
jcr:mixinTypes="[rep:AccessControllable]"
jcr:primaryType="cq:Page">
<jcr:content
cq:template="/libs/cq/replication/templates/agent"
jcr:description="Agent that replicates to the default publish instance."
jcr:primaryType="nt:unstructured"
jcr:title="Publish"
sling:resourceType="cq/replication/components/agent"

Javascript introduction

Data and operators

Writing a program is a lot like writing in English, there are certain rules to follow.

To describe what something is we use data. For example:

  • A number
  • True or false (ie: a boolean)
  • Some texxt (ie: a string)

Q1. What is the output of this program?

public class Test {
    public static void main(String[] args) {
        int n = 10;
        int next = 0;
        int nextNext = 1;
        for (int i = 1; i < n; i++) {
 nextNext = next + nextNext;
This file has been truncated, but you can view the full file.
/*************************************************************************
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2021 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
// Import the hello.groovy script
importer.script(binding, "hello.groovy")
// Execute the closure, passing your name
hello("Theo")
// Add a closure (that takes a name argument) to the binding as a variable
binding.hello = { name ->
println "Hello " + name
}
import com.icfolson.aem.groovy.console.api.BindingExtensionProvider;
import com.icfolson.aem.groovy.console.api.BindingVariable;
import com.icfolson.aem.groovy.console.api.context.ScriptContext;
import org.osgi.service.component.annotations.Component;
import java.util.HashMap;
import java.util.Map;
// Tells the Groovy Console bundle to use this class as an extension to the default Binding
@Component(service = BindingExtensionProvider.class, immediate = true)
<dependency>
<groupId>com.icfolson.aem.groovy.console</groupId>
<artifactId>aem-groovy-console</artifactId>
<version>15.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.15</version>