Web-hook Example to Invalidate Cache

Introduction

Goal

Invalidate resource data cache using a web hook.

Background

By default, the ResourceResolver component for product catalogs data in the demo project caches result data based on resource space name, operation name, relative resource path, path variables, etc. for 1 minute ("time-to-live"). So, for the same requests, it will return the cached data without having to invoke the backend REST service again as long the the cached data was not expired in 1 minutes ("time-to-live").

Suppose you want to increase the "time-to-live" internally to maximize cacheability but you also want to invalidate the cache, partially or entirely, whenever there any change occurrs in the backend by invoking a custom "Web-Hook" URL. "Web-Hook" is very useful in this scenario to maximize efficiency and performance.

Basic Web-Hook Page Example

The example "Web-Hook" in the demo project, invalidate-cache.jsp, was intentionally implemented in a simplified way for demonstration purposes. It will give you a basic understanding of how to implement a "Web-Hook" in a page, servlet, or otherwise.

You can invoke the demo "Web-Hook" page as follows with the two POST parameters (one to specifiy the target resource space name and the other for "secret" for minimal security):

$ curl http://localhost:8080/site/examples/invalidate-cache.jsp \
    -d "resource_space=demoProductCatalogs&secret=some_secret"

The example "Web-Hook" page is as follows. It eventually invokes ResourceServiceBroker#getResourceDataCache(resourceSpace).clear().

<%--
  Simple ResourceDataCache invalidation example for a resource space.
  This simple JSP page reads two post request parameters, "resource_space" and "secret",
  and clears the associated ResourceDataCache specified by the "resource_space" parameter value.
  For simplicity, this page compares the "secret" parameter with a hard-coded secret string for security.
  In practice, you will probably want to keep the secret in a different store for security, maintainability, etc.
--%>
<%@ page language="java" %>
<%@ page import="javax.servlet.http.HttpServletResponse" %>
<%@ page import="org.slf4j.LoggerFactory" %>
<%@ page import="org.slf4j.Logger" %>
<%@ page import="org.onehippo.cms7.crisp.api.broker.ResourceServiceBroker" %>
<%@ page import="org.onehippo.cms7.crisp.api.resource.ResourceDataCache" %>
<%@ page import="org.onehippo.cms7.crisp.hst.module.CrispHstServices" %>
 
<%!
private static final String DEFAULT_SECRET = "some_secret";
 
private static Logger log = LoggerFactory.getLogger("org.onehippo.cms7.crisp.demo.jsp.invalidate-cache");
%>
 
<%
if (!"POST".equals(request.getMethod())) {
    log.error("Must be a POST request.");
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    return;
}
 
String resourceSpace = request.getParameter("resource_space");
String secret = request.getParameter("secret");
 
if (resourceSpace == null || "".equals(resourceSpace.trim())) {
    log.error("Resource space name is missing.");
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    return;
}
 
if (!DEFAULT_SECRET.equals(secret)) {
    log.error("Wrong secret.");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    return;
}
 
ResourceServiceBroker broker = CrispHstServices.getDefaultResourceServiceBroker(HstServices.getComponentManager());
 
if (broker == null) {
    log.error("CRISP was not initialized.");
    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
    return;
}
 
ResourceDataCache resourceDataCache = broker.getResourceDataCache(resourceSpace);
 
if (resourceDataCache == null) {
    log.error("No resource data cache for the resource space.");
    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
    return;
}
 
log.info("Resource data cache cleared for resource space: '{}'", resourceSpace);
resourceDataCache.clear();
out.println("Resource data cache cleared for resource space: '" + resourceSpace + "'.");
%>
Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?