Welcome to MSDN Blogs Sign in | Join | Help
Microsoft Forefront Codename "Stirling" Beta 1

Hey Folks

As you might know, we released Microsoft Forefront Codename "Stirling" a couple of weeks ago at RSA 2008.  I encourage you all to watch the demo, download the product, and give it a try.   Please send feedback as well through the Connect program - your feedback is invaluable!

Read more about it here: http://www.microsoft.com/forefront/stirling/en/us/default.aspx 

Enjoy

Alan

Welcome again - New Team and Focus!

I have recently made the switch from Commerce Server to Forefront Server team on the Stirling product.  See more information about Stirling here: http://www.microsoft.com/forefront/prodinfo/roadmap/stirling.mspx  

I also worked on FCS Enterprise Manager.  More information here: http://www.microsoft.com/downloads/details.aspx?FamilyID=D9413461-9384-4B14-8A26-1E77E6D98182&displaylang=en 

I have taken a huge break on blogging but hope to get into it soon with some helpful posts!

-Alan

Sample Orchestration for Commerce Server 2007 Adapters on GotDotNet

I have uploaded a sample BizTalk Orchestration on GotDotNet.  You can download it here, under the Release section. 

Here are the instructions for using the orchestration (these instructions are also contained in the sample project):

1.  You will need to compile the Commerce Server Adapters located in the SDK: %ProgramFiles%\Commerce Server 2007\SDK\Adapters\MessageSchemas.
2.  You will need to add a reference to the compiled schema's dll to this sample orchestration
3.  You will need to modify the Biztalk Server name in the deployment settings of the project.
4.  Once you deploy the orchestration - You will need to bind the ports.  You can do this through BizTalk 2006 Administration Console.


Hope this Helps.

Alan

 

Commerce Server Community now on MSDN Forums

We have officially opened our new Commerce Server Community Support Group on MSDN Forums.

We would love for you to join and post any questions or issues that you have with Commerce Server 2007 or Commerce Server 2002.  You must have a Microsoft Passport account to post questions or issues. 

Hope to see you all there! 

Alan

 

DW/A Class Creation Script from Webcast

If you have seen our DW/A WebCast Series, I have placed the script that was used to create the DiscountsApplied DW/A Class.  Enjoy!

 'Create an ADO connection object.
   Dim cnnConnection
   Set cnnConnection = CreateObject("ADODB.Connection")

'Create an ADO command object.
   Dim cmdCommand
   Set cmdCommand = CreateObject("ADODB.Command")

'Create an ADO record object.
   Dim recNew
   Set recNew = CreateObject("ADODB.Record")

'Open a connection (bind) to the provider.
'Modify the values for Catalog, Database, User, and Password to match your
'resources.
   cnnConnection.Open "URL=mscop://InProcConnect/Server=localhost:" & _
    "Catalog=DWSchema:Database=StarterSite_datawarehouse:Trusted_Connection=Yes:" & _
    "FastLoad=True"

'Set the connection in the command object.
   Set cmdCommand.ActiveConnection = cnnConnection

'Turn on "Schema Change" mode.
'SchemaMode can be set to On, True, or 1 to turn the
' schema change mode on.
   cmdCommand.CommandText = "SchemaMode=1"
   cmdCommand.Execute

'Create a new class in the Class Definition table.
   recNew.Open "Class/DiscountsApplied", cnnConnection, _
    adModeWrite, adCreateOverwrite

'Set the attributes.
   recNew("ClassDefName") = "DiscountsApplied"
'Always set SourceDefName to test_Source for new classes.
   recNew("SourceDefName") = "test_Source"
   recNew("Description") = "Discount Applied."
   recNew("GenerateTableDef") = 1
   recNew("GeneratePartitionDef") = 1

'Create your own key.
   recNew("GenerateKeyDef") = 0

   recNew("GenerateIdentity") = 1

'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

'Create an instance in the Member Definition table for the first member.
   recNew.Open "Member/DiscountsApplied/OrderGroupId", cnnConnection, _
    adModeWrite, adCreateOverwrite

