A Generic WCF Service for BizTalk

I've been playing lately with a few WCF features as well as with the WCF Adapter in BizTalk Server 2006 R2. As part of that I had a need to set up a receive location using one of the WCF HTTP-based bindings.

Normally, this isn't a big deal; you can easily use the BizTalk WCF Service Publishing Wizard to create the receive location and IIS service application for an orchestration or from a set of BizTalk schemas.

However, this time I did not want to go that way. What I really wanted was just a simple receive location that would simply receive messages and submit them over to BizTalk without tying the receive location to a specific service definition. As far as I could see, the Service Publishing Wizard didn't really have an option for this, but I was confident it could be made to work.

To be honest, I did have a set of schemas I wanted to work with and even a bunch of predefined WSDL files. However, for many reasons (including the sheer complexity of the schemas and WSDL files involved) I didn't want to get that involved in my initial BizTalk message receiver and processor.

Fortunately, turns out that doing what I wanted was fairly easy stuff. In fact, it was so easy that was able to leverage an existing service I had previously created. I basically just copied the .SVC file (and renamed it) alongside the web.config file. I explicitly ignored all the stuff that normally gets generated under the App_Data directory.

I then manually created a matching receive location in BizTalk using the WCF-BasicHTTP adapter, and this worked right away perfectly for my needs!

Just in case you've never looked at what a WCF HTTP receive location generated files look like, it's actually fairly simple stuff. The SVC file contains just a single directive as expected:

<%@ ServiceHost Language="c#" Factory="Microsoft.BizTalk.Adapter.Wcf.Runtime.BasicHttpWebServiceHostFactory, Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>

You can see here that it references the WCF-BasicHTTP adapter. If you wanted to use, say, the WCF-WSHttp Adapter, then you'd use Microsoft.BizTalk.Adapter.Wcf.Runtime.WSHttpWebServiceHostFactory class instead.

The config file is pretty much the default config file generated by the Service Publishing Wizard as well:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <configSections>
      <section 
         name="bizTalkSettings" 
         type="Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkConfigurationSection,
            Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0,
            Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </configSections>
   <bizTalkSettings>
      <mexServiceHostFactory debug="false">
         <receiveLocationMappings>
            <!--add markupFileName="*.svc"
               receiveLocationName="?"
               publicBaseAddress="protocol://host[:port]" /-->
         </receiveLocationMappings>
      </mexServiceHostFactory>
      <webServiceHostFactory debug="false" />
      <isolatedReceiver disable="false" />
      <btsWsdlExporter disable="false" />
   </bizTalkSettings>
   <appSettings />
   <connectionStrings />
   <system.web>
      <compilation defaultLanguage="c#" debug="false">
         <assemblies>
            <add assembly="mscorlib, version=2.0.0.0, culture=neutral,
          60;     publickeytoken=b77a5c561934e089" />
            <add assembly="Microsoft.BizTalk.Adapter.Wcf.Common, Version=3.0.1.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
            <add assembly="Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
         </assemblies>
      </compilation>
      <authentication mode="Windows" />
   </system.web>
   <system.serviceModel>
      <behaviors>
         <serviceBehaviors>
            <behavior name="ServiceBehaviorConfiguration">
               <serviceDebug 
                  httpHelpPageEnabled="true" 
                  httpsHelpPageEnabled="false" 
                  includeExceptionDetailInFaults="false" />
               <serviceMetadata 
                  httpGetEnabled="false" 
                  httpsGetEnabled="false" />
            </behavior>
         </serviceBehaviors>
      </behaviors>
      <services>
         <service 
            name="Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance" 
            behaviorConfiguration="ServiceBehaviorConfiguration">
            <!--<endpoint
               name="HttpMexEndpoint"
               address="mex"
               binding="mexHttpBinding"
               bindingConfiguration=""
               contract="IMetadataExchange" />-->
            <!--<endpoint
               name="HttpsMexEndpoint"
               address="mex"
               binding="mexHttpsBinding"
               bindingConfiguration=""
               contract="IMetadataExchange" />-->
         </service>
      </services>
   </system.serviceModel>
</configuration>

It's extremely nice to see how the WCF adapter in BizTalk leverages a bunch of my favorite features in WCF to make this a lot simpler (compared to, say, the whole bunch of code that neede d to be generated for the original SOAP adapter).

