Customer Requirement

The customer is looking to take advantage of the Data Warehousing capabilities of Commerce Server 2009.  Commerce Server 2009 provides 39 reports to assist you in analyzing your web traffic.  Several of these reports, like the Shopping Basket events report, leverage the information generated by the Commerce Events infrastructure. 

Problem Statement

These events were traditional called from the site code in controller/helper classes.  For example, when an Item was added to the basket,  the method responsible for adding the item would call the AddItemToBasketEvent.  The following diagram depicts this design.

image

The direction of Commerce Server 2009 R2 is to provide an n-tier deployment model.  The model will include a segmentation between the MOSS farm and the Commerce Server farm.  This means it will no longer be desirable to reference the Commerce Server Orders runtime from site code running in MOSS.  The most likely place to put the code which calls these events would be in the Commerce Foundation.  Currently, none of the “out of the box” Operational Sequences implement the Commerce Events. 

Solution Overview

This section demonstrates a pattern which can be leveraged to provide the data necessary to populate the Commerce Events reports. In this example we will demonstrate how to provide data from the AddItemToBasketEvent to the Shopping Basket Events report.

The following diagram depicts the future state of an n-tier Commerce Server implementation.

image

In order to reduce the amount of re-work which would be necessary for a migration to Commerce Server 2009 R2 this solution is implemented as a custom Operational Sequence component. 

BasketEventProcessor

The BasketEventProcessor is the custom Operational Sequence component which creates the AddItemToBasketEvent and calls CommerceContext.LogCommerceEvent.  The LogCommerceEvent method writes the basket event symbols to the web.config.  This class inherits from BasketRelatedItemOperationalSequence Component.

Solution Implementation

The following section details the step necessary to implement the solution.

1.  Create a C# Class Library called BasketEventsComponents.

2.  Add references to the following Commerce Server assemblies

  • Microsoft.Commerce.Broker
  • Microsoft.Commerce.Common
  • Microsoft.Commerce.Contracts
  • Microsoft.Commerce.Providers
  • Microsoft.CommerceServer.Runtime

3.  Create a new class, BasketEventProcessor, derives from Microsoft.Commerce.Providers.Components.BasketRelatedItemOperationSequenceComponent. 

4.  Paste the following code into the class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Commerce.Providers;
using Microsoft.Commerce.Providers.Components;
using Microsoft.Commerce.Providers.Utility;
using Microsoft.Commerce.Common;
using Microsoft.Commerce.Common.MessageBuilders;
using Microsoft.Commerce.Contracts;
using Microsoft.Commerce.Contracts.CommerceEntities;
using Microsoft.Commerce.Contracts.Messages;
using Microsoft.CommerceServer;
using Microsoft.CommerceServer.Runtime;
using Microsoft.CommerceServer.Runtime.Orders;
using Microsoft.Commerce.Broker;

namespace BasketEventComponents
{
    /// <summary>
    /// This class is an implementation of a BasketRelatedItemOperationSequenceComponent. It is responsible
    /// for logging the Commerc
    /// </summary>
    public class BasketEventProcessor : BasketRelatedItemOperationSequenceComponent
    {
        #region Properties

        /// <summary>
        /// This returns the name for the relationship which is being passed in the
        /// CommerceRelatedItem
        /// </summary>
        protected override string RelationshipName
        {
            get
            {
                return "LineItems";
            }
        }

        #endregion

        #region Overriden Methods        

        /// <summary>
        /// This executes the AddToBasket event based on the line item model
        /// passed in on the CommerceCreateRelatedItem operation.
        /// </summary>
        /// <param name="createRelatedItemOperation"></param>
        protected override void CreateRelatedItem(CommerceCreateRelatedItem createRelatedItemOperation)
        {
            try
            {
                // Confirm we have a valid operation
                if (createRelatedItemOperation == null)
                    return;

                // Retrieve the model from the operation.
                CommerceEntity model = createRelatedItemOperation.GetModel("LineItem");

                // Cofirm we have a valid model
                if (model == null)
                    return;

                Microsoft.CommerceServer.Runtime.AddItemToBasketEvent BE = new AddItemToBasketEvent();

                BE.BasketName = "Default";
                BE.CatalogName = model.Properties["CatalogName"].ToString();
                BE.ProductId = model.Properties["ProductId"].ToString();
                BE.VariantId = model.Properties["VariantId"].ToString();
                

                LogStatus status = CommerceContext.LogCommerceEvent(BE);
            }
            catch (Exception excp)
            {
                string message = excp.Message;
            }

        }

        #endregion
    }
}

5.  For the new component to be successfully loaded by the Multi-channel Commerce Foundation during runtime the assembly that contains the component class has to be strongly named.

6. Add a reference to component to the CommerceQueryOperation_Basket after the Basket Committer component in the ChannelConfiguration.config.

<Component name="Basket Events Processor" type="BasketEventComponents.BasketEventProcessor, 
BasketEventComponents, Version=1.0.0.0, Culture=neutral,PublicKeyToken=498725766e8394cb" />
          

7.  This document assumes the Commerce Server Data Warehouse is already installed and configured.  It also assumes the Microsoft SQL Server Reporting Services is installed and the Reports server is configured.  I used the CS2009RTMSamples Order sample for testing this solution.

 

8. Enable logging in the web.config of your commerce application (Order Sample)

<commerceEvent>
    <add className="Microsoft.CommerceServer.Runtime.AddItemToBasketEvent" id="AddItemToBasket" loggingEnabled="true"/>
</commerceEvent>

9. Set ASPNET compat to true in your commerce application (Order Sample)

 

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

At this point your new component is ready to test. 

Solution Testing

The following section details the steps necessary to test the solution.  The following steps assume you are using the CS2009RTMSamples Order sample.

1.  Run the OrderAPIUsage project and add Item to your basket.                             

2.  Confirm the BasketEventProcessor wrote the event symbols to the IIS log file.  This is what I see in my log file

Default.aspx &CEVT={T=BSK,EVT=AIBSK,PRID="Adventure+Works+Catalog%3bAW042-03%3b51",BSKT=Default}

3.  Run the CSDWImportWizard.exe located under the Commerce Server 2007 installation directory.

  • Click "Next" on the Welcome screen.
  • Select your Commerce Server Site and check only "Web Server Logs", click "Next".
  • Select "Full Load" and click "Next".
  • Confirm your log file location is set and click "Next".
  • Select "Manually Select log files" to for this test, check your log file. and click "Next".
  • Check "Run this import immediately" only, and click "Next".
  • Click "Confirm".  This will start the import.  The report preparation step takes a couple minutes.
  • Package Execution Results should be Successful, Click "OK" and "Done".

4.  At this point you are ready to check the report for your data.

  • Open the Reports Manager
  • Click on "EN", this is the default reporting language.
  • Click on "Product Sales Report".
  • Click on "Shopping Basket Events" report.
  • On the Shopping Basket events report select your site name, Select "Today" in Date Range and Click “View Report”.
  • At this point you should see your even registered in the report.

clip_image002

Conclusion

This solution provides a way of implementing the Commerce Events infrastructure while maintaining the integrity of the n-tier model.  It demonstrated the AddItemToBasketEvent only.  There are 7 - 8 other click events which could be implemented in a similar manner.