January 2007 - Posts

This would be a real tragedy. Our thoughts and prays are with Jim and his family.

Posted by gsusx | with no comments

The W3C folks are not sleeping. The Semantic Annotations for WSDL and Xml Schema specification is now a W3C candidate recommendation!!

Posted by gsusx | with no comments
Filed under:

We have been waiting for this a few years now.

W3C has announced the release of eight (8) Recommendations, representing some eight years of work by members of the W3C XSL Working Group and XML Query Working Group, with widespread implementation experience and extensive feedback from users and vendors. These eight new standards in the XML Family support the ability to query, transform, and access XML data and documents. The primary specifications are "XQuery 1.0: An XML Query Language", "XSL Transformations (XSLT) 2.0", and XML Path Language (XPath) 2.0".

Now it is time for the different vendors to update the early implementations of XSLT 2.0, Xpath 2.0 and XQuery. Congratulations to the working groups!!

Posted by gsusx | with no comments
Filed under:

The new issue of the Architecture Journal is available in PDF format. The topics: Composite applications. Happy reading!!

Posted by gsusx | with no comments
Filed under:

For some time now I have been pushing the use of BizTalk BAM outside of BizTalk Server implementations. BizTalk BAM provides a generic interceptor framework to track relevant data on business processes. BizTalk Server is just one of the many products that can leverage that framework in order to add visibility into Business Processes. Finally, with the release of BizTalk R2, Microsoft provides BAM interceptor implementations for WCF and WF. Using those interceptors we can extend the classic BAM features like aggregation, tracking and alerting into generic foundations like WF and WCF.

To utilize BAM with WCF-WF we need to use two main components:

  • bm.exe, an enhanced version of the BAM deployment utility extended to modify interceptor configurations including add, remove, update, and list functionalities.
  • CommonInterceptorConfiguration.xsd, the Common Interceptor Foundation configuration XML schema. At minimum, all interceptor configurations must validate against this schema.

The WF BAM interceptor combines the above mentioned components with a custom tracking service that logs data to the BAMPrimaryImport database. Let’s explore a classic sample. I plan to explain the details of the different components of this example in following posts. Our workflow is a simple State Machine workflow that simulates a PO Process.

 

The observation model for this example was built using the Excel BAM plugin that ships with BizTalk Server. The model contains just one activity and a set of dimensions for further aggregation in the generated OLAP cubes.  The following is the XML generated by the Excel plugin.

<?xml version="1.0" encoding="UTF-16"?>

