Applies to IBM Web Content Management (WCM) for IBM WebSphere Portal
WCM Caching is awesome right? You can reduce several hundred hits to the JCR database by using a little stash of memory in the Portal JVM which improves performance by several factors. There are generally 5 ways to configure the "Advanced Caching" policy depending on what you want to do. But what if your scope of caching requirements goes beyond these 5 options? What if your WCM components are serving different content based on a header or cookie? Then we'll need to roll our sleeves up a little bit to have caches stored based on those needs.
Existing WCM 'Advanced' Cache Types
The current WCM Advanced Cache configuration options are as follows:
|Site caching||This is the same as the basic Web content cache except that cache parameters in connect tags and URL requests can be used to override your server's default advanced Web content caching settings.|
|Session caching||When session caching is enabled, a copy of each Web page a user visits is stored in the session cache. The User accesses the cached version of a Web page until they start a new session, or until the cached Web page is expired from the cache.|
|User caching||When user caching is enabled, a copy of each Web page a user visits is stored in the user cache. The user accesses the cached version of a Web page until the cached Web page is expired from the cache.|
|Secured caching||Secured caching is used on sites where the item security features are used to grant different users access to different Web pages and components based on the groups they belong to.|
|Personalized caching||Personalized caching is used to cache Web pages of users who have the same "personalization profile". This means that users who have selected the same personalization categories and keywords, and who belong to the same group, share a single cache.|
Usually I go for the Secured advanced caching option. This allows WCM to create caches based on groups since it is a best practice to secure content and Portal/WCM access based on group memberships.
Configuring the Cache
To set the WCM advanced caching for a WebSphere Portal Server or Portal cluster, navigate to the WebSphere Admin Console:
|Property Name||Property Value|
What if I need to cache based on other parameters in addition to the groups?
Leveraging Additional Cache Keys parameter
IBM introduced an APAR for Portal (PI27550) that allows users to define an additional cache key for the WCM Advanced Caching. This allows users to set an additional cache key depending on extra needs. There are two additional cache keys referenced in the APAR. Either one of these can be used as needed, and must be set as a custom property in the WCM Config Service resource environment provider. To set either parameter, navigate to the WebSphere Admin Console:
And use either property depending on your needs.
- Sets an additional cache key based on a request header (must specify the header name as a value)
- A user could also cache with multiple different keys for different headers, by specifying the value of the custom property with a comma separated list of the header names (for example: User-Agent, Referer)
Allows user to specify different caches based on pre-defined list of valid request attributes for this property
Additional Key Attribute Purpose Prerequisites
Enable caching based on browser locale.
18.104.22.168 CF10 (PI05101)
Enable caching based on portal context.
22.214.171.124 CF14 (PI20951)
Enable caching based on portal mapping.
126.96.36.199 CF14 (PI20951)
Enable caching based on portlet context.
188.8.131.52 CF14 (PI20951)
Enable caching based on device type.
184.108.40.206 CF15 (PI27550)
- Can also be set with multiple values by specifying a comma delimited list of the attributes in the custom property value
What if I want to create an additional cache key based on a single Cookie value?
Creating a custom HTTP request header based on Cookie value
Creating an additional cache key based n a single cookie value is a little bit trickier. Let's say for example, we have a WCM component setting a cookie named region and the value of this cookie is a specific region code, such as A1. Some users that are in the same groups have a different region cookie based on a popup that a user can select in the WCM site. We want to force the WCM cache to hold different cache contents for each region. If we don't, all users in the same LDAP group, even if they have different region cookies will see the same content for whichever the first user is that primes the cache for that WCM site. Say a user with cookie region and value A2 visits the page first with this cookie component, and then WCM caches it. A different user from say, region A1, will see the wrong content for that page because the site was cached with the A2 specific content.
The Cookie HTTP request header contains all the cookies a user might have. Every user will have a different unique Cookie request header because of the LtpaToken2 and JSESSIONID cookies will all be present in the value of the HTTP header, and those cookies will be unique for each user. So caching based on the request header "Cookie" is not an option to try add another WCM cache key based on the region cookie. Instead we need to isolate the region cookie and expose it as a request header. Additionally, if a user is visiting the site for the first time, the first request will not even contain the region cookie in the Cookie header until after the first or second response, and we want the first page to be cacheable also regardless if the Cookie is set with a specific region value or not set at all.
Creating a custom HTTP request header with the region value would allow us to define the custom header as the WCM additional cache key. To create a custom header without modifying any application code, utilize an HTTP server, such as IBM HTTP Server (IHS) in front of the WebSphere Portal server with the mod_headers HTTP module.
Setup the Apache / IBM HTTP Server to create a custom Request header and value based on Cookie name and value
Using the mod_headers module in IHS, we will setup some conditions for the value of the region cookie and create a header called Cache-Header. The value of the header Cache-Header will be the same value of as the user's region preference. Then we will set the connect.moduleconfig.ajpe.contentcache.additionalcachekeys.requestheaders custom property later to the name of our custom header, "Cache-Header".
Make sure mod headers is enabled in the httpd conf
In the HTTP server config , usually httpd.conf, set the conditions for all the cookie values and the Request Header value. These RequestHeader conditions can be set in the main httpd conf or if a VirtualHost is defined, they can be set within the VirtualHost.
After setting up these values and conditions, save the httpd.conf and restart the HTTP server.
How it works:
First we are going to set the custom header to the value "all-regions". This represent the unspecific cookie value, that way WCM will cache differently for no cookie value (no region specified). Next, if another region is chosen later, the application logic will change the cookie value. Once the cookie named region has it's value changed, the rules in the HTTP conf will change the header value.
Here would be a step by step use case:
- User accesses public WCM site for the first with no region Cookie
- mod_headers logic sets a custom HTTP Request Header with header name as Cache-Header and value all-regions
- The WCM additional cache key is defined as Cache-Header and the WCM cache will create a separate cache for the user group and the cache key Cache-Header with the value all-regions
- User accesses a different part of the site and sets his region to A1
- WCM component sets the region cookie with a value of A1
- mod_headers SetEnvIf logic sees the User's region cookie value is now A1 and sets a local HTTP server environment variable called regionCookieA1 with a value of 1.
- mod_headers RequestHeader logic updates the custom header Cache-Header to the value A1 because it sees the environment variable exists now called regionCookieA1 (regardless of the value of the environment variable)
- WCM server side logic sees the request header Cache-Header has a different value so it creates a separate cache entry in the WCM cache, even if it is the same page for the same group because the additional cache key parameter is telling WCM to cache based on our custom request header.
Why can't I see the HTTP request header in the browser developer tools?
Verifying the header is getting set correctly
Since the custom header is a request header getting set on the server side, the users will not be able to see this header in their web browsers using debugging tools or browser extensions. The header is getting added after the request from the client, and the browser only shows what the browser requested. And since it is defined in the HTTP conf as a request header, it will never show up in the browser response either. To verify the header is getting set correctly, use a JSP or servlet on the Portal JVM that iterates and prints out all the headers. This will print all the headers that originate from the client (web browser) and on any other server side components (HTTP server, Proxies, external security devices, etc).
I used this one here, so I can see all the server side and client request headers on the server:
And I placed the JSP inside the WCM application directory on the file system in order to access it without deploying or changing any other applications. Make sure if using the JSP above to change the "enum" name of the Enumerator object to something else. enum is a reserved name in Java and the JSP will fail to compile if it is used on a Java application server. I just simply changed the few references of enum to enum1.
Access the different user regions and verify the request header is getting changed when the cookie value is getting changed. If setup correctly, anytime the region cookie is changed, go back to the request Attributes JSP and verify the request header Cache-Header has the new region value.
Set the WCM Advanced Cache additionalcachekeys property to use the custom request header
After verifying the custom HTTP header is working as it should, configure the property to use the value of our custom request header.
Login to the WebSphere Admin Console and navigate to :
|Property Name||Property Value|
- Save changes, synchronize the nodes, and restart the Portal server(s) for the WCM cache property to take effect.
Voila! Now we have WCM Advanced Caching based on groups and cookie values.