Showing posts with label portalsiteoptimization. Show all posts
Showing posts with label portalsiteoptimization. Show all posts

Validation Cache - ETag

Portlet Specification 2.0 has concept of Validation cache in addition to expiration based cache. Basic idea is Validation-based caching allows portlets to return a validation token together with the markup response and expiration time. The portlet can set the validation token on the RenderResponse or ResourceResponse via the ETAG property from within servlets/JSPs or via the CacheControl setETag method from within the portlet. If no expiration time is set, the content should be viewed by the portlet container as expired

After the content is expired the portlet container should send a render or
serveResource request to the portlet with the validation token (called ETag in HTTP) of the expired content. The portlet can access the validation token provided by the portlet container either via the property ETAG of the RenderRequest or ResourceRequest, or the getETag method of the RenderRequest or ResourceRequest. The portlet can validate if the cached content for the given ETag is still valid or not. If the content is still valid the portlet should not render any output but either set the property USE_CACHED_CONTENT RenderResponse or ResourceResponse and a new expiry time, or setUseCachedContent on the CacheControl of the RenderResponse or
ResourceResponse and set a new expiry time. The portlet should set the validation
token, expiry time or caching scope before writing to the output stream as otherwise
portals / portlet containers may ignore the values.

I tried to modify my ValidationCacheSamplePortlet to see if the ETAG works in either doView() or render method and it seems that both Pluto and WebSphere Portal 6.1.5 ignore the ETAG


public class ValidationCacheSamplePortlet extends GenericPortlet {
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ValidationCacheSamplePortlet.doView()");
response.setContentType("text/html");
if (request.getETag() != null) { // validation request
System.out.println("ETag is not null, returning from cache");

response.getCacheControl().setExpirationTime(300);
response.getCacheControl().setUseCachedContent(true);
return;
}
System.out.println("ETag is null returning new content");
// create new content with new validation tag
response.getCacheControl().setETag("ABCD");
response.getCacheControl().setExpirationTime(6000);
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
"/validation.jsp");
rd.include(request, response);
System.out.println("Exiting ValidationCacheSamplePortlet.doView()");

}


public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
System.out
.println("Entering ValidationCacheSamplePortlet.serveResource()");
if (request.getETag() != null) { // validation request
System.out.println("ETag is not null, returning resource response from cache");

response.getCacheControl().setExpirationTime(300);
response.getCacheControl().setUseCachedContent(true);
return;
}
System.out.println("ETag is null returning new content");
response.getCacheControl().setETag("1212121ABCD");
response.getCacheControl().setExpirationTime(6000);
response.getWriter().println("Hello from ValidationCacheSamplePortlet.serveResource " + new Date());
System.out
.println("Exiting ValidationCacheSamplePortlet.serveResource()");
}
}


I was hoping that after the first invocation getETag() would return valid value and as a result the control will go to the block that says returning cached content but it did not work, getETag() always returns null

Validation Cache - Setting cache-control header

The portlet specification 2.0 has concept of Expiration Cache that allows you to make use of the Browser Cache to cache the response. The ValidationCacheSamplePortlet , demonstrates how to do that.

The Portlet Specification has introduced javax.portlet.CacheControl object that can be used to get granular control over the caching of the response. YOu can get object of CacheControl from either RenderResponse or ResourceResponse and call its method.

The ValidationCacheSamplePortlet portlet is very simple, all it does is that in the doView() method it forwards control to validation.jsp and in the validation.jsp it renders a button, which you click on that button it is making XHR call to the resource URL. Inside the serveResource method i am setting caching properties

public class ValidationCacheSamplePortlet extends GenericPortlet{
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ValidationCacheSamplePortlet.doView()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/validation.jsp").include(request, response);
System.out.println("Exiting ValidationCacheSamplePortlet.doView()");
}
public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
System.out.println("Entering ValidationCacheSamplePortlet.serveResource()");
response.getCacheControl().setExpirationTime(600);
response.getCacheControl().setPublicScope(true);

response.setContentType("text/html");
response.getWriter().println("Hello from ValidationCacheSamplePortlet.serveResource "
+ new Date());
System.out.println("Exiting ValidationCacheSamplePortlet.serveResource()");
}
}


In this sample code i am calling following two methods of CacheControl object in the
serveResource

  1. setExpirationTime(600): This method will set cache-control equal to 600, which is equivalent of telling browser that cache this response for 600 seconds or 10 minutes and dont make request to server to get new response during next 5 min.

  2. setPublicScope(true) This method is used for setting cache-control to public that means this response is not private to the user and its same for user A as well as user B, so even proxy can cache it. If you set this to false then that will tell proxy that this response is private and only browser can cache it



I tried deploying this portlet in WPS and accessing it through firefox and what i see is that portal is setting correct cache-control headers.



If you look at the Firefox cache then you will notice that the resource is cached for approx. 10 min. like this



Note: It seems that not all the portlet container support CacheControl and not uni-formally. Ex. This sample code to set cache-control header does not work in Pluto, it works in WebSphere Portal 6.1.5 in the serveResource() method but not in doView()