<BAMDefinition xmlns="http://schemas.microsoft.com/BizTalkServer/2004/10/BAM">

                    <Activity Name="POActivity" ID="IDD38284A4F64745409E88DC7BF608D414">

                                          <Checkpoint Name="Item" ID="IDF57663E311524757851437C1D9B8A183" DataType="NVARCHAR" DataLength="500"/>

                                          <Checkpoint Name="Quantity" ID="IDADEABF22B6C6416789C3ADF2D4CD2E59" DataType="INT"/>

                                          <Checkpoint Name="Received" ID="IDED14A7F26EC7477DA4ED63B8C08CBB86" DataType="DATETIME"/>

                                          <Checkpoint Name="Approved" ID="IDC1BADE06C3B04AC99BDDF544E84033BB" DataType="DATETIME"/>

                                          <Checkpoint Name="Shipped" ID="ID20C1465442184553929AB6B0EE49796C" DataType="DATETIME"/>

                                          <Checkpoint Name="Denied" ID="IDE88C30D7ADE5440B8F19191C288D6D74" DataType="DATETIME"/>

                    </Activity>

                    <View Name="POView" ID="IDDCA141B0E6E94D879B04CF6C4E8ED62A">

                                          <ActivityView Name="ViewPOActivity" ID="IDB0C4AA0BE204425590FB1704829D6E9F" ActivityRef="IDD38284A4F64745409E88DC7BF608D414">

                                                              <Alias Name="Approved" ID="ID6CF7A7B9BB4140218259616AA698587D">

                                                                                  <CheckpointRef>IDC1BADE06C3B04AC99BDDF544E84033BB</CheckpointRef>

                                                              </Alias>

                                                              <Alias Name="Denied" ID="ID4B6715A4FF434D61AD6B55B62DCE80EE">

                                                                                  <CheckpointRef>IDE88C30D7ADE5440B8F19191C288D6D74</CheckpointRef>

                                                              </Alias>

                                                              <Alias Name="Item" ID="IDAB2C1362300142B884A6F567D5AEEFDB">

                                                                                  <CheckpointRef>IDF57663E311524757851437C1D9B8A183</CheckpointRef>

                                                              </Alias>

                                                              <Alias Name="Quantity" ID="IDCE258F95A63B4177B383FC83F7923A1A">

                                                                                  <CheckpointRef>IDADEABF22B6C6416789C3ADF2D4CD2E59</CheckpointRef>

                                                              </Alias>

                                                              <Alias Name="Received" ID="ID6C75FDA099DE462EB145ABF00CA2AE4D">

                                                                                  <CheckpointRef>IDED14A7F26EC7477DA4ED63B8C08CBB86</CheckpointRef>

                                                              </Alias>

                                                              <Alias Name="Shipped" ID="IDE59DA0F05E7A428DA444CD2ACFA75ABE">

                                                                                  <CheckpointRef>ID20C1465442184553929AB6B0EE49796C</CheckpointRef>

                                                              </Alias>

                                          </ActivityView>

                    </View>

                    <Cube Name="POView" ID="ID1C2CF921025A47AC96A2F3382168FB08" CreateOlapCube="false" ActivityViewRef="IDB0C4AA0BE204425590FB1704829D6E9F">

                                          <Measure Name="TotalReceived" ID="ID04E27CBA4B2F4813B45BA59C3EA0BC2D" AliasRef="IDCE258F95A63B4177B383FC83F7923A1A" AggregationFunction="Sum"/>

                                          <Measure Name="TotalApproved" ID="ID915659F57AB9462BAE0E037F76CF2DF6" AliasRef="IDCE258F95A63B4177B383FC83F7923A1A" AggregationFunction="Sum"/>

                                          <TimeDimension Name="ApprovedDim" ID="ID97905E2E89734CBCA0169AC06934BE1B" TimeStampAliasRef="ID6CF7A7B9BB4140218259616AA698587D">

                                                              <TimeLevel>Year</TimeLevel>

                                                              <TimeLevel>Quarter</TimeLevel>

                                                              <TimeLevel>Month</TimeLevel>

                                          </TimeDimension>

                                          <TimeDimension Name="ReceivedDim" ID="ID61B667B6CF9F4409900B4F49EC3B6033" TimeStampAliasRef="ID6C75FDA099DE462EB145ABF00CA2AE4D">

                                                              <TimeLevel>Year</TimeLevel>

                                                              <TimeLevel>Quarter</TimeLevel>

                                                              <TimeLevel>Month</TimeLevel>

                                          </TimeDimension>

                    </Cube>

                    <Extension>

                                          <OWC xmlns:x="urn:schemas-microsoft-com:office:excel">

                                                             

                                          </OWC>

                    </Extension>

</BAMDefinition>

After generating this XML file, the next step is to deploy the observation model using the following syntax:

< installation path >\Program Files\Microsoft BizTalk Server 2006\Tracking\BM.exe deploy-all -definitionfile:< definitionfile.xml >

Once the bm.exe is completed, we need to create the interceptor configuration file which states how to map specific Workflow events and properties to BAM activities. Watch for more details about WF interceptor files in future postings. The interceptor configuration file for our example looks like the following.

<?xml version="1.0" encoding="utf-8" ?>

<ic:InterceptorConfiguration xmlns:ic="http://schemas.microsoft.com/BizTalkServer/2004/10/BAM/InterceptorConfiguration" xmlns:wf="http://schemas.microsoft.com/BizTalkServer/2004/10/BAM/WorkflowInterceptorConfiguration">

