Identity Management and CardSpace

Identity Management and CardSpace

Identity Management is not one of my priorities, but it’s a subject I’ve been interested about for sometime, and which is very related to the work I am doing at the moment. It all started with Kim Cameron’s Identity Blog and his Laws of Identity.


The most visible face of this whole Identity Management issue is the multiple logins people have to make while browsing the internet, creating accounts at several sites to access their services or contents. I’ve had to resort to password-management software, but the problem is deeper than memorizing your multiple logins and passwords, especially when financial transactions are involved.


Probably the best description of the problem, or at least an introduction (and also a demonstration of what great presentation skills are), is 2005’s *** Hardt’s Identity 2.0 introduction to the concept of Digital Identity.


Yesterday I listened to Hanselman’s Identity podcast, and came home to read more and try Windows CardSpace (.Net’s 4th pillar). CardSpace is included in .Net 3.0, but if you are using Windows Vista, it’s built in (just type “card” on the start menu and “Windows CardSpace” shows up :-)). I started it and created a simple card with some of my information, and went looking for a place to use it. I found one at .Net 3.0’s site, the SandBox. The SandBox is a Community Server installation with CardSpace support for user registration and login. When I registered, I got into Vista’s Secure Desktop mode, with CardSpace open, selected the card I wanted to present to the SandBox (I got shown what fields the SandBox would get from the card), and BAM, I was registered and logged in. All I had to do was to pick a nickname. Later I got an email with an username and password, just in case I want to log in using “traditional” methods.


CardSpace is based on some of the WS-* standards, such as WS-Security and WS-Trust, which supposedly make it both “safe and standard“, but what I like the most is really the end user experience. For me, the idea of no longer having to create logins everywhere, and being able to select the specific pieces of information I want to share with each site I visit, is a very interesting prospect. The question is, obviously, if there will be acceptance to this outside Microsoft, or if this will be another Passport/Hailstorm situation. A major difference, the way I see it, is that information is stored in your computer, not at Microsoft somewhere, so the trust obstacles are aleviated.


As to this being available in public sites, I have no idea. I found a comment in a blog saying that Community Server 2.1 should include full CardSpace support soon, for all users to install, but found no details on this having happened yet, and found no major implementation of it yet (time to throw out Passport).


One final note, out of curiosity: when the screen greys out in Vista, you are in what MS calls “Secure Desktop” mode. This is Windows’ mode that is used, for example, when you log into your Windows computer (running Xp, Vista, 2003, …) . This mode is designed to block out processes from execution, to make sure you are inserting your password in a secure environment where no keyloggers or such can work. In Vista, you get a greyed out/transparent background when you are in this mode (which is just a UI thing, the grey is really a screenshot with transparency 🙂 Human Factors stuff). More information about this here and here.


Just before I go: there’s already Firefox support for CardSpace, and Kim Cameron has an implementation of the identity system in Php. Also note that CardSpace can be used for much more than simple site login, I just wanted to blog about it because the first impression it leaves was really positive.

Assembly loading policy from the GAC

UPDATE: This does not apply to BizTalk … I’ve made an update post here. Sorry.

We’re working with a lot of code libraries that we use in different parts of our BizTalk solutions. As the are used on several servers and by loads of different “BizTalk parts” (both in orchestrations and maps) it’s important that we always keep the version number of the assemblies up to date. That means that every little change should increase the current version number. But as they are used in so many places people have started to skip this step as they thought they had to compile all parts that should use the new code (say it’s a bug fix and you’d like all “using parts” of the assembly to load the updated version). This is where GAC loading policy comes to the resource!

First we have to understand that every .NET assembly is identified using four characteristics:

  • Assembly name
  • Major or minor version
  • Public key token
  • Culture

Then we need to know that the first version number in for example version 1.1.2.1 is the major version. The second is the minor version and the third and fourth are build, revision version number. So this means that if you have 1.1.2.1 installed and make a minor change the easiest way to use the new assembly is to change the one of the build or revision numbers (the third or fourth number). Then the CLR will load the new assembly without any other changes!

But sometimes we have to change the minor or major version – and we still don’t have to recompile a thing! We can use a publisher policy file. This is an example of such a file defined for version 1.0.0.0 moving to 2.0.0.0.

<div><span style="color: #0000FF; "><</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">runtime</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">assemblyBinding </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">="urn:schemas-microsoft-com:asm.v1"</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">dependentAssembly</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
                </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">assemblyIdentity </span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="BaseHelper"</span><span style="color: #FF0000; "> publicKeyToken</span><span style="color: #0000FF; ">="18517ea673f8584b"</span><span style="color: #FF0000; "> culture</span><span style="color: #0000FF; ">="neutral"</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/></span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">bindingRedirect </span><span style="color: #FF0000; ">oldVersion</span><span style="color: #0000FF; ">="1.0.0.0"</span><span style="color: #FF0000; "> newVersion</span><span style="color: #0000FF; ">="2.0.0.0"</span><span style="color: #0000FF; ">/></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">dependentAssembly</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">assemblyBinding</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">runtime</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">></span></div>