I should mention though, that part of what made it so easy was that my needs were pretty simple: I wanted a simple two-way (request/response) port, and needed no metadata (WSDL) publishing at all (as I said, I already had working WSDL files I could provide to consumers of the service).  Making it one-way wouldn't have been a problem though; as the WCF adapter handles it very gracefully as well.

Technorati tags: ,

BasicHttpBinding with Transport Security

This is just something to remind myself next time I need to implement a WCF service using the BasicHttpBinding with transport-only security (SSL + client certificates)':

  • WCF expects that the "Require SSL" option in IIS is enabled.
  • If Metadata Exchange is needed, configure the MEX endpoint with a custom binding with the right settings; otherwise the service won't start.
  • Remember to set httpsGetEnabled="true" option in the <serviceMetadata> service behavior instead of the usual httpGetEnabled attribute.
  • WCF does not understand the "Accept Client Certificates" option in IIS. It treats it the same as "Ignore Client Certificates" option.

To use client certificates:

    • Enable the "Require Client Certificates" option in IIS
    • On the service side, use a custom binding to set the requireClientCertificate option of the httpsTransport binding element:

      <bindings>

         <customBinding>

            <binding name="sslBasicHttp">

               <textMessageEncoding messageVersion="Soap11" />

               <httpsTransport requireClientCertificate="true"/>

            </binding>

         </customBinding>

      </bindings>

    • On the client side, use basicHttpBinding with the security mode set to "Transport" and the option clientCredentialType set to "Certificate" on the <transport/> element.

SvcUtil Generated Config

Scott Seely seems to object to my previous comment on being careful about the defaults used by svcutil.exe. Scott goes on to describe in detail how svcutil figures out what should get written in the default configuration, which is pretty useful.

But, seems to me like Scott may have misunderstood my comment. Yes, I do know how svcutil.exe works and even why it chooses the defaults it chooses. I'm not arguing against it configuring default values (even for all binding properties, as cumbersome as that can be). I'm arguing against the rationale of the default values themselves, as they make little sense for a client side proxy.

Don't get me wrong, I fully agree with Scott's comment that "Bigger defaults would have made it easier to blow up your average WCF endpoint, and that wouldn't have been a good thing", but that's an assertion that makes a lot of sense for a service endpoint. A client side proxy, on the other hand, will rarely require such stringent settings and in fact it constantly gets in the way (only case where this would be significant is in the case of duplex contracts).

In other words, I'm arguing for SvcUtil being slightly more smart about the default values depending on the context. And even more, I'm arguing that the default security constraints configured by default on WCF bindings (SvcUtil or no SvcUtil) are too small. I'm not saying to make them unlimited, but they could benefit from slightly larger values, particularly for WSHttpBinding and friends.

But as long as we're on the topic, let's add one more to the mix: The truth is, that these kind of security constraints are sitting right in no man's land. Developers will very rarely look at them (unless they are already aware of the issue) simply because they test their services in limited environments, where, for example, messages might be small enough to cause no trouble. But then they go blow up in their faces in the production environment. Administrators on the other end, have no clue what this settings are or what they configure (in fact, they have no clue they even exist) and will simply ignore them... until they blow up in their faces as well. This is not a good situation by any means, because you know what people will do? They'll just get used to configure them always to the maximum possible value.

WCF Tips

My good friend Sam Gentile pointed me to David Pallmann's set of WCF tips. Lots of good stuff in there, and I found myself agreeing with most of the stuff David brought up.

One that particularly resonated with me was Tip #4 on default settings. One of my biggest gripes with svcutil.exe is that it generates a default client-side proxy configuration that is fairly useless, because it initializes all binding properties explicitly with values that are too small to be useful in many cases. What's worse, you may not realize the consequences of this during initial testing and may only notice the problem later on. In particular, message size and encoding quotas have default values that are too small.

Actually, I'll go one step further and say that a lot of these security quota settings make little sense for service consumers. However, you do want to configure them properly for services themselves (though the default values might still be too small for most scenarios), as they can help you protect against denial of service kind of attacks, or simply protect you from handling requests larger than your service can chew.

