Friday, 12 July 2019

WCS Webactivity not working properly for Customer segments

This problem is related to personalizationID. If
personalizationID is not updated, the activity will treat it as
same user and will be applied. So changing to a new
personalizationID is the solution. A new configuration is
introduced in instance xml. If configured, the new
personalizationID will be created in WC_PERSISTENT cookie when
the user logs off. By default, it is not configured and the
personalizationID will still be the same as original one.

To enable it, need to add "logoffRefresh="true"" element in
instance xml. See the following:
 <PersonalizationId display="false" enable="true"
logoffRefresh="true"/>

Friday, 6 April 2018

Add WCS v8 Search Rest Resource Customization in Search-Rest project


Add custom search profile in wc-rest-resourceconfig.xml for a rest resource

1. Create folder com.ibm.commerce.rest-ext in /Search-Rest/WebContent/WEB-INF/config/
2. Create wc-rest-resourceconfig.xml file in folder com.ibm.commerce.rest-ext
3. Add Resource as below
<ResourceConfig>
    <Resource name="sitecontent">
        <GetUri uri="store/{storeId}/sitecontent/keywordSuggestionsByTerm/{term}"
                description="Get keyword suggestions."
                defaultSearchProfile="true" searchProfile="X_IBM_findNavigationSuggestion_Keywords"/>                       
    </Resource>
</ResourceConfig>

4. Make sure that defaultSearchProfile attribute is set as true if you want to make X_IBM_findNavigationSuggestion_Keywords as default searchProfile for this rest resource
5. If you don't add defaultSearchProfile as true then WCS search will use searchProfile for original rest resource defined in wc-rest-resourceconfig.xml under com.ibm.commerce.rest folder

Tuesday, 10 January 2017

Apache HTTP Server Rewrite Rules Basics

Apache Rewrite Rules Basics:

Note : Please note rewrite rules are evaluated first and then conditions staring from first condition. 

Syntax Example (301 Redirect of a a request to old host to new host):

