Showing posts with label IBM WCS. Show all posts
Showing posts with label IBM WCS. Show all posts

Tuesday, February 4, 2014

Improve performance through Dynamic Cache – Overview

This content is taken from my company blog written by me
http://blogs.perficient.com/ibm/2014/02/04/improve-performance-through-dynamic-cache-overview/

When you go to restaurant and you came to know you have to wait for a while to get your table, will you wait or will you go to another restaurent where you are aware that there is no wait time and have same quality of food. You would prefer second restaurant to first. You feel like buying a head set for long time, it is one of the item in your must have list. On this intention you went to online store and start browsing for head set. What if that online store took 3 minutes to show the product? Will you wait for product to load or go to another web site that is much quicker to previous one? Second site is winner here.
Faster response time on online store has to be considered as a service provided by the online store and give much importance for better service to customer.
Websphere commerce addressed this faster response by introducing Dynamic Cache. Caching will maximize the performance and minimize the load on server. Let us dive little deep to understand what different types of content are in an online store and high level details configuration elements.
Online store contains static content and dynamic data. Static content consist of HTML,images,CSS and java scripts, Whereas dynamic data contains results that are retrieved from Websphere commands (from database tables ,properties and code). What is the best way to improve performance? Simplest way to ask, is the data I see online is retrieved from nearest place from browser or it is retrieved by passing through several components. For example, When user access head phone product, Server sends images to browser and it is stored in local machine. So on second visit, images will be displayed much faster than first time. Nearer to browser better the performance.
Cache id:
Websphere commerce (WC)saves the every cacheable object in terms of cache id. When I access head phones product , let’s say server requires store id and category id. WC creates a cache id with store id and category id and save the data in cache tables. Next time if any one try to access same product on same store ( same store id and category id) . WC will return the data much faster from cache by cache id.
Cache Invalidation:
Assume every 5 hours image of the head phones is chaging. One of determining for how long we can have the present image in cache for faster response. After 5 hours this cache object will be dropped and new cache id is created with new content. We can invalidate by time,any custom rule or dependency based.You can even invaidate cache manually.
Static Caching:
In WC , we can cache either full page or part of a page. For example, in product display page only content that might be changing is list of products and price of the products. Header,footer and menu will not be changed. In this case we can cache only these three.Where as in login, contact us page or about us page, Entire page can be cacheable.
Dynamic Caching:
Dynamic caching allows to cache servlet caching i.e servlets,jsps,Struts . It allows object caching, which is used to store, distribute and share java objects.
Where will we set the rules or policies to tell WC what have to be cached? Answer is cachespec.xml. cachespec.xml is the place where we can define following information
  • What static/dynamic objects to cached
  • On what bases WC have to cache
  • When to drop the cache object
  • How each Cache entry is related ( dependency cache objects might be present)
By now you understood that WC performance can be improved through caching and basics of caching. What has to be considered for designing caching for a page. To get more details on dynamic caching and configure cachespec.xml you can go through “Mastering DynaCache in Websphere Commerce

Monday, January 27, 2014

Order Management Sub System - Order Processing - Part 1



When ever we submit order, There are several action WC considers to complete the submission.
  1.  Order Process command is triggered.
  2. If BusinessFlowEventListener component is enabled in ws-server-*.xml, unified business function will be called.
  3. Flow type is OrderProcess . ProcessOrderCmdImpl task command is called.