My Favorite WCF Features

After working with Windows Communication Foundation for a while, I've reached the conclusion that the two features in WCF that I like the most are:

1. Generic Service Contracts: That is, the combination of using simple contracts with a single, catch-all operation and untyped data contracts (a.k.a. the System.ServiceModel.Channels.Message class). Particularly for one way, scenarios, these are really powerful and flexible. In other words, stuff like this:

[ServiceContract]
public interface IGenericOneWayService
{
[OperationContract(Action="*", IsOneWay=true)]
void Execute(Message msg);
}

2. Custom Bindings: Creating custom bindings by composing arbitrary sets of BindingElements is extremely flexible and a provides an excellent extensibility mechanism, particularly when you introduce custom protocol channels (i.e. above the transport channel) into the mix.

It took a bit of time for these to finally "click" for me, but I know fully realize this is a pretty cool thing to have in the framework. I do wish there was better validation of custom bindings, as well as a way to specify declaratively the requirements and capabilities of binding elements.

The Future of BizTalk/WCF/WF

Walter Michel commented on my recent entry on the BizTalk and WCF Messaging Models and asked if I had some guesses as to what the architecture of a future BizTalk version might look like in regards to WF/WCF integration. I think that, at this point in time, it is anybody's guess what it might look like, as it is just too early to tell.

Honestly, I don't know what it might end up looking like, and I can't even say I can make an educated guess (and there are people with far more criteria for making such educated guesses than me, such as Jon Flanders). Instead, I'll address the question in a different way, by mentioning what I consider a few challenges I see regarding the integration and other things like that.

The Impact of Significant Architecture Changes

One key aspect of the whole integration process between the three technologies is what the impact of significant changes to the core BizTalk architecture. Microsoft already went down that path during the transition between BizTalk 2002 and 2004, and while those of us developing BizTalk solutions are extremely grateful for the benefits that the new architecture brought over, companies with large investments in BizTalk 2000/2002 solutions were not so happy. For most of them, going to BizTalk 2004/2006 meant a complete rewrite of their integration solutions, and that can be very expensive, and though to justify to the business side, not only because of cost, but also because of the associated risks.

With BizTalk 2004/2006, BizTalk brought over not only a significantly revamped platform, but also a new, effective, and very welcome extensibility model that has been tested with time. That's why the current core product architecture has been good for three release cycles already, and the fact that even complex things like WCF could be integrated without significant changes to it is pretty substantial.

A lot of Microsoft clients and partners have made significant investments in that architecture and its not clear how that investment might be preserved (or at least their loss mitigated a bit) if significant architecture changes happen. I'm pretty sure the people at the Connected Systems Division at Microsoft are aware of this, and from my own, outside perspective, I can only say that it seems like a daunting and complex decision to make. Whatever way they decide to go, it's not going to be easy.

So, what happens if the complex changes do become a reality? We can only hope that good migration tools are not left by the side; but even with those migration tools, you'd probably be looking at a complete rewrite scenario again for the most part.

Messaging

In my previous entry, I commented that the current WCF integration in BizTalk 2006 R2 leverages the existing BizTalk messaging extensibility model (the adapter framework) on top of the messaging engine. However, I think that in the long run, keeping both is probably not the best solution. Despite their differences, there's still a lot of common ground and responsibilities between the BizTalk Messaging Engine and the WCF model, and simply keeping both models in place, with their independent extensibility models, would be too expensive (for example, keeping both the BizTalk adapter framework and the WCF transport channel model).

So my best guess is that, at some point in time, one of them would tend to disappear, and needless to say, that would have to be the BizTalk one. Does it mean that the BizTalk Messaging Engine will disappear? Probably not, but it will change and its responsibilities will adjust to that.

For example, assuming that the core message moving responsibilities are absorbed by the WCF stack, then the Messaging Engine would concentrate on it's other tasks: Managing Receive Locations/Ports and Send Ports/Port Groups (assuming those concepts still exists in some fashion), managing port configuration settings at runtime, managing errors and, assuming the Message Box concept remains (or some equivalent centralized routing agent), then submitting and retrieving messages from it.

