BizTalk RFID knocked my socks off…yet again!!!

BizTalk RFID knocked my socks off…yet again!!!

I’ve got a RFID project in the pipeline and I’m doing a ‘little playing’ at this point
seeing how far I can go through the APIs given this certain Reader and BizTalk
RFID Client APIs
. (I’m home and hosed on the BizTalk RFID APIs, but the questions
are more around the particular Provider AND what the device can/can’t do)

So I decided to venture a little further………..

Fired up a VPC and seeing this Reader is a USB connected device, (and as we know that
VPC/Virtual Server/Hyper-V 2008 does not share USB ports!!! After a little pain I
found a 3rd party software piece that did the job!) had to share it from another physical
host where the Reader is plugged into.

After a little playing with Provider/Device Settings within BizTalk RFID Manager –
away we go.

I decided to cut some code and do a GetDeviceCapabilities(…) sort
of call.

Check this out!!!!!

Line 25 – was my call on the Open Connection.

** I decided to run the code in debug mode and entered the same command in the Intermediate
Window

This was the part that took the cake….it’s got a whole collection of ENGLISH
TEXT as to what the device does!

If you’re like me…so many of these things fall down to byte structures with certain
bits here and there indicating different capabilities.

HOW GOOD IS THIS!!!! Well done to the RFID Team…..it’s great to have APIs that make
sense…. 🙂 (mostly smile_eyeroll)

VHD Heaven – MS has a little stash for download

I came across this Microsoft
Page
while on my travels which lets you browse for your VHD by product!!!!!

e.g. SQL 2008, BizTalk, SharePoint, VS2008 etc etc. Grab the VHD for your needs.

They are public domain VHDs so I’m guessing they’re ‘limited’ in some way (probably
time) – which means don’t go building your VOIP/RFID Corporation on them 🙂

Have fun!

Speaking at Developer Summit on Masterdata Management using BizTalk 2006

I recently spoke at the leading developer conference here in Sweden called Developer Summit. The talk was called Masterdata Management using BizTalk 2006. The slides can be found here.

I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like David Chappell, Jim Webber, Dan North and Christian Weyer in Sweden is really great!

This year I also liked the mix of presentation as some where more general presentation as for example Benjamin Ling who’s the director of platform at Facebook and who gave an insight to how the platform is managed and developed. I also really enjoyed (besides the obvious ones as for example Christian Weyer’s WCF talk) Frans Hanel’s talk on the history and architecture behind a major price comparison site called prisjakt.nu – very interesting and a great technical mix in otherwise Microsoft focused conference.

Speaking at Developer Summit on Masterdata Management using BizTalk 2006

I recently spoke at the leading developer conference here in Sweden called Developer Summit. The talk was called Masterdata Management using BizTalk 2006. The slides can be found here.
I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like David Chappell, Jim Webber, […]

BizTalk Server 2006R3

By now many of you will have heard the announcement for BizTalk Server 2006 R3. You can read about it on Steve Martin’s blog.

In addition to being a “synching” release that enables compatibility with SQL 2008 and VS.NET 2008, the high points (from the post) are:

  • New web service registry capabilities with support for UDDI (Universal Description Discovery and Integration) version 3.0
  • Enhanced service enablement of applications (through new and enhanced adapters for LOB applications, databases, and legacy/host systems)
  • Enhanced service enablement of “edge” devices through BizTalk RFID Mobile
  • Enhanced interoperability and connectivity support for B2B protocols (like SWIFT, EDI, etc)
  • SOA patterns and best practices guidance to assist our customer’s implementations

I think the most interesting part is the UDDI bit. This marks a migration of UDDI from the base OS (in Win2K3) into BizTalk Server. When I first saw that, I was surprised, but, thinking about it, it really makes a lot of sense. The migration of registry functionality is actually a steeping stone step, moving us closer to what Oslo will bring, where the process server is tightly tied to the registry (now) or repository (later, in Oslo).