<ic:EventSource Name="Workflow1" Technology="WF" Manifest="StPO.Workflow1, StPO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>

                    <ic:BamActivity Name="POActivity">

                                          <!--Workflow Initiated-->

                                          <ic:OnEvent Name="MyWorkflowEvent" Source="Workflow1" IsBegin="true">

                                                              <ic:Filter>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetWorkflowEvent" />

                                                                                                        <ic:Operation Name="Constant">

                                                                                                                              <ic:Argument>Created</ic:Argument>

                                                                                                        </ic:Operation>

                                                                                                        <ic:Operation Name="Equals" />

                                                                                    </ic:Expression>

                                                              </ic:Filter>

                                                              <ic:CorrelationID>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>InstanceId</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                  </ic:Expression>

                                                              </ic:CorrelationID>

                                                              <ic:Update DataItemName="Received" Type="DATETIME">

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>EventTime</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                          </ic:OnEvent>

                                          <!--PO Received...-->

                                          <ic:OnEvent Name="POReceived"  Source="Workflow1">

                                                              <ic:Filter>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetActivityName" />

                                                                                                        <ic:Operation Name="Constant">

                                                                                                                              <ic:Argument>OrderReceived</ic:Argument>

                                                                                                        </ic:Operation>

                                                                                                        <ic:Operation Name="Equals" />

                                                                                    </ic:Expression>

                                                              </ic:Filter>

                                                              <ic:CorrelationID>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>InstanceId</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:CorrelationID>

                                                              <ic:Update DataItemName="Quantity" Type="INT">

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetWorkflowProperty">

                                                                                                                              <wf:Argument>Quantity</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                                              <ic:Update DataItemName="Item" Type="NVARCHAR">

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetWorkflowProperty">

                                                                                                                              <wf:Argument>ItemName</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                          </ic:OnEvent>

                                          <ic:OnEvent Name="POApproved"  Source="Workflow1">

                                                              <ic:Filter>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetActivityName" />

                                                                                                        <ic:Operation Name="Constant">

                                                                                                                              <ic:Argument>POApproved</ic:Argument>

                                                                                                        </ic:Operation>

                                                                                                        <ic:Operation Name="Equals" />

                                                                                    </ic:Expression>

                                                              </ic:Filter>

                                                              <ic:CorrelationID>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>InstanceId</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:CorrelationID>

                                                              <ic:Update DataItemName="Approved" Type="DATETIME">

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>EventTime</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                          </ic:OnEvent>

                                          <ic:OnEvent Name="POShipped"  Source="Workflow1">

                                                              <ic:Filter>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetActivityName" />

                                                                                                        <ic:Operation Name="Constant">

                                                                                                                              <ic:Argument>POShipped</ic:Argument>

                                                                                                        </ic:Operation>

                                                                                                        <ic:Operation Name="Equals" />

                                                                                    </ic:Expression>

                                                              </ic:Filter>

                                                              <ic:CorrelationID>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>InstanceId</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:CorrelationID>

                                                              <ic:Update DataItemName="Shipped" Type="DATETIME">

                                                                                  <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>EventTime</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                          </ic:OnEvent>

                                          <ic:OnEvent Name="PODenied"  Source="Workflow1">

                                                              <ic:Filter>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetActivityName" />

                                                                                                        <ic:Operation Name="Constant">

                                                                                                                              <ic:Argument>PODenied</ic:Argument>

                                                                                                        </ic:Operation>

                                                                                                        <ic:Operation Name="Equals" />

                                                                                    </ic:Expression>

                                                              </ic:Filter>

                                                              <ic:CorrelationID>

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>InstanceId</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:CorrelationID>

                                                              <ic:Update DataItemName="Denied" Type="DATETIME">

                                                                                    <ic:Expression>

                                                                                                        <wf:Operation Name="GetContextProperty">

                                                                                                                              <wf:Argument>EventTime</wf:Argument>

                                                                                                        </wf:Operation>

                                                                                    </ic:Expression>

                                                              </ic:Update>

                                          </ic:OnEvent>

                    </ic:BamActivity>

</ic:InterceptorConfiguration>

After that we need to deploy the interceptor file using one of the enhancements to the bm.exe tool.