There are some interesting aspects deriving from this:

  • The pipeline model would disappear. Personally, I'm a little saddened by this because I consider the pipeline extensibility model to be simple [1], elegant and very effective; and it's one of the great assets BizTalk has when integrating against legacy and third party systems with peculiarities in the messages they generate/consume. That said, WCF does have a good extensibility story, though the responsibilities of where each things happened are a bit more diluted across the stack, instead of being centralized like in the BizTalk pipeline concept.
  • The WCF model has some bias towards XML/SOAP. Certainly, it allows other things as messages, depending on how much work you're willing to invest in it. This is changing a bit, though, in .NET 3.5 with the REST support, and I expect it will change even more in later releases. To be an effective messaging stack for an integration platform, however, this needs to be a non-issue.
  • WCF supports a more complex set of interactions (and MEPs) than those supported by BizTalk at this time, and it's not clear how some of those could be used to extend BizTalk. This includes things like composite duplex channels, as well as the durable services/sessions model supported in .NET 3.5 (the current implementation of which makes little sense if the service is backed by a real workflow in WF/BizTalk).

The Message Box

An interesting question that comes up is whether a future BizTalk version might still have the Message Box. Currently, the MessageBox is the cornerstone and heart of the BizTalk architecture, and a key element in supporting BizTalk's highly reliable, loosely-coupled, asynchronous model.

However, I don't discard that, if a major architecture change is done, the MessageBox model isn't reevaluated, because it also is a disadvantage at times. For example, it can impact message throughput and latency in low-latency, synchronous scenarios, and after a certain point, the centralized model doesn't scale all that well without some really heavy-duty DB servers (which is expensive).

I don't think the message box concept will go away soon, but it may change in how it is implemented. I also think (but this is just a wild guess) that we might see some support for more lightweight operation modes were you trade off some of the features of the MessageBox for lower latency for purely synchronous operations (this would be interesting, particularly for some messaging-only scenarios).

The Orchestration Engine

As far as I know (at least from the little tidbits MS has let out), XLANGs is going away to be replaced by a WF-based orchestration engine. At the least, this means that some migration tools would be needed here, possibly with a set of custom WF activities that match more closely to the behavior of the built-in XLANGs shapes in current BizTalk versions.

There are some interesting implications and questions coming from this change:

  1. One of the core advantages that WF has over the current BizTalk Orchestration model is that it is extensible through custom Activities. However, as we've already seen, some custom WF hosts will restrict the set of activities that can be used in Workflows executing on them. Whether BizTalk will have an open or closed model here is anybody's guess.
  2. WF has one low-level mechanism for getting data into a workflow: Workflow Queues (getting data out of a workflow isn't quite as clear). While the queue model is very flexible, it is also too low-level for what most people are comfortable with. Unfortunately, the current WF releases don't really have a very good higher-level mechanism for this (the HandleExternalEvent and CallExternalMethod activities are woefully inadequate). In other words, the existing Port model in BizTalk is a far better model, which the new WCF integration into WF in .NET 3.5 is sort of related to (at least they are much more similar).
    This is, in a lot of ways, a key point in making WF usable as an XLANGs alternative. The current port model in BizTalk is tied to the BizTalk MessageBox, and it is instrumental in the design of loosely-coupled orchestrations and services, scaling processing to multiple hosts (via the BizTalk Host model and bindings), and versioning complex long-running processes (direct binding is extremely useful when breaking up complex processes into multiple orchestrations and letting each one be versioned independently).
  3. A key difference between WF and XLANGs is the fact that XLANGs is message oriented. This means that messages are a first-class language construct, and so message construction, manipulation and the receiving/sending of messages is a clear concept. WF, on the other hand, has no clear of what a message is at all, and execution is not related at all to how data (messages) flows around the process. On one hand, this is an advantage because it opens new possibilities and adds expressiveness to the tool, but it is also a downside because the message-orientated nature of BizTalk and BizTalk orchestrations has been one of BizTalk's strongest points and really aligns it with Service-Oriented Architectures.
    In fact, even in the WCF integration in .NET 3.5, the concept of message isn't directly mentioned; instead we talk about [data]contracts, which are still just CLR objects. If this remains so, then an interesting follow-up question to consider is what happens to the existing BizTalk features that are closely related to its message-oriented nature, like maps and the support for non-XML message formats (including EDI and Flat Files, but not limited to them). There are certainly alternatives for this, and I do doubt we'll see a significant reduction in functionality in this space, though how it is accomplished could change significantly.

Human Workflow

Traditionally, BizTalk hasn't been oriented towards automating processes with heavy user-involvement (the stronghold of more workflow oriented tools like K2.net or Ultimus). With BizTalk 2004, Microsoft made a weak attempt at providing some tools for building these kind of solutions as part of EAI projects with Human Workflow Services (HWS), which were deprecated on BizTalk 2006.

WF has more potential in this arena, although the core WF is too basic to build human workflow solutions out of the box without a large number of extensions. I don't expect a future BizTalk version to incorporate more Human Workflow oriented features; given that Microsoft has said they are investing in positioning Microsoft Office Sharepoint Server as a contender in that space. We might see some more BizTalk to Sharepoint integration tools, though.

Business Rules Engine

Both BizTalk and WF have some business rules functionality. While the BRE in BizTalk is, in general terms, more advanced than WF's, it's not clear exactly what's going to happen. I seem to remember reading that both engines are now owned by the same dev team, so we should certainly be seeing some convergence there.

What is not clear to me is whether there will continue to exist two separate engines (one for the core WF and one for server oriented products like BizTalk). If both continue to exists, then that does mean a bit more confusion for BizTalk developers as it will mean having to choose on a case by case basis which of both engines to use from orchestrations (now WF workflows). If they converge into a single rules engine, then I would expect the WF engine to absorb, one way or another, the extended functionality offered by the BRE.

Conclusion

The only conclusion I can make of this is that I have more questions than answers :-). It's certainly going to be interesting to see how the core framework evolves and how that impacts the architecture and functionality of BizTalk as a standalone server product, and for us BizTalk developers it will sure have some significant impacts. The best I can say is that learning a bit about WCF and WF and understanding their architecture now sure will help when the time to make the transition comes along.