'Set the attributes.
   recNew("ClassDefName") = DiscountsApplied
   recNew("TypeName") = "UUID"
   recNew("Description") = "Identifier for an Order Group."
   recNew("IsPrimaryKey") = 0
   recNew("DefaultValueAsStr") = "{00000000-0000-0000-0000-000000000000}"
   recNew("MemberDefName") = "OrderGroupId"
   recNew("GenerateColumnDef") = 1


'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

'Create an instance in the Member Definition table for the first member.
   recNew.Open "Member/DiscountsApplied/LineItemId", cnnConnection, _
    adModeWrite, adCreateOverwrite

'Set the attributes.
   recNew("ClassDefName") = DiscountsApplied
   recNew("TypeName") = "UUID"
   recNew("Description") = "Identifier for an Line Item."
   recNew("IsPrimaryKey") = 0
   recNew("DefaultValueAsStr") = "{00000000-0000-0000-0000-000000000000}"
   recNew("MemberDefName") = "LineItemId"
   recNew("GenerateColumnDef") = 1


'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

'Create an instance in the Class Key Definition table.
   recNew.Open "Key/DiscountsAppliedKey", cnnConnection, _
    adModeWrite, adCreateOverwrite

'Set the attributes.
   recNew("ClassDefName") = "DiscountsApplied"
   recNew("Description") = "Unique key for the DiscountsApplied class."

'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

'Create an instance in the Key Member table for the first member.
   recNew.Open "KeyMember/DiscountsAppliedKey/ordergroup_id", _
    cnnConnection, adModeWrite, adCreateOverwrite

'Set the attributes for the first key member.
   recnew("MemDefName") = "OrderGroupId"
   recNew("OrdinalPosInKey") = 0
   recNew("Description") = "First member of DiscountsAppliedKey."
   recNew("KeyDefName") = DiscountsAppliedKey

'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

'Create an instance in the Key Member table for the second member.
   recNew.Open "KeyMember/DiscountsAppliedKey/OrderForm_Id", _
    cnnConnection, adModeWrite, adCreateOverwrite

'Set the attributes for the second key member.
   recnew("MemDefName") = "LineItemId"
   recNew("OrdinalPosInKey") = 1
   recNew("Description") = "Second member of DiscountsAppliedKey."
   recNew("KeyDefName") = DiscountsAppliedKey

'Save the new row.
   recNew("__Commit") = 1
   recNew.Fields.Update
   recNew.Close

 

'Commit the changes to the Data Warehouse schema.
   cmdCommand.CommandText = "CommitSchema"
   cmdCommand.Execute

'Turn off "Schema Change" mode.
'If SchemaMode is set to a value other than On, True, or 1
' it is turned off.
   cmdCommand.CommandText = "SchemaMode=0"
  
   cmdCommand.Execute

'Close the connection.
   cnnConnection.Close


Hope this helps!

Alan

Three new Data Warehouse WebCast published!

We added three new webcasts as part of a series on extending the Data Warehouse.  Here are the details, be sure to check them out!

Commerce Server Data Warehouse
Presenters: Brian Blum and Alan Faulkner, Microsoft
The Commerce Server Data Warehouse is a combination of a SQL Server database, an Online Analytical Processing (OLAP) database, and a set of processes that a system administrator uses to import and maintain data. In this three-part series, Brian and Alan will walk you through extending the Data Warehouse logical schema. In the first installment, you will learn how to extend an existing Data Warehouse class. The second installment illustrates the creation of a new Data Warehouse class. The third installment illustrates how to add a multi-value Data Warehouse class member.

Be sure to check out other Commerce Server 2007 webcasts here: http://www.microsoft.com/technet/prodtechnol/comm/2007/webcasts.mspx   

Hope this helps!

Alan

How to extend the Data Warehouse to include a custom Commerce Server event (Part 2)

This is the second part of a three part series in extending the Data Warehouse.  To recap the first part, take a look at this post here. 

This part will focus on adding a new Data Warehouse class for the MusicDownload event and adding the event to the CommerceEvent table in the Data Warehouse database.

