AEM 6 SP2 - Adding Dynamic Request Headers to Replication Requests

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


No comments:

Post a Comment