Cache invalidation in the BOD command framework
Unlike Get services, which do not make changes to business objects, the Change, Process and Sync services will change the business objects within the system and may need to invalidate existing cache representations of the business objects they service. For example, when a particular CatalogEntry is changed, any JSP or cached service that is referencing that object needs to be invalidated. When you are using the BOD command framework with a tool, such as the Management Center, or integrating with external systems, you need to make noun and related noun invalidation policies. When you are using the BOD command framework with a storefront, you need to make service command invalidation policies to invalidate the views in the storefront.
Invalidating the noun
As part of the Change, Sync and Process controller commands, there is an attribute called uniqueIDXPath that can be set. This attribute is part of a property that can be defined on the command which indicates the path to find the UniqueID of the Nouns that were changed as part of this request. This command attribute is used for caching purposes to resolve the identifier of the objects involved with the request.
The uniqueIDXPath attribute is used when the getUniqueID() method is called. The purpose of the getUniqueID() method is to return a collection of the internal identifiers of the object that is involved with the service request. For the case of Change, Process and Sync, it is the objects that have changed and require invalidation.
Alternatively, the BOD service controller commands can extend the getUniqueID() method and implement it to return a Collection of UniqueID that represents the Nouns that were changed as part of the current request. This approach requires coding changes and does not leverage the properties configuration that can be set on a command.
Setting the UniqueID XPath attribute
The command registration of the BOD service controllers is found in the CMDREG table. This database record contains the implementation the interface is associated with. Along with this association, the PROPERTIES column can be used to set default properties on the command when it is instantiated. For the purpose of cache invalidation, any BOD service controller command that extends the Abstract BOD service commands can have this property set so it can be registered to issue invalidation requests when changes are performed on specific nouns.
update CMDREG set properties = properties || '&uniqueIDXPath;=NounIdentifier/UniqueID'
where interfacename = 'bod service command controller interface'
Creating the noun invalidation policy
Once the command returns a collection of the UniqueID of the nouns that were changed as a result of the request, the cachespec.xml which defines the caching and cache invalidation needs to be configured to create the invalidation policy. Although it is not required, it is recommended that the cachespec.xml of each service module be located in the HTTPInterface Web module for that service module.
- The delay-invalidations property is set to true. This is to ensure that the invalidation occurs after the command executes to ensure the UniqueIDs have been resolved.
- The method to invoke is getUniqueID, and the multipleIDs attribute is set to true. Because getUniqueID returns a collection of UniqueID, the multipleIDs attribute will create an invalidation key for each element of the returned collection.
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogEntryCmdImpl</name>
<name>com.ibm.commerce.catalog.facade.server.commands.ProcessCatalogEntryCmdImpl</name>
<property name="delay-invalidations">true</property>
<invalidation>CatalogEntry
<component id="getUniqueID" type="method" multipleIDs="true">
<required>true</required>
</component>
</invalidation>
</cache-entry>
Invalidating related nouns
When you change a noun, this may also cause changes to related nouns based on the action performed. For example, when moving a CatalogEntry from one CatalogGroup to another, not only does the CatalogEntry need to be invalidated, but the old and new parent CatalogGroup nouns also need to be invalidated.
All actions are represented as action commands
that perform a specific action on either the noun (in the case of
Process) or the noun part (in the case of the Change and Sync). These
action commands are very specific and will typically be where changes
to the related nouns is performed. Following our example, the command
implementation that would be responsible for the CatalogGroup invalidation
would be the implementation associated with the com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogEntryPartCmd
interface
and /CatalogEntry[]/ParentCatalogGroupIdentifier
XPath
expression.
For invalidation purposes, as part of the command
implementation, it will keep a Collection object that records all
the related nouns that have changed. The collection is returned by
a method on the command, for example getModifiedCatalogGroups(), which
can be used by the cache invalidation policy. The suggested naming
convention for these get methods is getModifiedNounNames
to
explicitly declare the different related nouns that are effected as
part of this action command.
Creating the related noun invalidation policy
Once the command returns a collection of related Noun UniqueID that can be modified, the next step is to update the cachespec.xml of that service module with the invalidation command. The cachespec.xml is the same one used for registering the invalidation policy for the BOD controller commands.
The invalidation policy is very similar to the policy defined for the Change, Process or Sync controller commands. Set the delay-invalidation property to true, the method returns a collection of UniqueID to invalidate instead of one. The difference is that the method invoked is the custom getModifiedNounNames() method instead of the generic getUniqueID.
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogEntryParentCmdImpl</name>
<property name="delay-invalidations">true</property>
<invalidation>categoryId
<component id="getModifiedCatalogGroups" type="method" multipleIDs="true">
<required>true</required>
</component>
</invalidation>
</cache-entry>
Where a custom method, getModifiedCatalogGroup
,
is used to invalidate related catalog groups.
Catalog SOA commands invalidation rules for all stores
<!-- This list of unique IDs is to indicate which Catalog nouns have been involved with the change/process -->
<!-- request and requires to be invalidated. -->
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogCmdImpl</name>
<name>com.ibm.commerce.catalog.facade.server.commands.ProcessCatalogCmdImpl</name>
<property name="delay-invalidations">true</property>
<invalidation>catalogId
<component id="getUniqueID" type="method" multipleIDs="true">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<!-- This list of unique IDs is to indicate which CatalogGroup nouns have been involved with the change/process -->
<!-- request and requires to be invalidated. -->
<!-- The catalog id can be used to invalidate related pages when a catalog group is updated. -->
<!-- For example, when the name of a category is renamed (categoryId=50400000003), the CategoryDisplay page for this category needs to -->
<!-- invalidate: -->
<!-- CategoryDisplay?catalogId=504&categoryId=50400000003 -->
<!-- Since the CategoryDisplay pages for its parent category (categoryId=50400000013) and sibling categories (categoryId=50400000014) -->
<!-- also display the name of the category, they also need to invalidate. -->
<!-- CategoryDisplay?catalogId=504&categoryId=50400000013 -->
<!-- CategoryDisplay?catalogId=504&categoryId=50400000014 -->
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogGroupCmdImpl</name>
<name>com.ibm.commerce.catalog.facade.server.commands.ProcessCatalogGroupCmdImpl</name>
<property name="delay-invalidations">true</property>
<invalidation>categoryId
<component id="getUniqueID" type="method" multipleIDs="true">
<required>true</required>
</component>
</invalidation>
<invalidation>catalogId
<component id="getCatalogId" type="method">
<required>true</required>
</component>
</invalidation>
</cache-entry>
<!-- This list of unique IDs is to indicate which CatalogEntry nouns have been involved with the change/process -->
<!-- request and requires to be invalidated. -->
<cache-entry>
<class>command</class>
<name>com.ibm.commerce.catalog.facade.server.commands.ChangeCatalogEntryCmdImpl</name>
<name>com.ibm.commerce.catalog.facade.server.commands.ProcessCatalogEntryCmdImpl</name>
<property name="delay-invalidations">true</property>
<invalidation>productId
<component id="getUniqueID" type="method" multipleIDs="true">
<required>true</required>
</component>
</invalidation>
</cache-entry>
Sample catalog invalidation
Copy
the contents
of the WCDE_installdir\samples\dynacache\invalidation\catalog\cachespec.xml file
to the end of the WAS_installdir\profiles\instance_name\installedApps\cell_name\WCServer_enterprise_archive\Stores.war\WEB-INF\cachespec.xml file
immediately preceding the </cache>
element.
- Time-based invalidation
This approach is easy to implement, but could leave some entries stale for a period of time. For an example, see the MiniShopCarDisplay.jsp entry in the Madisons starter store cachespec.xml file. For information see, Time-based invalidation in the Cache invalidation topic.
- Database triggers on the CACHEIVL table
For information see, Dynacache API and CACHEIVL table invalidation in the Cache invalidation topic.
- Custom Java code to issue invalidation messages using Dynacache
APIs.
This approach requires a good understanding of Dynacache APIs. For information see, IBM WebSphere Application ServerTM, Release 7 API Specification: Dynacache API and Mastering DynaCache in HCL Commerce.