Let's get right to it:

  • First, we need to create the MusicDownload.  We will do this by executing the below script (you can take this script and modify it for your specific class/event):
    • '------------------------------------------------
      ' Creates the Wishlist01 class for use with the
      ' Extending Commerce Events sample and the
      ' Commerce Server 2007 Data Warehouse.
      '------------------------------------------------
    • Public Const fPrimaryKey = 1
      Public Const fMultiValued = 2
      Public Const fHasDefaultVal = 4
      Public Const fIsRequired = 8
      Public Const fIsJoinKey = 16
      Public Const fDontClear = 32
      Public Const fGenerateColDef = 64
      Public Const fIsUniqueKey = 128
      Public Const fIsIdentityMember = 256

      '--- flags for clsdef
      Public Const fGenerateIdentity = &H1
      Public Const fGenerateTableDef = &H2
      Public Const fGenerateKeyDef = &H4
      Public Const fGeneratePartDef = &H8
      Public Const fIsAbstract = &H10

      Public Const fHasAggrExp = &H100 'member is aggregate
      Public Const fIsDimension = &H1000
      Public Const fIsMeasure = &H10000

      Main
      Sub Main()

      'Create an ADO connection object.
      Dim objConn
      Set objConn = CreateObject("ADODB.Connection")
      'Create an ADO command object.
      Dim cmdCommand
      Set cmdCommand = CreateObject("ADODB.Command")
      'Create an ADO record object.
      Dim recNew
      Set recNew = CreateObject("ADODB.Record")
      'Open a connection to the provider.
      'Modify the connection string to match your configuration.
      objConn.Open "URL=mscop://InProcConnect/Server=localhost:" & _
      "Catalog=DWSchema:Database=Startersite_datawarehouse: Trusted_Connection=Yes:" _
      & "FastLoad=True"
      'Set the connection in the command object.
      Set cmdCommand.ActiveConnection = objConn
      'Turn on "Schema Change" mode.
      cmdCommand.CommandText = "SchemaMode=1"
      cmdCommand.Execute
      ' This is the event name
      strClsDef="MusicDownload"
      'Create a class.
      'Always set SourceDefName to test_Source for new classes.
      CreateClassDef objConn, strClsDef, "DWSchema", "test_Source", "", _
      False
      '-- MEM1 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "Event"
      strMemDefType = "WSTR"
      strDefVal = "0"
      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType , _
      lMemFlags, strDefVal, strAggrExp

      '-- MEM1 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "Artist"
      strMemDefType = "WSTR"
      strDefVal = "0"
      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal,strAggrExp
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "Album"
      strMemDefType = "WSTR"
      strDefVal = "0"
      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags , strDefVal,strAggrExp
      '-- MEM2 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "Title"
      strMemDefType = "WSTR"
      strDefVal = "0"
      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal,strAggrExp

      'The follwoing members are the required for every Commerce Event.

      '-- MEM4 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "DTimeStamp"
      strMemDefType = "FILETIME"
      strDefVal = "1900-1-1 0:0:0.0"

      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal, strAggrExp
      '-- MEM8 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "VisitNum"
      strMemDefType = "INT64"
      strDefVal = "0"

      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal, strAggrExp

      '-- MEM5 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "RequestIndex"
      strMemDefType = "SHORT"
      strDefVal = "0"

      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal, strAggrExp

      '-- MEM6 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "UriKey"
      strMemDefType = "INT64"
      strDefVal = "0"

      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal, strAggrExp

      '-- MEM7 : create non key member
      lMemFlags = fGenerateColDef + fHasDefaultVal
      strMemDef = "UserKey"
      strMemDefType = "INT64"
      strDefVal = "0"

      CreateMemberDef objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags, strDefVal, strAggrExp

      strChildClassName = strClsDef
      iRelType = 5 'indicating virtual relationship for performance
      'reasons

      '-- Rel1 : create virtual relationship to uri
      strParentClassName = "URI"
      strRelDefName = strParentClassName & strChildClassName & "Rel"
      strParentClassKey = strParentClassName & "Key"

      CreateRelDef objConn, strRelDefName, strParentClassName, _
      strChildClassName, strParentClassKey, iRelType

      '-- Rel2 : create virtual relationship to loguser
      strParentClassName = "LogUser"
      strRelDefName = strParentClassName & strChildClassName & "Rel"
      strParentClassKey = strParentClassName & "Key"

      CreateRelDef objConn, strRelDefName, strParentClassName, _
      strChildClassName, strParentClassKey, iRelType

      iRelType = 2 'indicating real relattionship

      '-- Rel3 : create relationship to Registereduser
      strParentClassName = "RegisteredUser"
      strRelDefName = strParentClassName & strChildClassName & "Rel"
      strParentClassKey = strParentClassName & "Key"

      CreateRelDef objConn, strRelDefName, strParentClassName, _
      strChildClassName, strParentClassKey, iRelType

      '-- Rel4 : create relationship to Site
      strParentClassName = "Site"
      strRelDefName = strParentClassName & strChildClassName & "Rel"
      strParentClassKey = strParentClassName & "Key"

      CreateRelDef objConn, strRelDefName, strParentClassName, _
      strChildClassName, strParentClassKey, iRelType

      '-- Rel5 : create relationship to TaskHistory
      strParentClassName = "TaskHistory"
      strRelDefName = strParentClassName & strChildClassName & "Rel"
      strParentClassKey = strParentClassName & "Key"

      CreateRelDef objConn, strRelDefName, strParentClassName, _
      strChildClassName, strParentClassKey, iRelType

      '------------------------------------------------
      ' Commit Schema
      '------------------------------------------------
      cmdCommand.CommandText = "CommitSchema"
      cmdCommand.Execute

      'Turn on "Schema Change" mode
      cmdCommand.CommandText = "SchemaMode=0"
      cmdCommand.Execute

      End Sub

      '----------------------------------------------------------------------
      ' Procedure : CreateClassDef
      ' Parameters : objConn
      ' strClsDef - name of classdef to be created
      ' strCatalog - catalog in which we want to create
      ' strSrcDef - source definition name
      ' strBaseClsName - this is useful for aggregations
      ' simple classes can pass ""
      ' bGenKeyDef = true - generate key definition
      ' automatically
      ' Notes : The schema change mode should have been set to true prior
      ' to calling this function.
      '
      '----------------------------------------------------------------------
      Sub CreateClassDef(objConn, strClsDef, strCatalog, strSrcDef, _
      strBaseClsName, bGenKeyDef)

      WScript.Echo "DBG: Class : " & strClsDef
      Dim rec
      Set rec = CreateObject("ADODB.Record")
      rec.Open "Class/" & strClsDef, objConn, 3, adCreateOverwrite
      rec("IsPersistent") = 1
      rec("ClassDefName") = strClsDef
      rec("SourceDefName") = strSrcDef
      rec("GeneratePartitionDef") = 1
      rec("GenerateTableDef") = 1
      If bGenKeyDef Then
      rec("GenerateKeyDef") = 1
      Else
      rec("GenerateKeyDef") = 0
      End If
      'to create an aggregate class --
      If strBaseClsName <> "" Then
      rec("BaseClassName") = strBaseClsName
      End If
      rec("GenerateIdentity") = 1
      rec("__Commit") = 1
      rec.Fields.Update
      rec.Close
      End Sub

      '----------------------------------------------------------------------
      ' Procedure : CreateMemberDef
      ' Purpose : Utility to create members
      ' Parameters : objConn
      ' strClsDef - name of classdef
      ' strMemDef - name of member
      ' strMemDefType - type of the memberdef
      ' lMemFlags - MemberDef Creation flags
      '
      ' Notes : User is supposed to set the schema mode to updatable and
      ' reset after the member is created.
      '----------------------------------------------------------------------
      Sub CreateMemberDef(objConn, strClsDef, strMemDef, strMemDefType, _
      lMemFlags , strDefVal,strAggrExp )
      Dim rec
      ' On Error Resume Next
      WScript.Echo "DBG: Mem : " & strMemDef
      set rec = CreateObject("ADODB.Record")
      rec.Open "Member/" & strClsDef & "/" & strMemDef, objConn, _
      adModeReadWrite, adCreateOverwrite
      rec("MemberDefName") = strMemDef
      If (lMemFlags And fGenerateColDef) > 0 Then 'default case
      rec("GenerateColumnDef") = 1
      End If
      If (lMemFlags And fPrimaryKey) > 0 Then
      rec("IsPrimaryKey") = 1
      End If
      If (lMemFlags And fMultiValued) > 0 Then
      rec("IsMultiValued") = 1
      End If
      If (lMemFlags And fHasDefaultVal) > 0 Then
      rec("DefaultValueAsStr") = strDefVal
      End If
      If (lMemFlags And fIsUniqueKey) > 0 Then
      rec("IsUniqueKey") = 1
      End If
      If (lMemFlags And fIsIdentityMember) > 0 Then
      rec("IsIsIdentityMember") = 1
      End If

      'Aggregate member, then set the aggregate expressions.
      if (lMemFlags And fHasAggrExp) > 0 then
      rec("ExpressionStr") = strAggrExp
      End if
      if (lMemFlags And fIsDimension) > 0 then
      rec("IsDimension") =1
      End if
      if (lMemFlags And fIsMeasure ) > 0 then
      rec("IsMeasure") = 1
      End if
      rec("TypeName") = strMemDefType
      rec("__Commit") = 1
      rec.Fields.Update
      rec.Close
      End Sub

      '----------------------------------------------------------------------
      ' Procedure: CreateRelationDef
      ' Purpose: Create a Relation Definition
      ' Notes : The classes that the parent and child referred to must
      ' exist. The Keydefinition for the parent must exist
      ' (1-M).
      '
      '----------------------------------------------------------------------
      Sub CreateRelDef(objConn, strRelName, strClsParent, strClsChild, _
      strKeyParent, iRelType)
      Dim rec
      'On Error Resume Next
      WScript.Echo "DBG: Rel : " & strRelName
      set rec = CreateObject("ADODB.Record")
      rec.Open "Relation/" & strRelName, objConn, adModeWrite, _
      adCreateOverwrite
      rec("ParentClassName") = strClsParent
      rec("ParentClasskey") = strKeyParent
      rec("ChildClassName") = strClsChild
      rec("RelType") = iRelType
      rec("__Commit") = 1
      rec.Fields.Update

      rec.Close
      Set rec = Nothing
      End Sub

  • Now that we have the event class in the Data Warehouse, you will notice that the Data Warehouse database has a new table created, which is the following:
    • MusicDownload    - This is where the events will be stored.  The events are parsed from the IIS logs, resolved, processed and added to this table. 
  • Now we need to add the event information to the CommerceEvent table, we do this by running the below Sql commands.  You can modify these commands for your specific event and database.
    • INSERT INTO [Startersite_datawarehouse].[dbo].[CommerceEvent]([CommerceEventID], [CommerceEventClassName], [CommerceEventInternalFlag], [CommerceEventMemberName], [StorageClassName], [StorageMemberName])
      VALUES(0x000000001000, 'MusicDownload', 0, 'Artist', 'MusicDownload', 'Artist')
      INSERT INTO [Startersite_datawarehouse].[dbo].[CommerceEvent]([CommerceEventID], [CommerceEventClassName], [CommerceEventInternalFlag], [CommerceEventMemberName], [StorageClassName], [StorageMemberName])
      VALUES(0x000000001001, 'MusicDownload', 0, 'Album', 'MusicDownload', 'Album')
      INSERT INTO [Startersite_datawarehouse].[dbo].[CommerceEvent]([CommerceEventID], [CommerceEventClassName], [CommerceEventInternalFlag], [CommerceEventMemberName], [StorageClassName], [StorageMemberName])
      VALUES(0x000000001002, 'MusicDownload', 0, 'Title', 'MusicDownload', 'Title')

 

