Sunday, February 23, 2014

Making events asynchronous in WCS

 All events in websphere commerce are synchronous events by default. Sometimes it is essential to make the events asynchronous to ensure guest is not waiting for the events to complete. For Example, if you are transferring orders to back end system, it can be handled as asynchronous. 
To make the events asynchronous add the priority attribute to the event in wc-server.xml
<component    compClassName="com.ibm.commerce.event.impl.ECEventEnableComponent"
          enable="true" name="OrderSubmit Event" priority="LOW">
            <property display="false">
                <event name="OrderSubmit"/>
            </property>
        </component>
Priority can take 3 values, HIGH, MEDIUM, LOW
HIGH - Will make it synchronous and will run in the same transaction as the event initiator.
MEDIUM - Will make it asynchronous and immediately picked by the event listener. 
LOW - Will run with slight delay as per the scheduler run time and will be processed in a different transaction. 

Saturday, February 22, 2014

WebSphere Commerce AJAX framework Cont.. Some example for Order Module

With WebSphere Commerce feature pack 4 onward,  we now have three variations of invoking the Order Management URL's. Lets look at each of them and when and how to use them considering the performance.

1. Struts Actions invoking WebSphere Commerce Command.
Invoke the struts Action configured to a Websphere commerce command, either using the HTTP/HTTPS and passing the request parameters using a GET or a POST method.

Ex: OrderItemAdd action invoking the OrderItemAdd command.

        <action
            parameter="com.ibm.commerce.orderitems.commands.OrderItemAddCmd"
            path="/OrderItemAdd" type="com.ibm.commerce.struts.BaseAction">
            <set-property property="https" value="0:1"/>
            <set-property property="authenticate" value="0:0"/>
        </action>

       Request:  https://localhost/....../OrderItemAdd?catEntryId-123&<otherparameters>

Here the request parameters are passed from a browser or a any client as name/value pair and processed directly by the OrderItemAdd command, well of course there can be struts validator framework validating the parameter being passed. 

2. SOI Actions invoking the SOI client and the Commerce Command

Invoke the SOI action configured in struts, which will further invoke the SOI client and then pass it on to the Commerce Command.

Ex: AjaxOrderChangeServiceItemAdd invoking the Component Service

        <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>

This action if invoked from a browser passing the name-value pair parameters, will convert them to OAGIS message first, then converts back into name-value pair and invokes the OrderItemAddCmd. So there is a additional conversion of name-value pair to OAGIS message and then back to name/value pair, as the OrderItemCmd will only understand this format. 

If invoked from browsers, this could have negative impact on the performance of Order management functionality.

This can be used if the client needs to pass the OAGIS message format into the Websphere Commerce Server.

3. REST services introduced in FEP4.

Invoke the struts action and pass the request as JSON. 

Ex: POST /wcs/resources/store/10101/cart HTTP/1.1
Host: localhost
Content-Type: application/json

{
   "orderItem": [
      {
         "productId": "10541",
         "quantity": "2.0",
         "itemAttributes": [
          {
           "attrName": "10297",
           "attrValue": "4T"
          }
         ]
      },
      {
         "productId": "10823",
         "quantity": "3.0"
      },
      {
         "productId": "10260",
         "quantity": "1.0"
      }
   ]     
}

Here the request is first interpreted by the REST webservice, which converts the JSON string into a Map of name/value pairs and then invokes the SOI service of OrderManagement (section 2 above), then further processing by SOI and the return response is converted back into JSON.

With REST, we now have two more conversions one from JSON to name/value pair, then name/value pair to OAGIS message, then OAGIS to name/value pair.


JSON is very well used format for AJAX requests and for exposing Restful services, but do we need two level of conversion before the request is actually process. 

WebSphere Commerce AJAX framework

WebSphere Commerce AJAX framework

The WebSphere Commerce AJAX framework is an extension of the Dojo AJAX and events API. It provides an easy to use framework that meets most AJAX requirements for storefront development, and hides some of the complexity and repetitive code that a storefront developer often encounters.
There are four common scenarios involved with the WebSphere Commerce AJAX framework:
  1. An AJAX call is made to the WebSphere Commerce server to update a business object. Sections of the page are refreshed with new content if the update is successful. The new content is retrieved using subsequent AJAX calls to the WebSphere Commerce server.
  2. An AJAX call is made to refresh a section of the page because of certain customer interactions.
  3. An AJAX call is made to the WebSphere Commerce server to update a business object. Sections of the page should refresh with new content if the update is successful. The new content is retrieved using subsequent AJAX calls to the WebSphere Commerce server. This is a repeat of the first scenario, however, instead of making the code modular, a less traffic intensive approach to the server is wanted.
In this scenario, an AJAX call is made to the WebSphere Commerce server to update a business object. Sections of the page are refreshed with new content if the update is successful. All the relevant information to refresh the contents of the page are returned as a JSON object. The client then has the contents of the JSON object and uses the DOM manipulation API to modify all the areas of the page that should change as a result of the successful update.
  1. An AJAX call is made to the WebSphere Commerce server requesting JSON data. Sections of the page are then updated using JavaScript and the DOM manipulation API.