[1] The only reason writing pipeline components is complex at times is because of the COM-compatible interfaces you need to implement to satisfy the old, internal unmanaged implementation in the Messaging Engine, as well as the need to do streaming as much as possible to minimize the performance impact.

OneWayBinding

After writing my last post, I realized that an even better way to do this is to actually formalize the binding as a custom binding:

public class OneWayBinding : CustomBinding
{
public OneWayBinding(Binding baseBinding)
: base(baseBinding)
{
}
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection bec = base.CreateBindingElements();
bec.Insert(0, new OneWayBindingElement());
return bec;
}
}

Then you can simply say:

CustomBinding binding = new OneWayBinding(new NetTcpBinding());

IOutputChannel over IRequestChannel

Udi Dahan ranted a bit about the WCF transport channel model and it's extensive use of generics. More to the point, Udi was running into some trouble trying to simply send a message, one way, over an arbitrary transport channel that could either be one way or not. The problem he runs into is dealing in a generic fashion with the different Channel Shapes that WCF exposes.

I commented on his blog that maybe it would be possible for him to use a custom binding and using the OneWayBindingElement binding element to "change" the shape of the underlying, two-way channel into a single-way channel he could use by just coding against the IOutputChannel interface. Udi responsed:

"I’m trying to write transports for NServiceBus which will make use of the WCF bindings. So, since BasicHttpBinding only supports IRequestChannel and not IOutputChannel I have to deal with this. It’s just nuts that there isn’t some more useful shared interface between them." 

From his description, I gather that Udi is (with good intentions of keeping things simple) equating channels with standard bindings, but this isn't quite so. The BasicHttpBinding is just a binding; not a channel itself. However, this standard binding will certainly force a matched two-way channel shape (IRequestChannel) based on the underlying transport channel used (HttpTransportChannel/HttpsTransportChannel).

There's nothing inherently wrong about creating a new binding that is based on one of the standard channels but has extra binding elements layered on top. Here's a sample:

