Improving high availability in HCL Commerce with IBM Db2 HADR

You can enable IBM Db2 HADR to ensure that your HCL Commerce site is available to shoppers in cases of database failures or planned outages. HADR also ensures that business data can be recovered with minimal disruption to your site.

Procedure

  1. Enable High Availability Disaster Recovery in your IBM Db2 database.
  2. Enable IBM Db2 Automatic Client Rerouting (ACR) in HCL Commerce.
    Ensure that the data are persisted to your Docker containers by setting custom properties in your Transaction and Search datasources. In case of a HADR takeover scenario, this will enable you to seamlessly switch from using a Primary database to a Standby one. The custom properties to be updated, which will enable IBM Db2 ACR for both the Transaction and Search containers, are:
    • clientRerouteAlternateServerName (this is mandatory),
    • clientRerouteAlternatePortNumber (mandatory),
    • maxRetriesForClientReroute (optional) and
    • retryIntervalForClientReroute (optional).
      Note: The retry interval for the automatic retries for client reroute is measured in seconds.
    Add these variables and their values the configuration file that is appropriate to your environment (your configuration files may be YAML files, Helm Charts, or XML properties files). At Docker deployment, the command that build the container uses these values as arguments for its own scripts to set the above custom properties.
    1. The Transaction server Docker container is derived from the WebSphere Application Server architecture. Therefore, when you deploy a new Docker container, use wsadmin scripting to update the above properties. For more information, see wsadmin tool in the IBM WebSphere Application Server Knowledge Center.
    2. Search transaction is derived from the WebSphere Application Server Liberty server architecture. Liberty is configured using XML files, with database connections configured in the file datasource.xml. When you deploy a new Docker container, update this file (programmatically) to add the above properties for Automatic Client Rerouting.

Example

Example 1: Setting ACR in the Transaction server Docker container
This example is for the Transaction server. It is written using Python and uses wsadmin commands to set up ACR for the Transaction server Docker container.

The script name is update_txn_alternate_server.py.

Its parameters (the parameters are the respective values for ACR WebSphere custom properties) are:
  • <alternate_server_name>,
  • <alternate_port_number>,
  • <max_retries_for_client_reroute>, and
  • <retry_interval_for_client_reroute>

Create the script within your Transaction server Docker container /SETUP/scripts/ directory.

The contents of this script should be as follows:
# Init variables 
propertyNames  = [ 'clientRerouteAlternateServerName', 'clientRerouteAlternatePortNumber', \
                   'maxRetriesForClientReroute', 'retryIntervalForClientReroute' ]
propertyValues = [ <alternate_server_name>, <alternate_port_number>, \
                   <max_retries_for_client_reroute>, <retry_interval_for_client_reroute> ]
propertyTypes  = [ 'java.lang.String', 'java.lang.Integer', 'java.lang.Integer', \
                   'java.lang.Integer' ]
    
# Get the datasource
datasource = AdminConfig.getid('/Cell:localhost/Node:localhost/Server:server1/JDBCProvider:WCDataSource_provider/DataSource:WCDataSource/')
print 'datasource = ', datasource
    
# Get the property set 
propertySet = AdminConfig.showAttribute( datasource, 'propertySet')
print 'propertySet = ', propertySet
    
# Get the list of properties
propertyList = AdminConfig.list('J2EEResourceProperty', propertySet).splitlines()
a = [ p.split( '(' )[ 0 ] for p in propertyList ]
    
# Adding or updating ACR custom variables
for i in range( len( propertyNames ) ):
    if propertyNames[ i ] not in a:
        propertyAttributes = [['name', propertyNames[ i ]], ['value', propertyValues[ i ]], \
                              ['type', propertyTypes[ i ]], ['description', ''], \
                              ['required', 'true']]
        AdminConfig.create( 'J2EEResourceProperty', propertySet, propertyAttributes )
        print propertyNames[ i ], ' created'
    else:
        propertyAttributes = [['value', propertyValues[ i ]], ['description', ''], \
                              ['required', 'true']]
        AdminConfig.modify( propertyNames[ i ], propertyAttributes )
        print propertyNames[ i ], ' updated'
AdminConfig.save()
Call the script using the following command syntax:
/opt/WebSphere/AppServer/profiles/default/bin/wsadmin.sh -conntype NONE 
     -f /SETUP/scripts/update_txn_alternate_server.py alternate_server_name alternate_port_number 
         max_retries_for_client_reroute retry_interval_for_client_reroute
Example 2: Setting ACR for Search container
This example is also written using Python and it setup ACR for Search container. The script's name is update_search_alternate_server.py, and the syntax for calling it is as follows:
python update_search_alternate_server.py alternate_server_name alternate_port_number max_retries_for_client_reroute 
retry_interval_for_client_reroute
This is the python script:
import sys
import xml.etree.ElementTree as et

filename = '/opt/WebSphere/Liberty/usr/servers/default/configDropins/overrides/datasources.xml'

tree = et.parse( filename )
root = tree.getroot()
d = root.find( 'dataSource' )
children = d.getchildren()
for child in children:
     if 'properties.db2.jcc' in str( child ):
         print 'found'
         print child.tag, child.attrib
         dict = child.attrib
         print 'dict = ', dict
         dict[ 'clientRerouteAlternateServerName' ] = sys.argv[0]
         dict[ 'clientRerouteAlternatePortNumber' ] = sys.argv[1]
         max_retries_for_client_reroute = sys.argv[2]
         retry_interval_for_client_reroute = sys.argv[3]
         if len( max_retries_for_client_reroute ) != 0:
              dict[ 'maxRetriesForClientReroute' ] = max_retries_for_client_reroute
         if len( retry_interval_for_client_reroute ) != 0:
              dict[ 'retryIntervalForClientReroute' ] = retry_interval_for_client_reroute

         d.remove( child ) 
         b = et.SubElement( d, 'properties.db2.jcc' )
         b.attrib = dict
         tree.write( filename )