RewriteCond %{REQUEST_URI} ^/hello1/hello2/*
RewriteCond %{HTTP_HOST} ^([a-z]{2})\.([a-z]+)\.xyz\.com
RewriteRule ^/(hello1)/(hello2)/* http://www.%2.xyz.com/$1/$2 [R=301,L]

# Note: 1 %n (where n could be any numeric from 1 to 9) is backreference notation which contains matched group value in the right hand side of the last RewriteCond part,in above example %2 is value of host which matches regex condition ([a-z]+)
#Note2 : $n (where n could be any numeric from 1 to 9) is backreference notation which contains matched group value in the left hand side of the RewriteRule part,in above example $1 is hello1 and $2 is hello2

List of Specific Characters Set in RewriteCond or RewriteRule :

RewriteCond %{REQUEST_URI} ^/(en|ca|it|fr)\-(us|ca|it|fr)/*
RewriteRule ^/(en|ca|it|fr)\-(us|ca|it|fr)/* http://www.xyz.$2 [R=301,L]

#Note: en-it or en-ca or any combination of above characters list will match the regex condition in RewriteCond and RewriteRule

White List of to allow a specific site access and block remaining:

RewriteCond %{HTTP_HOST} ^www\.xyz\.com
RewriteCond %{REMOTE_ADDR} !^aa.bb.cc.dd$
RewriteCond %{REMOTE_ADDR} !^aa1.bb1.cc1.dd1$
RewriteRule ^/* http://www.abc.com [R=301,L]

#Note: In above rewrite rule any request coming to host www.xyz.com will be redirected to host  http://www.abc.com unless requst is coming from above list public ip addresses aa.bb.cc.dd or aa1.bb1.cc1.dd1

URL Masking or Reverse Proxy:
Accessing a site xyz.com but internally it is serving content from internal site abc.com or in other way redirected to site abc.com however browser host url in will not be changed to abc.com. Example

RewriteCond %{HTTP_HOST} !^www\.xyz\.com
RewriteCond %{REQUEST_URI} ^/proxy$
RewriteRule ^(.*) http://www.abc.com$1 [P,L]

#Note: In above request url www.xyz.com/proxy will be internally redirected to site http://www.abc.com/proxy but in browser address bar we still see url www.xyz.com/proxy. Here config flag [P] is important as this flag is meant for proxy.

Friday, 27 May 2016

Format currency in WCS backend business logic instead of using JSTL tag in jSP



NumberFormat formatter = null;
formatter= NumberFormat.getCurrencyInstance(getCommandContext().getLocale());
               
DecimalFormat df = (DecimalFormat)formatter;
DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

dfs.setCurrencySymbol(getCurrencySymbol());
df.setDecimalFormatSymbols(dfs);
               
String formattedAmoun= df.format(amount);

Tuesday, 12 April 2016

WCS Web Activity Caching Issue

 If you have whole page cache setup for CategoryDisplay pages or any other pages and one of the eSpots on these pages used for creating web activities and this web activity for content recommendation does work when  you visit the page first time and once it is cached next hit to this page does not display the correct content as per web activity evaluation logic then possible cause could be your cachespec.xml config issue. Make sure that cache-entry for CategoryDisplay cache-id or any other cache-id setup for whole page cache (i.e. consume-subfragments is set to true) below  attributes highlighted in RED colour are excluded from save-attributes= false property list.

<cache-entry>
<class>servlet</class>
<name>com.ibm.commerce.struts.ECActionServlet.class</name>
<property name="consume-subfragments">true</property>
<property name="save-attributes">false
<exclude>jspStoreDir</exclude>
<exclude>javax.servlet.forward.path_info</exclude>
<exclude>requestURIPath</exclude>
<exclude>requestServletPath</exclude>
</property>
              <cache-id>
<component id="" type="pathinfo">
<value>/CategoryDisplay</value>
<required>true</required>
</component>
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
<component id="DC_lang" type="attribute">
<required>true</required>
</component>
<component id="categoryId" type="parameter">
<required>true</required>
</component>
<component id="top_category" type="parameter">
<required>false</required>
</component>
<component id="parent_category_rn" type="parameter">
<required>false</required>
</component>
</cache-id>
<cache-entry>


Issue is that if whole page is cached then request to that page will be served directly from dynacache sever and backend controller command will not be executed. In this case WCS marketing engine uses command URL (e.g. CategoryDisplay) to execute the web activity target condition and for this to be executed correctly cached page must persist above mentioned request attributes for each category. This is specially applicable for web activities where target conditions are like customer views a specific category for example brake pads then recommend some content for eSpot.

Monday, 14 March 2016

How to run a .sql file from java process specially if data is huge in the database and jdbc connections time out due to long running query




private  void extractDataInCsv() {

    try {
   
   
    File file = new File(this.getClass().getResource("/com/ibm/commerce/data/OrdersDataExtract.sql").toURI());

       
        Runtime rt = Runtime.getRuntime();
        String  executeSqlCommand= null;
       
        if(getRequestProperties().getBoolean("localDev",false)){
        executeSqlCommand = "db2cmd /c /i /w && db2 -tvf "+file.getAbsolutePath(); // local dev  windows
        }else{
        executeSqlCommand = "db2 -vf "+file.getAbsolutePath();  // linux
        }
       
        Process pr = rt.exec(executeSqlCommand);
       
        BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
    System.out.println(line);
 }
//pause for 15se
Thread.sleep(15000);
       
     } catch (Exception e) {
     e.printStackTrace();
     }
}

Script in OrdersDataExtract.sql is as follows:


connect to dbname user dbusername using password
set schema db2inst1

-- extract data
EXPORT TO /opt/IBM/WebSphere/AppServer/temp/OrdersDataExtract.csv OF DEL MODIFIED BY NOCHARDEL striplzeros decplusblank select with ur
terminate


Friday, 11 March 2016

ShippingModeListDataBean does not return Shipping modes and Charges


If store reference data is all setup correctly and ShippingModeListDataBean still does not return allowed shipping modes and corresponding charges for a store then potential root cause could be that the shipping calcode for all products is not set for in table CATENCALCD.
A row in this table indicates that a CalculationCode is attached to a CatalogEntry. And it is also attached to the CatalogEntry's PRODUCT_ITEM children (or all CatalogEntries) for the specified Store. And also it is attached to TradingAgreement (or all TradingAgreements).

WCS applyCalculation Charges logic looks for indirectly attached calcode for a product and for that it looks into this table. There could also be directly attached calcode for 10% off promotion applied to a specific product then this calcode is attached to product directly.

How to customize java.util.logging.Logger class to write logs in separate file than System.out.log in Websphere commerce/ HCL commerce)

/** * This method updated the passed in java.util.logging.Logger object with * custom file handler to write logs data form that class ...