This is also great news and a really good move for current BizTalk devs, as hopefully it will help move registry access more into the mainstream. And once you drink the registry koolaid, you’re well on your way to ESB nirvana 🙂

Technorati Tags: BizTalk,SOA,ESB Guidance,Oslo,ESB

Writing BizTalk context properties to a message from a WCF service using behaviors

Writing BizTalk context properties to a message from a WCF service using behaviors

The new WCF adapter in BizTalk 2006 R2 offers a lot of new possibilities. One of those is to write data to the BizTalk Message context properties directly from an exposed WCF Service. A practical use of this technic could be to write the username from the Windows credentials of the calling client into the context of the BizTalk message. This could be useful as this information is encrypted in messages that are received via the WCF adapter and isn’t possible to read when inside BizTalk. I’ll try and demonstrate the technique in this post.

If you have used the SOAP adapter before you might know that all you had to do was to turn on Windows based security for the exposed SOAP service and the username was automatically promoted to the context of the incoming BizTalk message. That username could then be used for routing, tracking which user called the service or using the value in plain text when communicating further to other connected systems. However using the WCF adapter this is not true anymore – when using the new WCF Message Security model the username and password is encrypted in the message and once the message is received by BizTalk it’s to late to read it. Basically we have to read the username in the actual service and write it into our own context property (that doesn’t get encrypted).

