Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

I can not find how to implement executeActivate and executeDelete method.

Avatar

Level 4

Hello Everyone,

Here is FlushOnPublish.java

I can not find how to implement executeActivate and executeDelete method.

-executeActivate : the method to cache the content to cache when flushing on publish.

-executeDelete   : the method to delete the content from cache when flushing on publish.

Can you teach me how to implement it?

---------------------------------------------------------------

public class FlushOnPublish {

    private static Logger log = LoggerFactory.getLogger(FlushOnPublish.class);

    public static void execute(BundleContext bundleContext, Event event) {

        if (bundleContext != null && event != null) {

            final ServiceReference rrServiceReference = bundleContext.getServiceReference(ResourceResolverFactory.class.getName());

            final ResourceResolverFactory resolverFactory = (ResourceResolverFactory)bundleContext.getService(rrServiceReference);

            final ResourceResolver resolver = AdminService.getResourceResolver(resolverFactory);

            final ReplicationAction replicationAction = ReplicationEvent.fromEvent(event).getReplicationAction();

            final ReplicationActionType replicationActionType = replicationAction.getType();

            if (replicationActionType.equals(ReplicationActionType.ACTIVATE)) {

                // make 2 requests:

                // 1) request to delete cache

                // 2) request to cache new content

                executeCurlCommand(getDispatcherUris(resolver), replicationAction.getPaths(), ReplicationActionType.DELETE);

                executeCurlCommand(getDispatcherUris(resolver), replicationAction.getPaths(), ReplicationActionType.ACTIVATE);

            }

            else if (replicationActionType.equals(ReplicationActionType.DEACTIVATE) ||

                    replicationActionType.equals(ReplicationActionType.DELETE)) {

                // make 1 request: delete cache

                executeCurlCommand(getDispatcherUris(resolver), replicationAction.getPaths(), ReplicationActionType.DEACTIVATE);

            }

        }

    }

    private static String[] getDispatcherUris(ResourceResolver resolver) {

        final String DISPATCHER_FLUSH_PATH = "/etc/replication/agents.publish/flush/jcr:content";

        Resource resource = resolver.getResource(DISPATCHER_FLUSH_PATH);

        String[] dispatcherUris = null;

        if (resource != null) {

            ValueMap valueMap = resource.getValueMap();

            if (valueMap.containsKey("dispatchers")) {

                dispatcherUris = valueMap.get("dispatchers", "").split(",");

            }

        }

        /**

         * i.e. [{protocol}://{dispatcher-server-hostname:port}/dispatcher/invalidate.cache]

         */

        return dispatcherUris;

    }

    private static void executeCurlCommand(String[] dispatchers, String[] paths, ReplicationActionType methodType) {

        /**

         *

         * curl

         * -H "CQ-Action:Flush"

         * -H "CQ-Handle: /content/geometrixx/en/toolbar"

         * -H "CQ-Path:/content/geometrixx/en/toolbar"

         * -H "Content-Length: 0"

         * -H "Content-Type: application/octet-stream"

         * http://dispatcher-server-hostname:port/dispatcher/invalidate.cache

         *

         * In Newer version of dispatcher try this

         *

         * curl

         * -H "CQ-Action: DELETE" -> methodType

         * -H "CQ-Handle:/content/geometrixx/en/toolbar" -> path

         * -H "CQ-Path:/content/geometrixx/en/toolbar" -> path

         * -H "Content-Length: 0"

         * -H "Content-Type: application/octet-stream"

         * http://dispatcher-server-hostname:port/dispatcher/invalidate.cache -> path

         */

        for (String path : paths) {

            for (String dispatcher : dispatchers) {

                // Execute dispatcher flush

                // The HTTP request should be called without waiting for response (asynchronously)               

                if (methodType.equals(ReplicationActionType.ACTIVATE)) {

                    //issue a curl request to cache the content (which is: path)

                    executeActivate();

                }

                else if (methodType.equals(ReplicationActionType.DELETE)) {

                    //issue a curl request to delete the content (which is: path)

                    executeDelete();

                }

            }

        }

    }

    private static void executeActivate() {

    }

    private static void executeDelete() {

    }

}

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

