Thursday, January 8, 2015

Finally Enabling multiple logon for the same user | Available from Fix pack 9


This was something that was not available for a long time but with the new fix pack. This is available. I might have an old blog where i had mentioned, it was not available in the previous versions.

Many WebSphere Commerce websites are using REST services to serve both mobile and desktop pages then it's important to allow multiple logon for the same user from different channels in a simple way. To activate this feature a specific tag should be added to the wc-server.xml in the SessionManagement section

<allowmultiplelogonforsameuser display="false" enabled="true"></allowmultiplelogonforsameuser>

Tuesday, January 6, 2015

Performance Improvements StringBuilder and ArrayList and HashMap

Use StringBuilder if Synchronization is not required.

I have used StringBuffer when performing concatenations on string and is far better than using Immutable Strings in Java but if you don't need the synchronization, which most likely could be the case so use StringBuilder

Quote from StringBuilder API:
This class [StringBuilder] provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

Using ArrayList vs LinkedList

LinkedList is great when you don't know the size of the list as it helps.

The default initial capacity of an ArrayList is pretty small (10 from Java 1.4 - 1.7).
But since the underlying implementation is an array, the array must be re-sized if you add a lot of elements.
To avoid the high cost of resizing when you know you're going to add a lot of elements, construct the ArrayList with a higher initial capacity. What's important is to initialize the list when you know upfront the size of the ArrayList and if it is going to be more than 10

List catalogDataVOList = new ArrayList<CatalogDataVO>((int) resultCount);

Reference: http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist

Use HashMap vs Hashtable:
If Synchronization is not required use HashMap, Hashtable is a syncrhonized version and typically non synchronized objects perform better.

Wednesday, November 19, 2014

Tuning cache size and disk offload and disk cache size | Dynacache

Default cache size is 2000 and for production environments, it should be tuned to 10000 and this value would work in most cases.

It is a good idea to check enable disk offload in production environment. As the cache size exceeds the limit, it would offload to disk
Also make sure the disk in production environment has space allocated for this disk offload and 10 GB for production environment would be a good range in production. Make sure this setting is replicated on all application servers.



Tuesday, November 18, 2014

JVM Settings | Tuning heap size


It is very important to tune heap size with correct values in production.
Default values are minimum 256 MB and maximum heap size of 1024 MB.  For production environments the values are ideally around minimum heap size 4GB (4096m) and max heap size 6GB(6144m)
e.g.
java -Xmx6144m -Xms4096m

Application Server
In the Administration Console select Servers
Expand Server Type and select WebSphere application servers
Click on the name of your server
Expand Java and Process Management and select Process Definition






Thursday, November 13, 2014

OverRide OOB outbound order XML to write to a table !!

If we need OverRide OOB outbound order XML process to write to a table, please find the below steps:

1. Create an EJB for a custom table XOrderTransfer table.
2. Override wc-component-client.xml as mentioned below
3. Override class as mentioned below.
4. In WC adminconsole, set up a broadcast job for the command "RaiseECEvent"

OverRide XML:
C:\IBM\WCDE_ENT70\workspace\WC\xml\config\com.ibm.commerce.order.external-ext\wc-component-client.xml

<_config:DevelopmentClientConfiguration xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../xsd/wc-component-client.xsd">
<_config:invocationservice>

<_config:invocationbinding
bindingImpl="com.custom.commerce.foundation.internal.client.services.invocation.impl.CustomJCAInvocationBindingImpl">
</_config:invocationbinding>

<_config:action name="ProcessOrder" asynchronous="false">
</_config:action>

</_config:invocationservice>
</_config:DevelopmentClientConfiguration>