This kb article describes what to do next:

  1. Change the version and recompile. The first step is to create the new version of your component. After you’ve done that, you will need to modify the version number in the AssemblyInfo file for your component.
    Create the publisher policy file. Create the publisher policy file for the assembly using the format shown above.
    Use Assembly Linker (Al.exe) to create the publisher policy assembly. The Assembly Linker is included with the .NET Framework SDK. To create the publisher policy assembly that redirects a binding from version 1.0 of Website.dll to version 2.0 using a publisher policy file called website.config, run the following command:

    al /link:BaseHelper.config /out:policy.1.0.BaseHelper.dll /keyfile:c:keyfile.snk

This command will create a new assembly called policy.1.0.BaseHelper.dll. This naming convention is important, as indicated in the “What Is a Publisher Policy Assembly?” section.

  1. Install the publisher policy assembly into the Global Assembly Cache. The publisher policy assembly is installed into the GAC. It will be used by the .NET runtime when any application attempts to bind to version 1.0 of the BaseHelper.dll, and it will force the application to bind to the new version automatically.

  2. Install the new version into the Global Assembly Cache. Install the new version of the component into the GAC. After the new version has been installed, the old version can be safely removed.

So no more excuses for not updating the version number!

Using the BizTalk Server R2 BAM interceptor for WF

v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}

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.

Visual Studio Template for SharePoint Solution Packages (WSP)

[Via Mark] Every SharePoint developer knows that creating SharePoint Solution Packages (WSP files) for deploying your web parts, event handlers, features, … is the way to go: it allows the SharePoint administrators to easily deploy the customizations, even scheduled deployments and multi front-end-webserver deployments are supported. But every SharePoint developer also knows that creating Sharepoint Solutions Packages is … wel, let’s put it nicely: not a lot of fun to do. 🙂

Vince Rothwell seems to have a very clean solution for this: a Visual Studio 2005 Template which generates a SharePoint Solution. Read the details in his blog post.

BizTalk 2006 issues with SQL 2005 SP1 – watch out! (SSIS wont start)

After upgrading a BTS 2006 B1 R2 vpc image to Win2003 R2 all was not good.

Services were not starting and erroring all over the place (worked fine before Win2003
R2) and they seemed to be centered around SQL.

So I thought I’d ‘re-apply’ SQL 2005 SP1….and this fixed some of the problems….others
still remained.

I was getting “Event ID 7000: Sql Server Integration Services did not start or respond
to a control message in a timely fashion”

(I was also getting this with Analysis Services)

After much research here’s the circumstances that cause the problem:

(1) machine running sql is not directly connect to the internet (data
centers etc.) SSIS wants to go out to the internet to check the status of a certificate
or two (crl.microsoft.com…) when it starts up.

(2) SQL 2005 SP1 applied.

Solution: There are alternatives but my good buddy AB came
up trumps with Some
SQL Hotfixes to apply 

(at the bottom of his article)

I’m on the road at the moment and when looking at the post SP1 SQL Hotfixes – the
first one of a SQL Server ‘hotfix’ of 25MB scared my and my GPRS phone off 🙂

Thanks AB.

Direct link to HOTFIX HERE

BizTalk and the Connected Systems Division are hiring!

Do you have a passion for BizTalk Server and the .NET Framework? Want to build the next generations of Microsoft’s process and service platforms? Well, we’re hiring! Here’s what our HR dept has to say:


The Connected Systems Division and the BizTalk team are looking for great people to help build the next generation end-to-end application platrform.  We have several open positions and many exciting job opportunities. If you or someone you know is interested in growing his/her career in Microsoft, please send email to our recruiter, Kerry Van Voris – [email protected].

BizTalk: Wire Tap

BizTalk: Wire Tap

Debugging in BizTalk (and other async/messaging-based solutions) can be complex, and very often the UIs (the Admin Console and Hat) don’t give you enough tracking information, either because you’ve just re-deployed and lost tracking settings, or because the Sql Agent is turned off. This tends to happen frequently during development when you want to look at the body of the messages.

A very simple and very useful technique in this situation, and one I often find is not fully used, is to create a “Wire Tap”. A Wire Tap is an Integration Pattern that allows the inspection of messages that travel across a channel. In BizTalk, this translates to simply creating a (Static, One Way) Send Port that looks for specific messages (using its Filters), and sends them to some destination, typically, a file folder (SMTP email is another frequent choice). This port is not bound to any orchestration, it’s a content-based solution only.

One thing to remember about these Send Ports is that if you have a Send Port that has no filters, it catches nothing. Always remember to set up a filter. The ones I used the most are based on the message type (BTS.MessageType) and the receive port the message came in through (BTS.ReceivePortName).

I actually find that understanding and resorting to this mechanism is frequently a good indicator of the maturity of the BizTalk developer and his understanding of the pub/sub model in BizTalk Server.