Welcome to the IBM Websphere Commerce Hub


Welcome to the IBM Websphere Commerce Hub

Come join me in my journey to explore the various features and capabilities of IBM Websphere Commerce and understand how retailers can benefit from its really cool out-of-box functionality.

Sunday, June 14, 2015

Attribute Dictionary - Defining Attributes

Basic Concepts :


What is Attribute Dictionary?

An attribute dictionary is a set of common attributes and attribute values that can be reused by multiple products. The attribute management tool in Management Center provides business users the ability to create, update, assign, and manage product attributes.

More detailed understanding can be found here in the Infocenter.


What are defining and descriptive attributes?

There are two types of attributes: descriptive attributes and defining attributes.
  • Descriptive attributes are not intended for SKU resolution. These attributes only provide additional information about the product. An example would be “Operating System Installed” with the values “Windows 7”, “Windows 8” etc.
  • Defining attributes are used for SKU resolution and you won’t be able to buy an item until you have given values for these defining attributes. An example would be a T-Shirt and the defining attributes “Size” and “Colour”. Once a value has been given for the two different defining attributes such as Colour: Red and Size: Medium, we will be able to determine the item/SKU that corresponds to medium, red colour shirt.


Problem Statement:


The task that we have in hand is to display all the "possible" allowed values of the defining attribtes on the PDP so that it can be used for SKU resolution when a customer makes his/her choice of the values of the defining attributes from the dropdown. The reason I say "possible" is because attribute dictionary Standardizes attributes and attribute values that are common among multiple products. For example , in the attribute dictionary , you may have a attribute called size with all allowed values of "XS" , "S" , "M" , "L" , "XL". But for a particular product - the only possible values from the list may be "S" , "M" and "L". In this scenario, I would only want to display the possible "allowed" values of "S" , "M" and "L" - rather than all the 5 allowed values 


Solution & Approach:  


I first wanted to explore if there was any OOB DSL components (get-data expressions / access profiles) which would help me accomplish my requirement.

One useful reference link in Infocenter which could help me understand this was -

From the list of access-profiles listed in the link above , I found that access-profile "IBM_Store_CatalogEntryAttributesParent" . One of the associated sql statements to this access profile in the corresponding tpl file clearly does what we require

<!-- ========================================================== 
     Adds the allowed values of attribute dictionary 
     attributes (ATTRVAL table) to the
      resultant data graph.         
     The allowed values which are not used by valid SKU of the product are filtered out                        
     ========================================================== -->
BEGIN_ASSOCIATION_SQL_STATEMENT
name=IBM_AttributeDictionaryAttributeSchemaAllowedValue

I could not , however , find a get expression associated with this accessprofile. So , I extended the corresponding \Stores\WebContent\WEB-INF\config\com.ibm.commerce.catalog-ext\get-data-config.xml (Please follow the recommended process to extend the get-data-config.xml) and added the below expression:

<expression-builder>
<name>getParentCatalogEntryAttrDictDefiningAttributesByID</name>
<data-type-name>CatalogEntry</data-type-name>
<expression-template>{_wcf.ap=$accessProfile$;_wcf.dataLanguageIds='$dataLanguageIds$'}/CatalogEntry[CatalogEntryIdentifier[(UniqueID='$catEntryId$')]]</expression-template>
<param>
<name>accessProfile</name>
<value>IBM_Store_CatalogEntryAttributesParent</value>
</param>
<param>
<name>dataLanguageIds</name>
<value></value>
</param>
</expression-builder>

And in the storefront JSP , used the following code-snippet to fetch the data using the above get expression:


<wcf:getData type = "com.ibm.commerce.catalog.facade.datatypes.CatalogEntryType" var = "catalogEntryWithAttr" expressionBuilder = "getParentCatalogEntryAttrDictDefiningAttributesByID">
<wcf:contextData name = "storeId" data = "${param.storeId}"/>
<wcf:param name = "catEntryId" value = "${product.productID}"/>
<wcf:param name = "dataLanguageIds" value = "${param.langId}"/>
</wcf:getData>

<c:forEach var="attribute" items='${catalogEntryWithAttr.catalogEntryAttributes.attributes}'> 
<c:if test="${attribute.usage== 'Defining'}" >
<p>
         <label><c:out value = "${attribute.name}"/>:</label>
<select id= "${attribute.name}" name = "${attribute.name}">
     <c:forEach var='attributeVal' items='${attribute.allowedValue}'> 
  <option value="${attributeVal.value}">${attributeVal.value}</option>
     </c:forEach>
</select>
</p>
</c:if>
</c:forEach>

Please ensure proper values are being passed (based on the JSP in which the above snippet is being introduced ) for the input parameters highlighted in red.

An another useful Infocenter link which may help us accomplish this is provided below. I havent tried it myself but providing it for reference.