< installation path >\Program Files\Microsoft BizTalk Server 2006\Tracking\BM.exe deploy-interceptor -filename:< icfile.xml >

The final and most important step is to add the BAM tracking service to the WF runtime. The following shows the required code which must be added to the WF host.  The additional code is highlighted below.


using System.Threading;

using System.Workflow.Runtime;

using System.Workflow.Runtime.Hosting;

using Microsoft.BizTalk.Bam.Interceptors.Workflow;

#endregion

namespace StPO

{

            class Program

              {

                            static void Main(string[] args)

                            {

                                          using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())

                                          {

                                                        AutoResetEvent waitHandle = new AutoResetEvent(false);

                                                        System.Collections.Specialized.NameValueCollection serviceParams= new System.Collections.Specialized.NameValueCollection();

                                                        serviceParams.Add("InterceptorConfigurationPollingInterval", "5");

                                                        serviceParams.Add("ConnectionString", "Integrated Security=SSPI;Data Source=.;Initial Catalog=BAMPrimaryImport");

                                                        workflowRuntime.AddService(new BamTrackingService(serviceParams));

CODE…

                                          }

                            }

              }

}

While running the workflow, the data gets saved into the BAMPrimaryImport database and aggregated in OLAP representations. At this point we can use some of the existing BAM end-user tool to get a real-time representation of the workflow activity. The following figure shows a view of the BAM Portal rendering the views of the observation model of our target workflow.



The source code for this example will be available on www.AdapterWorx.com in the next few days.

After compiling a lot of feedback from Microsoft and customers our team started working in the next version of the Service Broker adapter for BizTalk Server 2006. Yesterday we finally made available the new version in AdapterWorx (Read Joel Post). This is not a major release in terms of new features but includes significant enhancements to existing features like dynamic ports and transactional receiving.

I am still looking for testers for the R2 version of the Service Broker Adapters so if you are interested drop me line at jrodriguez@twoconnect.com

One of the main differences between .NET 3.0 and BizTalk adapter frameworks is the approach to handle metadata. Metadata is a key component of a message-based adapter framework specially when comes to interact with LOB applications. The use of metadata raises the level of abstraction of untyped send-receive operations with data that has a semantic meaning for the LOB or technology the adapter is abstracting.

 In the case of BizTalk Server Adapter framework metadata is represented as context properties or as part of the message schema itself. Both cases implied that metadata is always generated at design time (add adapter wizard, context properties, etc.); in other words there is no notion of dynamic metadata at runtime.  Metadata Exchange is always relevant in scenarios where target system artifacts changes frequently. For instance; if the signature of a stored procedure changes more than likely developers will need to recreate the schema definition using the Adapter Metadata Wizard. Also the BizTalk Adapter Framework is intended to handle low level send-receive operations but it does not provide a way to define high level LOB specific operations like ReceivePO, etc. Those operations need to be implemented using other BizTalk orchestrations.

The .NET 3.0 Adapter Framework presents a more generic way to abstract metadata. This is part given that WCF presents a more generic messaging framework compared with BizTalk Server. One of the cool features of the new adapter framework is the support for searching, browsing and retrieving metadata at both design and runtime. This is accomplished using interfaces like IMetadataBrowseHandler, IMetadataSearchHandler, IMetadataResolverHandler, etc. Taking the same previous example a .NET 3.0 adapter can query SQL Server at runtime to regenerate the metadata required to invoke the new stored procedure.  

Also the .NET 3.0 adapter framework introduces the notion of operation metadata and type metadata (based on WCF Service and Data Contract). The operation metadata is related to specific operations in the LOB system like ReceivePO, etc. The type metadata represents messages associated with those operations. The use of both Operation and Type metadata allow developers to build high level interfaces (for instance WCF services) raising the level of abstraction for the client applications.  

Posted by gsusx | 5 comment(s)
Filed under: ,

My friend Clemens Utsching and colleagues has started writing the Oracle SOA Suite best practices. The first three articles of the series are super worth reading.

Posted by gsusx | with no comments
Filed under: , ,
More Posts