EndpointAddress epa =
new EndpointAddress("http://localhost:8254/myservice/myserv.svc");
WSHttpBinding wsHttp = new WSHttpBinding(SecurityMode.None, false);
CustomBinding binding = CreateOneWayBinding(wsHttp);
// could also be
// CreateOneWayBinding(new BasicHttpBinding());
IChannelFactory<IOutputChannel> factory =
binding.BuildChannelFactory<IOutputChannel>();
factory.Open();
IOutputChannel channel = factory.CreateChannel(epa);
Message myMessage = Message.CreateMessage(
binding.MessageVersion, "Process", "some sample contents"
);
channel.Open();
channel.Send(myMessage);
channel.Close();
factory.Close();

The CreateOneWayBinding() method used in the sample above is fairly simple:

static CustomBinding CreateOneWayBinding(Binding baseBinding)
{
List<BindingElement> elems = new List<BindingElement>();
elems.Add(new OneWayBindingElement());
elems.AddRange(baseBinding.CreateBindingElements());
return new CustomBinding(elems);
}

It basically creates a new CustomBinding based on the binding elements of the original binding (in this case one of the standard ones) and then layers the OneWayBindingElement, channel shape changing element on top.

Note: For some reason, this would not work if message security was enabled with the WSHttpBinding, but I didn't spent too much time looking at what the issue was, but otherwise works fine with the WSHttpBinding, BasicHttpBinding and NetTcpBinding, which is enough to make it useful on its own.

WCF and BizTalk Messaging

Jesus Rodriguez started an interesting discussion here about the differences between WCF Behaviors and BizTalk Server Pipelines, focused on what the right use cases for each one are when developing solutions on BizTalk Server 2006 R2 and the WCF adapters included in it. I think this is a really interesting discussion, and one I've given a bit of thought over the past few weeks. As Jesus correctly points out, this discussion is also more important because of the changes that might ripple through the product as WCF and WF permeate the underlying BizTalk architecture as they get integrated into the core product.

Instead of explicitly talking about Behaviors Vs. Pipelines; I'd like to approach the topic from a slightly different point of view: the messaging stacks.

In BizTalk 2006 R2, integration between WCF and BizTalk is done by talking advantage of one of the key extensibility points in BizTalk: The adapter framework. In other words, both WCF send and receive facilities are exposed to BizTalk (and from BizTalk) through a set of adapters that hook the WCF model to the BizTalk Messaging Engine (and ultimately the BizTalk Message Box).

This is obviously a simplification of sorts, but the main idea is that, for this release, the BizTalk architecture itself didn't suffer significant changes in order to enable WCF connectivity. At the same time, WCF didn't need itself any changes either; though certainly a number of extensions needed to be added in order to create fully functional BizTalk our of the core WCF binding/channels. In many ways, this is a testament of the power and flexibility of the extensibility models for both platforms. On the other hand, it means that both messaging stacks are almost fully present, with all the differences and similarities they have.

What will future versions of WCF/BizTalk look like? I honestly don't know, but one can speculate a bit. An interesting thing that might give us some clues about what is to come is to examine some interesting differences between the two models. While there are many similarities, there are also some key aspects where WCF approaches things differently from BizTalk. Here are a few:

Messages

A lot of people mistakenly think that BizTalk Server is all about XML messages and that anything flowing through BizTalk must be XML. While it is true that XML messages are first class citizen in BizTalk and that many aspects are modeled around XML-like concepts, this isn't really true.

In particular, at the messaging level, when you're working with Adapters and Pipelines, messages are simply streams of bytes. What those bytes contain is really irrelevant to BizTalk; all it cares is that it can read and manipulate those streams. In fact; it's pretty easy at this layer to deal with purely obscure or binary data; though obviously some components will make assumptions about what the data should look like (example: the Xml Disassembler expects to be able to interpret the message stream as XML text).

In WCF, on the other hand, the message concept is more closely tied to XML; however, not to the textual XML representation, but rather to the XML InfoSet. This means that it is still perfectly possible to deal with other kinds of data as long as there's a component in the WCF stack that can make it look like an XML Infoset. This can be done either by actually translating from another representation into XML (say a database structure to XML) or by "faking it" (such as a binary stream with fake open/close XML tags).

In practical terms it means that, for the most part, you can accomplish the same thing in both models; though it does mean some things get done at different layers in the stack. For example, in BizTalk, interpreting message content is usually done fairly up in the stack (i.e. the pipeline, unless you have an application adapter with specific needs), meaning things like message format are only looked into until fairly late in the game. In WCF, however, these tasks are usually done very early own, usually at the request of the Transport Channel.