The WebSphere Commerce AJAX framework is not required for the third and fourth scenarios, as these scenarios can be performed directly using the Dojo AJAX API.
Important: Avoid making concurrent Ajax calls for commands. In particular, avoid concurrent calls that turn a generic user into a new guest user with a user activity token. The concurrent calls result in multiple user activity tokens in the session, which causes undesired results.
You can make concurrent Ajax calls for views.

Scenario 1: Updating a business object in WebSphere Commerce using AJAX, then refreshing multiple areas using subsequent AJAX requests to get the refresh contents

There are two parts to this scenario:
  1. An AJAX call is made to a WebSphere Commerce controller command or WebSphere Commerce service to update a business object (or multiple business objects).
  2. Subsequent AJAX get requests are made to WebSphere Commerce views to retrieve the new HTML contents for each area if the update is successful.
The following two diagrams show which interactions occur between the client and the WebSphere Commerce server in this scenario.
Interaction diagram when calling WebSphere Commerce controller commands:
Interaction diagram when calling WebSphere Commerce controller commands
Interaction diagram when calling WebSphere Commerce services:
Interaction diagram when calling WebSphere Commerce services
1. Making an AJAX call to a WebSphere Commerce controller command or service
Before the client is able to call a WebSphere Commerce controller command or service using AJAX, the WebSphere Commerce server must define that the controller command or service can be called using AJAX (rather than the traditional programming model where the request is made and a new redirect is implied by the WebSphere Commerce runtime).
To define a controller command or service to be available for AJAX type requests, simply define a new struts-action entry in the struts-config XML file that identifies the controller command or service as an AJAX type of action. For example, to create a new struts-action for the InterestItemAdd controller command that can be called using AJAX, it must be defined it in the struts configuration XML file:
Figure 1. 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>
Figure 2. 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 these JSP files
  • WC_eardir/Stores.war/AjaxActionResponse.jsp (success case)
  • WC_eardir/Stores.war/AjaxActionErrorResponse.jsp (failure case)
  • WebSphere Commerce Developer WCDE_installdir/workspace/Stores/WebContent/AjaxActionResponse.jsp
  • WebSphere Commerce Developer WCDE_installdir/workspace/Stores/WebContent/AjaxActionErrorResponse.jsp
Now that AJAX struts-actions are defined, the wc.service.declare API is used in the JavaScript code to define a service for each of the required URLs being called in the page. The wc.service.declare API declares a JavaScript service object that is able to call WebSphere Commerce AJAX type struts-actions. This gives the control to the client for when to execute the AJAX call. For example, the following JavaScript code in the client defines a service object for calling InterestItemAdd using AJAX:
wc.service.declare({
  id: "AjaxInterestItemAdd",
  actionId: " AjaxInterestItemAdd",
  url: " AjaxInterestItemAdd",
  formId: "",
 
successHandler: function(serviceResponse) {
      alert("success");        
    },
 
failureHandler: function(serviceResponse) {
    if (serviceResponse.errorMessage) {
      alert(serviceResponse.errorMessage);
    }
  } 
});
The above definition simply defines an object, and does not yet trigger the AJAX call to the WebSphere Commerce server. 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 are published automatically by the framework when the request completes successfully. The events that are published are called modelChanged and modelChanged/actionId, and Dojo automatically notifies all subscribed listeners.
2. Making AJAX calls to WebSphere Commerce views to get refresh contents
The WebSphere Commerce AJAX framework provides two more JavaScript objects called refresh controllers and refresh areas. 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. This sample code defines a refresh area in the page:
<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. The following sample code shows how to define a refresh controller:
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) {
 
  }
 
});
It is important to recognize the URL that defines the WebSphere Commerce server URL to call and get the new HTML contents for the refresh area that the refresh controller is associated to. 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. Note that the modelChangedHandler function 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.
Another useful function is the postRefreshHandler function of the refresh controller, as this 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.
Note: The refresh controllers need a render context object. In this scenario, the render context is not used, however, a dummy render context per page must be used to make use of refresh controllers and refresh areas.

Scenario 2: Refreshing an area of the page using an AJAX request to get the refresh contents

Areas of the page should refresh with new content when users interact with the user interface. This scenario uses the render context, refresh area and refresh controllers API from the WebSphere Commerce AJAX framework.
A render context object keeps track of context information of the client and it can trigger renderContextChanged events whenever updates occur to any of the properties in the render context object. The refresh controllers are automatically registered to listen to all the renderContextChanged events. The refresh controller logic determines if the context change should trigger an update of a refresh area widget. Therefore, in the refresh controller's renderContextChangedHandler, the API is used to compare the context properties testForChangedRC to determine if the context property has changed and then trigger the refresh of the refresh area.
An example for declaring the refresh area to work with shopping cart paging is as follows:
<div dojoType="wc.widget.RefreshArea" widgetId="OrderItemPagingDisplay" id="OrderItemPagingDisplay" controllerId="OrderItemPaginationDisplayController" 
         role="wairole:region" waistate:live="polite" waistate:atomic="false" waistate:relevant="all">
    <%out.flush();%>
      <c:import url="${jspStoreDir}ShoppingArea/CheckoutSection/SingleShipment/OrderItemDetailSummary.jsp"> 
      <c:param name="catalogId" value="${WCParam.catalogId}" />
      <c:param name="langId" value="${WCParam.langId}" />
      <c:param name="storeId" value="${WCParam.storeId}" />
      <c:param name="orderPage" value="summary" />
      </c:import>
    <%out.flush();%>