maybe I missed it, but what are you trying to implement? Where is this code suppose to run (Author? Publish?) And why are you using curl if you have a http client available?

Jörg

View solution in original post

8 Replies

Avatar

Community Advisor

You need to send Post request inside executeActivate and executeDelete method with parameters

E.g.

String url = "http://dispatcher-server-hostname:port/dispatcher/invalidate.cache";  

URL obj = new URL(url); 

HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();   

//add reuqest header 

con.setRequestMethod("POST"); 

con.setRequestProperty("CQ-Action", DELETE);  

con.setRequestProperty("CQ-Handle", "/content/geometrixx/en/toolbar");

con.setRequestProperty("CQ-Path", "/content/geometrixx/en/toolbar");

con.setRequestProperty("Content-Length", "0");

con.setRequestProperty("Content-Type", "application/octet-stream");

Please check below to see how to make post request from java

https://www.journaldev.com/7148/java-httpurlconnection-example-java-http-request-get-post

How to send HTTP request GET/POST in Java – Mkyong.com



Arun Patidar

Avatar

Level 4

Thank you for your reply.

I implemented executeActivate.

But When I do publishing page for test.html, test.html is deleted.

I do not know why.

This is code for executeActivate.

private static void executeActivate(String dispatcher, String path) {

  HttpClient client = new HttpClient();

  HostConfiguration configuration = new HostConfiguration();

   // This uri is http://dispatcherhost:dispatcherport/dispatcher/invalidate.cache
  // Without this host configuration there will be and exception with the message "Host is null"
   configuration.setHost(dispatcher);

  client.setHostConfiguration(configuration);

  PostMethod post = new PostMethod(dispatcher);

   // CQ-Action:Delete will delete the cache from dispatcher.
  // For cache invalidation Activate action should be used.
   post.setRequestHeader("CQ-Action","Activate");

   // pagePath specifies the page that needs to be invalidated
   post.setRequestHeader("CQ-Handle",path);

  post.setRequestHeader("CQ-Path",path);

   try {

  StringRequestEntity body = new StringRequestEntity(path, null, null);

  post.setRequestEntity(body);

  post.setRequestHeader("Content-length",String.valueOf(body.getContentLength()));

  } catch (UnsupportedEncodingException ignore) {

  }

   // post.setRequestHeader("Content-Length", "0");
   post.setRequestHeader("Content-Type", "application/octet-stream");

   try {

   log.error("[Step02] executeActivate3 >> NEW TEST PUBLISH: {} {} {}", path, dispatcher);

  client.executeMethod(post);

  } catch (IOException ignore) {

  }

  post.releaseConnection();

}

Avatar

Community Advisor

Hi,

test page is getting deleted from cache because you are doing via code.

Manually Invalidating the Dispatcher Cache

To invalidate (or flush) the Dispatcher cache without activating a page, you can issue an HTTP request to the dispatcher. For example, you can create an AEM application that enables administrators or other applications to flush the cache.

The HTTP request causes Dispatcher to delete specific files from the cache. Optionally, the Dispatcher then refreshes the cache with a new copy.

Delete cached files

Issue an HTTP request that causes Dispatcher to delete files from the cache. Dispatcher caches the files again only when it recieves a client request for the page. Deleting cached files ins this manner is appropraite for web sites that are not likely to receive simultaneous requests for the same page.

The HTTP request has the following form:

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

Dispatcher cache updated document in cache only when the document is requested or If the document is configured for auto-invalidation, the Dispatcher checks whether it is older or newer than the last change available. If it is older, the Dispatcher requests the current version from the AEM instance and replaces the version in the cache.

Dispatcher Overview



Arun Patidar

Avatar

Correct answer by
Employee Advisor

Hi,

maybe I missed it, but what are you trying to implement? Where is this code suppose to run (Author? Publish?) And why are you using curl if you have a http client available?

Jörg

Avatar

Level 4

1597462_pastedImage_0.png

As you told me, I just wanted to use curl.

But when I use curl command, it doesn't work to activate to cache and delete from cache.

Can you help me to fix this problem?

I have no idea why it doesn't work.

Here is my source code for executeCurlCommand.

