Tuesday 2 September 2014

AEM Dispatcher - Manual cache flushing/invalidation

CQ comes with a Default flush agent that flushes cache on activation. But what if you manually want to flush or invalidate the cache?

The solution is:

The CQ cache can be deleted by using an HTTP request which looks like:

POST /dispatcher/invalidate.cache HTTP/1.1
CQ-Action: Activate
CQ-Handle: path-pattern
Content-Length: 0


CQ Actions:  

1.Activate
  • It touches the .stat file( at and above the CQ-handle path heirarchy) to the latest timestamp
2.Delete/Deactivate
  • It touches the .stat file( at and above the CQ-handle path heirarchy) to the latest timestamp 
  • It deletes the cache at the CQ-Handle path provided

We can write a flushcache servlet to serve the purpose:

package com.adobe.example;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

@Component(metatype=true)
@Service
public class Flushcache extends SlingSafeMethodsServlet {

    @Property(value="/bin/flushcache/html")
    static final String SERVLET_PATH="sling.servlet.paths";

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
        try{
            //retrieve the request parameters
            String handle = request.getParameter("handle");
            String page = request.getParameter("page");

            //hard-coding connection properties is a bad practice, but is done here to simplify the example
            String server = "localhost:80";
            String uri = "/dispatcher/invalidate.cache";

            HttpClient client = new HttpClient();

            PostMethod post = new PostMethod("http://"+server+uri);
            post.setRequestHeader("CQ-Action", "Activate");
            post.setRequestHeader("CQ-Handle",handle);

            StringRequestEntity body = new StringRequestEntity(page,null,null);
            post.setRequestEntity(body);
            post.setRequestHeader("Content-length", String.valueOf(body.getContentLength()));
            client.executeMethod(post);
            post.releaseConnection();
            //log the results
            logger.info("result: " + post.getResponseBodyAsString());
        }
        catch(Exception e){
            logger.error("Flushcache servlet exception: " + e.getMessage());
        }
    }
}

 

How it works:
The .stat file is touched to the latest timestamp everytime we hit the servlet.

Demo:

Initial .stat file


After hitting http://localhost:4503/bin/flushcache/html?handle=/content&page=/content, the stat file timestamp gets updated:







2 comments:

  1. While manually invalidating cache (through Flush Servlet-https://docs.adobe.com/docs/en/dispatcher/page-invalidate.html#Manually%20Invalidating%20the%20Dispatcher%20Cache) for below request:
    CQ-Handle: /content/unifiedweb/en_US/article.DOC2058.html
    CQ-Path: /content/unifiedweb/en_US/article.DOC2058.html
    I am facing an issue. When I run the Servlet code, it is deleting all the article.*.html which are present in the content/unifiedweb/en_US/ of the dispatcher cache. Could you please suggest what could be the possible cause and fix for this?

    ReplyDelete
  2. Hey Divya did you found any solution for your problem statement

    ReplyDelete