If you want to see the sample project and also the scripts used, I have uploaded the project as a zip file in our GotDotNet Workspace located here

For our next part of the series, I will show you how to create a new report that utilizes the MusicDownload event. 

Hope this helps!

Alan

Why is my Hits Count the same for all pages in Sql Server 2005?

So you are seeing that your Hits Count on your Top Requested Pages report indicating that all pages have the same exact hit count?  We have identified that this a problem which is traced to the Page Usage cube definition in Sql Server 2005.  This does NOT affect Sql Server 2000 cube definitions. 

Here is how to fix this issue:

  • Open Sql Server Management Studio
  • Connect to the Analysis Server that contains the Commerce Server Analysis database.
  • In the Page Usage Cube - And use the Create To Scripting option to output the cube create script to a file (or output window).
  • Add the below snippet to the cube definition script:
    • The code addition begins with <Dimension xsi:type="RegularMeasureGroupDimension">
    • <Cube xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ID>Page Usage</ID>

      ....

      <MeasureGroups>
      <MeasureGroup>
      ...
      <Dimensions>
      ...
      <Dimension xsi:type="RegularMeasureGroupDimension">
      <CubeDimensionID>Uri</CubeDimensionID>


      <Attributes>
             <Attribute>
                     <AttributeID>Uri attribute</AttributeID>
                     <KeyColumns>
                           <KeyColumn>
                                 <DataType>BigInt</DataType>
                                 <Source xsi:type="ColumnBinding">
                                        <TableID>HitsInfo</TableID>
                                        <ColumnID>uriKey</ColumnID>
                                 </Source>
                           </KeyColumn>
                    </KeyColumns>
                    <Type>Granularity</Type>
             </Attribute>
      </Attributes>

      </Dimension>

  • Delete the existing Page Usage Cube
  • Create the new Page Usage cube using the updated create script.