</div>

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

This scenario can be achieved using the Dojo API directly. Therefore, there is no need to use the WebSphere Commerce AJAX framework if this scenario is of relevant interest. 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. For example
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. In this scenario, the assumptions are that the same JSP file handles the error scenario as we set the errorViewName to the same MiniCartContentsJSON view. The client then gains control back and either the load or error function is called depending on the respective success or failure.
Note: 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. The load function 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.

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


This scenario can be achieved using the Dojo API directly. Therefore, there is no need to use the WebSphere Commerce AJAX framework if this scenario is of relevant interest. 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.

Creating a new application in Endeca with you own data

Following steps describe the details about creating a new application with a new data (other than sample wine data) and deploying to Endeca. It also gives information about the tutorial which need to be followed to help you understand the basic learning process for Endeca.

Note: Following Endeca packages should be installed first:

- MDEX Engine  -
- Platform Services
- Endeca Workbench
- Endeca Deployment package.
- Endeca Developer Studio

Read Endeca Concepts Guide to get a basic understanding of what the above packages mean and to understand the terminology used in Endeca.

Step 1: Use the deployment template to create the folder structure and required information to provision the new application.
a. Run the initialize file under the path C:\Endeca\Solutions\deploymentTemplate-3.1\bin  (Check the directory path of the deployment template)
b. Follow the instructions. Application name specified in this step will be used in the Developer Studio when creating the scripts for the data foundry (ITL process)
Note: You can create as many application as you need with unquie ports of the dgraph and the log server. The EAC and workbench ports remain the same. Additional information Read: DeploymentTemplateUsageGuide.pdf, Chapter 2: Deploying an EAC application on Windows

This would have created a directory structure to store the files required for Endeca. Examine the folders. Most important you will need to look
C:\Endeca\APPS\MyApp\config\pipeline   - Will contaon the scripts used in the ITL process. You will see the Sample Wine data scripts, which you replace later.
C:\Endeca\APPS\MyApp\test_data\baseline - Contains the data which will be loaded into Endeca. You will see sample wine data, which you can replace with your own data.

Step 2: Run the initialize_services.bat under the folder C:\Endeca\APPS\MyApp\control. This would initialize the application, you will now be able to see the application in the Endeca IAP Workbench (http://localhost:8006) > EAC Administration -> Admin Console.
This will ensure that you have successfully provisioned the application in Endeca. You will now need data to be loaded into the application.

Step 3: If you want the use the Sample wine data. Run following two commands.
load_baseline_test_data.bat  - Will copy the data from C:\Endeca\APPS\MyApp\test_data\baseline to C:\Endeca\APPS\MyApp\data\incoming
baseline_update.bat - Process the data and loads it into MDEX engine for use from the application.

If you want to process a different data set of you project:

a. copy the data(a zip or any file) into C:\Endeca\APPS\MyApp\test_data\baseline.
b. Open Endeca Developer Studio and create a new project (note project name should be same as the application name provided in the step 2). In this case MyApp.
c. Following the Endeca Dev Studio document, Chapter 3: Preparing Data, Properties, and Dimensions. This will help you create the pipeline which will be used by Endeca ITL process to prepare your data and load into MDEX engine.
d. Copy the files created by Endeca Developer Studio into C:\Endeca\APPS\MyApp\config\pipeline folder.  Note most of the files name start with name MyApp, the name you provided during application creation.
e. Now run load_baseline_test_data.bat and baseline_update.bat.
f. Access the Endeca Reference application http://localhost:8006/endeca_jspref. Host: localhost, Port is that of DGraph provided in the Step 1.
g. You will see the processed data in the endeca reference application.

Documents to read to learn about Endeca
Here are some of the documents you can refer to learn more about endeca. Based on your role  or interests choose the documents you want to read and understand.

Doc 1: Basics Concepts of Endeca - Basic terminology used in Endeca.
Doc 2: Developer Studio Guide - If you want to work on creating the pipeline, properties, dimension and configure other search related features.
Doc 3: Forge Guide - To understand the Endeca Information Transformation Layer, a follow-on guide to Doc 2:.
Doc 4: Deployment Template - To understand the Endeca deployment concepts.
Doc 5: Search Developer Basic  - To understand the API details to query the MDEX Engine.
Doc 6: Advanced Development Guide - To understand the wild card search, auto correct, did you mean, phrase search, thesaurus.