Thursday, May 28, 2015

RESOLVED - com.ibm.wsspi.webcontainer.util.RequestUtils parseQueryString SRVE0325E: Exceeding maximum parameters allowed per request 10,000 ,current 10,000 , cannot add more.(SOLR)

Sometimes , you may find that the SOLR Search and Browse cease to function and you may keep hitting "No Search Results". On further investigating the SOLR logs , you may find the below exceptions -




[5/26/15 11:27:08:586 BST] 00000027 SolrCore      I org.apache.solr.core.SolrCore execute [MC_10001_CatalogEntry_en_GB] webapp=/solr path=/select params={q=shortDescription:tv} hits=905 status=0 QTime=1

[5/26/15 11:27:36:127 BST] 00000027 util          E com.ibm.wsspi.webcontainer.util.RequestUtils parseQueryString SRVE0325E: Exceeding maximum parameters allowed per request 10,000 ,current 10,000 , cannot add more.

[5/26/15 11:27:36:131 BST] 00000027 SolrDispatchF E org.apache.solr.common.SolrException log java.lang.IllegalArgumentException

        at com.ibm.wsspi.webcontainer.util.RequestUtils.parseQueryString(RequestUtils.java:196)

        at com.ibm.ws.webcontainer.servlet.RequestUtils.parsePostData(RequestUtils.java:356)

        at com.ibm.ws.webcontainer.srt.SRTServletRequest.parseParameters(SRTServletRequest.java:2051)

        at com.ibm.ws.webcontainer.srt.SRTServletRequest.getParameterMap(SRTServletRequest.java:2568)

        at org.apache.solr.request.ServletSolrParams.<init>(ServletSolrParams.java:29)

        at org.apache.solr.servlet.StandardRequestParser.parseParamsAndFillStreams(SolrRequestParsers.java:394)

        at org.apache.solr.servlet.SolrRequestParsers.parse(SolrRequestParsers.java:115)

        at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:223)

        at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)

        at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:125)

        at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:80)

        at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:908)

        at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:935)

        at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:503)
        at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest

This is caused when the SOLR query string has more than 10,000 query string parameters. SOLR cannot handle that and fails with an internal server error. To resolve this issue , please follow the below steps -

1. In the administrative console click 
Servers > Application Servers > server_name > Web Container settings > Web Container 

2. Under Additional Properties select Custom Properties. And add a new 

Property name: com.ibm.ws.webcontainer.maxParamPerRequest 

Value : some number 

The default value for this is 10000. You can set it a different number or you can set this property to -1 if you do not want to limit the number of parameters that can be included in a request
 

Wednesday, May 27, 2015

WC Search Customization Points

A simple Mind map which depicts the commonly customized files/components with their purpose while extending the WC Search.


SearchPreProcessor
A query preprocessor modifies the native SolrQuery object right before it is sent to the Solr server for processing.

The custom query preprocessor needs to be mapped in the wc-search.xml.

For more details , refer to the infocenter link

SearchPostProcessor
A query postprocessor modifies the physical DataObject, SolrEntityContainerImpl, immediately after the QueryResponse is returned from the Solr server.

The custom query postprocessor needs to be mapped in the wc-search.xml

For more details , refer the infocenter link 

SearchProfile
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 and result filters, 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). 

For more details , refer the infocenter link 

Business Object Mediator
The business object mediator maps physical search index fields to their corresponding logical fields in the CatalogEntryView noun. Custom physical index fields can be mapped by using the UserData fields.

For more details , refer the infocenter link 

Preprocessor and Data Import Handler (DIH)
The preprocessing tasks are controlled by the wc-dataimport-preprocess XML files. The files contain table definitions, database schema metadata, and references to the Java classes used in the preprocessing steps. Those files are invoked by the di-preprocess utility, which extracts and flattens WebSphere Commerce data and then outputs the data into a set of temporary tables inside the WebSphere Commerce database. The data in the temporary tables is then used by the index building utility to populate the data into Solr indexes using Solr's Data Import Handler (DIH). 

For more details , refer the infocenter link

Search Schema
Typically, WebSphere Commerce data is stored in a relational database. In WebSphere Commerce search, another repository also stores WebSphere Commerce data. That is, the product information is stored in a search index for searching purposes. Most of the data that are stored in the search index is extracted from the relational database. Similar to the database schema, the search index also contains a schema. The fields that are defined in this schema are used by WebSphere Commerce search.
By customizing the schema.xml , we define fields in the search schema that store the data to be searched. Once the new fields are defined, the mappings must be configured for the fields to the database schema.

For more details , refer the infocenter link

I hope you will find the mindmap really useful. As always , please feel free to add your comments and suggestions.

Tuesday, May 26, 2015

Commerce Composer in a Nutshell

