Thursday, May 7, 2015

Test C2050-725: IBM WebSphere Commerce V7 (FEP 7), Application Development

Study Guide


  • WebSphere Commerce product overview
  • Highlights of Feature Pack 7
  • WebSphere Commerce common architecture
  • WebSphere Commerce runtime framework enhancements
  • [Exam notes]

    • Important! Extended sites, contracts and entitlement: only Enterprise edition
    • Dialog activities, sales center, workspaces, auctions: only Professional and Enterprise editions
    • Highlights of Feature Pack 7 -
      • Commerce Composer tool
      • Aurora starter store enhancements -
        • Responsive Web Design
        • Important! The store preview offers click-to-edit support for Commerce Composer objects, including pages, layouts, and widgets.
        • Ribbon ads (image overlays) for catalog entry thumbnails
      • Integration with IBM Marketing Center
    • Important! Functional architecture: Presentation layer, Controller layer, Business logic layer, Persistence layer
    • Important! Recommended isolation level for entity bean: Read committed
    • Important! WebSphere Commerce subsystems: Marketing, Trading, Payments


  • Application changes when enabling features in Feature Pack 7
  • Enabling features
  • Enabling features > ... Management Center
  • Installing WebSphere Commerce Developer
  • Installing WebSphere Commerce Developer maintenance
  • Prerequisites for installing WebSphere Commerce
  • Troubleshooting: WebSphere Commerce Developer fix pack issues
  • Troubleshooting: Fix pack installation or uninstallation fails due to a "mkdirs failed for" error
  • Troubleshooting: Checking that a WebSphere Commerce Developer feature is enabled on your instance
  • Troubleshooting: Massload error during feature enablement
  • Troubleshooting: Determining what APARs are installed on WebSphere Commerce
  • WebSphere Application Server Update Installer fails to install a fix pack due to a "mkdirs failed for", "failed to delete", "text file busy", or "Error 79 -- Unable to open destination file" error on Windows
  • [Exam notes]

    • Important! WebSphere Commerce development database: Apache Derby, DB2, Oracle
    • Important! Installing WebSphere Commerce Developer fix packs and feature packs:
      • Log in to Windows as a user with Administrator privileges.
      • WebSphere Commerce Fix Pack and Feature Pack installation is a separate endeavor from WebSphere Commerce base product installation.
      • Back up any customized files that are to be altered during fix pack installation. After the fix pack is applied, you must reimplement your customization against the updated files.
    •  When you enable this feature...  These dependent features are automatically enabled 
       location-services
      • management-center
      • foundation
       store-enhancements Important!
      • management-center
      • foundation
       No changes are made to the database.
       content-version
      • management-center
      • foundation
       management-center
      • foundation
       No changes are made to the database.
       foundation
    • If enableFeature.xml for management-center feature runs successfully in the runtime environment, you see a BUILD SUCCESSFUL message in the command window where you ran the enablement script and a BUILD SUCCESSFUL message in enablemanagement-center_timestamp.log.
    • Important! If enableFeature.bat for management-center feature runs successfully in the development toolkit, you see an enableFeature.bat completed message in the command window where you ran the script. For enablement details, refer to log file: enableFeature.log
    • The following warning messages in the feature pack enablement log for management-center feature can be safely ignored:
      +++ Warning +++: Tue Mar 10 15:45:50 EDT 2009    
      java.lang.NoClassDefFoundError: 
      com.ibm.commerce.catalog.facade.CatalogFacade
           at java.lang.ClassLoader.defineClassImpl(Native Method)
           at java.lang.ClassLoader.defineClass(ClassLoader.java:258)
      Attribute value cannot be migrated ${parent.width} in file D:\IBM\WCDE_P~1\components\management-center\backup\LOBToolsCustom\WebContent\WEB-INF\src\lzx\commerce\shell\ApplicationMenuItems.lzx
      Attribute value cannot be migrated ${this.getPromptText(this.parent.parent.promptText)} in file D:\IBM\WCDE_P~1\components\management-center\backup\LOBToolsCustom\WebContent\WEB-INF\src\lzx\commerce\promotion\restricted\objectDefinitions\BasicCodePatternBuilder.lzx
      Attribute value cannot be migrated ${parent.assetGroup.visible} in file D:\IBM\WCDE_P~1\components\management-center\backup\LOBToolsCustom\WebContent\WEB-INF\src\lzx\commerce\marketing\propertiesViews\WebActivityBuilder.lzx
    • After updating to a new WebSphere Commerce Fix Pack and Feature Pack level -
      • Previously installed APARs, which are not included in the new Fix Pack or Feature Pack, must be reinstalled at the appropriate APAR build level.
      • Feature enablement must be re-run for continued functionality of previously utilized features.
    • Troubleshooting Fix pack uninstallation fails with the following error message:
      CWUPI0010E: Cannot uninstall an installed maintenance package. No corresponding 
      maintenance backup package is available in the product maintenance backup directory.
      Solution: Remove all software, such as the WebSphere Commerce Feature Packs, that is dependent on the fix pack.
    • Important! Troubleshooting updatedb script fails in the development toolkit during fix pack application
      Solution: Manually update the database by running updatedb.bat. Ensure that you have a backup of the database.
    • Important! Troubleshooting WebSphere Application Server Update Installer fails to install a fix pack due to a "mkdirs failed for", "failed to delete", "text file busy", or "Error 79 -- Unable to open destination file" error on Windows
      Solution: Review Update Installer log file updatelog.txt
      • Error message states "mkdirs failed for" or "failed to delete" a different file during each attempt
        Important! If Update Installer is reporting issues with "text" file type, such as .txt, .xml, .jsp, or .html, shut down indexing services.
        If Update Installer is reporting issues with "binary" or "code" file types, such as .dll, .jar, or .exe, shut down real-time security scanners.
      • Error message states "mkdirs failed for" or "failed to delete" the same file even after multiple attempts
        Shut down all processes associated with the product. Verify the integrity of the particular file.
      • Error message states "Text file busy" and Update Installer fails to update "java" or "java.exe" or any DLL file
        Shut down all processes associated with the product.
      • Error message states "Error 79" or "Failed to delete" on "WASServiceMsg.dll"
        Disable automatic server startup so that Windows does not attempt to load and lock WASServiceMsg.dll, and reboot the system.
    • Important! Troubleshooting Massload error during feature enablement
      loadBootstrapData:
      Massloading C:\IBM\WCDE_E~1\components\foundation\xml\wcs.bootstrap_foundation.xml
      -dbname BEAERO -dbuser db2admin -dbpwd ****** -infile C:\IBM\WCDE_E~1\components\foundation\xml\wcs.bootstrap_foundation.xml -method sqlimport -commitcount 1000 -maxerror 1 -customizer -schemaname DB2ADMIN
      Error in MassLoading, please check logs for details.
      
      BUILD FAILED
      
      C:\IBM\WCDE_E~1\components\common\xml\enableFeatureForToolkit.xml:52: The following error occurred while executing this line:
      C:\IBM\WCDE_E~1\components\common\xml\enableFeatureForToolkit.xml:122: The following error occurred while executing this line:
      C:\IBM\WCDE_E~1\components\common\xml\databaseTasks.xml:22: The following error occurred while executing this line:
      C:\IBM\WCDE_E~1\components\common\xml\databaseTasks.xml:105: Error in massloading
      When you look in wcs.bootstrap_foundation.error.xml, you see an error message similar to the following:
      <?xml version="1.0" encoding="UTF-8"?>
      <import>
      <error id="SAXException" locus="com.ibm.wca.MassLoader.Parser.DefaultParser">
      <message>Element type "keys" must be declared. </message>
      </error>
      </import>
      You can find a similar message in messages.txt:
      > 2011-00-00 00:00:00.000, <Thread-6>, com.ibm.wca.MassLoader.Parser.ParserHandler::error, S1
      Error Element type "keys" must be declared. : 19 : 162
      Solution: wcs.dtd is corrupted. Replace the file with a copy of the file from a working environment on the same WebSphere Commerce Version 7 feature pack level.
    • Important! Troubleshooting Determining what APARs are installed on WebSphere Commerce
      Solution: Check NIFStack.xml.
    • Troubleshooting Checking that a WebSphere Commerce Developer feature is enabled on your instance
      Solution: The WCDE_installdir/properties/version/feature_name.toolkit.70.component file exists for every feature that is enabled, for example, management-center.toolkit.70.component.


  • Store publish process
  • Publish wizard publish parameters
  • Creating a customized asset store
  • [Exam notes]

    • Important! store-refs.xml file defines the Publish wizard publish parameters (such as, store directory, store identifier).
    • ibm-wc-load.xml file determines what tasks will be completed during the publish process and the sequence of these tasks. You may add new tasks to ibm-wc-load.xml, but any new task must extend com.ibm.commerce.tools.devtools.publish.tasks.DeployTaskCmd.
    • store-data-asset.xml file includes placeholders for all the data assets that will be consolidated during publish.
    • Important! To customize asset store identifier directly in the SAR file, modify ForeignKeys.dtd and keys.dtd




  • Workspaces locking policies
  • Considerations when selecting a locking policy
  • Changing workspaces locking policy
  • Enabling e-mail notification for workspaces
  • [Exam notes]

    • Workspaces locking policy applies to the entire WebSphere Commerce site and is not configurable by store
    • Workspaces locking policies -
      • With Workspace locking policy enabled, a managed asset is locked to the workspace in which it is first changed. Within the same workspace, the last task group to modify a managed asset becomes its owner.

        Problem scenario:

        • A product (productX) is created in a task group (TG1) and assigned to the catalog.
        • productX's description is subsequently updated in a second task group (TG2).
        When TG1 is completed, the commit will fail because productX will belong in TG2. TG1 and TG2 will need to be committed together when both are complete.

      • With Task group locking policy enabled, a managed asset is locked to the task group in which it is first changed. Task group locking is the default locking policy for workspaces. Task groups are the smallest unit of work in a workspace that can be committed to the production-ready data.

        Problem scenario:

        • Under one task group (TG1), a product (productX) and two SKUs (sku1, sku2) are added to the master catalog under a category (categoryX).
        • Under a second task group (TG2), productX is visible and is used and added into a sales catalog under a category (categorySCX).
        • Under a third task group (TG3), productX is visible and is used to create an upsell association to product (productY).
        • Under a fourth task group (TG4), productX is used in a promotion where its upsell association is used to reference content in an eSpot.
        If TG2, TG3, or TG4 are completed and approved before TG1 is complete, they will experience a commit failure because they are dependent on productX which does not exist in the production-ready data and a database exception will occur. When TG1 is completed and approved, the system will attempt to commit all available task groups under a single transaction.
        If TG4 is completed and approved first, there are no errors except that the content that the marketing promotion refers to does not exist. The Workspace Content Contributor or Task Group Approver of TG4 who previewed and saw the content correctly will not see the content after TG4 is committed.

      • With Task locking policy enabled, a managed asset is locked to the task in which it is first changed.
      • With No locking policy enabled, any user in any workspace can change managed assets. Within the same workspace, the last task group to modify a managed asset becomes its owner. When the same managed asset is updated by multiple workspaces under this locking policy each workspace can store its own instance of the managed asset.

        Important! Problem scenario:

        • A Workspace Content Contributor adds a new product under category X in one workspace.
        • Another Workspace Content Contributor deletes category X in a different workspace.
        If the data in the second workspace is committed to the production-ready data first, then the data in the first workspace cannot be committed.

    • Important! Changing workspaces locking policy
      • Open wc-resource-containers.xml
      • <wc:DefaultConfiguration
           lockingPolicy="Workspaces_locking_policy"
           enableDynamicWorkspaceCreation="false"
           readPrefixName="WCR"
           writePrefixName="WCW"
          />
      • Replace Workspaces_locking_policy with one of the policy classes shown below -
        • com.ibm.commerce.context.content.locking.WorkspaceLockingPolicy
        • com.ibm.commerce.context.content.locking.TaskGroupLockingPolicy
        • com.ibm.commerce.context.content.locking.TaskLockingPolicy
        • com.ibm.commerce.context.content.locking.NoLockingPolicy
    • Important! Enabling e-mail notification for workspaces
      • Assign following message types to e-mail transport method -
        • RejectTaskNotification
        • ReadyToApproveTaskGroupNotification
        • ActivateTaskNotification
      • Modify wc-workspace.xml -
        <ActivateTaskEmail isEmailEnabled="true" from="" cc="" bcc="" language="en_US" />
        <RejectTaskEmail isEmailEnabled="true" from="" cc="" bcc="" language="en_US" />
        <ApproveTaskGroupEmail isEmailEnabled="true" from="" cc="" bcc="" language="en_US" />


  • Data Load utility
  • Data Load input file format
  • Configuring the business object configuration file
  • Configuring the data load order
  • Delta load
  • Loading data into custom tables > Configuring the environment settings
  • Loading data into custom tables > Configuring the business object configuration file
  • Loading data into custom tables > Configuring the load order configuration file
  • Troubleshooting: Business object changes are not reflected in the Management Center
  • [Exam notes]

    • Data Load input file format: CSV, XML
    • Configuring the business object configuration file
      <_config:DataloadBusinessObjectConfiguration> 
        <_config:DataLoader className="com.ibm.commerce.foundation.dataload.BusinessObjectLoader" >   
          <_config:DataReader className="com.ibm.commerce.foundation.dataload.datareader.CSVReader" firstLineIsHeader="true" useHeaderAsColumnName="true" >
            <_config:property name="keyColumns" value="PartNumber" />
          </_config:DataReader>	
          <_config:BusinessObjectBuilder className="com.ibm.commerce.foundation.dataload.businessobjectbuilder.BaseBusinessObjectBuilder" 
            packageName="com.ibm.commerce.catalog.facade.datatypes.CatalogPackage" dataObjectType="CatalogEntryType" >
            <_config:DataMapping>
              <_config:mapping xpath="CatalogEntryIdentifier/ExternalIdentifier/PartNumber" value="PartNumber" />
              <_config:mapping xpath="catalogEntryTypeCode" value="Type" />
              <_config:mapping xpath="ParentCatalogEntryIdentifier/ExternalIdentifier/PartNumber" value="ParentPartNumber"  />  
              <_config:mapping xpath="displaySequence" value="Sequence" />
              <_config:mapping xpath="Description[0]/Name" value="Name" />
              <_config:mapping xpath="Description[0]/ShortDescription" value="ShortDescription" />    
            </_config:DataMapping>      
            <_config:BusinessObjectMediator className="com.ibm.commerce.catalog.dataload.mediator.CatalogEntryMediator"	
               componentId="com.ibm.commerce.catalog" >
            </_config:BusinessObjectMediator>
          </_config:BusinessObjectBuilder>    
          <_config:BusinessObjectBuilder className="com.ibm.commerce.foundation.dataload.businessobjectbuilder.TableObjectBuilder" >
            <_config:Table name="XWARRANTY">
              <_config:Column name="CATENTRY_ID" value="catentry_Id" valueFrom="IDResolve" 
              <_config:IDResolve tableName="CATENTRY" generateNewKey="false" >
              <_config:UniqueIndexColumn name="PARTNUMBER" value="PartNumber" />
              <_config:UniqueIndexColumn name="MEMBER_ID" value="storeOwnerId" valueFrom="BusinessContext" />
              </_config:IDResolve>
              </_config:Column>
              <_config:Column name="WARTERM" value="WarrantyTerm" />
              <_config:Column name="WARTYPE" value="WarrantyType" />
            </_config:Table>      
            <_config:Table name="XCAREINSTRUCTION">
              <_config:Column name="CATENTRY_ID" value="catentry_Id" valueFrom="IDResolve" />
              <_config:Column name="LANGUAGE_ID" value="langId" valueFrom="BusinessContext" />
              <_config:Column name="CAREINSTRUCTION" value="CareInstruction" />
            </_config:Table>
            <_config:BusinessObjectMediator className="com.ibm.commerce.foundation.dataload.businessobjectmediator.TableObjectMediator" >
            </_config:BusinessObjectMediator>
          </_config:BusinessObjectBuilder>
        </_config:DataLoader>
      </_config:DataloadBusinessObjectConfiguration>
    • Configuring the environment settings file
      <_config:DataLoadEnvConfiguration>
        <_config:BusinessContext storeIdentifier="Aurora" catalogIdentifier="AuroraCatalog" languageId="-1" currency="USD">
        </_config:BusinessContext>
        <_config:Database type="derby" name="..\db\mydb" schema="mydbschema"/>
        <_config:IDResolver className="com.ibm.commerce.foundation.dataload.idresolve.IDResolverImpl" cacheSize="10000000"/>
        <_config:DataWriter className="com.ibm.commerce.foundation.dataload.datawriter.JDBCDataWriter" />
      </_config:DataLoadEnvConfiguration>
    • Configuring the load order configuration file
      <_config:DataLoadConfiguration>  
        <_config:DataLoadEnvironment configFile="wc-dataload-env.xml" />
        <_config:LoadOrder >
          <_config:LoadItem commitCount="1" batchSize="1" dataLoadMode="Replace" name="Warranty" businessObjectConfigFile="wc-warrantytableobject-loader.xml">
            <_config:DataSourceLocation location="WarrantyTableLoad.csv"/>
          </_config:LoadItem>
        </_config:LoadOrder>
      </_config:DataLoadConfiguration>
    • If commitCount is N = 10 and an error occurs in line 25:
      • If the error is an SQL exception, the data between line 1 - 20 is committed to the database. The data between line 21 - 25 is not added in the database.
      • If the error is not an SQL exception, the data between line 1 - 24 is committed to the database. The data in line 25 is not added in the database.
    • dataLoadMode can be set to either Insert, Replace (Default), or Delete.
      • In insert mode, you can specify a primary key range in the <_config:BusinessObjectMediator> element with startKey and endKey. If there is a flag in the input data to indicate that this object is to be deleted, the flag is ignored. This mode is recommended for initial loading of data to improve performance.

        Problem scenario: A CSV file contains a line that creates a product and a product description. If the file also contains a second line that loads the same product with a description in a different language, the load process fails. Since the utility creates the product and description in the first line, when the utility encounters the second line, the utility attempts to create the product again. Since the product exists, the load fails. To load this product and description data, you can use one of the following methods:

        • Run the Data Load utility in replace mode.
        • Run the Data Load utility in insert mode, but load your product and description information separately. Use one input file to load your product information, and a different input file to load all of your descriptions.

      • In replace mode (Default), if one record in the input data represents a new object, it is inserted. If the object is in the database already, it is replaced. If some column information is not in the input data, the column value is updated to null or the default value if any. If there is a flag in the input data to indicate that this object is to be deleted, the object is deleted.
      • In delete mode, if there is a flag in the input data to indicate that this object is to be deleted, the flag is ignored.

        Limitation: If your site uses WebSphere Commerce search, the delta search index might not rebuild correctly when you delete some catalog objects with the Data Load utility in delete mode. When you delete a child object of a catalog entry or category with the utility in delete mode, both the child and parent object are removed from the delta search index rebuild. This removal can cause the parent catalog entry or category to no longer be indexed or display correctly in the storefront.

        Use the utility in replace mode to delete catalog objects when your site uses WebSphere Commerce search. To delete objects with the utility in replace mode, include the value 1 for the Delete column of an object in your input file. If you do decide to delete catalog objects with the utility in delete mode, run a full index rebuild after the load operation completes.

    • Delta load configuration recommendations -
      • Important! Set dataLoadMode="Replace, commitCount="1", batchSize="1"
      • Do not specify a key range with startKey and endKey
      • Set IDResolver cacheSize="0" if your database is large
    • Business object mediators are available for the following components:
      • Catalog
      • Inventory
      • Price and Catalog filter
      • Member
      • Location
      • Commerce Composer
      To load other data, you can use the TableObjectMediator, or you can create your own custom business object mediators.
    • The TableObjectMediator does not support workspace locking.
    • The member component business object mediators do not support the following actions with the Data Load utility:
      • deleting users or organizations
      • loading user passwords
      • modifying the parent organization of a member
      • modifying the distinguished name (DN) of an organization
      • modifying the entity type of an organization
    • Important! Troubleshooting Business object changes are not reflected in the Management Center

      Problem scenario:

      1. You observe that the price for a product is $20.
      2. You update the product price to $15 using the Data Load utility.
      3. You refresh the product, but the product price is still $20 in the Management Center.
      4. You check the database, and the product price is changed to $15.

      Solution: Enable data cache invalidation.

      <_config:BusinessObjectMediator className="com.ibm.commerce.price.dataload.mediator.OfferMediator" componentId="com.ibm.commerce.price">
      		<_config:property name="DataCacheInvalidationEnabled" value="true" />
      </_config:BusinessObjectMediator>


  • IBM Digital Analytics JavaScript library types: standard and custom
  • Configuring the store to communicate with IBM Digital Analytics(biConfig.xml)
  • Configuring Management Center to work with IBM Marketing Center
  • [Exam notes]

    • You are using the custom IBM Digital Analytics library if:
      • Your eluminate.js library file version does not end with the letter H, and/or
      • You have a locally hosted cmcustom.js file.
    • Sample biConfig.xml file for IBM Digital Analytics
      <BIConfiguration>
        <ssoKey></ssoKey>
        <biproviders>
          <biprovider name="coremetrics">
            <header>
              <![CDATA[<script type="text/JavaScript">
              <!--
              ]]>
            </header>
            <footer>
              <![CDATA[
              //-->
              </script>]]>
            </footer>
          </biprovider>
        </biproviders>
        
        <stores>
          <store storeId="10101" 
            biprovider="coremetrics" enabled="true" debug="true" 
            marketingCenterEnabled="true"
            useHostedCMHLibraries="true" useEmailForCustomerId="false" 
            segmentExportMode="append" >
            <useCookies>true</useCookies>
            <clientid>69999999</clientid>
            <url>https://welcome.coremetrics.com/analyticswebapp/analytics.jsp</url>
            <marketingCenterUrl>https://mc.coremetrics.com/mcwebapp/welcome.do</marketingCenterUrl>
            <output section="header">
              <![CDATA[
              <script type="text/javascript" src="//libs.coremetrics.com/eluminate.js"></script> 
              <script type="text/javascript"> 
              cmSetupNormalization("krypto-_-krypto");
              
              // send data to production system 
              //cmSetClientID("99999999",true,"data.coremetrics.com","thesite.com"); 
              
              // send data to test system 
              cmSetClientID("69999999",false,"testdata.coremetrics.com","thesite.com"); 
              </script> 				
              ]]>
            </output>
          </store>
        </stores>
      </BIConfiguration>   
    • ssoKey identifies a secret key for single sign-on to the analytics provider from Management Center. url element identifies the URL for launching the analytics provider from Management Center.
    • Important! useHostedCMHLibraries="true" indicates the store is using the standard IBM Digital Analytics library. useHostedCMHLibraries="false" indicates the store is using the custom IBM Digital Analytics library.
    • Important! marketingCenterEnabled is the enablement flag for integrating Management Center with IBM Marketing Center. If Management Center is integrated with IBM Marketing Center, marketingCenterUrl element can be used to override the default URL to IBM Marketing Center.


  • Enabling custom tables for staging
  • Enabling custom tables for staging > Customized database table requirements
  • stagingprop utility
  • Troubleshooting: Unable to propagate updates using the WebSphere Commerce stagingprop utility
  • Troubleshooting: How to increase memory to staging copy when an out of memory exception is received
  • [Exam notes]

    • Important! Enabling custom tables for staging
      • In both the staging server and the production server, depending on the scope of the table:
        • For site tables, insert only into STGSITETAB.
        • For merchant tables, insert only into STGMERTAB.
        • For tables which contain both site and merchant data, insert into STGSITETAB, STGMERTAB, and STGMRSTTAB.
      • If you are inserting customized parent and child tables, ensure the TABNBR column value for the child tables are higher than the TABNBR column value for the parent tables. If your customized table is a parent table of a WebSphere Commerce table, ensure that the TABNBR column value for the customized table is lower than the TABNBR column value for the WebSphere Commerce table.
      • On the staging server, create database triggers for the custom database table to record changes to the custom database table to the STAGLOG table.
    • Important! Custom database table requirements
      • Define a primary key or a unique index. Rows in staging-enabled tables must be uniquely identifiable by at most five columns: Two columns that contain strings (maximum length: 254 characters) and three columns that contain numbers (maximum length: BIGINT).
      • A referential integrity (RI) constraint cycle cannot exist among the tables.
      • The names of custom tables must be lowercase within the STAGLOG database table.
      • The custom tables must contain only configuration data.
      • All foreign key relationships in the custom tables should specify ON DELETE CASCADE.
    • Important! When stagingprop utility is run without consolidationSize parameter, the default behavior of stagingprop is to perform the consolidation phase for all unprocessed records in the STAGLOG table at once.

      Consider the scenario where the value specified for consolidationSize is x and the total number of unprocessed records in the STAGLOG table is y:

      1. If x >= y, stagingprop's consolidation phase behavior remains the same as the default behavior.
      2. Otherwise, consider a staged table, A, whose total number of unprocessed records in the STAGLOG table is z:
        • If z <= x, A's entire set of unprocessed records in the STAGLOG table is fetched once.
        • If z > x, A's unprocessed records in the STAGLOG table is retrieved in (1 + floor(z/x)) number of fetches.

    • Troubleshooting Unable to propagate updates using the WebSphere Commerce stagingprop utility

      UPDATE mbrgrpusg SET FIELD1=? WHERE mbrgrp_id=? AND mbrgrptype_id=? SELECT FIELD1 FROM mbrgrpusg WHERE mbrgrp_id=? AND mbrgrptype_id=? begin to propagate table mbrgrpusg The command failed to propagate the change related to the STAGLOG record 10193. [IBM][CLI Driver] CLI0115E Invalid cursor state. SQLSTATE=24000 SQLState: 24000 Vendor Error Code: -99999 Stack trace: COM.ibm.db2.jdbc.DB2Exception: [IBM][CLI Driver] CLI0115E Invalid cursor state. SQLSTATE=24000 at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Unknown Source) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Unknown Source) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.check_return_code(Unknown Source) at COM.ibm.db2.jdbc.app.DB2ResultSet.getString2(Unknown Source) at COM.ibm.db2.jdbc.app.DB2ResultSet.getString(Unknown Source) at COM.ibm.db2.jdbc.app.DB2ResultSet.getObject(Unknown Source) at COM.ibm.db2.jdbc.app.DB2ResultSet.getObject(Unknown Source) at COM.ibm.db2.jdbc.app.DB2ResultSet.getObject(Unknown Source) at com.ibm.commerce.staging.StagingProp.setValuesInSql(StagingProp.java:832) at com.ibm.commerce.staging.StagingProp.propagateRows(StagingProp.java:749) at com.ibm.commerce.staging.StagingProp.transactTableGroup(StagingProp.java:488) at com.ibm.commerce.staging.StagingProp.propagate(StagingProp.java:452) at com.ibm.commerce.staging.StagingProp.main(StagingProp.java:265) 10193: UPDATE table mbrgrpusg - mbrgrp_id-161, mbrgrptype_id-2

      Solution:
      • If this is caused by deleting data from the staging database while the stagingprop utility is running, re-run the stagingprop utility.
      • The stagingprop utility has the limitation of not being able to perform an update action when the content that is being updated is a primary key. If this is caused by attempting to make an update to the primary key of a database entry -
        1. Locate the STAGLOG records that show either the unique index or primary keys of a table that is referenced in the stagingprop log is being modified as a part of an UPDATE action.
        2. Manually update the target production database with the primary key updates.
        3. Update the associated STAGLOG records with STGPROCESSED=1.


  • Using logging and tracing in the WebSphere Commerce custom code
  • Configuring WebSphere Application Server logging
  • Logging and tracing IMS TM resource adapter information
  • Changing log details levels for WebSphere Business Monitor server
  • Configuring logging
  • Application server log files
  • Trace components
  • [Exam notes]

    • Important! WebSphere Application Server administration console is used to view and edit the trace specification. The console shows you two tabs, Configuration and Runtime. Changes made to Configuration are stored on the file system and applied when the server starts. You must restart the server to pick up any changes. Modifications to Runtime are applied immediately and are lost after the server is restarted. When trace specification is changed, a line is printed in SystemOut.log, for example -
      The trace state has changed. The new trace state is *=info:com.ibm.websphere.commerce.WC_ORDER=all:com.mycompany.orders=all.
    • Important! Adding logging to your code
      package com.mycompany.commerce;
      
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import com.ibm.commerce.foundation.common.util.logging.LoggingHelper;
      
      public class ExtGetContractUnitPriceCmdImpl extends GetContractUnitPriceCmdImpl {
        private static final String CLASS_NAME = ExtGetContractUnitPriceCmdImpl.class.getName();
        private static final Logger LOGGER = LoggingHelper.getLogger(ExtGetContractUnitPriceCmdImpl.class);
      
        public void performExecute() throws ECException {
           final String methodName = "performExecute";
      
            if (LoggingHelper.isEntryExitTraceEnabled(LOGGER))
               LOGGER.entering(CLASSNAME, methodName);
      
            try {
               super.performExecute();
               boolean a = someOtherFuntion();
               if (LOGGER.isLoggable(Level.FINE))
                  LOGGER.logp(Level.FINE, CLASS_NAME, methodName, "someOtherFunction returned " + a);
            } catch (Exception e) {
               LOGGER.logp(Level.SEVERE, CLASS_NAME, methodName, e.getClass().getName() + "Your Logging Message", e);
            }
      		
            if (LoggingHelper.isEntryExitTraceEnabled(LOGGER))
               LOGGER.exiting(CLASSNAME, methodName);
         }
      }
    • Important! You can configure independent log levels for classes as well as packages.
    • Application server log files: stopServer.log, SystemErr.log, SystemOut.log, trace.log
    • Important! Application server log file location in WebSphere Commerce Developer: WCDE_installdir/wasprofile/logs/server1
    • Both SystemOut.log and SystemErr.log should be checked after starting an application server to confirm that the applications inside the application server being started have also started successfully.
    • Important! Troubleshooting Promotion evaluation
      Solution: Enable logging on the following trace components -
      • com.ibm.websphere.commerce.WC_ORDER
      • com.ibm.commerce.marketing.promotion
    • Troubleshooting Promotion Authoring (Management Center)
      Solution: Enable logging on the following trace components -
      • com.ibm.commerce.promotion.facade.server
      • com.ibm.commerce.marketing.promotion
    • LevelSystemOut.logSystemErr.logtrace.log
      SEVEREYESNOYES
      WARNINGYESNOYES
      INFOYESNOYES
      CONFIGYESNOYES
      FINENONOYES
      FINERNONOYES
      FINESTNONOYES
    • When you enable logging at a certain level, you are also enabling all the levels above it. For example, if logging is set to INFO (usually enabled by default), messages that use SEVERE and WARNING are also logged.


  • Outbound services > Creating an outbound message
  • Outbound services > Sending services
  • Outbound services > Creating an outbound message > Example: Using the messaging system composition service
  • Outbound services > Creating an outbound message > Examples: Outbound messaging using SendMsgCmd
  • Outbound messages
  • Configuring outbound email notification messages
  • Assigning a message type to a transport method for a site or store
  • [Exam notes]

    • Important! WebSphere Commerce Administration Console is used to assign a message type to a transport method for a site or store.
    • Important! Sending services
      • sendImmediate()
        This method sets the sending mode to send the message immediately to the recipients. The caller is blocked until the message has been sent.
      • sendTransacted()
        This method sets the sending mode such that it sends the message in transacted mode. This set stores the message in the MSGSTORE table and lets the scheduler batch job send the messages at predetermined time intervals. The advantage of doing this is to avoid sending the message if the caller of this command encounters exception after calling this command. The caller is not blocked.
      • sendReceiveImmediate()
        This method sets the sending mode to send the message and wait for a reply. byte[] getResult() method returns the result of a send-and-receive sending operation, and should be called AFTER the execute for the command is called.
    • Important! Outbound messaging using SendMsgCmd
      com.ibm.commerce.messaging.commands.SendMsgCmd sendMsgCmd = 
      				(com.ibm.commerce.messaging.commands.SendMsgCmd) CommandFactory.createCommand(SendMsgCmd.NAME, getStoreId());
      
      //To use the site-level configuration, set store id to "0".
      sendMsgCmd.setStoreID(getStoreId()); 
      sendMsgCmd.setMsgType("OrderReceived");
      
      String orderNotifyMsg = new String("...");
      
      //The first parameter is null, this means the default transport method associated with this message type will be used.
      //sendMsgCmd.setContent(null, getCommandContext().getLanguageId().toString() , orderNotifyMsg.getBytes());
      
      TypedProperty typedProperty = new TypedProperty();
      typedProperty.put("ORDER_REF_NUMBER", getOrderRn().toString());
      typedProperty.put("LANGUAGE_ID", getCommandContext().getLanguageId());
      
      //The first parameter is null, this means the default view name associated with this message type in MSGTYPES table will be used. 
      //Another view name may be specified to override the default. 
      //If view can not be found under the store id in command context object, the messaging system will attempt to look up the view with store id of "0".
      sendMsgCmd.compose(null, getCommandContext(), typedProperty); 
      
      sendMsgCmd.setConfigData("subject","Your Order has been received");
      sendMsgCmd.setConfigData("recipient","recipient@recipient.com");
      sendMsgCmd.setConfigData("sender","storeAdmin@storeABC.com");
      
      sendMsgCmd.sendTransacted();
      sendMsgCmd.setCommandContext(getCommandContext());
      sendMsgCmd.execute();
    • If both SendMsgCmd.setContent and SendMsgCmd.compose are used:
      • If SendMsgCmd.setContent is called with the languageId parameter, its generated content is overridden when SendMsgCmd.compose is called.
      • If SendMsgCmd.setContent is called without the languageId parameter, its generated content is not overridden when SendMsgCmd.compose is called.
    • Important! To use messaging system composition service, add an entry to Struts configuration file for the JSP file to use for composing the outbound message.
      <forward className="com.ibm.commerce.struts.ECActionForward" name="ActivateTaskNotificationView/0/-3" path="/ActivateTaskNotification.jsp">
      	<set-property property="direct" value="true"/>
      	<set-property property="properties" value="storeDir=no"/>	
      	<set-property property="resourceClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
      	<set-property property="interfaceName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommand"/>
      	<set-property property="implClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
      </forward>
    • Important! To add a new message mapper, add it to the WebSphere Commerce configuration file (wc-server.xml).
    • user_template.xml is an XML message template definition file that allows you to add new inbound XML messages to be supported by your system.


  • Implementing access control in data beans
  • Implementing access control policies in views
  • Setting access control for a page
  • Role-based policies
  • Troubleshooting: Member hierarchy of resource owner is invalid
  • [Exam notes]

    • Important! Implementing access control in data beans
      • Any data bean that is to be directly protected, must implement the com.ibm.commerce.security.Protectable interface. As such, the bean must provide an implementation of the getOwner() and fulfills(Long member, String relationship) methods.
      • Any data bean that is to be directly or indirectly protected, must implement the com.ibm.commerce.security.Delegator interface. In order to be directly protected, the getDelegate method should return the data bean itself. In order to be indirectly protected, the data bean returned by the getDelegate method must implement the Protectable interface.
      • A bypass of the access control checks occurs in the following cases:

        • If the JSP makes direct calls to access beans, rather than using data beans.
        • If the JSP invokes the data bean's populate() method directly.

    • Important! Setting access control for a page
        <Policies>
             <Action Name="ProductDisplayView" CommandName="ProductDisplayView"/>
      	   
             <ActionGroup Name="AllSiteUsersViews" OwnerID="RootOrganization">
                   <ActionGroupAction Name="ProductDisplayView"/>
             </ActionGroup>
        </Policies>
    • Important! Troubleshooting Member hierarchy of resource owner is invalid
      WC_ACCESSCONT PolicyManagerImpl.getParentOrganizationsForResource 
      Error: No parent organizations; defaulting to Root Organization. 
              MBRREL table or Dynacache may be in invalid state.
      
      WC_ACCESSCONT PolicyManagerImpl.isAllowed isAllowed? 
              User=100000000517; Action=Execute;
             
      Resource=com.ibm.commerce.scheduler.commands.ListRegistryCmdImpl; 
              Owner=555; Resource Ancestor Orgs=-2001; Resource
      Applicable Orgs=-2001
      Solution: Given the preceding error message that member 555 does not have a parent organization, the MBRREL table should be populated, to specify its ancestors. If its parent organization is 2002, and its grandparent organization is Root Organization, the MBRREL table should be populated as shown below -

      descendant_idancestor_idsequence
      55520021
      555-20012


  • WebSphere Commerce AJAX framework
  • WebSphere Commerce Struts framework > Web application > Mapping URLs to controller commands: action-mappings
  • Dynamic caching > Cache invalidation
  • Dynamic caching > WebSphere Commerce store pages properties
  • Member subsystem
  • Trading subsystem
  • Name-value pair command framework > Command error handling
  • Member data model
  • Order data model
  • updatedb utility
  • IBM Gift Center for the Consumer direct sample store
  • IBM Gift Center actions > GiftRegistryAuthentication
  • Session management
  • Persistent sessions (Remember Me)
  • Enabling multiple logon support for the same user
  • WebSphere Commerce database schema > BASEITEM
  • WebSphere Commerce database schema > LANGUAGE
  • WebSphere Commerce database schema > PATTRIBUTE
  • WebSphere Commerce database schema > SRCHCONF
  • [Exam notes]

    • Making an AJAX call to a WebSphere Commerce controller command or service:

      To define a controller command or service to be available for AJAX type requests, define a struts-action entry in the struts-config XML file that identifies the controller command or service as an AJAX type of action.

      Commands:

      <action
        parameter="com.ibm.commerce.interestitems.commands.InterestItemAddCmd"
        path="/AjaxInterestItemAdd"
        type="com.ibm.commerce.struts.AjaxAction">
          <set-property property="authenticate" value="0:0"/>
          <set-property property="https" value="0:1"/>
      </action>

      Services:

      <action 
        parameter="order.addOrderItem" 
        path="/AjaxOrderChangeServiceItemAdd" type="com.ibm.commerce.struts.AjaxComponentServiceAction">
          <set-property property="authenticate" value="0:0"/>
          <set-property property="https" value="0:1"/>
      </action>

      The characteristics of an AjaxAction type URL is that after the execution of the command or service, the WebSphere Commerce runtime automatically forwards the request to one of two well known views to compose a JSON object containing all the entries in the response back to the client. The two well known views map to AjaxActionResponse.jsp (success case) and AjaxActionErrorResponse.jsp (failure case).

      Important! wc.service should be declared beforehand if you want to handle the response JSON in a page. The wc.service.declare API declares a JavaScript service object that is able to call WebSphere Commerce AJAX type struts-actions.

      wc.service.declare({
        id: "AjaxInterestItemAdd",
        actionId: " AjaxInterestItemAdd",
        url: " AjaxInterestItemAdd",
        formId: "",
      
      successHandler: function(serviceResponse) {
            alert("success");	
          },
      
      failureHandler: function(serviceResponse) {
          if (serviceResponse.errorMessage) {
            alert(serviceResponse.errorMessage);
          }
        } 
      });

      To invoke the AJAX call, the following API is used:

      wc.service.invoke("AjaxInterestItemAdd");
      The successHandler function defined in the service declaration is executed and two model changed Dojo events (modelChanged and modelChanged/actionId) are published automatically by the framework when the request completes successfully, and Dojo automatically notifies all subscribed listeners.
    • Making AJAX calls to WebSphere Commerce views to get refresh contents:

      Any HTML element of a page can be designated as a refresh area. The content within the HTML tag will be replaced by new content from the WebSphere Commerce server whenever the refresh controller associated with the refresh area triggers the refresh request.

      <div dojoType="wc.widget.RefreshArea" 
        id="MiniShoppingCart" 
        widgetId="MiniShoppingCart" 
        controllerId="MiniShoppingCartController">
      </div>

      A refresh area always has a refresh controller associated with it. The refresh controllers are automatically registered to listen to modelChanged and renderContextChanged events. Therefore, they will be notified when these events occur. They then evaluate the model changes and/or render context changes and decide if the refresh areas that it manages should be refreshed or not.

      wc.render.declareRefreshController({
        id: "MiniShoppingCartController",
        renderContext: wc.render.getContextById("MiniShoppingCartContext"),
        url: "MiniShoppingCartView",
        formId: "",
      
      modelChangedHandler: function(message, widget) {
          if(message.actionId in order_updated){
            widget.refresh();
          }
        },
      
      renderContextChangedHandler: function(message, widget) {
          
        },
      
      postRefreshHandler: function(widget) {
      
        }
      
      });
      The modelChangedHandler function is executed by the WebSphere Commerce AJAX framework as soon as there is a model changed event triggered by successful wc.service.invoke() actions. It first checks that the model changed is for an actionId that is of interest to the refresh area. The widget.refresh() is the code that makes an AJAX call to the WebSphere Commerce server for the URL specified in the refresh controller. Once the new HTML fragment returns from the server, the framework destroys anything that exists in the current refresh area and replaces its contents with the new HTML fragment returned by the view. The postRefreshHandler function is the last function that the framework calls after a refresh area is successfully refreshed with new contents. It can be used to unblock the user interface if it was blocked during the AJAX calls.

    • Updating a business object in WebSphere Commerce using AJAX and returning all relevant update information using JSON:

      The dojo.xhrPost API is used in conjunction with the traditional WebSphere Commerce runtime programming model, where a request is made to a controller command or a service, and after execution, the WebSphere Commerce runtime redirects the request to whatever is specified in the URL or errorViewName parameters in the original request.

      var parameters = {};
        parameters.storeId = storeId;
        parameters.langId=langId;
        parameters.catalogId=catalogId;
        parameters.catentryId=productId;	
        parameters.URL="MiniCartContentsJSON";
        parameters.errorViewName="MiniCartContentsJSON";
      
        dojo.xhrPost({
          url: "OrderChangeServiceItemAdd",				
          handleAs: "json-comment-filtered",
          content: parameters,
          service: this,
          load: refreshMiniCart,
          error: function(errObj,ioArgs) {
          alert("error");
          }
        });
      This code snippet makes an AJAX request to the OrderChangeServiceItemAdd service and then redirects to the MiniCartContentsJSON view, which is mapped to a JSP file that creates a JSON object with its content. The client then gains control back and either the load or error function is called depending on the respective success or failure. The error scenario is only called when there are difficulties communicating with the WebSphere Commerce server. Otherwise, a success or exception from the WebSphere Commerce code executes the load function which determines from the JSON object whether the request was successful or it failed. The load function uses the JSON object and DOM manipulation API to replace all the elements in the page that should be updated with new data that resulted from the server update. URLs do not need to be registered as AjaxAction, as this scenario does not make use of any of the new WebSphere Commerce AJAX framework.

    • Calling WebSphere Commerce server using AJAX to gather new data as a JSON object and refreshing the page contents:

      The dojo.xhrPost API is used in conjunction with the traditional WebSphere Commerce runtime programming model, where a request is made to a view that maps to a JSP file that creates a JSON object. On the load function of the xhrPost API, the DOM manipulation API is used to put the JSON contents in the web page elements.

    • Mapping URLs to controller commands
      <action-mappings type="com.ibm.commerce.struts.ECActionMapping">         
         <action path="/StoreCatalogDisplay" 
                 parameter="com.ibm.commerce.catalog.commands.StoreCatalogDisplayCmd" 
                 type="com.ibm.commerce.struts.BaseAction" />
      
         <action path="/AddressAdd" 
                 parameter="com.ibm.commerce.usermanagement.commands.AddressAddCmd" 
                 type="com.ibm.commerce.struts.BaseAction">
              <set-property property="https" value="0:0,201:1" />
              <set-property property="authenticate" value="201:1" />
              <set-property property="credentialsAccepted" value="201:P" />
         </action>
      </action-mappings>
    • Representing view implementations
      <global-forwards>
      	<forward name="AddressBookForm" path="/AddressBookForm.jsp"/>
      	<forward className="com.ibm.commerce.struts.ECActionForward" 
      		 name="AddressBookForm/201" 
      		 path="/UserArea/AccountSection/AddressbookSubsection/AddressBookForm.jsp">
      		 <set-property property="resourceClassName" value="com.ibm.commerce.command.HttpForwardViewCommandImpl" />
      	</forward>
      	<forward className="com.ibm.commerce.struts.ECActionForward" 
      		 name="GenericPasswordErrorView" 
      		 path="/GenericApplicationError.jsp">
      		 <set-property property="properties" value="storeDir=no" />
      		 <set-property property="resourceClassName" value="com.ibm.commerce.command.HttpForwardViewCommandImpl" />
      	</forward>
      </global-forwards>
      
      <action-mappings type="com.ibm.commerce.struts.ECActionMapping">         
      	<action path="/AddressBookForm"
      		type="com.ibm.commerce.struts.BaseAction">
      		<set-property property="https" value="0:0,201:1" />
      		<set-property property="credentialsAccepted" value="201:P" />
      	</action>
      	<action path="/GenericPasswordErrorView" 
      		type="com.ibm.commerce.struts.BaseAction" />
      </action-mappings>
    • Cache invalidation methods: Time based invalidation, Command based invalidation, Dynacache API and CACHEIVL table invalidation, Group based invalidation
    • Important! When building the command-based invalidation policies in cachespec.xml, keep in mind the following restrictions:
      • Only the methods invoked by the command that return the input instance variables can be used in the method component.
      • All the methods that are used to construct the invalidation IDs, must be provided in the command interface and be implemented.
      • The request attributes component type cannot be used.
    • Important! Properties used in cachespec.xml file: EdgeCacheable, consume-subfragments, save-attributes, store-cookies, sharing-policy
    • Trading subsystem includes auctions, contracts, and Request for Quote (RFQ)
    • Important! Types of command exceptions:
      • ECApplicationException
        This exception is thrown if the error is related to user input and will always fail. For example, when a user enters an invalid parameter, an ECApplicationException is thrown. When this exception is thrown, the solution controller does not retry the command, even if it is specified as a retriable command.
      • ECSystemException
        This exception is thrown if a runtime exception or a WebSphere Commerce configuration error is detected. Examples of this type of exception include create exceptions, remote exceptions, and other EJB exceptions. When this type of exception is thrown, the solution controller retries the command if the command is retriable and the exception was caused by either a database deadlock or database rollback.
    • updatedb utility is used to update the WebSphere Commerce database to the latest fix pack level that is installed for your system.
    • Important! You can create a custom table to capture wedding anniversary date, 1st child name, 2nd child name, 1st child date-of-birth, 2nd child date-of-birth, etc during user registration and display the information in account profile summary. The custom table should be related to USERPROF table.
    • WebSphere Commerce offers Gift Center solution for Consumer direct sample store and Madisons starter store.
    • IBM Gift Center enablement script: enableGiftCenterForServer.xml or enableGiftCenterForToolkit.xml
    • Important! GiftRegistryAuthentication action grants access to the gift registry to any user (whether a gift registrant, co-registrant, or a gift giver). If the user is authenticated, the action creates a gift registry context for the user.
    • Important! BaseItems in BASEITEM table are used exclusively for fulfillment.
    • Important! SRCHCONF is the configuration table for WebSphere Commerce search integration.
    • WebSphere Commerce session cookies -
      • WC_ACTIVEPOINTER
        This cookie contains the value of the store ID of the session. This value is used to select the store to run a command, if one is not specified on the URL.
      • WC_AUTHENTICATION_ID
        This cookie is used to authenticate the user over SSL-connections.
      • WC_GENERIC_ACTIVITYDATA
        This cookie exists only if it is a generic user (-1002) session. This cookie stores the session values such as store ID, language ID, and contracts.
      • WC_SESSION_ESTABLISHED
        This cookie is created on the first request that is processed by WebSphere Commerce run time. For example, a non-cache request.
      • Important! WC_USERACTIVITY_ID
        This cookie is a user session cookie that flows between the browser and server over both SSL or non-SSL connection. It is used for user identification over non-SSL connections. It contains user session values such as login timeout, or session identifier.
    • All session cookies, except for WC_SESSION_ESTABLISHED, can be used in the Management Center preview environment.
    • Persistent sessions (Remember Me)
      • When a remembered guest user returns to the site, a new guest user is created when the session tries to access a protected request (configured through the Struts configuration). The shopping cart of the previous guest user is reset to the new guest user and all sensitive information of the order, such as address and credit card, is removed.
      • By default, the Logoff command deletes the persistent session. However, if rememberMe=true is passed to the Logoff command then the registered user is logged off but remembered.
      • WC_PERSISTENT cookie is used to persist user ID, language ID, and currency for each store ID visited in the session. Multiple sets of identifiers can exist if the user visits more than one store.
    • Important! Enable multiple logon support to allow for the same authenticated user to use the site from multiple browsers or locations. This feature eliminates the termination of the session and the request to reauthenticate a user, if that same user logs in from a different browser or location. With multiple logon support enabled, each user session acts independently. For example, each session can timeout or be logged out without affecting the other. All site functions are shared between user sessions. Any changes that are made to the cart through one session, for example, are reflected in the other session. Multiple logon support can be enabled from WebSphere Commerce configuration file (wc-server.xml).
      <SessionManagement>
      	<url-rewriting display="false" enabled="false"/>
      	<cookie acceptance="false" age="-1" display="false"
      		domain="" enabled="true" path="/" persistence="wcs"/>
      	<referrerCookie age="-1"/>
      	<PersistentSession cookieExpiry="30"
      		delayNewPersistentGuestSession="true" display="false" enable="true"/>
      	<PersonalizationId display="false" enable="true"/>
      	<AllowMultipleLogonForSameUser display="false" enabled="true"/>
      </SessionManagement>


  • Developing Commerce Composer assets
  • Defining the storefront assets for Commerce Composer layout templates
  • Registering a Commerce Composer widget
  • Enabling Commerce Composer support for a Madisons starter store
  • Commerce Composer widget library > Facet Navigation widget
  • Creating and editing Commerce Composer objects directly from store preview
  • Page layout framework > JSP widget library
  • [Exam notes]

    • Data Load utility is used to turn on the Commerce Composer store function in the Madisons starter store.
    • Important! Storefront components for Commerce Composer layout templates

      1. The container JSP file identifies any configurable slots that are to be included in the template where a widget can be added and marks these slots with the wcpgl:widgetImport tag. Each slot is defined by an internal slot ID, which must be unique within the container. The container JSP file is also used to identify the environment setup file and any predefined widgets.
      2. The environment setup file.
      3. The container HTML grid and slots provide the visual design of the template. This design includes the location of the slot placeholders (5) within the container (4) that a widget can be included within.
      <%@include file="../Common/EnvironmentSetup.jspf" %>
      <%@taglib uri="http://commerce.ibm.com/pagelayout" prefix="wcpgl"%>
      <div class="rowContainer" id="container_${pageDesign.layoutID}">
        <div>
          <div class="col6 acol12" data-slot-id="1"><wcpgl:widgetImport slotId="1"/></div>
          <div class="col6 acol12" data-slot-id="2"><wcpgl:widgetImport slotId="2"/></div>
        </div>
        <div>
          <div class="col3 acol12" data-slot-id="3"><wcpgl:widgetImport slotId="3"/></div>
          <div class="col3 acol12" data-slot-id="4"><wcpgl:widgetImport slotId="4"/></div>
          <div class="col3 acol12" data-slot-id="5"><wcpgl:widgetImport slotId="5"/></div>
          <div class="col3 acol12" data-slot-id="6"><wcpgl:widgetImport slotId="6"/></div>
        </div>
        <div>
          <div class="col12" data-slot-id="7"><wcpgl:widgetImport slotId="7"/></div>
        </div>
      </div>
    • Important! Before you can use your custom widget in the Commerce Composer tool, you must register the widget with the Commerce Composer framework. You must also have a store subscribe to the widget before you can use the widget in a page layout for that store. Use the Data Load utility to register your widget in the Commerce Composer framework and have your store subscribe to your widget.
    • Important! Tasks performed by an application developer in Commerce Composer framework:
      • Create layout template
      • Create widget
    • The Facet Navigation widget can be used only in layouts for category pages and search results pages. This widget is designed for use in layouts that also contain the Catalog Entry List widget. When the customer selects a facet value, the catalog entries in the Catalog Entry List widget are filtered accordingly. Ensure that you configure the facets for your store by using the Catalogs tool so that this widget can retrieve and display the facets. You cannot specify facets directly in the widget. The Facet Navigation widget uses the settings in the Catalogs tool to determine which facets to display in the widget. Facet Navigation widget properties: Widget name, Widget orientation (Vertical, Horizontal)
    • Aurora starter store JSP widget library: Important! Breadcrumb, Department, CategoryRecommendation, ContentRecommendation, ProductRecommendation, IntelligentOffer, FacebookActivity, FacebookConnect, Important! FacebookLike, Footer, Header, LanguageCurrency, MiniShopCartDisplay, Search, ComponentListing, LeftNavigation, Discounts, InventoryStatus, MerchandisingAssociation, PriceDisplay, PriceQuantity, ProductDescription, ProductFullImage, ProductTab, Reviews, TechnicalSpecification, ShoppingList, BundleSummary, Important! PackageSummary, CompareProduct


  • Management Center framework > Business Object Editor definitions
  • [Exam notes]

    • Important! wcfBusinessObjectEditor class is a base class that all Management Center tools must extend.
    • wcfOrganizationalObjectDefinition class describes an organizational object definition. Organizational objects are represented in the explorer view and the utilities browse view as high level navigation tree nodes. You can only declare instances of wcfOrganizationalObjectDefinition as children of wcfBusinessObjectEditor.
    • wcfTopObjectDefinition class is an organizational object definition that describes the root object for an instance of the wcfBusinessObjectEditor class. This root object is the starting point for populating the navigation tree.
    • wcfPrimaryObjectDefinition class contains the definition for a primary object that describes a top level business object that exists as its own entity, independent of other objects.
    • wcfChildObjectDefinition class contains the definition for a child object that describes a secondary business object that is owned by a primary object or another child object.
    • wcfPropertyDefinition class describes a named property of a business object.
    • wcfParentReferenceObjectDefinition class defines a parent-child relationship in which each child can only have one parent. In this relationship, the parent is the owning object and the child is the referenced object. The owning object is the primary object definition that contains the parent reference object definition.
    • wcfCollectionReferenceObjectDefinition class defines a parent-child relationship in which each child can have more than one parent. In this relationship, the parent is the owning object and the child is the referenced object. The owning object is the primary object definition that contains the collection reference object definition.
    • wcfReferenceObjectDefinition class describes a relationship between two primary objects. This relationship object must be owned by one of these two primary objects, called the owning object. The other primary object is called the referenced object.


  • Management Center test automation framework
  • Management Center test automation framework > wcfAutoRunTestCaseAction
  • Management Center test automation framework > wcfAutoFindObjectAction
  • Management Center test automation framework > wcfAutoVerifyObjectAction
  • Management Center test automation framework > wcfAutoVerifyPropertyAction
  • [Exam notes]

    • Important! The Management Center test automation framework uses an XML file that describes the list of actions you want to run. To point to the XML file that contains the actions you want to run, add a URL parameter named testdata to the Management Center URL. For example: https://<host>:8000/lobtools?testdata=/testdata/MyCompany/test.xml

      XML file structure:

      <testcase>
      	<action name="wcfAutoSetValueAction">
      		< param name="valueKey" value="storeIdentifier"/>
      		< param name="value" value="AdvancedB2BDirect"/>
      	</action>
      	 
      	<action name="wcfAutoRunTestCaseAction">
      		< param name="url" value="/testdata/commerce/catalog/restricted/test.xml"/>
      	</action>
      </testcase>
      The test automation framework supports the following actions:
      • wcfAutoRunTestCaseAction action downloads a test case XML file from the specified URL and inserts the actions from this file at the start of the list of pending actions.
      • wcfAutoOpenToolAction action opens a specified Management Center tool, such as the Catalogs tool. If the tool is already open, it becomes the active tool.
      • wcfAutoSetValueAction action sets a value that can be used by other actions. This action is typically run during the setup portion of a test case so that other actions in the test case can refer to the value by way of the valueKey parameter.
      • wcfAutoSelectStoreAction action switches the store for the current business object editor to the specified store.
      • wcfAutoCreateNewObjectAction action creates a new instance of a business object.
      • wcfAutoSetPropertyAction action sets a property value.
      • wcfAutoDeleteObjectAction action deletes the specified business object.
      • wcfAutoFindObjectAction action searches for the specified business object and saves it for other actions to use.
      • wcfAutoGetChildObjectAction action locates the specified child business object and saves it for other actions to use.
      • wcfAutoLoadChildrenAction action runs the get children services for the specified business object.
      • wcfAutoSaveAllAction action saves all unsaved business objects for the active Management Center tool.
      • wcfAutoRefreshAllAction action resets the active tool by releasing all of the objects that are currently loaded.
      • wcfAutoVerifyObjectAction action verifies that the specified business object exists.
      • wcfAutoVerifyNoObjectAction action verifies that the specified business object does not exist.
      • wcfAutoVerifyPropertyAction action verifies that the specified property matches a specified value.
      • wcfAutoRunCustomServiceAction action invokes a custom service on the specified business object.
      • wcfAutoCreateVersionAction action creates a version of a business object (sales catalog, category, and catalog entries).


  • Working with Catalog Upload > Creating catalog data in CSV format
  • Triggers in Dialog activities > Trigger: Customer Registers
  • Click-to-edit function in store preview
  • Adding a new validation rule for a Web activity on the OpenLaszlo client side
  • [Exam notes]

    • Important! Marketing subsystem provides functionality to send a welcome email message to new registrants.
    • Click-to-edit function in store preview is available for the following objects in the Catalogs tool, Marketing tool, and Commerce Composer tool:

      Business objectWhat you can do from store preview
       Catalog entries (products, SKUs, bundles, and kits) Edit only
       Categories Edit only
       E-Marketing Spots Create and edit
       Web activities  Create and edit

       Edit links are not shown for web activities in store preview that are:

      • Inactive
      • Scheduled outside of the current preview date and time

       Marketing content Edit only
       Search rules  Create and edit

       Edit links are not shown for search rules in store preview that are:

      • Inactive
      • Scheduled outside of the current preview date and time
      • Not triggered by the keyword that you used to search

       Pages Edit only
       Layouts Create and edit
       Widgets Edit only

    • Click-to-edit function in store preview is not available if you are previewing the store by using a generated preview URL.
    • In order to add a new validation rule for a Web activity on the OpenLaszlo client side, create a new validator class that extends the wcfValidator class.


  • Content management integration configuration properties
  • Troubleshooting: Configuring WebSphere Commerce with WebSphere MQ
  • Customizing the WebSphere Commerce pricing engine
  • Configuring WebSphere Commerce for order and inventory processing
  • Customizing to allow multiple manual adjustments in the getOrderPrice API
  • SQL error codes > -612
  • [Exam notes]

    • Important! wc.resolveContentURL.cmsHost is a configuration property for integrating WebSphere Commerce with a content management system. It defines the host name of the content URLs from the content management system.
    • Troubleshooting Important! After setting up WebSphere Commerce Developer to work with WebSphere MQ, the following (or similar) exception is observed during server startup:
      [2/21/06 9:55:03:848 CST] 52989e1b SystemErr R java.lang.UnsatisfiedLinkError: 
      C:\WebSphere\WebSphere MQ\Java\lib\mqjbnd05.dll: Can't find dependent libraries
      Solution: The cause is the MQ_INSTALL_ROOT variable by default is pointing to the WebSphere MQ client installation instead of the server installation.
    • Troubleshooting When sending a message to a back-end system with WebSphere MQ, unexpected characters show up in the front of the XML message. For example, from the WebSphere Commerce logs:
      com.ibm.commerce.messaging.outboundservice.Messaging.sendReceiveImmediate() Message content is: 
      Solution: The default value is "JMS" when a JNDI entry is defined for an outbound queue. The value of the targetClient field should be changed to MQ.
    • Troubleshooting When a two-phase commit (2PC) is configured incorrectly the following message is displayed:
      [1/12/11 12:23:45:124 EST] 0000002a CommerceSrvr E com.ibm.commerce.messaging.listener.
         TransportAdapterSerialDispatcher process() CMN9907E: A resource exception occurred 
         during processing: "com.ibm.commerce.messaging.adapters.jca.exception.WcResourceException: 
         Messaging system cannot commit a JMS Session for QueueConnectionFactory null
      . Error: javax.jms.IllegalStateException: Method not permitted in global transaction
      Solution: Disable the two-phase commit for the queue connection factory.
    • Important! To customize the WebSphere Commerce price engine, override the following classes:
      • ComparisonConditionElementCmdImpl
      • PriceEquationCalculationCmdImpl
      • PriceListElementCmdImpl
    • Important! For side-by-side integration, WebSphere Commerce must be configured to use Sterling Order Management for inventory and order processing:
      • Update WebSphere Commerce store to use DOM inventory system (STORE.INVENTORYSYSTEM=-5).
      • Insert records into INVCNF (represents DOM inventory cache configuration) and INVCNFREL (represents the relationship of an item and/or location with an inventory configuration) tables.
      • Update WebSphere Commerce configuration file to add a new EditableProperty element to the JMS outbound connector's InteractionSpec to set JMSHeaderProperty
      • Edit WC_eardir/xml/config/com.ibm.commerce.order.external/wc-component-client.xmlto set asynchronous="true" for ProcessOrder message and to bind the action for the GetOrder message.
      • Copy Sterling JAR files to WebSphere Commerce server.
      • Enable flexflow for "Sterling OMS integration" in the CMC store management tool.
      • Configure and activate the following transports from WebSphere Commerce Administration Console: Sterling OMS transport, Webservices over HTTP, WebSphere MQ.
        Sterling OMS transport configuration parameters: Integration URL, Integration User Id (WCIntegrationUser), Inventory System Heartbeat URL, Order System Heartbeat URL
      • Create message type "Message for external inventory system" with transport "WebServices over HTTP" to process inventory.
      • Create message type "Message for external order system" with transport "WebSphere MQ" to transfer orders.
      • Create message type "Message for GetOrder from external order system" with transport "WebServices over HTTP" to get order list.
    • Customizing to allow multiple manual adjustments in the getOrderPrice API:
      • (WebSphere Enterprise Service Bus) In GetOrderPriceToProcessOrderInput.xsl file, locate the CalculationInfo section and replace the following at the line, order, and or shipment level(s):

        <_ord:AdjustmentApplyPolicy>
        <xsl:text>FixedReplacement</xsl:text>


        with

        <_ord:AdjustmentApplyPolicy>
        <xsl:text>FixedAdjustment</xsl:text>
      • (WebSphere Commerce) To enable the manual adjustment policy, run the applicable SQL commands:
        • Important! For an order-level adjustment (OrderAdjustment):

          UPDATE CALRANGE SET CALMETHOD_ID=-13 WHERE CALRANGE_ID=-11;
          UPDATE CALRLOOKUP SET VALUE=0 WHERE CALRLOOKUP_ID=-11;
        • For a shipping-level manual adjustment (ShippingAdjustment):

          INSERT INTO CALMETHOD VALUES (newidXXXXX, -1, -7, 'com.ibm.commerce.order.calculation.FixedAmountCalculationRangeCmd','method for a shipping discount range returning a fixed discount', 10, 'CalculationRange', NULL);

          UPDATE CALRANGE SET CALMETHOD_ID = newidXXXX WHERE CALRANGE_ID=-12;
          UPDATE CALRLOOKUP SET VALUE=0 WHERE CALRLOOKUP_ID=-12;
    • DB2 SQL error code -612 is returned when a non-unique name was specified where a unique name is required. Column and period names must be unique within an index, a table, or a view, and in the UPDATE OF clause of a trigger definition.


  • Responsive Web Design (RWD) framework
  • Installing the Storefront Test Automation Engine
  • Storefront Test Automation Engine usage > Data files
  • Android hybrid applications using IBM Worklight
  • Test recommendations for smart phone and tablet starter stores
  • [Exam notes]

    • Important! Responsive Web Design (RWD) framework:
      • Technologies and design patterns: Fluid layouts and grids, Column stacking, Column nesting, Stacking order
      • The fluid grid system is defined in base.css file.
      • A row is always divided into 12 columns, regardless of the breakpoint.
      • A row's child element can span 1 to 12 columns, regardless of the breakpoint, by using one of the col* classes.
      • If a row has child elements spanning a total of more than 12 column, they flow according to how HTML handles float elements.
        For example, for a row containing 3 child elements spanning 8, 8 and 4 columns:
        1. The first child element is positioned at the top left of the row spanning 8 columns. That is, 2/3 of the row's width.
        2. The second child element is positioned under the first child element, also spanning 8 columns.
        3. The third child element is positioned to the right of the second child element, spanning 4 columns. That is, 1/3 of the row's width.
      • A row's child element can respond to the RWD-A (Mobile device) and RWD-C (Desktop device) breakpoints by using the acol* class for RWD-A (Mobile device) or ccol* class for RWD-C (Desktop device).
        For example, a row's child element can span 6 columns by default and 12 columns in the RWD-A (Mobile device) breakpoint by using class="col6 acol12".
      • Rows and their child elements should have a flexible or automatic height.
      • The fluid grid system does not have built-in gutters, or margins, between a row's child elements.
      • Do not apply any margin to a row's child elements. However, row margins are acceptable.
      • Avoid borders or padding to a row's child elements. This rule also applies for rows.
      • The col* classes contain no breakpoints. Elements with only the col* classes do not stack, regardless of the viewport width.
      • Column stacking can be enabled by specifying the column span for the RWD-A (Mobile device) breakpoint using the acol* classes. It is implemented in the following way: All child elements of a row use acol12. For example, for a row containing 2 child elements with the col4 acol12 classes and col8 acol12 classes respectively. In this scenario, the child elements are side by side by default, spanning 4 and 8 columns respectively. The acol12 class, however, makes the child elements span 12 columns each in the RWD-A (Mobile device) breakpoint, so that they are laid out vertically, each spanning the full width of the row.
      • It is possible to merge rows to reduce HTML markup, as long as their child elements can be divided into groups that span 12 columns in total.
      • The col* classes are used instead of bcol* since it is used not only for RWD-B (Tablet device), but for all viewport widths, regardless of breakpoint. That is, RWD-B (Tablet device) is used by default and the acol* and ccol* classes are used as overrides.
      • A row and its child elements can be nested within the child element of another row.
      • The stacking order lets you control where a sidebar element is stacked, relative to the content element.
    • Web test engine offers functionality to the tests to interact with a web browser. It abstracts the tests from the test tool that is being used.
    • Important! Selenium WebDriver is an open source tool that you can use to automate web browser interactions. Selenium WebDriver makes direct calls to the browser by using each browser's native support for automation. It does not require a Selenium server to execute test cases. The Storefront Test Automation Engine automatically starts the Selenium WebDriver on the local machine during test execution.
    • Storefront Test Automation Engine includes a mechanism to load values from XML data files.
      <Scenario name="SCENARIO_NAME">
        <Env>
          <Parameter name="SHARED_1" value="value 1" />
          <Parameter name="SHARED_2" value="value 2" />
        </Env>
          <Test name="TEST_1">
            <Datablock name="BLOCK_1">
      	  <Input>
      	    <Parameter name="PARAMETER_1" value="value 1.1" />
      	    <Parameter name="PARAMETER_2" value="value 2.1" />
      	  </Input>
      	  <Output>
      	    <Parameter name="PARAMETER_1" value="value 3.1" />
      	    <Parameter name="PARAMETER_2" value="value 4.1" />
      	  </Output>
      	</Datablock>
      	<Datablock name="BLOCK_2">
      	  <Input>
      	    <Parameter name="PARAMETER_1" value="value 1.2" />
      	    <Parameter name="PARAMETER_2" value="value 2.2" />
      	  </Input>
      	  <Output>
      	    <Parameter name="PARAMETER_1" value="value 3.2" />
      	    <Parameter name="PARAMETER_2" value="value 4.2" />
      	  </Output>
      	</Datablock>
          </Test>
          <Test name="TEST_2">
      	<Datablock name="BLOCK_1">
      	  <Input>
      	    <Parameter name="PARAMETER_1" value="value 1.3" />
      	    <Parameter name="PARAMETER_2" value="value 2.3" />
      	  </Input>
      	</Datablock>
          </Test>
      </Scenario>
      The data files can be accessed within a test case that has the following field and annotation defined:
      //A Variable to retrieve data from the data file.
      @DataProvider
      private final WteDataProvider dsm;
    • Important! To develop Android hybrid applications using IBM Worklight, publish (FEP6) AuroraMobile.sar or (FEP7+) Aurora.sar


  • Payments subsystem
  • Early Approval payment rule
  • Configuring the SimpleOffline plug-in with two payment methods
  • Developing a payment plug-in
  • Enabling punch-out payment using a redirect to the third party payment service provider
  • [Exam notes]

    • Important! Early Approval payment rule:

      Payment event Target state of payment Description
      prime payment APPROVED The payment is approved when the order is captured.
      reserve payment APPROVED The payment is approved when the order is released to fulfillment.

      Specifically, ensure the payment is in the APPROVED state. If it is, take no action. If it is not, approve it. If it is only partially approved, ensure that the difference is approved.

      finalize payment DEPOSITED The payment is deposited when the order is fulfilled.

      Example: A customer places an order for two items that total 300 Euro: item A costs 100 EUR and is in stock. Item B costs 200 EUR and is not in stock but will be available in two days. The customer uses credit card brand X to pay for the order.

      Payment event Validation amount Reservation amount Finalization amount Back-end system
      Amount approved Amount deposited
      prime payment (order capture)

      The initial amount is 100 EUR because only one item is available.

      100 0 0 100 0
      Release A
      reserve payment (release to fulfillment) 100 100 0 100 0
      finalize payment (shipping) 100 100 100 100 100
      Release B
      reserve payment (release to fulfillment) 0

      The validation amount is zero at this stage because no validation activity is occurring.

      200 0 200 0
      finalize payment (shipping) 0

      The validation amount is zero at this stage because no validation activity is occurring.

      200 200 200 200

    • EDPGlobalConfigs.xml file is used to configure a payment system to use synchronous payment event. Change the <AlwaysExecuteProcessBGInFG> element to true.
    • PaymentMethodConfigurations.xml file is used to configure payment method details.
      <PaymentMethodConfigurations>
            <PaymentMethodConfiguration
                          name="CreditCardOffline"
                          paymentSystemName="OfflineCreditCardSystem"
                          systemEditable="true"
                          humanEditable="true"
                          refundAllowed="true"
                          minimumAmount="0"
                          maximumAmount="Unbounded"
                          priority="MEDIUM"
                          partiallyConsumable="true"/>
           </PaymentMethodConfiguration>
      </PaymentMethodConfigurations>
    • Important! PaymentMappings.xml file is used to configure the mapping from payment method to payment method configuration and payment rule.
      <PaymentMappings>
      	<Mapping paymentMethod="VISA"
      		 paymentConfiguration="CreditCardOffline"
      		 paymentActionRule="Early Approval" />
      	<Mapping paymentMethod="Check"
      	         paymentConfiguration="CheckOffline"
      		 paymentActionRule="Early Deposit" />
      </PaymentMappings>
    • PaymentSystemPluginMapping.xml file is used to configure the mapping from payment system name to payment plug-in for different payment configuration groups.
      <Mapper>
        <RetainKeywords>
             <Keyword name="billing_address_id"/>
        </RetainKeywords>     
        <PaymentSystemName 
                name="SimpleOffline" >
                <Mapping paymentConfigurationId="default" PluginName="SimpleOffline" >
                    <Keyword name="cc_cvc" mask="-" plain="0" removeAfterApproval="true" neverPersist="true"/>
                    <Keyword name="cc_nameoncard" mask="*" plain="0" removeAfterApproval="true" neverPersist="true" />
                    <Keyword name="account" mask="*" plain="-5" searchable="true"/>
                </Mapping> 
        </PaymentSystemName>
      </Mapper>
      
    • A payment plug-in is a stateless session bean that implements the Plugin interface. The interface defines a list of financial transactions that can be implemented by a plug-in:
      • checkPaymentInstruction
      • validatePaymentInstruction
      • approveAndDeposit
      • approve
      • reverseApproval
      • deposit
      • reverseDeposit
      • credit
      • reverseCredit
    • Payment plug-in deployment descriptors are named PluginDeployment.xml and can be used to configure the payment protocol properties that you want to keep in the extended data for the payment instructions.
    • POLICY, POLICYDESC, and POLICYCMD tables are used to configure payment business policies for a store.
    • Important! POLICYCMD table is used to set up the business policy commands:
      • DoPaymentActionsPolicyCmdImpl
      • EditPaymentInstructionPolicyCmdImpl
      • QueryPaymentsInfoPolicyCmdImpl


  • Data service layer
  • Data service layer query processing > Query template file
  • Working with the data service layer > Creating a query
  • Working with the data service layer > Extending the WebSphere Commerce schema using the data service layer > Adding query templates to include custom information
  • Working with the data service layer > Enabling optimistic concurrency control for custom tables
  • Configuring WebSphere Commerce Developer for Web service development > WebServicesRouter Web module configuration
  • Representational State Transfer (REST) services
  • WebSphere Commerce BOD command framework
  • SOI and BOD service modules
  • Working with WebSphere Commerce SOI services > Client library for WebSphere Commerce services > Client library authentication mechanisms
  • Working with WebSphere Commerce SOI services > Testing a WebSphere Commerce service
  • Creating a WebSphere Commerce web service module (SOI)
  • Extending an SOI service with UserData
  • Extending an SOI service with Overlays
  • Extending a BOD service to manage UserData with the Data Service layer
  • [Exam notes]

    • Important! WebSphere Commerce persistence mechanisms: Data Service Layer, Enterprise Java Beans (EJB)
    • The data service layer (DSL) provides an abstraction layer for data access that is independent of the physical schema. DSL consists of three pieces: the business object mediation service, the physical object persistence service, and the data service facade.

      The business object mediation service initializes mediators that perform bidirectional transformations between the physical service data objects (SDO) and logical SDOs. It allows you to perform CRUD operations on the logical SDOs so that the business logic layer can work with them rather than the physical schema. Each service module provides its own mediators, and there are two kinds: Read and Change mediators. They are listed in the Business Object Mediator configuration file. Read mediators are used to process the OAGIS Get requests. Change mediators handle the OAGIS Change, Process and Sync requests.

      The mediators access the physical data through the physical object persistence service. This service translates XPath queries to SQL queries.

      The Data Service Facade provides a single entry point into DSL. It provides interfaces to work with both physical and logical data, and it delegates to the business object mediation service or to the physical persistence service. It also allows each service module to register with the data service layer, and loads the service module-specific configuration files.

      For read operations, the data service layer facade receives a query from the business logic layer. The query consists of an XPath expression and an access profile, which are extracted from the OAGIS GET verb. The data service layer forwards this query to the business object mediator (BOM) who, in turn, passes it to the persistence service. That service looks up the correct SQL template for the query, and uses it to generate one or more SQL statements. It then runs these statements, and maps their result sets into physical SDOs. This mapping, between the database schema (tables and columns) and the SDO classes, is defined by XML called Object-relational metadata. Lastly, the physical SDOs are returned to the BOM. The BOM configuration describes how to instantiate the necessary mediators, which are returned to the business logic layer.

      For change operations (create, update, delete), the data service layer facade receives the OAGIS nouns as input, and passes them to the business object mediation service. This service instantiates the appropriate change mediators. In turn, they fetch the physical representation of the nouns from a service called the physical object mediation service. The BOM then returns the mediators to the business logic layer. The mediators are then called with specific actions to create, update, or delete nouns and noun parts. The logic inside the mediators translates these actions into operations on physical SDOs. For example, a create request will create new physical objects and populate them with noun values. After making all its changes, the business logic layer instructs the change noun mediator to save the updated physical SDOs. The mediator calls a physical object persistence service to update the database.

      Data service layer limitations:

      • All tables must have a primary key.
      • Multi-column primary keys are not supported for base tables.
      • The default graph composer is only able to merge the result sets of the association SQL statements if these result sets do not fetch identical records from tables other than the base table.
      • If ordering of the result is necessary, it is recommended to use a single-step query.
      • The pagination parameters are always required for the sub noun-level pagination service.
      • Extensions to SOI service modules should not use the data service layer.
      • Extension to BOD service modules must exclusively use the data service layer.
      • Parametric search queries must use two-step queries.
      • You should not be using the EJB and data service layer persistence models in the same transaction.
      • You should never read or update the same data using the JDBCQueryService and the PhysicalDataContainer within the same transaction.

    • Important! Query template file names must be prefixed with wc-query and use the extension .tpl. For example, wc-query-MyCompanyCatalogEntry-get.tpl.
    • A query template file has five main sections, of which the first two are mandatory:
      • SYMBOL_DEFINITIONS defines column symbols that are used and referenced in the SELECT list of SQL template statements. There must be only one BEGIN_SYMBOL_DEFINITIONS, END_SYMBOL_DEFINITIONS block per query template file.
      • XPATH_TO_SQL_STATEMENT links the logical and physical layers by mapping an XPath key directly to an SQL statement. The name of the XPATH_TO_SQL_STATEMENT is the key of the XPath expression. If an XPath key is defined in more than one query template file, the one defined in the file last loaded overrides the others. There can be more than one BEGIN_XPATH_TO_SQL_STATEMENT, END_XPATH_TO_SQL_STATEMENT block.
      • ASSOCIATION_SQL_STATEMENT defines a specific SQL query. These queries can then be reused to build different access profiles that are defined in the PROFILE section. There can be more than one BEGIN_ASSOCIATION_SQL_STATEMENT, END_ASSOCIATION_SQL_STATEMENT block.
      • SQL_STATEMENT contains named SQL statements. The SQL statements are executed directly via the JDBC interface with the JDBCQueryService class. This class is similar to the session bean JDBC helper used by SOI service modules.
      • PROFILE defines access profiles that use associated SQL statements. If needed, more than one associated SQL statement can be used by a profile. Each associated SQL statement performs in turn and the results of the different associated SQL statements are merged together with a GraphComposer class. Queries that are associated with an access profile must always be defined in the same file where the access profile is defined. The exception for this definition location is when you extend an access profile. The extension mechanism provides you the capability to reuse the default associated SQL statements without having to redefine them in your custom query template file. There can be more than one BEGIN_PROFILE, END_PROFILE block. All the profile blocks have to be at the end of the file.
      • PROFILE_ALIASES define any aliases for profiles. The aliases have a global scope and are used for supporting deprecated access profiles that are renamed.
    • The data service layer supports two types of queries: single-step and two-step.
      • For single-step queries, the access profile name along with the XPath key is used to select a single XPath to SQL query to retrieve all the requested information. Multiple queries can retrieve different levels of detail for the same XPath expression and different access profiles.
        The following example defines a single-step query for the XPath key /Catalog[CatalogIdentifier[(UniqueID=))] and access profile IBM_Admin_Details:
        BEGIN_SYMBOL_DEFINITIONS
        	COLS:CATALOG=CATALOG:*
        	COLS:CATALOGDSC=CATALOGDSC:*	
        COLS:STORECAT=STORECAT:*
        
        END_SYMBOL_DEFINITIONS
        			
        BEGIN_XPATH_TO_SQL_STATEMENT
        	name=/Catalog[CatalogIdentifier[(UniqueID=)]]+IBM_Admin_Details
        	base_table=CATALOG
        	sql=
        		SELECT 
        			CATALOG.$COLS:CATALOG$,
        			CATALOGDSC.$COLS:CATALOGDSC$,
        			STORECAT.$COLS:STORECAT$
        		FROM
        			CATALOG
        				JOIN STORECAT ON STORECAT.CATALOG_ID=CATALOG.CATALOG_ID 
        					AND STORECAT.STOREENT_ID IN ($STOREPATH:catalog$)
        				LEFT OUTER JOIN CATALOGDSC ON CATALOGDSC.CATALOG_ID = 	CATALOG.CATALOG_ID 
        					AND CATALOGDSC.LANGUAGE_ID IN ($CONTROL:LANGUAGES$)
             WHERE
                CATALOG.CATALOG_ID IN (?UniqueID?)
        
        END_XPATH_TO_SQL_STATEMENT
        In the preceding example, the XPath expression queries the catalogs with specified unique identifiers and the IBM_Admin_Details access profile selects all columns from the CATALOG, CATALOGDSC, and STORECAT tables for these catalogs.
      • Two-step queries use the XPath to SQL statements and the association SQL statements. The XPath to SQL statements fetch the primary keys of the base objects that are of interest for search criteria specified by the XPath query. The association SQL statements, scoped by profile name, retrieve the information about those objects.
        The following example defines a two-step query for the XPath key /CatalogEntry[CatalogEntryIdentifier[(UniqueID=)]] and access profile IBM_Admin_CatalogEntryDescription:
        BEGIN_SYMBOL_DEFINITIONS
        	COLS:CATENTRY=CATENTRY:*
        	COLS:CATENTRY_ID=CATENTRY:CATENTRY_ID
        	COLS:CATENTDESC=CATENTDESC:*
        END_SYMBOL_DEFINITIONS
        
        BEGIN_XPATH_TO_SQL_STATEMENT
        	name=/CatalogEntry[CatalogEntryIdentifier[(UniqueID=)]]
        	base_table=CATENTRY
        	sql=
        		SELECT 
        			CATENTRY.$COLS:CATENTRY_ID$
        		FROM
        			CATENTRY
        			  JOIN STORECENT ON (CATENTRY.CATENTRY_ID = STORECENT.CATENTRY_ID 
        				AND STORECENT.STOREENT_ID = $CTX:STORE_ID$)
        		WHERE
                 CATENTRY.CATENTRY_ID IN (?UniqueID?) AND
                 CATENTRY.MARKFORDELETE = 0
        END_XPATH_TO_SQL_STATEMENT
        
        BEGIN_ASSOCIATION_SQL_STATEMENT
        	name=IBM_RootCatalogEntryWithDescription
        	base_table=CATENTRY
        	additional_entity_objects=true
        	sql=
        		SELECT 
        			CATENTRY.$COLS:CATENTRY$,
        			CATENTDESC.$COLS:CATENTDESC$
        		FROM
        			CATENTRY
        			    LEFT OUTER JOIN CATENTDESC ON CATENTDESC.CATENTRY_ID = CATENTRY.CATENTRY_ID 
        					AND CATENTDESC.LANGUAGE_ID IN ($CONTROL:LANGUAGES$)
        		WHERE
               CATENTRY.CATENTRY_ID IN ($ENTITY_PKS$)
        END_ASSOCIATION_SQL_STATEMENT
        
        BEGIN_PROFILE 
        	name=IBM_Admin_CatalogEntryDescription
        	BEGIN_ENTITY 
        		base_table=CATENTRY 	  
        		associated_sql_statement=IBM_RootCatalogEntryWithDescription
        	END_ENTITY
        END_PROFILE
        In the preceding example, the XPath to SQL statement is used to fetch the primary keys from the base table, CATENTRY. The base table for the XPath to SQL statement must be the same as the base table for the association SQL statement. The PROFILE section lists the associated SQL statements to run for the IBM_Admin_CatalogEntryDescription access profile. This example lists a single associated SQL statement, IBM_RootCatalogEntryWithDescription, which is run with the primary keys substituted for the $ENTITY_PKS$ tag to retrieve all the data requested by the original query.
    • Important! To enable optimistic concurrency control for custom tables, add an OPTCOUNTER column (of type SMALLINT or INTEGER) to the table. The column could be nullable.
    • In the WebServicesRouter project, ibm-webservices-ext.xmi file is used to specify security settings for Web services.
    • Important! In the WebServicesRouter project, ibm-webservices-bnd.xmi file maps Web services to the transport listeners found in the WebServicesRouter project.
    • Important! In order to test a WebSphere Commerce service with a unit test case, a CallbackHandler implementation is created where the user identity and password can be specified so the service is invoked under that identity.
    • WebSphere Commerce REST services are JAX-RS REST services that are built on top of Apache Wink. JSON is the only response format that is supported by the WebSphere Commerce search REST API by default.
    • Important! BOD command framework processing patterns: Get, Process, Change, Sync
    • When running a JUnit test case for a Business Object Document (BOD) in WebSphere Commerce Developer, TCP/IP monitor can be used to observe the request and response documents.
    • Important! Steps involved in extending OrderItem noun with UserData to include engraving information:
      1. Define engraving attributes in the PATTRIBUTE table.
      2. Extend OrderFacadeClient.java to expect new engraving attributes from the store. Extend ExtendOrderItemProcessCmdImpl.java (implements ExtendOrderItemProcessCmd) and ComposeOrderDetailsCmdImpl.java (implements ComposeOrderCmd+IBM_Details) to persist and retrieve the engraving information of an order item to the PATTRVALUE table.
    • Steps involved in extending OrderItem noun with Overlays to include engraving information:
      1. Define engraving attributes in the PATTRIBUTE table.
      2. Create an XSD file that extends the OrderItemType to include your new engraving attributes.
      3. Extend OrderFacadeClient.java to expect new engraving attributes from the store. Extend ExtendOrderItemProcessCmdImpl.java (implements ExtendOrderItemProcessCmd) and ComposeOrderDetailsCmdImpl.java (implements ComposeOrderCmd+IBM_Details) to persist and retrieve the engraving information of an order item to the PATTRVALUE table. Extend OrderFactoryImpl.java to override the order factory so that your customized OrderItemType is used.
      4. Add the overlay engraving objects to the mapping files: ChangeOrderSOIBODMapping.xml and component-services-user-template.xml
    • Customize the Catalog service to support warranty information and care instructions for catalog entries:
      • Warranty information is added to the CatalogEntry noun UserData element.
      • Product care instructions are added to the CatalogEntryDescription noun part attributes element.
      • <_cat:CatalogEntry catalogEntryTypeCode="ProductBean">
              <_cat:CatalogEntryIdentifier>
                <_wcf:UniqueID>10251</_wcf:UniqueID>
                <_wcf:ExternalIdentifier ownerID="7000000000000000101">
                  <_wcf:PartNumber>FULO-01</_wcf:PartNumber>
                </_wcf:ExternalIdentifier>
              </_cat:CatalogEntryIdentifier>
              <_cat:Description language="-1">
                <_cat:Name>White Fabric Roll Arm Chaise</_cat:Name>
                <_cat:Thumbnail>images/catalog/FULO_01_sm.jpg</_cat:Thumbnail>
                <_cat:FullImage>images/catalog/FULO_01.jpg</_cat:FullImage>
                <_cat:ShortDescription>Plumply padded for your ultimate comfort.</_cat:ShortDescription> 
                <_cat:Attributes name="catentryId">10251</_cat:Attributes>
                <_cat:Attributes name="languageId">-1</_cat:Attributes>
                <_cat:Attributes name="careinstruction">Warranty description for the chaise.</_cat:Attributes>
              </_cat:Description>
              <_wcf:UserData>
                <_wcf:UserDataField name="warterm">30</_wcf:UserDataField>
                <_wcf:UserDataField name="wartype">LIMITED</_wcf:UserDataField>
              </_wcf:UserData>
        </_cat:CatalogEntry>
      Steps:
      1. Customize WebSphere Commerce schema by adding new tables to store warranty and care instruction information: XWARRANTY->CATENTRY, XCAREINSTRUCTION->CATENTRY,CATENTDESC
      2. Use the Data Service Layer wizard to perform the following tasks:
        • Create an extension configuration folder for the Catalog service module: WC_eardir\xml\config\com.ibm.commerce.catalog-ext
        • Generate a custom object-relational metadata file that maps the database tables and columns to physical SDOs: WC_eardir\xml\config\com.ibm.commerce.catalog-ext\wc-object-relational-metadata.xml
        • Generate physical SDO Java classes and place them in the WebSphereCommerceServerExtensionsLogic project. Physical SDOs are service data objects that represent tables in WebSphere Commerce.
        • Create a utility Java class to return the physical SDO root class (and its package) for the service module.
        • Create an extension service module configuration file that instructs WebSphere Commerce to use the newly created catalog physical SDO class: WC_eardir\xml\config\com.ibm.commerce.catalog-ext\wc-component.xml
        • Create an extension business object mediator configuration file: WC_eardir\xml\config\com.ibm.commerce.catalog-ext\wc-business-object-mediator.xml.
      3. Create a custom get query template file: WC_eardir\xml\config\com.ibm.commerce.catalog-ext\wc-query-MyCompanyCatalogEntry-get.tpl
        • Create an access control policy for the new access profile declared in the get query template file so that all users have access to view the new data. By default, only the users with a site administrator role have access to the new data.
      4. Create a custom update query template file: WC_eardir\xml\config\com.ibm.commerce.catalog-ext\wc-query-MyCompanyCatalogEntry-update.tpl
        • Update wc-business-object-mediator.xml to instruct the Catalog service module to use the newly defined access profiles. This profile causes the Catalog service module to use the new queries, which include the custom tables, instead of the default queries provided by WebSphere Commerce.


  • WebSphere Commerce search programming model, extension points, and customization tasks > .... in Feature Pack 7 or later
  • Adding catalog entry properties to search rule actions or targets
  • Search properties in the component configuration file (wc-component.xml) (Search EAR)
  • Indexing profit margin data for use in dynamic product recommendation (FEP7)
  • Adding custom catalog entry information to WebSphere Commerce Search
  • Getting category navigation search rules to work with category facet displayable flag
  • Troubleshooting tips: Catalog storefront services > Error scenarios
  • [Exam notes]

    • Important! WebSphere Commerce search extension points:
      • An "expression provider" implements custom business logic for modifying the main search expression before it is sent to the search engine. Each expression provider can be separately registered to any search profile query section so that it can be reused for other search operations. That is, a search profile defines a list of search providers that are used for assembling the main expression for a search request.
      • A "query preprocessor" modifies the native SolrQuery object right before it is sent to the Solr server for processing.
      • A "query postprocessor" modifies the physical DataObject, SolrEntityContainerImpl, immediately after the QueryResponse is returned from the Solr server.
      • WebSphere Commerce search uses "search profiles" to control the storefront search experience at a page-level. Search profiles group sets of search runtime parameters such as search index name, search index fields, expression providers, query pre and postprocessors, paging and sorting, and search feature configurations such as text highlighting, facets, and spelling correction. Search profiles are defined in the WebSphere Commerce search configuration file (wc-search.xml).
    • Important! Troubleshooting Displayable flag not being considered when unset for a category in Management Center. For example, if you have a facet set as displayable, then for a particular category, you mark the facet as nondisplayable, it will still be displayed on the storefront.
      Solution: Create a custom query preprocessor to check and remove the nondisplayable facets.
    • Important! Adding new indexed catalog entry properties to search rule actions or targets:
      1. Register the new indexed catalog entry property in the SRCHATTR table.
      2. Specify the usage and data type of the property in the SRCHATTRPROP table.
      3. Specify the language sensitive display name of the added indexed catalog entry property in the SRCHATTRDESC table.
    • Important! Indexing profit margin data for use in dynamic product recommendation:
      • Update search schema (schema.xml) to include profit margin field.
      • Configure Data Import Handler mapping (wc-data-config.xml) to calculate profit margin and include it into the search index.
      • Important! Register profit margin as a new indexed catalog entry property in SRCHATTR, SRCHATTRPROP, and SRCHATTRDESC tables so that profit margin displays as a filter and sort criteria in product recommendations.
      • Modify user data field name mapping (wc-component.xml) to map the profit margin field to a user data.
      • Modify search configuration file (wc-search.xml) to let it return the value of the profit margin field in a new search profile.
      • Since the product recommendation widget uses the byIds service, add the custom search profile to the byIds service under productview (wc-rest-resourceconfig.xml).


    [Exam notes]

    • Important! Problem: A company is upgrading from Fix Pack 5 to Fix Pack 8. There is a power outage after ubdatdb utility has been running for several hours. After power is restored, ubdatedb utility is run again. It fails with an sql error code -612.
      Solution: It indicates ubdatedb utility has already ran. So, restore database and run ubdatedb utility again.
    • Important! Problem: A company wants to implement "Buy one Get one free" promotion where the free item will be determined by an external service.
      Solution: Extend OrderItemAddCmd/OrderCalculateCmd to call the external service. CartHandler will automatically recognize the extension.
    • Important! Problem: A multilingual site wants to display proprietary information (string & number type data) on product display page.
      Solution: Use CATENTDESC custom fields (field1, field2).
    • Important! Problem: A site wants to display up to 20 messages on product display page that can be used as engraving text.
      Solution: Create XCATENTRY table, create access bean/data bean to fetch information from the table.
    • Important! Problem: A site uses WebSphere Commerce Search and is storing product loyalty points in CATENTRY.FIELD1. Which components need to be modified to display this information on product display page via search?
      Solution: schema.xml, wc-data-config.xml, <_config:result ....> in wc-search.xml
    • Important! Problem: A site wants to customize user registration use case by capturing special occasion date (eg, anniversary date) and special occasion description. Which components need to be modified?
      Solution: struts-config-member-services.xml, UserRegistrationAddCmd
    • Important! Problem: An application developer has been asked to remove the "No Inventory" option from Store Publish Wizard. Which file should be modified?
      Solution: store-refs.xml


2 comments:

  1. Thanks for sharing very good information about OCI Punchout.
    OCI Punchout

    ReplyDelete
  2. Appreciate you sharing, great article post.Really looking forward to read more. Cool.
    etl testing online courses

    ReplyDelete