Edge caching

Caching on the edge is a simple and effective way to improve the performance of your system. The WebSphere Application Server's dynacache has built-in functionality so that setting the EdgeCacheable property of a cache entry to true will allow it to be cached on the edge. This property takes care of the ESI for you, making edge caching easy with virtually no setup overhead.

Note: You can use Edge caching for stores that run on the Transaction server (stores that are migrated from previous versions of HCL Commerce). For stores that run on the Store server, the Edge Server caching feature is not available.

The cache servlet filter creates request attributes with session information to be used by WebSphere Application Server's DynaCache to construct the cache ID, dependency ID, and invalidation ID. Session requests attributes cannot be used to construct the cache ID if the user wants to cache the servlet or JavaServerPage (JSP File) outside of the application server. For Web Server or Edge Server caching, only the URL parameters or cookies can be used as the cache ID. In order to cache HCL Commerce store pages the session information is put into session cookies.

Store pages content is based on user session information. In order to cache these store pages the session information is required as part of the Cache ID. By default the session information (language ID, preferred currency ID, parent Organization, contract ID, and member group) is setup as request attributes by the cache filter. In order to cache outside of the application server this information will be stored as session cookies based on the configuration settings in instanceName.xml. These attributes can be renamed, added, or removed in wc-server.xml.

Edge Side Include (ESI) is a simple markup language you can use to define Web page components for dynamic assembly and delivery of Web applications at the edge of the Internet.

The ESI processor's cache can be monitored through the cache monitor application. In order for the ESI processor's cache to be visible in the cache monitor (refer to Dynamic cache monitor section for more details), the DynaCacheEsi application must be installed as described above and the esiInvalidationMonitor property must be set to true in the plugin-cfg.xml file.

Example:
<?xml version-"1.0"?>
<Config>
        <Property Name="esiEnable" Value="true"/>
        <Property Name="esiMaxCacheSize" Value="1024"  
        <Property Name="esiInvalidationMonitor"
Value="true"/>

Enabling edge cookie generation in wc-server.xml

HCL Commerce store pages contents are generated based on the user session information. Therefore in order to cache these store pages, the session information is needed as part of the cache IDs. Currently the session information (buyer contract IDs, and member groups) are setup as request attributes by the cache filter. Session information is set up as session cookies based on the configuration setting in the wc-server.xml file.

You can enable cookies by changing the enable attribute to true in the following component:

<component
       
compClassName="com.ibm.commerce.dynacache.filter.EdgeCacheCookieHelper"
        enable="
true" name="DynaCacheCookie">
        <property
                CookieDomain=""
                CookiePath="/"
                MutipleStores="true"
                Timeout="3600" display="false">
                <ec name="memberGroups" value="true"/>
                <ec name="buyerContractIds" value="true"/>
        </property>
</component>
By changing the value attribute in the above component, you can select which of the following cookies you want to enable or disable:
  • WCDC_CACHEID2 (memberGroups)
  • WCDC_CACHEID3 (buyerContractIds)

Enabling cookie support

With the capability of caching outside of WebSphere Application Server, it is possible to provide caching for each store. In cachespec.xml the multiple store cache entry includes the store id in the component id. Also, cache-id entries are made for each store.

You can use Edge Caching in the following way:

  • with a single store
  • with multiple stores

The DynaCache Event Listener listens to the session change events triggered by the userId or storeId change and then performs the following actions:

  • Delete all old session cookies (if they exist)
  • Create new session cookies based on the settings of the com.ibm.commerce.dynacache.DynaCacheCookie object and data obtained from the basic catalogue structure
  • Each cookie is given an expiry period of one day
  • Each cookie is hashed using a one-way hash of the value + merchant key + today's date (yyyymmdd)
  1. For use of Edge Caching to cache pages outside of the WebSphere Application Server, esiEnable must be set to true. Verify that the esiEnable property is set to true

    The ESI processor is configurable through the WebSphere Web server plug-in configuration file, plugin-cfg.xml which is found in the WAS_installdir/config/cells/ directory. For example:

    
    <Property Name="esiEnable" Value="true"/>
    
  2. Open cachespec.xml in the Web application archive (WAR) WEB-INF or enterprise bean WEB-INF directory.
  3. Add a property to the cachespec.xml file to enable Edge Caching.
    
    <property name="EdgeCacheable">true</property>
    
  4. Perform one of the following steps:
    • Single store scenario:
      1. Add the following component entries to the cachespec.xml file inside the <cache-entry> tag.
        <component id="Component ID" type="cookie">
                <required>true</required>
        </component>
        
        Component ID Definition
        WCDC_CACHEID2 Member groups
        WCDC_CACHEID3 Buyer contract ID
    • Multiple store scenario:
      1. Insert a <cache-id> entry for each store into the cachespec.xml with the following structure and properties
        
        <!-- StoreCatalogDisplay?storeId=10001 -->
        <cache-id>
        <component id="" type="pathinfo">
                <required>true</required>
                <value>/StoreCatalogDisplay</value>
        </component>
        <component id="storeId" type="parameter">
                <required>true</required>
                <value>10001</value>
        </component>
        <component id="catalogId" type="parameter">
                <required>true</required>
        </component>
        <component id="WC_LANGID_10001" type="cookie">
                <required>true</required>
        </component>
        <component id="WC_CACHEID5_10001" type="cookie">
                <required>true</required>
        </component>
        </cache-id>
        
        <!-- StoreCatalogDisplay?storeId=10002 -->
        <cache-id>
        <component id="" type="pathinfo">
                <required>true</required>
                <value>/StoreCatalogDisplay</value>
        </component>
                <component id="storeId" type="parameter">
                <required>false</required>
        <value>10002</value>
        </component>
        <component id="catalogId" type="parameter">
                <required>true</required>
        </component>
        <component id="WC_LANGID_10002" type="cookie">
                <required>true</required>
        </component>
        <component id="WC_CACHEID5_10002" type="cookie">
                <required>true</required>
        </component>
        </cache-id>
        

        At runtime the cookie generator dynamically produces a cookie named based on this storeId. For example, given the storeId 10001 and an English store the cookie WC_LANGID_10001=-1 will be generated.

Caching static data

By default, static data such as images and HTML are cached by the ESI processor when served up by the WebSphere Application Server. The cached entries have a default time-out of 300 seconds. The time-out value can be changed by setting the system property com.ibm.servlet.file.esi.timeOut in your JVM.

For example: -D com.ibm.servlet.file.esi.timeOut=60

By default, HCL Commerce does not cache static data. You can enable it by specifying a cache-entry in the cachespec.xml file. Refer to Simple file servlet section for more details.

Caching full pages using ESI

To mark an entry to be cached using ESI, use the property EdgeCacheable. This property also implies the property of consume-subfragments. The page will be cached as a full page including all its sub fragments unless one of these sub fragments are specified to be cacheable separately (refer to Caching fragments using ESI for details). To cache pages with ESI, define the Cache ID using parameter and cookie type components. You cannot use request attributes in the cache-id's definition because they are not available at the network's edge.

The following example shows the cache-entry that uses the ESI plugin:


<cache-entry>
        <class>servlet</class>
       
<name>strutsname</name>
        <property name="store-cookies">false</property>
        <property
name="save-attributes">false</property>
        <property name="EdgeCacheable">true</property>
Where strutsname is com.ibm.commerce.struts.ECActionServlet.class (for HCL Commerce Version 9.0.0.x, or com.ibm.commerce.struts.v2.ECActionServlet.class for Version 9.0.x.

   <cache-id>
                <component id="" type="pathinfo">
                        <required>true</required>      
            
                       
<value>/StoreCatalogDisplay</value>
                </component>
                <component id="storeId" type="parameter">
                        <required>true</required>
                </component>
                <component id="catalogId" type="parameter">
                        <required>true</required>
                </component>
        </cache-id>
</cache-entry>

Fragments with ESI

HCL Commerce uses the model-view-controller (MVC) programming model, where calls to a controller servlet might include one or more child JSP files to construct the view. In order for the child JSP files to be edge cacheable, they have to be able to request these JSP files externally. The ESI processor requires that the edgeable fragments be externally requestable on the edge. For example, the fragments should not rely on information set by their parent and other fragments on the same request. Each fragment is routed back through the controller servlet using the alternate_url property set in the cache policy. If the fragments rely on a request attribute set by their parent, these fragment will fail to execute. A possible workaround to this situation is to compute the attribute value using a custom servlet filter that is executed on the alternate_url.

In common product pages, the sidebar dynamically includes a fragment (MiniCartDisplay.jsp) that displays a personalized mini shopping cart.

In order to cache this product page and the mini shopping cart on the edge construct cache ID rules which only contain URL parameters or cookies. For the product page, it will not be a problem since all the information needed to cache it are on the URL. However, since the mini shopping cart is unique per user, in order to cache it on the edge use the user's ID as the cache ID.

Since only URL parameters and cookies can be used to define the cache ID rule, and the URL would not contain the user's information, the only other way is to use a custom cookie that contain the user's ID information and use that as the cache ID. Use servlet filter chaining to chain up with HCL Commerce's cache filter to create a custom cookie named WCDC_USERID based on the request attribute DC_userId as created by the cache filter.

Here is an example of the cachespec.xml:


<cache-entry>
        <class>servlet</class>
        <name>/ToolTech/include/MiniShopCart.jsp</name>
        <property name="EdgeCacheable">true</property>
        <property
name="alternate_url">/servlet/ToolTech/include/MiniShopCart.jsp</property>
        <property
name="save-attributes">false</property>
        <property
name="do-not-consume">false</property>
        <cache-id>
                <component id="WCDC_USERID" type="cookie">
                        <required>true</required>
                </component>
        </cache-id>
</cache-entry>

<cache-entry>
        <class>servlet</class>
       
<name>strutsname</name>
        <property name="store-cookies">false</property>
        <property
name="save-attributes">false</property>
        <property name="EdgeCacheable">true</property>
        <cache-id>
                <component id="" type="pathinfo">
                        <required>true</required>
                       
<value>/TopCategoriesDisplay</value>
                </component>
                <component id="storeId" type="parameter">
                        <required>true</required>
                </component>
                <component id="catalogId" type="parameter">
                        <required>true</required>
                </component>
        </cache-id>
</cache-entry>
Where strutsname is com.ibm.commerce.struts.ECActionServlet.class (for HCL Commerce Version 9.0.0.x) or com.ibm.commerce.struts.v2.ECActionServlet.class for (Version 9.0.x).