Goal
Replication Agent for Publish adds default headers Action, Path, Handle to request. Any custom headers can be added to requests by configuring Extended tab -> HTTP Headers of Publish Agent http://localhost:4502/etc/replication/agents.author/publish.html
This post is on adding dynamic headers to publish replication requests carried out using workflows. A process step introduced into workflow adds timestamp header eaem-unique-key to agent configuration before activation
Demo | Package Install | Source Code
Sample Request with Header eaem-unique-key
Solution
1) Create a Workflow Process OSGI Service apps.experienceaem.replication.SetUniqueKeyReplicationHeader, add the following code
package apps.experienceaem.replication;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.exec.WorkflowProcess;
import com.day.cq.workflow.metadata.MetaDataMap;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.Session;
import java.util.*;
@Component(metatype = false)
@Service
@Property(name = "process.label", value = "Experience AEM Unique Key Replication Header")
public class SetUniqueKeyReplicationHeader implements WorkflowProcess {
private static final Logger log = LoggerFactory.getLogger(SetUniqueKeyReplicationHeader.class);
private static String PUBLISH_AGENT_CONFIG = "/etc/replication/agents.author/publish/jcr:content";
private static String PROTOCOL_HTTP_HEADERS = "protocolHTTPHeaders";
private static String EAEM_UNIQUE_KEY = "eaem-unique-key: ";
@Reference
private ResourceResolverFactory rrFactory;
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args)
throws WorkflowException {
try {
Session session = workflowSession.getSession();
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, session);
Resource res = rrFactory.getResourceResolver(authInfo).getResource(PUBLISH_AGENT_CONFIG);
if(res == null){
log.warn("Resource - " + PUBLISH_AGENT_CONFIG + ", not available");
return;
}
ValueMap vm = res.adaptTo(ValueMap.class);
String[] headers = vm.get(PROTOCOL_HTTP_HEADERS, String[].class);
headers = addUniqueKeyHeader(headers);
res.adaptTo(Node.class).setProperty(PROTOCOL_HTTP_HEADERS, headers);
session.save();
} catch (Exception e) {
throw new WorkflowException(e);
}
}
private String[] addUniqueKeyHeader(String[] headers){
if(ArrayUtils.isEmpty(headers)){
headers = new String[]{
"Action: {action}",
"Path: {path}",
"Handle: {path}",
EAEM_UNIQUE_KEY + new Date().getTime()
};
return headers;
}
for(int i = 0; i < headers.length; i++){
if(headers[i].startsWith(EAEM_UNIQUE_KEY)){
headers[i] = EAEM_UNIQUE_KEY + new Date().getTime();
}
}
return headers;
}
}
2) Add a Process Step in Request for Activation workflow (http://localhost:4502/cf#/etc/workflow/models/request_for_activation.html), configure it with apps.experienceaem.replication.SetUniqueKeyReplicationHeader (donot forget to save workflow)
3) Any activation requested through Request for Activation workflow now adds a eaem-unique-key header to the publish agent configuration (/etc/replication/agents.author/publish/jcr:content) just before activation (there might be synchronization issues when there is heavy replication using other workflows or direct activations )
4) A sample publish request with header eaem-unique-key
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish Sending POST request to http://localhost:4503/bin/receive?sling:authRequestLogin=1
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish sent. Response: 200 OK
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish ------------------------------------------------
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish Sending message to localhost:4503
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> POST /bin/receive HTTP/1.0
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> Action: Activate
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> Path: /content/geometrixx/en
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> Handle: /content/geometrixx/en
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> eaem-unique-key: 1430403556120
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> Referer: about:blank
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish >> ...spooling 56653 bytes...
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish --
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << HTTP/1.1 200 OK
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << Date: Thu, 30 Apr 2015 14:19:16 GMT
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << Content-Type: text/plain;charset=UTF-8
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << Content-Length: 30
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << Server: Jetty(8.1.14.v20131031)
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish <<
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish << ReplicationAction ACTIVATE ok.
(com/day/cq/replication/job/publish)] com.day.cq.replication.Agent.publish Message sent.
5) Publish agent settings after the SetUniqueKeyReplicationHeader process step executes. The key eaem-unique-key changes with every activation