How to send page multiple paths to invalidate dispatcher cache in one request instead of loop?
import com.amazonaws.http.apache.request.impl.HttpGetWithBody;
import com.esa.service.CacheInvalidationConfig;
import com.esa.service.CacheInvalidationService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
@component(service = CacheInvalidationService.class, immediate=true)
public class CacheInvalidationServiceImpl implements CacheInvalidationService {
@reference
private CacheInvalidationConfig cacheInvalidationConfig;
private static final String DISPATCHER_URL_PATH_API = "/dispatcher/invalidate.cache";
private static final Logger LOG = LoggerFactory.getLogger(CacheInvalidationServiceImpl.class);
public void invalidateCache(Set<String> pagePaths) {
String [] dispatcherHost = cacheInvalidationConfig.getDispatcherURL();
for (String path : pagePaths) {
for (String dispatcherURL : dispatcherHost) {
String apiURL = dispatcherURL + DISPATCHER_URL_PATH_API;
Request request = Request.Get(apiURL);
request.setHeader("Host", "flush");
request.setHeader("CQ-Action", "Activate");
request.setHeader("CQ-Handle", path);
HttpResponse httpResponse = null;
try {
httpResponse = request.execute().returnResponse();
LOG.info("Prepared URL : {} ,CQ Handle : {}", apiURL, path);
if (null != httpResponse && null != httpResponse.getStatusLine()) {
final int statusCode = httpResponse.getStatusLine().getStatusCode();
LOG.info("Response Code for Cache Clear Request: {}", statusCode);
}
}
catch (Exception e) {
LOG.error("Dispatcher API Error : {}",e.getMessage(),e);
}
}
}
}
}
Views
Replies
Total Likes
Hi @NehaMi
You can pass multiple paths in request body , please check
Please check the recache part here, it may create load on publishers if there are too many URLs to invalidate
Hi @arunpatidar ,
I have tried to send multiple paths in request body with this code, but in dispatcher log , i can see only one entry for invalidate cache -
Activation detected: action=Activate [/content/esa/hn/cphi]
package com.esa.service.impl;
import com.amazonaws.http.apache.request.impl.HttpGetWithBody;
import com.esa.service.CacheInvalidationConfig;
import com.esa.service.CacheInvalidationService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Set;
@Component(service = CacheInvalidationService.class, immediate=true)
public class CacheInvalidationServiceImpl implements CacheInvalidationService {
@Reference
private CacheInvalidationConfig cacheInvalidationConfig;
private static final String DISPATCHER_URL_PATH_API = "/dispatcher/invalidate.cache";
private static final Logger LOG = LoggerFactory.getLogger(CacheInvalidationServiceImpl.class);
public void invalidateCache(String path) {
String[] dispatcherHost = cacheInvalidationConfig.getDispatcherURL();
for (String dispatcherURL : dispatcherHost) {
String requestBody = "/content/esa/hn/pharmapack,/content/esa/hn/cphi";
String apiURL = dispatcherURL + DISPATCHER_URL_PATH_API;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(apiURL);
httpPost.setHeader("Content-Type", "text/plain");
httpPost.setHeader("Host", "flush");
httpPost.setHeader("CQ-Action", "Activate");
httpPost.setHeader("CQ-Handle", path);
httpPost.setEntity(new StringEntity(requestBody));
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
LOG.info("invalidateCacheNew :: Prepared URL : {} ,CQ Handle : {}", apiURL, path);
int statusCode = response.getStatusLine().getStatusCode();
LOG.info("invalidateCacheNew :: Response Code for Cache Clear Request: {}", statusCode);
}} catch (Exception e) {
LOG.error("invalidateCacheNew :: Dispatcher API Error : {}",e.getMessage(),e);
}
}
}
}
Hi @NehaMi
You can try something like below
HttpPost post = new HttpPost(dispatcherHost);
post.addHeader("CQ-Action", "Activate");
post.addHeader("CQ-Handle", cqHandlePath);
post.addHeader("Host", domain);
post.addHeader("CQ-Action-Scope", "ResourceOnly");
post.addHeader("Content-Type", "text/plain");
String bodyString = StringUtils.join(pagesToInvalidate, "\n");
StringEntity body = new StringEntity(bodyString);
post.setEntity(body);
where pagesToInvalidate is a arrayList type
Hi @arunpatidar ,
After implementing this approach, we receive a 200 response, but the cache is only cleared for the path specified in cq-handle.
In this case, the cache is cleared only for /content/test/hn/test-site1 and not for /content/test/hn/test-site2.
Code
@Override
protected void doGet(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException {
String paths = request.getParameter("paths");
String cqHandle = request.getParameter("cqHandle");
ArrayList<String> list = new ArrayList<>(Arrays.asList(paths.split(",")));
cacheInvalidationService.invalidateCacheTest(cqHandle,list);
}
public void invalidateCacheTest(String path, ArrayList<String> pagesToInvalidate) {
String[] dispatcherHost = cacheInvalidationConfig.getDispatcherURL();
for (String dispatcherURL : dispatcherHost) {
String requestBody = StringUtils.join(pagesToInvalidate, "\n");
String apiURL = dispatcherURL + DISPATCHER_URL_PATH_API;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(apiURL);
httpPost.setHeader("Content-Type", "text/plain");
httpPost.setHeader("Host", "flush");
httpPost.setHeader("CQ-Action", "Activate");
// httpPost.addHeader("CQ-Action-Scope", "ResourceOnly");
httpPost.setHeader("CQ-Handle", path);
httpPost.setEntity(new StringEntity(requestBody));
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
LOG.info("invalidateCacheNew :: Prepared URL : {} ,CQ Handle : {}, Request Body : {}", apiURL, path, requestBody);
int statusCode = response.getStatusLine().getStatusCode();
LOG.info("invalidateCacheNew :: Response Code for Cache Clear Request: {}", statusCode);
}} catch (Exception e) {
LOG.error("invalidateCacheNew :: Dispatcher API Error : {}",e.getMessage(),e);
}
}
}
Hi @NehaMi
You may need to use path patterns for CQ-Handle header, try to use some kind of wild card or deepest path
I was checking same for other implementation and there
POST /dispatcher/invalidate.cache HTTP/1.1
CQ-Action: Activate
Content-Type: text/plain
CQ-Handle: path-pattern
Content-Length: numchars in bodypage_path0
page_path1
...
page_pathn
Why don't you use the replication API for this?
Hi @Jörg_Hoh ,
The replication API is useful for publishing pages, but in our case, we don’t need to republish the page since there are no changes. It’s an asset content update that is already available on the publisher. We just need to clear the dispatcher cache from the author instance
Well, for me that feels like a bandaid for a different problem...
@NehaMi Did you find the suggestions helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies