Writing commands for command-based invalidation
In order to allow a command call be intercepted by the dynamic cache, the command must be
written to the WebSphere Command Framework with its implementation class extending from
CacheableCommandImpl
(in the com.ibm.websphere.command
package).
To simplify command writing for command-based invalidation, HCL Commerce has updated the
abstract classes, ControllerCommandImpl
and TaskCommandImpl
to
extend from CacheableCommandImpl
so that any commands extend from these abstract
classes would also extend from CacheableCommandImpl
and therefore be eligible for
command-based invalidation.
About this task
When writing such commands, it is also important to know what the invalidation IDs are going to be, and understand the invalidation rules that intercepts calls to the commands. Since invalidation IDs are generated based on methods and fields present in the command as input parameters, all the methods that are required to construct the invalidation IDs, should be provided in the command interface and be implemented.
An example of using command invalidation in HCL Commerce
The following example shows how HCL Commerce uses command invalidation. When the
command DeleteMemberGroupMemberCmdImpl
which deletes a particular member belonging
to a particular member group is executed successfully, the dynamic cache will invalidate the
cache-entry defined in the invalidation rule. In this example, it is defined as " DC_userId:
userId
" where userId is the value being returned from the
getMemberId
method. For example, DC_userId:-1000
,
DC_userId:-1001
, and so on. This command has a get method,
getMemberId()
, that retrieves the user ID that is being deleted and this method is
used in computing which cache entries with a dependency ID based on a user ID gets deleted. The same
logic applies for the command AddMemberGroupMemberCmdImpl
which also has a get
method, getMemberId()
:
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.membergroup.commands.AddMemberGroupMemberCmdImpl</name>
<name>com.ibm.commerce.membergroup.commands.DeleteMemberGroupMemberCmdImpl</name>
<invalidation>DC_userId
<component type="method"id="getMemberId">
<required>true</required>
</component>
</invalidation>
</cache-entry>
cachespec.xml
file.Cache invalidation example
The following example shows how to set up caching policies in the cachespec.xml
file to cache the ProductDisplay
JSP page for the B2C business model in HCL Commerce and how to invalidate the cache entry by defining the invalidation rules in the same
XML file. The example defines multiple dependency IDs along with the cache ID generation rule for
the JSP file. Each dependency ID is used to invalidate the cache entry when the cache entry is
updated under different circumstances. This example only shows a subset of policies required to
invalidate the CachedProductDisplay
JSP. For a complete example and detailed
information, see the README file in the
WCDE_installdir/samples/dynacache/invalidation directory.
<cache>
<cache-entry>
<class>servlet</class>
<name>/ConsumerDirect/ShoppingArea/CatalogSection/CatalogEntrySubsection/CachedProductDisplay.jsp</name>
<property
name="save-attributes">false</property>
<!-- Cache ProductDisplay.jsp -->
<cache-id>
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
<component id="productId" type="parameter">
<required>true</required>
</component>
<component id="DC_lang" type="attribute">
<required>true</required>
</component>
<component id="DC_curr" type="attribute">
<required>true</required>
</component>
<component id="DC_porg" type="attribute">
<required>true</required>
</component>
<component id="DC_cont" type="attribute">
<required>true</required>
</component>
<component id="DC_mg" type="attribute">
<required>true</required>
</component>
</cache-id>
<!-- Used for invalidating the product display cache
entry -->
<!-- that belongs to a specific store
-->
<dependency-id>storeId
<component id="storeId" type="parameter">
<required>true</required>
</component>
</dependency-id>
<!-- Used for invalidating the cache entry of a specific
product -->
<dependency-id>productId
<component id="productId" type="parameter">
<required>true</required>
</component>
</dependency-id>
<!-- Used for invalidating the product display cache
entry -->
<!-- that belongs to a specific catalog in the store
-->
<dependency-id>storeId:catalogId
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
</dependency-id>
<!-- Used for invalidating the product display cache
entry -->
<!-- that is under a specific contract
-->
<dependency-id>contractId
<component id="DC_cont0" type="attribute">
<required>true</required>
</component>
</dependency-id>
</cache-entry>
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.catalogmanagement.commands.AddCatalogDescCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateCatalogDescCmdImpl</name>
<!--
********************************************************* -->
<!-- Invalidate all the product page cache entries that
-->
<!-- might be affected when the catalog description is
changed -->
<!--
********************************************************* -->
<invalidation>storeId:catalogId
<component id="getStoreId" type="method">
<required>true</required>
</component>
<component id="getCatalogId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.catalogmanagement.commands.ListpriceAddCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.ListpriceDeleteCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.ListpriceUpdateCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.OfferAddCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.OfferDeleteCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.OfferUpdateCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.ProductAttributeUpdateCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.AttributeValueUpdateCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.AddListpriceCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.DeleteListpriceCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateListpriceCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.AddOfferCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.DeleteOfferCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateOfferCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateAttributeCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateAttributeValueCmdImpl</name>
<!--
********************************************************* -->
<!-- Invalidate the specific product page cache entry
when the -->
<!-- product is updated
-->
<!--
********************************************************* -->
<invalidation>productId
<component id="getCatentryId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.contract.commands.ContractSuspendCmdImpl</name>
<name>com.ibm.commerce.contract.commands.ContractTCDeployCmdImpl</name>
<!--
********************************************************* -->
<!-- Invalidate all the product page cache entries under a
-->
<!-- specific contract
-->
<!--
********************************************************* -->
<invalidation>contractId
<component id="getContractId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.tools.devtools.store.commands.StoreProfileUpdateCmdImpl</name>
<name>com.ibm.commerce.tools.devtools.flexflow.ui.commands.impl.FlexflowUpdateCmdImpl</name>
<name>com.ibm.commerce.store.commands.StoreOpenCmdImpl</name>
<name>com.ibm.commerce.store.commands.StoreCloseCmdImpl</name>
<!--
********************************************************* -->
<!-- Invalidate all the product page cache entries that
-->
<!-- belong to the store when the store is updated
-->
<!--
********************************************************* -->
<invalidation>storeId
<component id="getStoreId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.catalogimport.commands.CatalogImportJobAddCmd</name>
<!--
********************************************************* -->
<!-- Invalidate all the product page cache entries that
-->
<!-- belong to the store when the store catalog is
updated -->
<!--
********************************************************* -->
<invalidation>storeId
<component id="getStoreId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
</cache>