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, WebSphere 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 WebSphere Commerce
The
following example shows how WebSphere 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 Consumer Direct business
model in WebSphere 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
WC_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>