That's it - you should see updated hits count for your requested pages in Commerce Server reports.

Hope this helps!

Alan

Importing Web Logs from different sources in a Web Farm Scenario

Consider the scenario where you have multiple web log sources (let's say you have mulitple web servers for your site) and you want to import those web logs in parallel.  This allows requests by a single user served by different sources be counted in a single user's visit. 

Here is a sample vb script that illustrates how to invoke the web log import across multiple data sources. 

Note:  You need to get your data source names from the ServerGroup table in your data warehouse.

(A special thanks to Brian Blum for the script content)

Dim ImportObj 'As Object

Dim error

Dim Shell

set Shell = WScript.CreateObject("WScript.Shell")

Dim ProcEnv

set ProcEnv = Shell.Environment("Process")

Dim localDbServer

localDbServer = ProcEnv("ComputerName")

'Import tracing flags - Not required.

ProcEnv("TraceParseHits")  = "true"

ProcEnv("TraceParseCookie")  = "false"

ProcEnv("TraceParserStats")  = "true"

ProcEnv("TraceInferenceSteps")  = "false"

ProcEnv("TraceIEStatistics")  = "false"

ProcEnv("TraceFilters")  = "false"

ProcEnv("TraceHitStructureOnFilter")  = "false"

ProcEnv("TraceIEJobCreate") = "false"

ProcEnv("TraceMaxHits") = "false"

ProcEnv("TraceOpenUserVisits")  = "false"

ProcEnv("TraceOverlapTime") = "True"

ProcEnv("BenchMarkParser") = "false"   

ProcEnv("BenchMarkIE") = "false"

Dim LogDataSource(1)

LogDataSource(0) = "Log Data Source 1"   ' Data Source name from the ServerGroup table

LogDataSource(1) = "Log Data Source 2"   ' Data Source name from the ServerGroup table

Set ImportObj = WScript.CreateObject("Commerce.PrivateDTSWebLogImport")

On Error Resume next

error = ImportObj.Init(localDbServer, localDbServer, "startersite_datawarehouse", "dwschema", "", "", "StarterSite")

ReDim LogFiles(1) 'As String

LogFiles(0) = "D:\Logs\S120060901.log"

LogFiles(1) = "D:\Logs\S220060901.log"

error = ImportObj.AddLogDataSource(LogDataSource(0), LogFiles(0), 1)

error = ImportObj.AddLogDataSource(LogDataSource(1), LogFiles(1), 1)

error = ImportObj.Run()

WScript.DisconnectObject ImportObj

Set ImportObj = Nothing

 

Hope this helps!

-Alan

How to Debug the Data Warehouse

Some of you might wonder, how do I debug the Data  Warehouse Import Tasks?  There are two options:

  1. Perform a Sql Trace against the Data Warehouse database.
  2. Run the Data Warehouse debug server.  The debug server is a utility which allows you to see trace output from the OLE DB provider for Commerce Server. 
    1. To run the debug server, open the command prompt window and navigate to "C:\Program Files\Common Files\Microsoft Shared\Enterprise Servers\Commerce Server\" and execute: "CSDWDbgSrv.exe -f traceoutput".  This will create a text file name with "traceoutput" as a prefix and a time stamp as the suffix. 

Hope this helps!

-Alan

Where is the Data Warehouse Documentation?

Many of you might wonder where the Data Warehouse documentation is located.  It's not bundled with the product documentation but rather, thanks to our hard working Program Writers, available online as of today!  Further, you will soon be able to download the documentation so that you can have the content on your local Commerce Server installation.

We are refining and updating our documentation so expect more content to come!

Enjoy and hope this helps!

-Alan

How to extend the Data Warehouse to include a custom Commerce Server event (Part 1)

Here I am going to show you how to write your own custom Commerce Server event and utilize it in the Data Warehouse for reporting purposes.  In this case, we are going to create a fictitious MusicDownload event, which, if you have a music Commerce Server site, can record an event on every music download.  This event will keep track of the Artist, Album, and Title.  This will be a two part series where the first part focuses on the custom event and part 2 focuses on extending the Data Warehouse. 

  • Let's create a new DLL C# project.  We need to Add a Reference to the Microsoft.CommerceServer.Runtime dll.  You can find this dll in the C:\Program Files\Microsoft Commerce Server 2007\Assemblies\ directory.
  • So now we create the Class MusicDownloadEvent.  To have a Commerce Server event, we need to extend the BaseCommerceEvent, thus overriding the Validate Method.  Here is the entire class with comments below:

        1 using System;

        2 using System.Collections.Generic;

        3 using System.Text;

        4 using Microsoft.CommerceServer.Runtime;

        5 

        6 namespace CompanyName.Project.MusicDownloads

        7 {

        8     [CommerceEvent("MusicDownload")]

        9     public class MusicDownloadEvent : BaseCommerceEvent

       10     {

       11         #region Members

       12         string _title;

       13         string _artist;

       14         string _album;     

       15         #endregion

       16 

       17         /// <summary>

       18         /// Default Constructor

       19         /// </summary>

       20         public MusicDownloadEvent()

       21             : base()

       22         {

       23 

       24         }

       25 

       26         public MusicDownloadEvent(string title, string artist, string album)

       27         {

       28             _title = title;

       29             _artist = artist;

       30             _album = album;

       31 

       32         }

       33 

       34         [CommerceEventMember("Artist")]

       35         public string Artist

       36         {

       37             get { return _artist; }

       38             set { _artist = value; }

       39         }

       40 

       41         [CommerceEventMember("Album")]

       42         public string Album

       43         {

       44             get { return _album; }

       45             set { _album = value; }

       46         }

       47 

       48         [CommerceEventMember("Title")]

       49         public string Title

       50         {

       51             get { return _title; }

       52             set { _title = value; }

       53         }

       54 

       55         /// <summary>

       56         /// Validates that this is a valid Event

       57         /// </summary>

       58         /// <returns></returns>

       59         public override bool Validate()

       60         {

       61             if (string.IsNullOrEmpty(_title) ||

       62                 string.IsNullOrEmpty(_artist) ||

       63                 string.IsNullOrEmpty(_album))

       64             {

       65                 return false;

       66             }

       67             return base.Validate();

       68         }

       69     }

       70 }

  • You notice that we had to apply attributes to the class indicating that this is a Commerce Event with the name "MusicDownload".  This is required. 

        8  [CommerceEvent("MusicDownload")]

        9     public class MusicDownloadEvent : BaseCommerceEvent

  • You also notice that each property that we want to include in the event must have the attribute CommerceEventMember, with the event name as a parameter, as illustrated below:

       34  [CommerceEventMember("Artist")]

       35         public string Artist

       36         {

       37             get { return _artist; }

       38             set { _artist = value; }

       39         }

  • Once you compile and sign this dll, you need to add the DLL as a reference in the site's Visual Studio project. 

  • Next, you need to add the entry for the event in your web.config file.  It's important to note that the assembly name must be fully qualified.  Here is what our MusicDownloadEvent looks like in the web.config file:

 <add className="CompanyName.Project.MusicDownloads.MusicDownloadEvent, CompanyName.Project.MusicDownloads, Version=1.0.0.0, Culture=neutral" id="MusicDownload" loggingEnabled="true"/>

  • Now, let's create a very simplistic Aspx page that uses this event, here it is below:

        1 using System;

        2 using System.Data;

        3 using System.Configuration;

        4 using System.Collections;

        5 using System.Web;

        6 using System.Web.Security;

        7 using System.Web.UI;

        8 using System.Web.UI.WebControls;

        9 using System.Web.UI.WebControls.WebParts;

       10 using System.Web.UI.HtmlControls;

       11 using CompanyName.Project.MusicDownloads;

       12 using Microsoft.CommerceServer.Runtime;

       13 

       14 

       15 public partial class MusicDownload : System.Web.UI.Page

       16 {

       17     protected void Page_Load(object sender, EventArgs e)

       18     {

       19         MusicDownloadEvent evt = new MusicDownloadEvent("Back in black", "AC/DC", "Unknown");

       20         CommerceContext.LogCommerceEvent(evt);

       21 

       22     }

       23 }

  • Next Step is to Extend the Data Warehouse to include this event.  This will be covered in Part 2, where I hope to have some utilities that will make it easy for you to extend!

 

Hope this helps!

 

-Alan

Commerce Server 2007 Startersite CTP Now Available!

We are pleased to announce that the CS2007 Startersite CTP is now available through our Microsoft Connect site.  For more details, see Ryan Donovan's Post here!

Enjoy and please give feedback through the Newsgroups (good or bad - seriously!). 

-Alan

Orders Adapter Purchase Order Update and Welcome Max Akbar to Commerce Server blogging!

There have been a lot of questions on whether you can use the Biztalk Orders Adapter on an extended Orders system for Purchase Order updates.  The answer is a yes....but, for updates, you can only update Strongly Typed Properties (STP).  The Orders Adapter will not update Weakly Typed Properties (WTP), regardless of whether they are mapped to storage or not.  It will also not update WTP on the base Orders system as well.  

I would also like to welcome a colleague of mine to the world of Commerce Server blogging, it's Max Akbar.  He already has posted some very valuable post:

I expect some great information from Max's blog.

 

Hope this helps!

Alan

Why aren't my Profile objects copied to the Data Warehouse?

In Commerce Server 2007, using our profile system to create Users (UserObjects), Addresses and Currency objects that you would like to transfer (via DTS Import) to a site level Data Warehouse, you must remember the following:

On all Guid values in a profile, you must include a bracket before and after the Guid in order for the DTS Import to successfully import the profile object.  For instance, here is example of a Guid which would NOT work with our Data Warehouse.  This is a Guid from the u_address_id, which is part of the Address schema:

000025df-2143-4e09-b2db-05bc8f873e34

In order for that Address cooresponding to the above Guid to be successfully imported, it must be modified/created like this:

{000025df-2143-4e09-b2db-05bc8f873e34}

It's imperative that your Commerce Server site code take this into account if you plan on integrating your Commerce data into a Data Warehouse!

 

Hope this helps!

Alan

More Posts Next page »
Page view tracker