public class CustomJCAInvocationBindingImpl extends JCAInvocationBindingImpl implements InvocationBinding {

public InvocationServiceObject invoke(Action action, InvocationServiceObject requestDataObject) throws InvocationServiceException {
final String methodName = "invoke";
LOGGER.entering(CLASSNAME, methodName);
String inputXML = new String(requestDataObject.getXML());
//get the orderId from the request data object
ProcessOrderType processOrderType = (ProcessOrderType) requestDataObject.getDataObject();
OrderType currentOrder = (OrderType)processOrderType.getDataArea().getOrder().get(0);
String orderId = currentOrder.getOrderIdentifier().getUniqueID();
Long orderIdLong = new Long(orderId);

//persist the order XML in the XORDERTransfer table.
XOrderTransferAccessBean orderTransferAB = new XOrderTransferAccessBean(orderIdLong, inputXML);
orderTransferAB.setInsertedTime(TimestampHelper.now());
orderTransferAB.setProcessedFlag('0');
orderTransferAB.commitCopyHelper();

//invoke super class's implementation for actual message transfer
InvocationServiceObject invocationServiceObject = super.invoke(action, requestDataObject);

LOGGER.exiting(CLASSNAME, methodName);
return invocationServiceObject;
}

Debugging Solr Search Sort Issue on Department(Category) pages

It loads the page Layouts/CategoryNavigationResults.jsp and when selecting different sort options
When debugging the Ajax call in the Net tab, you will see the orderBy value corresponding to the values defined in the search profile.
http://localhost/CategoryNavigationResultsView?searchType=&filterCollQuery=&langId=-1&beginIndex=0&sType=SimpleSearch&metaData=&pageSize=48&manufacturer=&resultCatEntryType=&catalogId=10051&productBeginIndex=0&categoryId=13632&storeId=10151&filterFacet=
beginIndex=0
catalogId=10051
contentBeginIndex=0
facet=
isHistory=false
langId=
maxPrice=
minPrice=
objectId=
orderBy=6
orderByContent=
pageSize=0
pageView=grid
productBeginIndex=0
requesttype=ajax
resultType=products
searchTerm=
storeId=10151
Enable Trace:
*=info: com.ibm.commerce.catalog.*=all: com.ibm.commerce.foundation.*=all: com.ibm.commerce.search.*=all

Search in trace.log: Find searchProfile=[IBM_ in logs
e.g: found
searchProfile=[IBM_ComposeFacetListByCategoryId]
schema.xml  : Make sure the entries are correctly available in the schema file
      <field name="abcRanking" type="tfloat" indexed="true" stored="false" multiValued="false" />
 <field name="abcRanking_display" type="float" indexed="true" stored="true" multiValued="false" />


Do not make any customization's to the FEP for this file and this would have performance impact and would cause multiple issues in future upgrades.
There are targetable versions for each environment wc-search.xml, make sure
Find the corresponding search profile in extended wc-search.xml
 <_config:profile indexName="CatalogEntry" name="IBM_ComposeProductListByCategoryId">


Check for the attribute value in the database by running in DB
select av.value,cat.partnumber,cat.catentry_id from attrvaldesc av, catentryattr cattr, attr a, catentry cat where
av.attrval_id = cattr.attrval_id
and cattr.attr_id = a.attr_id
and cattr.catentry_id =cat.catentry_id
and a.identifier='abcAttribute' order by value desc

Make sure the attribute is searchable:

Check for the Attribute in the following tables:

It is possible that attrdictsrchconf .SRCHFIELDNAME is mapped to a different name than the actual attribute name in

select * from attrdictsrchconf where attr_id in (select attr_id from attr where identifier in ('abcAttribute'))

select * from srchattr where identifier like '%abcAttribute';

C:\IBM\WCDE_ENT70\workspace\WC\xml\config\com.ibm.commerce.catalog-fep\wc-search.xml
C:\IBM\WCDE_ENT70\workspace\WC\xml\config\com.ibm.commerce.catalog-ext\wc-search.xml

    <_config:profile indexName="CatalogEntry" name="IBM_ComposeProductListByCategoryId">
        <_config:query>
            <_config:param name="maxRows" value="50"/>
            <_config:param name="maxTimeAllowed" value="15000"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByCategoryExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByManufacturerExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByPriceExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByFacetExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByStorePathExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByPublishedEntryOnlyExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByCustomExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchFacetConditionExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchTypeExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchSequencingExpressionProvider"/>
            <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchProductEntitlementExpressionProvider"/>
            <_config:field name="name"/>
        </_config:query>
        <_config:sort>
            <_config:field name="1" value="mfName_ntk asc"/>
            <_config:field name="2" value="name_ntk asc"/>
            <_config:field name="3" value="price_* asc"/>
            <_config:field name="4" value="price_* desc"/>
            <_config:field name="5" value="quantitySold desc"/>
            <_config:field name="6" value="abcRanking desc" />
            <_config:field name="7" value="totalPriceSold desc"/>
        </_config:sort>
        <_config:result>
            <_config:filter classname="com.ibm.commerce.catalog.facade.server.services.search.metadata.SearchCatalogEntryViewPriceResultFilter"/>
            <!--
            <_config:filter classname="com.ibm.commerce.catalog.facade.server.services.search.metadata.SearchCatalogEntryViewSingleSKUResultFilter"/>
            -->
            <_config:filter classname="com.ibm.commerce.catalog.facade.server.services.search.metadata.SearchCatalogNavigationViewPreviewResultFilter"/>
            <_config:filter classname="com.ibm.commerce.catalog.facade.server.services.search.metadata.SearchCatalogNavigationViewDynamicKitResultFilter"/>
            <_config:filter classname="com.ibm.commerce.catalog.facade.server.services.search.metadata.SearchCatalogEntryViewDescriptionResultFilter"/>
            <_config:filter classname="com.custom.commerce.search.query.solr.SolrFacetEntryViewImageAndSequenceResultFilter"/>
        </_config:result>
        <_config:facets>
            <_config:param name="sort" value="count"/>
            <_config:param name="minCount" value="1"/>
            <_config:param name="limit" value="200"/>        
        </_config:facets>
    </_config:profile>

Tuesday, November 11, 2014

Enabling server side logs and levels | WCS

How to get to Admin console:
Right click on Server -->Administration -->Run Administrative Console

Left menu Troubleshooting->Logs and trace and click on server and get to (Logging and Tracing > server1 > Change log detail levels).

If you need the trace to be in effect immediately, do the same setting on the Runtime tab and if you need the settings saved post server start, you would put that in Configuration.

Important trace components: e.g:
*=info: com.ibm.websphere.commerce.WC_USER=all: com.ibm.websphere.commerce.WC_ORDER=all: com.ibm.websphere.commerce.WC_SERVER=all

Do not try to leave trace logs on in production since it will have a huge impact on performance and even on toolkit if you don't need , i would avoid since it slows down quite a bit.