One way of achieving this is to read the username in the service and then to add it to the WCF Message Headers. All WCF message headers will by default be written to a the BizTalk Message context property called InboundHeaders (in the http://schemas.microsoft.com/BizTalk/2006/1/Adapters/WCF-properties namespace). First we’ll create an EndpointBehavior that will use a MessageInspector to add the username to the message header. Finally we create BehaviorExtensionElement so we can use a WCF Custom Binding in BizTalk and configure it to add our new behavior.

Creating the new EndpointBehavior

To create the configurable behavior we’ll need the three classes we mentioned above.

  1. A class that implements the IDispatchMessageInspector interface to handle to reading and writing to the actual message.

  2. A class that implements the IEndpointBehavior interface to define what kind of endpoint we’re creating and what it should do.

  3. A class that implements the BehaviorExtensionElement abstract class to create the behavior and make it configurable.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Description;
    using System.ServiceModel.Configuration;

    namespace CustomWCFProperties.Behavior
    {
    ///


    /// PromoteUserNameMessageInspector implements IDispatchMessageInspector and adds the name from the WindowsIdentity to a WCF header called WindowsUserName in the http://CustomWCFProperties.Schema namespace. BeforeSendReply only returns as we’re not interested in handling the response.
    ///
    public class PromoteUserNameMessageInspector : IDispatchMessageInspector
    {
    #region IDispatchMessageInspector Members

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">object</span><span style="color: #000000"> AfterReceiveRequest(</span><span style="color: #0000ff">ref</span><span style="color: #000000"> System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            </span><span style="color: #0000ff">string</span><span style="color: #000000"> windowsUserName </span><span style="color: #000000">=</span><span style="color: #000000"> ServiceSecurityContext.Current.WindowsIdentity.Name;
            request.Headers.Add(MessageHeader.CreateHeader(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">, windowsUserName));
            </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> BeforeSendReply(</span><span style="color: #0000ff">ref</span><span style="color: #000000"> Message reply, </span><span style="color: #0000ff">object</span><span style="color: #000000"> correlationState)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">#endregion</span><span style="color: #000000">
    }
    
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"><summary></span><span style="color: #008000">
    </span><span style="color: #808080">///</span><span style="color: #008000"> PromoteUserNameBehavior implements IEndpointBehavior and adds a message inspector to the dispatch behavior. Doesn't use any binding parameters, doesn't validate any configuration etc and can't be used in a client (only in a service).
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"></summary></span><span style="color: #808080">
    

    public class PromoteUserNameBehavior : IEndpointBehavior
    {
    #region IEndpointBehavior Members

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            </span><span style="color: #0000ff">throw</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Exception(</span><span style="color: #000000">"</span><span style="color: #000000">The method or operation is not implemented.</span><span style="color: #000000">"</span><span style="color: #000000">);
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(</span><span style="color: #0000ff">new</span><span style="color: #000000"> PromoteUserNameMessageInspector());
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> Validate(ServiceEndpoint endpoint)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">#endregion</span><span style="color: #000000">
    }
    
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"><summary></span><span style="color: #008000">
    </span><span style="color: #808080">///</span><span style="color: #008000"> Defines the behavior.
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"></summary></span><span style="color: #808080">
    

    public class PromoteUserNameBehaviorElement : BehaviorExtensionElement
    {
    protected override object CreateBehavior()
    {
    return new PromoteUserNameBehavior();
    }

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">override</span><span style="color: #000000"> Type BehaviorType
        {
            </span><span style="color: #0000ff">get</span><span style="color: #000000"> { </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">typeof</span><span style="color: #000000">(PromoteUserNameBehavior); }
        }
    }
    

    }

Finally we have to sign the assembly using a strong key and add it to the GAC.

Configure the machine.config

As we need BizTalk and the WCF adapter to pick up the need behavior and make it possible to configure our receive port we need to to add the behavior element to the machine.config.aspx). The easiest way of doing this is to use the new WCF Service Configuration Editor tool and point to the machine.config file.

After the dll been added and the machine.config file has been saved the the line below should have been added to the element (that is if you use the same strong name key as in the sample project I’ve linked here).

<div><span style="color: #0000ff"><</span><span style="color: #800000">add </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addCustomWCFProperties"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="CustomWCFProperties.Behavior.PromoteUserNameBehaviorElement, AddCustomWCFPropertiesBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=705e34637fdffc54"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/></span></div>

Create the BizTalk Receive Port and Receive Location

Next thing to do is to start the BizTalk WCF Service Publishing Wizard. Choose to publish a service endpoint and make sure you enable metadata and create a receive location. In this example we’ll next choose to “Publish schemas as WCF service” and then define our service by naming service operations and so on.

When you then browse to the URL you choose to publish your service to you’ll see the nice example of how to instance the service you just defined.

If we then send a request message to service (you’ll find a client as part of the attached solution here) and inspect the message and its context properties in BizTalk we’ll see that the username of the calling client is nowhere to be found.

Configure a WCF-Custom binding and adding a Endpoint Behavior

To add the username to the message context we’ll need to add our newly created behavior to our service. We’ll do this by switch the service over to use a WCF-Custom binding to enable configuration. We then need to add the URL in the address field, define the binding type to a wsHttpBinding and to add our addCustomeWCFProperties behavior to the list of endpoint behaviors.

>
> [![note](../assets/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-thumb.gif)](../assets/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-2.gif) NOTE: there is a limitation in the BizTalk WCF implementation in that you can’t create the WCF-Custom receive location that uses a HTTP in-process based binding (like the wsHttpBinding used in a WCF-Custom endpoint is) first and then use the WCF Publishing Wizard to only publish a metadata endpoint.
>
>

>
> [Richard Seroter writes about it here](http://www.topxml.com/code/cod-72_10213_biztalk-and-wcf-part-v-publishing-operations-patterns.aspx) and I found the same thing to be true.
>
>

>
> _”This error doesn’t have to do with mixing MEX endpoints and “regular” endpoints in the same IIS web site, but rather, creating MEX endpoints for in-process HTTP bindings seems to trigger this. **Note that an IIS-hosted MEX endpoint CAN be created for IIS-hosted HTTP endpoints, but not for in-process hosted HTTP endpoints.”**_
>
>

>
> If you however choose a different binding that Http or (as in this case) publishes the metadata first and then switches over to a custom binding you’re ok.
>
>

If we then post another message to the service and inspect the message we’ll see that the behavior actually added a header and that it’s part of our BizTalk context properties. The adapter is also smart enough to know that this header isn’t part of the original headers and therefore stores in it’s own field within the context properties (you’ll find as part of the InboundHeaders block as well).

One problem remains – the actual value of the user is nested inside a XML node and the property isn’t promoted.

Extract and promote the value

To extract and promote the value we use an old fashion pipeline component using the following code in the execute method (the complete project is part of the downloadable sample project).

<div><span style="color: #000000">        </span><span style="color: #0000ff">public</span><span style="color: #000000"> IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            StringReader reader </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> StringReader(inmsg.Context.Read(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">).ToString());

            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (reader </span><span style="color: #000000">!=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">)
            {
                XPathDocument document </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> XPathDocument(reader);
                XPathNavigator navigator </span><span style="color: #000000">=</span><span style="color: #000000"> document.CreateNavigator();
                </span><span style="color: #0000ff">string</span><span style="color: #000000"> value </span><span style="color: #000000">=</span><span style="color: #000000"> navigator.SelectSingleNode(</span><span style="color: #000000">"</span><span style="color: #000000">/</span><span style="color: #000000">"</span><span style="color: #000000">).Value;
                inmsg.Context.Promote(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">, value);
            }

            </span><span style="color: #0000ff">return</span><span style="color: #000000"> inmsg;
        }</span></div>

All the component does is reading the XML node the value exists inside and then it reads the actual value. Finally it writes the value back and promotes it. To be able to promote the value we also have to have a Property Schema deployed with a corresponding property name and namespace (WindowsUser and http://CustomeWCFProperties.Schema in this case).

The end results looks something like this.

The username is extracted and promoted and available for example for tracking or to for example use in a routing scenario.

This technique could of course be used for all kinds of scenarios where you like to add information to the context properties and could potentially replace a lot of the classic scenarios for custom pipelines.

All kind of comments are of course more than welcome!

Download the sample solution here.

Why Safari May Become the Browser of Choice!

If you're a web designer, web developer or just someone that keeps up with the latest "Web 2.0" technologies, you know that a lot of progress is being made by ALL the major browsers to become "standards compliant". You also know that the Web Standards Project has created a number of "Acid" tests that help all the browser developers ensure that their browser works as "expected". If you're an experienced web designer or developer, you probably use several different browsers (IE, Firefox, Opera, Camino, Safari, etc.) to test your sites against everyday.

What you may not be aware of is some of the very "advanced" features Safari (WebKit actually) has in the works which may well change the way we think about developing Web 2.0 applications.

  1. Web Fonts
  2. Client-Side Database Storage
  3. CSS3 Transforms
  4. CSS3 Animation
  5. SVG Support
  6. CSS Gradients
  7. CSS Box Shadow
  8. And Many, Many More…

If you look at any one of these new features individually, they are very cool! If you look at integrating these new features together, you begin to see the potential for replacing today's Javascript (Ajax) "eye-candy" with native browser rendering support!

And why you ask, is WebKit (and Safari) pushing these advanced features out the door so quickly?

Safari on iPhone!

Starts you thinking, doesn't it!

Currently listening to: Eric Merienthal's "Just Around the Corner"

Upgrade Windows SDK link

If you are reading the upgrade documentation

http://www.microsoft.com/downloads/details.aspx?FamilyID=df2e8a88-fb23-49a4-9ac7-d17f72517d12&displaylang=en

(Upgrading to BizTalk Server 2006 R2 from BizTalk Server 2006.doc)

“To apply the HIPAA33ForR2.mst transform”

You can download the Windows SDK from http://go.microsoft.com/fwlink/?linkid=75636

That link doesn’t work, you need to go here and choose the right environment:

http://msdn2.microsoft.com/en-us/windowsserver/bb980924.aspx

Thanks windows SDK blog for the quick turn around!