A excellent video to learn about the amazing Commerce Composer tool - which enables business to create new pages without IT assistance. Available FEP7 and above.

Not only does it allow the business to control - how the page looks but also enables them to add SEO metadata contents for improved search capabilities and associate search terms which lead to the display of the page.

 http://www-01.ibm.com/support/knowledgecenter/SSZLC2_7.0.0/com.ibm.commerce.management-center.doc/demo/PageComp/PageComp.html


 

Monday, April 7, 2014

Debugging BOD Framework

Important Trace Strings to debug BOD


BOD Request / Response:  

com.ibm.commerce.foundation.server.command.bod.*

Data Service Facade Trace String: 

com.ibm.commerce.foundation.server.services.dataaccess.DataServiceFacade 

Get Service Flow Trace Strings:

Useful to understand if the code is breaking midway and if you would like to enable tracing for individual commands.

Fetch<ComponentName>Cmd 

The first point to debug the Get / Search service failures. 
The Fetch command fetches the data.Extensions of this Fetch command are associated with a particular XPath expression.The command framework can use the XPath expression and Fetch task command to resolve the Get request to a particular implementation by using the existing WebSphere Commerce command registry (CMDREG) data. Instead of having one implementation for a Fetch business task, the command framework uses the XPath as the selector to resolve the implementation. If a specific implementation is not defined for the given XPath, then a default Fetch is used.

For example , The InventoryAvailability noun uses a default Fetch implementation and to debug , you must enable the trace for :



com.ibm.commerce.inventory.facade.server.commands.FetchInventoryAvailabilityForDKCmdImpl
 
Compose<ComponentName>Cmd 

The Fetch Command calls the Compose commands to composes the response.When the Get command calls the Compose command, it uses the access profile of the request as the key to select the appropriate Compose implementation. Because the access profile is just a superset of another access profile, the Compose commands delegates to the parent access profile to first populate the logic model and add any required information.

For example , The InventoryAvailability noun uses the below Compose implementations and to debug , you must enable the trace depending on the Inventory system used :



DOMInventorySystem com.ibm.commerce.inventory.facade.server.commands.ComposeDOMInventoryAvailabilityForDKInBatchCmdImpl

NonATPInventorySystem
com.ibm.commerce.inventory.facade.server.commands.ComposeNonATPInventoryAvailabilityCmdImpl

ATPInventorySystem
com.ibm.commerce.inventory.facade.server.commands.ComposeATPInventoryAvailabilityForDKCmdImpl
 
ReadBusinessObjectMediators 

The read mediator constructs the logical object based on the values in the corresponding physical entity.The Read mediators can be found by looking at the below file:



/WC/xml/config/<component-name>/wc-business-object-mediator.xml


For example , The InventoryAvailability service debugging , enable the trace for the below :
com.ibm.commerce.inventory.facade.server.services.dataaccess.bom.mediator.ReadInventoryAvailabilityMediator  
If you do not wish to enable the trace on a granular level , you could also enable the trace for the entire component service.

For example , for Inventory services , enable the below trace :
com.ibm.commerce.inventory.facade.server.*

Debugging Query Template File


XPATH Syntax Validator (wcs_xpathkey utility):

The XPath key generator command-line utility takes an XPath expression as input and generates an XPath key. This key is used to locate the XPATH_TO_SQL_STATEMENT template in the query template file.This utility can help you validate the format of the XPATH Key as well such as missing closing brackets etc or misplaced tokens. Please note this would not however match the XPATH with the actual Noun definition.

wcs_xpathkey MyXPath
For example:
wcs_xpathkey /CatalogEntry[(@catalogEntryTypeCode='ProductBean' 
  or @catalogEntryTypeCode='ItemBean') and 
   ParentCatalogGroupIdentifier[ExternalIdentifier[GroupIdentifier='Coffee Table']]]

The output from this command , if sucessful, would be:
/CatalogEntry[(@catalogEntryTypeCode=) and 
   ParentCatalogGroupIdentifier[ExternalIdentifier[GroupIdentifier=]]]

In case of failures , would display certain error messages.

Query Template File Syntax Validator

Use this page to validate your query template file syntax.
http://localhost/webapp/wcs/admin/servlet/dsl.jsp

In case you are seeing NullPointer exceptions on querying even the OOB services, make the below changes in the dsl.jsp.

Search for the below line:
sc.setXPath(sbQuery.toString());

Add the following line of code below the above line:
sc.setComponentId(componentId); 

Reloading the configuration of a BOD service module

During development, you may want to modify and reload configuration, without having to restart the server. Follow the below Infocenter link  for more details:


http://pic.dhe.ibm.com/infocenter/wchelp/v7r0m0/topic/com.ibm.commerce.developer.soa.doc/tasks/tsdreloadconfig.htm