In BusinessFlowEventListener
  • Execute OrderProcessPreApprovalCmd, which invokes PreProcessOrderCmd
  • Execute OrderProcessCheckApprovalCmd to check whether approval is required
  • Execute OrderProcessPostApprovalCmd, which invokes ProcessOrderCmd
         4.  ProcessOrder command will do inventory check , payment finalization, tax calculation to complete the order.

    Note:

    If your store does not require approval of the order, You do not require Business Flow. Set BusinessFlowEventListener to false in ws-server.xml. This will call processOrderCmd Directly.

    Wednesday, December 25, 2013

    Webshere Commerce - Data Cache (Part 3) - wc-server.xml


    Populating data in CacheIVL: <WCD>\schema\db2\wcs.cacheivl.trigger.sql will do the job of copulating cache table when ever there is a add,delete and update.

    Configure wc-server.xml:
    Ensure that you have the following element in wc-server.xml under instanceProperties element

    <CrossTransactionCache
                clearCacheOnMaxInvalidationIdsPerTransaction="false"
                clearUserDataCacheOnLogoff="false" clearUserOnLogoff="true"
                commandCaching="default" defaultResultSizeThreshold="8"
                enabled="true" maxInactivityTime="86400"
                maxInvalidationIdsPerTransaction="100000"
                maxTimeToLive="172800" reduceInvalidationIds="false" reduceMemory="false">
                <WCSystemDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>
                <com.ibm.commerce.user.objsrc.OrganizationCache enabled="true"/>
                <com.ibm.commerce.taxation.objsrc.CountryCache enabled="true"/>
                <com.ibm.commerce.taxation.objsrc.StateProvinceCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.MemberGroupCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.RoleCache enabled="true"/>
                <com.ibm.commerce.fulfillment.objsrc.ShippingModeCache enabled="true"/>

                <com.ibm.commerce.fulfillment.objsrc.ShippingModeDescriptionCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.StoreEntityDescriptionCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.CurrencyCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.CurrencyDescriptionCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.LanguageCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.LanguageDescriptionCache enabled="true"/>
                <com.ibm.commerce.catalog.objsrc.CatalogCache enabled="true"/>
                <com.ibm.commerce.catalog.objsrc.CatalogDescriptionCache enabled="true"/>
                <com.ibm.commerce.common.objsrc.SupportedLanguageCache enabled="true"/>
                <com.ibm.commerce.fulfillment.objsrc.FulfillmentCenterCache enabled="true"/>

                <com.ibm.commerce.attachment.beansrc.AttachmentRelationUsageCache enabled="true"/>

                <com.ibm.commerce.attachment.beansrc.AttachmentRelationUsageDescriptionCache enabled="true"/>

                <com.ibm.commerce.infrastructure.facade.server.commands.CreateAttachmentUsageConfigurationCmdImpl enabled="true"/>
                <com.ibm.commerce.user.beansrc.PolicyAccountCache enabled="true"/>
                <com.ibm.commerce.user.beansrc.PolicyAccountLockoutCache enabled="true"/>
                <com.ibm.commerce.user.beansrc.PolicyPasswordCache enabled="true"/>
                <WCSessionDistributedMapCache enabled="true"
                    maxInactivityTime="900" maxTimeToLive="172800" reduceMemory="false"/>

                <com.ibm.commerce.component.contextservice.commands.ContextDataSerValueCacheCmdImpl enabled="true"/>
                <WCContractDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>
                <com.ibm.commerce.contract.beansrc.BusinessPolicyCache enabled="true"/>
                <com.ibm.commerce.contract.beansrc.PolicyDescriptionCache enabled="true"/>
                <WCPromotionDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>
                <com.ibm.commerce.fulfillment.objsrc.CalculationCodeCache enabled="true"/>

                <com.ibm.commerce.fulfillment.objsrc.CalculationCodeDescriptionCache enabled="true"/>

                <com.ibm.commerce.tools.epromotion.objimpl.CalculationCodePromotionCache enabled="true"/>

                <com.ibm.commerce.marketing.promotion.AbstractPromotionSessionBeanPersistenceManager enabled="true"/>

                <com.ibm.commerce.marketing.promotion.group.PromotionGroupSessionBeanPersistenceManager enabled="true"/>

                <com.ibm.commerce.marketing.promotion.policy.PromotionPolicySessionBeanPersistenceManager enabled="true"/>

                <com.ibm.commerce.marketing.promotion.runtime.ShopcartDrivenAgendaBuilder.SHOPCART enabled="true"/>

                <com.ibm.commerce.marketing.promotion.runtime.ShopcartDrivenAgendaBuilder enabled="true"/>
                <WCMarketingDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>

                <com.ibm.commerce.tools.campaigns.CampaignInitiativeEvaluateCmdImpl enabled="true"/>

                <com.ibm.commerce.marketing.commands.elements.DisplayMerchandisingAssociationActionTaskCmdImpl.MASSOCCECE enabled="true"/>

                <com.ibm.commerce.marketing.commands.elements.DisplayMerchandisingAssociationActionTaskCmdImpl enabled="true"/>
                <com.ibm.commerce.marketing.dialog.util.MarketingUtilCatalog enabled="true"/>
                <WCUserDistributedMapCache enabled="true"
                    maxInactivityTime="900" maxTimeToLive="172800" reduceMemory="false"/>

                <com.ibm.commerce.membergroup.commands.ListMemberGroupsForUserCmdImpl enabled="true"/>
                <com.ibm.commerce.user.objsrc.DemographicsCache enabled="true"/>
                <com.ibm.commerce.dynacache.commands.MemberGroupsCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.MemberGroupMemberCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.MemberRelationshipsCache enabled="true"/>

                <com.ibm.commerce.user.beansrc.MemberRelationshipsExtendedCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.MemberRoleCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.MemberCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.UserCache enabled="true"/>
                <com.ibm.commerce.user.objsrc.UserRegistryCache enabled="true"/>

                <com.ibm.commerce.accesscontrol.policymanager.CommandLevelAuthorizationCache enabled="true"/>

                <com.ibm.commerce.accesscontrol.policymanager.ParentOrganizationCache enabled="true"/>

                <com.ibm.commerce.marketing.promotion.runtime.PromotionArgumentSessionBeanPersistenceManager enabled="true"/>
                <WCCatalogGroupDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>
                <com.ibm.commerce.catalog.objsrc.CatalogGroupCache enabled="true"/>

                <com.ibm.commerce.catalog.objsrc.CatalogGroupDescriptionCache enabled="true"/>
                <com.ibm.commerce.catalog.beansrc.CatalogGroupRelationCache enabled="true"/>
                <WCCatalogEntryDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>

                <com.ibm.commerce.fulfillment.objsrc.CatalogEntryShippingCache enabled="true"/>
                <com.ibm.commerce.catalog.objsrc.CatalogEntryCache enabled="true"/>

                <com.ibm.commerce.catalog.objsrc.CatalogEntryDescriptionCache enabled="true"/>
                <com.ibm.commerce.catalog.objsrc.ItemCache enabled="true"/>
                <com.ibm.commerce.catalog.objsrc.ProductCache enabled="true"/>
                <com.ibm.commerce.catalog.util.CatalogHelperCache enabled="true"/>

                <com.ibm.commerce.catalog.beansrc.CatalogGroupCatalogEntryRelationCache enabled="true"/>
                <WCPriceDistributedMapCache enabled="true"
                    maxInactivityTime="86400" maxTimeToLive="172800" reduceMemory="false"/>
                <com.ibm.commerce.catalog.beansrc.ListPriceCache enabled="true"/>
                <com.ibm.commerce.order.objsrc.OfferCache enabled="true"/>
                <com.ibm.commerce.order.objsrc.OfferPriceCache enabled="true"/>
                <com.ibm.commerce.price.commands.RetrievePricesCmdImpl enabled="true"/>
            </CrossTransactionCache>


    After configuring distirbutedMap on server. You should see following logging statements in sysouts

    ResourceMgrIm I   WSVR0049I: Binding WCUserDistributedMapCache as services/cache/WCUserDistributedMapCache
    ResourceMgrIm I   WSVR0049I: Binding WCSessionDistributedMapCache as services/cache/WCSessionDistributedMapCache
    ResourceMgrIm I   WSVR0049I: Binding WCCatalogEntryDistributedMapCache as services/cache/WCCatalogEntryDistributedMapCache
    ResourceMgrIm I   WSVR0049I: Binding WCCatalogGroupDistributedMapCache as services/cache/WCCatalogGroupDistributedMapCache
     This means all the configured distirbutedMaps are active now.


    This will ensure all the settings regarding the data cache is completed. Still i have to find if WC is considering cacheivl? is the invalidation schedule job provided by the IBM is working? why i ask this question is simple. Trigger ran twice for catalog table and there is double data in cacheivl. when i ran invalidation job. data was not removed from cacheivl. If any one know more on this please share.

    Tuesday, December 24, 2013

    Webshere Commerce - Data Cache (Part 2) - Enabling and configuring distributedMap

     There are two ways to configure data cache

    • By creating cacheinstance.properties
    • By configuring on application server.  This is discussed below

      Step By Step setup:

    • Step 1: Click on Object Cache instances
    • Step 2: Click New
    • Step 3: Get the distributed Map you want configure (here)
    • Step 4: Here i am setting properties for a single JVM . JNDI has to be services/cache/distributedMapName ( you will get that from Step 3)

    Monday, December 23, 2013

    Websphere Commerce Data Cache (Part 1) - Distribution Maps


     In Data Cache we have to know what distribution mapping has to be configured for caching.We cover how to configure in a while. Before configuring we need to know what are the distribution maps available.


    WCContractDistributedMapCache, WCSystemDistributedMapCache

    Cache any system data like Organization, Country, StateProvince,MemberGroup, Role, ShippingMode, Currency,Language, BusinessPolicy


    WCPromotionDistributedMapCache, WCMarketingDistributedMapCache

    These distribution maps will cache marketing and promotional data like CalculationCode, Promotion, PromotionGroup, PromotionPolicy, MerchandisingAssociation


    WCCatalogGroupDistributedMapCache

    This will cache catalog Group related data like CatalogGroup, CatalogGroupRelation


    WCCatalogEntryDistributedMapCache, WCPriceDistributedMapCache

    Catalog Entry related data will be cached for this distribution Map like Item, Product, Shipping, Price.


    WCUserDistributedMapCache, WCSessionDistributedMapCache

    User and session related data like user related and session related data


    WCFlexFlowDistributedMapCache,WCSearchxxxDistributedMapCache,WCSEOxxxDistributedMapCache

    Some Essential data.

    Note: Command caching is enabled using cachespec.xml

    How to configure distributedMap data cache on server? Click here

    Reference:




    Friday, December 20, 2013

    Caching intro


    Well .. before i started going through the websphere commerce caching features. I was under assumption only JSPs, Static content only can be cached for easy access.

    IBM Websphere commerce cache almost everything like JSP, Sevlets, Commerce commands.
    What are other features IBM WC provides for caching?
    • IBM WC verifies if content of cache is valid . And this validation is run on rule based, time based , group based(What is this? got to find out)  and programmatic.
    • If you have multiple servers it can replicate caching on all the servers.
    • When you are restarting server large chunk of cache will be preserved to reused after restart. ( this is really news to me. Most of the time we restart server to ensure there is no cache is present on server. IBM WC does a smart saving of cache) So next time if you are still seeing old data after restart remember to clear cache using cache monitor.

    Now question is how are we going to enable above features and where. Here is the answer cachespec.xml

    Based on type of content some content of data can be cached at browser level , If data is more secured then cache data at server level ( more secure) . IBM WC can cache full page or partial page based on what you define.

    I will cover Cachespec.xml and how to utilize better caching.



    Sunday, November 17, 2013

    Configuring inbound messages


    When I am new to WC environment. My first challenging task was to provide inbound message to our SAP team.
    Given the fact that i am not new to integration, I know exactly what has to be done in typical J2EE environment but not in WC environment.

    In typical J2EE environment, First i will design what should be the XML format, Then configuration MQ and many more based on the requirement. But in WC XML format is available for most of the requirements.

    WC provide XML format for following functionalities.
    1. Create/Update Customer
    2. Update order status
    3. Update product inventory
    4. Create pick batch
    5. Inquire PickpackList details
    6. Inventory Reciept
    7. Expected inventory record
    8. Shipment confirmation
    9. Price and availability
    10. Shopping cart transfer
    11. Batch availability

    All the files has to adhere to the definitions given by WC. To know in details

    wc-server.xml:

    In wc-server.xml search for "Messaging" you will see

    <Messaging
                EcInboundMessageDtdFiles="NCCommon.mod, NCCustomer_10.mod, Create_NC_Customer_10.dtd, Update_NC_Customer_10.dtd, Update_NC_OrderStatus_10.dtd, Update_NC_ProductInventory_10.dtd, Update_NC_ProductPrice_10.dtd, Create_WCS_Customer_20.dtd, Create_WCS_Customer_30.dtd, Update_WCS_Customer_20.dtd, Update_WCS_Customer_30.dtd, Update_WCS_OrderStatus_20.dtd, Update_WCS_ProductPrice_20.dtd, Inquire_WCS_PickPackListDetail_10.dtd, Create_WCS_PickBatch_10.dtd, Create_WCS_ExpectedInventoryRecord_10.dtd, Create_WCS_InventoryReceipt_10.dtd, Update_WCS_InventoryReceipt_10.dtd, Create_WCS_ShipmentConfirmation_10.dtd, Create_WCS_ShipmentConfirmation_20.dtd, Update_WCS_ProductInventory_20.dtd, Request_WCS_BE_ProductInventory_10.dtd, Update_WCS_OrderStatus_30.dtd, Update_WCS_PriceAndAvailability_10.dtd, Update_WCS_ShoppingCartTransfer_10.dtd, Update_WCS_BatchAvailability_10.dtd"
                EcInboundMessageDtdPath="messaging"
                EcMimePropFile="lang_mime.data"
                EcSystemTemplateFile="sys_template.xml"
                EcTemplatePath="messaging"
                EcUserTemplateFile="user_template.xml" XMLWebControllerUserId="wcsadmin"/>
     EcInboundMessageDtdFiles gives information on what all definitions are available in WC.
     EcInboundMessageDtdPath gives where these files are present
     EcSystemTemplateFile gives the mapping between dtd file and parameters we can use in the code.
     EcUserTemplateFile : If you want to update any parameter in sys_template.xml , Copy entire template to user_template.xml and modify in this file. Do not modify anything in sys_template

    Lets take and example and see understand what is happening.

    Consider your procurement team found a particular order has to be returned/refund. Procurement has to send message to WC.

    How should be the structure of xml? Open Update_WCS_OrderStatus_20.dtd . This file give the definition of how should the xml looks like.

    After procurement team creates the xml and send to WC. WC reads the understands the xml. But how would we access the values defined in the xml? for that
    Open sys_template.xml and search for Update_WCS_orderstatus and consider the version in TemplateDocument/DocType version attribute is has to be 2.0

    Now you understand name of the dtd and name inside the sys_template.xml are related for understanding purpose.

    Lets go little depth to understand sys_template:

    <TemplateDocument>
            <DocumentType version='2.0'>Update_WCS_OrderStatus</DocumentType>
            <StartElement>Update_WCS_OrderStatus</StartElement>
            <TemplateTagName>OrderStatus20Map</TemplateTagName>
            <CommandMapping>
                <Command CommandName='OrderConfirmStatus' Condition='OrderConfirmCommand' />
                <Command CommandName='OrderShippingStatus' Condition='OrderShippingCommand' />
                <Command CommandName='OrderInvoiceStatus' Condition='OrderInvoiceCommand' />
                <Command CommandName='OrderStatus' Condition='OrderStatusCommand' />
            </CommandMapping>

    </TemplateDocument>

    Notice TemplateTagName element in above example. This element states that refer to
    <TemplateTag name='OrderStatus30Map'> in sys_template for relation between DTD and WC parameters.

    Lets take a tag
    <Tag XPath='DataArea/OrderStatus/OrderStatusItem/TotalPriceInfo/TotalNetPrice' Field='priceTotal' />

    This tag states value under Xpath DataArea/OrderStatus/OrderStatusItem/TotalPriceInfo/TotalNetPrice  is present in priceTotal parameter.

    Lets move to CommandMapping element:

     Below tag defines, If xml contains XPath = DataArea/OrderStatus then OrderStatusCommand condition matches with commandName OrderStatus

     <Tag XPath='DataArea/OrderStatus' Field='OrderStatusCommand' FieldInfo='COMMAND' />

     To know what command will be triggered for OrderStatus , Search in struts-config.xml for "/OrderStatus", by this you will know what command is called.

    For customizing extend the command the command and overwrite

    public  boolean doProcess(TypedProperty typedproperty)

    typedproperty contains the properties that are defined in sys_template.xml

    To find outbound messages OOTB provides click here

    Wednesday, November 13, 2013

    The user does not have the authority to run this command "com.ibm.commerce.user.beans.OrganizationDataBean".





    Issue:

    javax.servlet.ServletException: com.ibm.commerce.exception.ECApplicationException: The user does not have the authority to run this command "com.ibm.commerce.user.beans.OrganizationDataBean".


    How to Replicate:
    There could be several scenarios to replicate this. This is one scenario to replicate.

    1. Register user  to an organization say Organization X.
    2. In Organization console give privileges to user as buyer for organization Y.
    3. Now log on to your storefront and change the role of user with which he is buying the products ( In this case Organization Y). This step may not be present for all the sites. Point to note is User has to place an order as buyer for organization Y.
    4. Now in any of the jsp/class try to access OrganizationDataBean by using the organization user registered with ( In this example: Organization X)
    For example,
    I was using this below code

    UserRegistrationDataBean buyurdb=new UserRegistrationDataBean();
        buyurdb.setUserId(requisitionerId);
        com.ibm.commerce.beans.DataBeanManager.activate(buyurdb, request);
     
        OrganizationDataBean buyorgdb = new OrganizationDataBean();
        buyorgdb.setInitKey_MemberId(
    buyurdb.getOrganizationId());
         com.ibm.commerce.beans.DataBeanManager.activate(buyorgdb, request);


    Cause:
    If you notice USERREG table has the data stating this user is registered to Organization X, But not the role with which he is buying in the storefront.

    Fix: 
    My objective was to get the organization information with which user placed the order. When user place the order , organization id will be stored in ORDERS table. Get the organization id from ORDERS table instead of UserRegistationDataBean.

     OrganizationDataBean buyorgdb = new OrganizationDataBean();
        buyorgdb.setInitKey_MemberId(
    buyurdb.getOrganizationId()); --Member id has to get from ORDERS table
         com.ibm.commerce.beans.DataBeanManager.activate(buyorgdb, request);