private static void executeCurlCommand(String[] dispatchers, String[] paths, ReplicationActionType methodType) {

        /**

         *

         * curl

         * -H "CQ-Action:Flush"

         * -H "CQ-Handle: /content/geometrixx/en/toolbar"

         * -H "CQ-Path:   /content/geometrixx/en/toolbar"

         * -H "Content-Length: 0"

         * -H "Content-Type: application/octet-stream"

         * http://dispatcher-server-hostname:port/dispatcher/invalidate.cache

         *

         * In Newer version of dispatcher try this

         *

         * curl

         * -H "CQ-Action: DELETE" -> methodType

         * -H "CQ-Handle:/content/geometrixx/en/toolbar" -> path

         * -H "CQ-Path:/content/geometrixx/en/toolbar" -> path

         * -H "Content-Length: 0"

         * -H "Content-Type: application/octet-stream"

         * http://dispatcher-server-hostname:port/dispatcher/invalidate.cache -> path

         */

        for (String path : paths) {

            for (String dispatcher : dispatchers) {

                // Execute dispatcher flush

                // The HTTP request should be called without waiting for response (asynchronously)

                log.error(" executeCurlCommand >> NEW TEST PUBLISH: {} {} {}", path, dispatcher, methodType.getName());

                String[] command = {

                        "curl",

                        "-H", "CQ-Action: " + methodType.getName(),

                        "-H", "CQ-Handle: " + path,

                        "-H", "CQ-Path: " + path,

                        "-H", "Content-Length: 0",

                        "-H", "Content-Type: application/octet-stream",

                        dispatcher

                };

                try

                {

                    ProcessBuilder process = new ProcessBuilder(command);

                    process.start();

                }

                catch (IOException e) {

                    log.error(e.getMessage(), e);

                }

            }

        }

    }

Right now I fixed it using curl commands.

I have tested it in different browsers.

when I publish or unpublish in Chrome browser, it is activated to cache and is deleted from cache in Firefox brower successfully.

-Chrome browser  : http://localhost-aem-dispatcher:4502/editor.html/content/voyagerhealthpoc/test3.html

-Firefox browser : http://localhost-aem-dispatcher/content/voyagerhealthpoc/test3.html

when I publish or unpublish in Firefox browser, it is activated to cache and is deleted from cache in Chrome brower successfully.

-Firefox browser : http://localhost-aem-dispatcher:4502/editor.html/content/voyagerhealthpoc/test3.html

-Chrome browser  : http://localhost-aem-dispatcher/content/voyagerhealthpoc/test3.html

On the contrary to this,

when I publish or unpublish in Chrome browser, it is not activated to cache and is not deleted from cache in Chrome brower

-Chrome browser  : http://localhost-aem-dispatcher:4502/editor.html/content/voyagerhealthpoc/test3.html

-Chrome browser  : http://localhost-aem-dispatcher/content/voyagerhealthpoc/test3.html

when I publish or unpublish in Firefox browser, it is not activated to cache and is not deleted from cache in Firefox brower

-Firefox browser : http://localhost-aem-dispatcher:4502/editor.html/content/voyagerhealthpoc/test3.html

-Firefox browser : http://localhost-aem-dispatcher/content/voyagerhealthpoc/test3.html

I think that if I test cache dispatcher at same browser in my local computer, cache dispatcher doesn't work because of session.

Avatar

Employee Advisor

I still don't get it.

* From what environment do you want to activate?

* From what environment do you want to invalidate the dispatcher cache? Is it the dispatcher in front of the publish instance(s)?

* Have you tried locally from that instance using curl (that means invoking it via shell)? What's the result?

Avatar

Level 4

i solved it locally from that instance using curl.

I wanted to activate and delete dispatcher cache when I publish from author.environment to publish environment.

Thank you.

Avatar

Employee Advisor

INvalidating the dispatcher cache of the publish dispatcher from authoring is not working reliably. Because you might invalidate these caches before the new content actually arrives at the publish instances. And in the time before between "invalidation" and "content arrives on publish" old content might get requested and stored in the cache.

That's the reason why the invalidation of the publish dispatchers should always originate from the publish instances.