This does not mean that the transport channel author has to necessarily need to implement things like message parsing, but it may mean that it is his/her responsibility to ensure it gets done. For example, a transport channel will call the configured MessageEncoder to encode/decode messages into/from the network.

Message Structure

Another interesting aspects is message structure. In BizTalk Server, messages are not really a single entity. Instead, each message is composed of one or more "message parts", each one containing it's own data stream independent of the rest, with one of them being marked as the "body" of the message. Also, each message carries around a property bag [1] associated to it (the Message Context), which can be used to carry "out-of-band" data.  and that is a critical part of BizTalk's Pub/Sub mechanism.

Bts-Wcf-Messages

WCF messages aren't quite structured the same way. In fact, WCF messages don't quite have the concept of "multi-part messages" as clear as the one in BizTalk Server (though support for protocols like MTOM certainly make it possible) and so only really have a single, body data stream (or really, Xml feed) associated with them. However, unlike BizTalk, they also have two different ways to carry out of band data: Message Headers (obvious, if you consider that the WCF model is closely tied to SOAP), and Message Properties.

Assembling and Disassembling

Another interesting difference between BizTalk and WCF, and that Jesus already pointed to, is the fact that, in WCF, interchanges are really one-to-one throughout the WCF stack. That is, one message comes in, one message comes out.

This is rather different from BizTalk, in which the assembling and disassembling stages of send and receive pipelines respectively were created explicitly with the idea that messages might be joined or split during processing. This is why the stages are referred to using the terms assemble/disassemble and not simply as "parsing" or "translating".

On the receive side, this enables some really powerful mechanics for processing large interchanges, by breaking (debatching) messages as they come in into smaller parts that can be processed individually. Similarly, on the send side, multiple messages can be joined into a single, larger message. Unfortunately, the latter functionality is never used by the messaging engine (though it is accessible when calling pipelines directly from orchestrations).

So this is one point where there's a significant difference between the two messaging models. Certainly, nothing would prevent a WCF transport channel from implementing it's own disassembling/assembling functionality, though it might be a complex job, and likely not very reusable. It might be possible to implement it at higher levels of the channel stack as well, but I really haven't looked too closely into this, as, in general, this isn't as useful a feature in the context WCF services are normally used (but it is a very important one in the context BizTalk is used).

Channel Shapes

BizTalk Server only really has two different Message Exchange Patterns: Either you support exchanging messages in a single direction (one-way) or in both directions (two-way).

WCF, however, supports 3 different message exchange patterns (you could say the third one can also be simulated in BizTalk). The ke y differentiating here, however, is that WCF creates, on top of these three basic MEPs, a large number of different Channel Shapes, which complement the basic interactions by separating stateless and state-aware variants. Thus, the appearance of Session-aware channels.

It's obvious that WCF's model is here quite a bit more powerful than what BizTalk offers right out of the box, though it can be argued as well that this makes the model a lot more complex (and more confusing) for channel authors. BizTalk essentially assumes that all interactions are stateless (i.e. the concept of session doesn't exist); which is partially mitigated by the powerful orchestration + correlation sets combo.

I think it will be extremely interesting to see how the concept of sessions is brought into the main BizTalk architecture in a future version as WCF gets integrated more deeply with the BizTalk messaging engine. It certainly adds a few new challenges to the decoupled, highly asynchronous interaction model between BizTalk components.

Conclusion

I don't really know what the future will bring for these two platforms, but certainly the combination of WCF + WF + BizTalk is going to bring significant changes to the platform. I have a few gut-feelings about what it may look like, but they don't even qualify as educated guesses :-). Still, it's going to be pretty interesting to see how it evolves.

[1] There's also a property bag associated with each message part; but it is used less often and isn't as important as the message context.

WCF LOB Adapter SDK

Sonu Arora has a great post on what exactly the WCF LOB Adapter SDK does and how it relates (i.e. extends) the capabilities of the normal WCF channel and extensibility model. Her entire blog is worth checking out if you've been wondering just what the fuzz is about, particularly since now a Release candidate of the SDK has been made available to the public.

Technorati tags: