It's 2008. Where's my flying car? RSS 2.0
 Friday, April 27, 2007

Christian Weyer shows off the few lines of pretty straightforward WCF code & config he needed to figure out in order to set up a duplex conversation through BizTalk Services.

Friday, April 27, 2007 4:53:15 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
Architecture | SOA | BizTalk | WCF | Web Services | XML
 Thursday, April 26, 2007

Steve has a great analysis of what BizTalk Services means for Corzen and how he views it in the broader industry context.

Thursday, April 26, 2007 3:09:51 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
Architecture | SOA | IT Strategy | Technology | BizTalk | WCF | Web Services
 Tuesday, April 24, 2007

"ESB" (for "Enterprise Service Bus") is an acronym floating around in the SOA/BPM space for quite a while now. The notion is that you have a set of shared services in an enterprise that act as a shared foundation for discovering, connecting and federating services. That's a good thing and there's not much of a debate about the usefulness, except whether ESB is the actual term is being used to describe this service fabric or whether there's a concrete product with that name. Microsoft has, for instance, directory services, the UDDI registry, and our P2P resolution services that contribute to the discovery portion, we've got BizTalk Server as a scalable business process, integration and federation hub, we've got the Windows Communication Foundation for building service oriented applications and endpoints, we've got the Windows Workflow Foundation for building workflow-driven endpoint applications, and we have the Identity Platform with ILM/MIIS, ADFS, and CardSpace that provides the federated identity backplane.

Today, the division I work in (Connected Systems Division) has announced BizTalk Services, which John Shewchuk explains here and Dennis Pilarinos drills into here.

Two aspects that make the idea of a "service bus" generally very attractive are that the service bus enables identity federation and connectivity federation. This idea gets far more interesting and more broadly applicable when we remove the "Enterprise" constraint from ESB it and put "Internet" into its place, thus elevating it to an "Internet Services Bus", or ISB. If we look at the most popular Internet-dependent applications outside of the browser these days, like the many Instant Messaging apps, BitTorrent, Limewire, VoIP, Orb/Slingbox, Skype, Halo, Project Gotham Racing, and others, many of them depend on one or two key services must be provided for each of them: Identity Federation (or, in absence of that, a central identity service) and some sort of message relay in order to connect up two or more application instances that each sit behind firewalls - and at the very least some stable, shared rendezvous point or directory to seed P2P connections. The question "how does Messenger work?" has, from an high-level architecture perspective a simple answer: The Messenger "switchboard" acts as a message relay.

The problem gets really juicy when we look at the reality of what connecting such applications means and what an ISV (or you!) were to come up with the next cool thing on the Internet:

You'll soon find out that you will have to run a whole lot of server infrastructure and the routing of all of that traffic goes through your pipes. If your cool thing involves moving lots of large files around (let's say you'd want to build a photo sharing app like the very unfortunately deceased Microsoft Max) you'd suddenly find yourself running some significant sets of pipes (tubes?) into your basement even though your users are just passing data from one place to the next. That's a killer for lots of good ideas as this represents a significant entry barrier. Interesting stuff can get popular very, very fast these days and sometimes faster than you can say "Venture Capital".

Messenger runs such infrastructure. And the need for such infrastructure was indeed an (not entirely unexpected) important takeaway from the cited Max project. What looked just to be a very polished and cool client app to showcase all the Vista and NETFX 3.0 goodness was just the tip of a significant iceberg of (just as cool) server functionality that was running in a Microsoft data center to make the sharing experience as seamless and easy as it was. Once you want to do cool stuff that goes beyond the request/response browser thing, you easily end up running a data center. And people will quickly think that your application sucks if that data center doesn't "just work". And that translates into several "nines" in terms of availability in my book. And that'll cost you.

As cool as Flickr and YouTube are, I don't think of none of them or their brethren to be nearly as disruptive in terms of architectural paradigm shift and long-term technology impact as Napster, ICQ and Skype were as they appeared on the scene. YouTube is just a place with interesting content. ICQ changed the world of collaboration. Napster's and Skype's impact changed and is changing entire industries. The Internet is far more and has more potential than just having some shared, mashed-up places where lots of people go to consume, search and upload stuff. "Personal computing" where I'm in control of MY stuff and share between MY places from wherever I happen to be and NOT giving that data to someone else so that they can decorate my stuff with ads has a future. The pendulum will swing back. I want to be able to take a family picture with my digital camera and snap that into a digital picture frame at my dad's house at the push of a button without some "place" being in the middle of that. The picture frame just has to be able to stick its head out to a place where my camera can talk to it so that it can accept that picture and know that it's me who is sending it.

Another personal, and very concrete and real point in case: I am running, and I've written about that before, a custom-built (software/hardware) combo of two machines (one in Germany, one here in the US) that provide me and my family with full Windows Media Center embedded access to live and recorded TV along with electronic program guide data for 45+ German TV channels, Sports Pay-TV included. The work of getting the connectivity right (dynamic DNS, port mappings, firewall holes), dealing with the bandwidth constraints and shielding this against unwanted access were ridiculously complicated. This solution and IP telephony and video conferencing (over Messenger, Skype) are shrinking the distance to home to what's effectively just the inconvenience of the time difference of 9 hours and that we don't see family and friends in person all that often. Otherwise we're completely "plugged in" on what's going on at home and in Germany in general. That's an immediate and huge improvement of the quality of living for us, is enabled by the Internet, and has very little to do with "the Web", let alone "Web 2.0" - except that my Program Guide app for Media Center happens to be an AJAX app today. Using BizTalk Services would throw out a whole lot of complexity that I had to deal with myself, especially on the access control/identity and connectivity and discoverability fronts. Of course, as I've done it the hard way and it's working to a degree that my wife is very happy with it as it stands (which is the customer satisfaction metric that matters here), I'm not making changes for technology's sake until I'm attacking the next revision of this or I'll wait for one of the alternative and improving solutions (Orb is on a good path) to catch up with what I have.

But I digress. Just as much as the services that were just announced (and the ones that are lined up to follow) are a potential enabler for new Napster/ICQ/Skype type consumer space applications from innovative companies who don't have the capacity or expertise to run their own data center, they are also and just as importantly the "Small and Medium Enterprise Service Bus".

If you are an ISV catering shrink-wrapped business solutions to SMEs whose network infrastructure may be as simple as a DSL line (with dynamic IP) that goes into a (wireless) hub and is as locked down as it possibly can be by the local networking company that services them, we can do as much as we want as an industry in trying to make inter-company B2B work and expand it to SMEs; your customers just aren't playing in that game if they can't get over these basic connectivity hurdles.

Your app, that lives behind the firewall shield and NAT and a dynamic IP, doesn't have a stable, public place where it can publish its endpoints and you have no way to federate identity (and access control) unless you are doing some pretty invasive surgery on their network setup or you end up building and running run a bunch of infrastructure on-site or for them. And that's the same problem as the mentioned consumer apps have. Even more so, if you look at the list of "coming soon" services, you'll find that problems like relaying events or coordinating work with workflows are very suitable for many common use-cases in SME business applications once you imagine expanding their scope to inter-company collaboration.

So where's "Megacorp Enterprises" in that play? First of all, Megacorp isn't an island. Every Megacorp depends on lots of SME suppliers and retailers (or their equivalents in the respective lingo of the verticals). Plugging all of them directly into Megacorp's "ESB" often isn't feasible for lots of reasons and increasingly less so if the SME had a second or third (imagine that!) customer and/or supplier. 

Second, Megacorp isn't a uniform big entity. The count of "enterprise applications" running inside of Megacorp is measured in thousands rather than dozens. We're often inclined to think of SAP or Siebel when we think of enterprise applications, but the vast majority are much simpler and more scoped than that. It's not entirely ridiculous to think that some of those applications runs (gasp!) under someone's desk or in a cabinet in an extra room of a department. And it's also not entirely ridiculous to think that these applications are so vertical and special that their integration into the "ESB" gets continuously overridden by someone else's higher priorities and yet, the respective business department needs a very practical way to connect with partners now and be "connectable" even though it sits deeply inside the network thicket of Megacorp. While it is likely on every CIO's goal sheet to contain that sort of IT anarchy, it's a reality that needs answers in order to keep the business bring in the money.

Third, Megacorp needs to work with Gigacorp. To make it interesting, let's assume that Megacorp and Gigacorp don't like each other much and trust each other even less. They even compete. Yet, they've got to work on a standard and hence they need to collaborate. It turns out that this scenario is almost entirely the same as the "Panic! Our departments take IT in their own hands!" scenario described above. At most, Megacorp wants to give Gigacorp a rendezvous and identity federation point on neutral ground. So instead of letting Gigacorp on their ESB, they both hook their apps and their identity infrastructures into the ISB and let the ISB be the mediator in that play.

Bottom line: There are very many solution scenarios, of which I mentioned just a few, where "I" is a much more suitable scope than "E". Sometimes the appropriate scope is just "I", sometimes the appropriate scope is just "E". They key to achieve the agility that SOA strategies commonly promise is the ability to do the "E to I" scale-up whenever you need it in order to enable broader communication. If you need to elevate one or a set services from your ESB to Internet scope, you have the option to go and do so as appropriate and integrated with your identity infrastructure. And since this all strictly WS-* standards based, your "E" might actually be "whatever you happen to run today". BizTalk Services is the "I".

Or, in other words, this is a pretty big deal.

Tuesday, April 24, 2007 8:28:23 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [1] - Trackback
Architecture | SOA | IT Strategy | Microsoft | MSDN | BizTalk | WCF | Web Services
 Monday, April 09, 2007

Tim O'Reilly's "code of conduct" is a "we need more laws" overreaction to the fact that real world making its way into blogland. Yes, as much as there may be a sense in some people that there's a "we" amongst bloggers and "we" need to stay together or some folks still think that bloggers are some kind of an elite: "Blogger" is a mainstream occupation and hobby now. That means: you'll find that some folks are assholes. Get over it. It's not that we hadn't had those along for the ride all the way from the beginning...

So, no, thank you very much.

Monday, April 09, 2007 8:06:19 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [1] - Trackback
Blog
 Monday, April 02, 2007

We just published a great whitepaper written by our WCF/WF Performance PM Saurabh Gupta on the relative performance of WCF compared to ASMX, WSE, Enterprise Services, and Remoting. This is material for your favorites folder. The summary says:

To summarize the results, WCF is 25%—50% faster than ASP.NET Web Services, and approximately 25% faster than .NET Remoting. Comparison with .NET Enterprise Service is load dependant, as in one case WCF is nearly 100% faster but in another scenario it is nearly 25% slower. For WSE 2.0/3.0 implementations, migrating them to WCF will obviously provide the most significant performance gains of almost 4x.

The one scenario where WCF is slower are some comparison scenarios with ES. I'd say that even getting within strinking distance of ES/COM+/DCOM/RPC performance for a V1 release that's based on Web services technology is quite an astonishing accomplishment. The ES/COM+/DCOM/RPC stack underneath had almost 15 years to get to where it's at. And the 4x should give you a really convincing reason to make the move from WSE to WCF.

Monday, April 02, 2007 2:41:34 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [1] - Trackback
WCF

Before I continue pointing out SDK samples, why not take a look at a great end-to-end .NET Framework 3.0 demo first? It's been out there for a while and hence this isn't really news, but in case you've not seen it (or the latest revision of it) go check out DinnerNow. The demo covers WCF, Workflow, CardSpace and PowerShell. Awesome piece of work from our Evangelism team.

Monday, April 02, 2007 12:46:26 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
WCF | Workflow | CardSpace
 Friday, March 30, 2007

One of the "niche" features in WCF that deserves a lot more attention than it is getting is our P2P support. The NetPeerTcpBinding looks, from the developer perspective, mostly like any other binding. The main difference between P2P applications and "normal" client/server apps is, of course, that they are serverless. Hence, P2P apps are commonly based on message exchanges where every peer node in a mesh talks to everyone else in a broadcast fashion and that model favors (but doesn't require) symmetric duplex contracts*

When I say that it works like mostly any other binding, I really only mean the developer experience. The NetPeerTcpBinding packs so much network intelligence under its hood that it boggles the mind. The P2P technology underneath will figure out the optimal layout for a peer mesh, propagate messages through the mesh in an optimal fashion using members of the mesh as routers as appropriate. You can hook in filters to control the message propagation, you can control the hop counts, there are detection mechanisms for when a party gets split off the mesh and reconnects, and there are various ways to secure your meshes. And you basically get all the stuff for free if you just pick that binding and configure it.

The Peer Channel team has a blog, too. Links to samples:

(a) Basic NetPeerTcpBinding samples - Uses the PNRP resolver mode
(b) Scenario samples:
       (i) Chat - Demonstrates Chat using the non-PNRP custom resolver
       (ii) Custom Resolver - Demonstrates how to write your own Custom Resolver service and client.


* A symmetric duplex contract defines itself as the callback contract:
[ServiceContract(CallbackContract = typeof(IChat))]
public interface IChat
{
  ...
}

Friday, March 30, 2007 8:44:41 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
WCF
 Thursday, March 29, 2007

There are a lot of blog entries that I'd write if they weren't already written. Stupid statement. No, really. One of the great qualities of the documentation that we built for WCF and WF and CardSpace is that it's completely legible and understandable :)

Since there's just a lot of stuff in the SDK docs and one easily gets lost in the forest, I'll point out a few of the conceptual docs and/or samples and may add the one or the other commentary here or there. For the first one that I selfishly point out the only actual commentary is that I wrote that piece ;)

Go read about Message Inspectors and how to implement client- and/or server-side schema-based validation in WCF, complete with the ability to refer to the validation schemas by config. Adventure-seekers might be interested in poking around in that code and replace the schema validation and the schemas with XSLTs and transforms. That would create some interesting followup-challenges for synthesizing the ContractDescription that projects out the correct pre-transformation representation for WSDL, but I guess that'd be part of the fun.

Thursday, March 29, 2007 2:03:59 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
WCF

A bad sign for how much I’m coding these days is that I had a HDD crash three weeks ago and only restored Visual Studio into fully working condition with all my tools and stuff today. I’ve decided that that has to change otherwise I’ll get really rusty.

Picking up the thread from “Professor Indigo” Nicholas Allen, I’ve built a little program that illustrates an alternate handling strategy for poisonous messages that WCF throws into the poison queue on Vista and Longhorn Server if you ask it to (ReceiveErrorHandling.Move). The one we’re showing in the docs is implementing a local resolution strategy that’s being fired within the service when the service ends up faulting; that’s the strategy for ReceiveErrorHandling.Fault and works for MSMQ 3.0. The strategy I’m showing here requires our latest OS wave.

When a message arrives at a WCF endpoint through a queue, WCF will – if the queue is transactional – open a transaction and de-queue the message. It will then try to dispatch it to the target service and operation. Assuming the dispatch works, the operation gets invoked and – might – tank. If it does, an exception is raised, thrown back into the WCF stack and the transaction aborts. Happily, WCF grabs the next message from the queue – which happens to be the one that just caused the failure due to the rollback – and the operation – might – tank again.

Now, the reasons why the operation might fail are as numerous as the combinations of program statement combinations that you could put there. Anything could happen. The program is completely broken, the input data causes the app to go to that branch that nobody ever cared to test – or apparently not enough, the backend database is permanently offline, the machine is having an extremely bad hardware day, power fails, you name it.

So what if the application just keeps choking and throwing on that particular message? With either of the aforementioned error handling modes, WCF is going to take the message out of the loop when its patience with the patient is exhausted. With the ReceiveErrorHandling.Fault option, WCF will raise an error event that can be caught and processed with a handler. When you use ReceiveErrorHandling.Move things are a bit more flexible, because the message causing all that trouble now sits in a queue again.

The headache-causing problem with poison messages is that you really, really need to do something about them. From the sender’s perspective, the message has been delivered and it puts its trust into the receiver to do the right thing. “Here’s that $1,000,000 purchase order! I’m done, go party!”. If the receiving service goes into the bug-induced loop of recurring death, you’ve got two problems: You have a nasty bug that’s probably difficult to repro since it happens under stress, and you’ve got a $1,000,000 purchase order unhappily sitting in a dark hole. Guess what your great-grand-boss’ boss cares more about.

The second, technically slightly more headache-causing problem with poison messages (if that’s possible to imagine) is that they just sit there with all the gold and diamonds that they might represent, but they are effectively just a bunch of (if you’re lucky) XML goo. Telling a system operator to go and check the poison message queues or to surface their contents to him/her and look what’s going on there is probably not a winning strategy.

So what to do? Your high-throughput automated-processing solution that does the regular business behind the queue has left the building for lunch. That much is clear. How do you hook in some alternate processing path that does at least surface the problem to an operator or “information worker”– or even a call center agent pool – in a legible and intelligible fashion so that a human can look at the problem and try finding a fix? In the end, we’ve got the best processing unit for non-deterministic and unexpected events sitting  between our shoulders, one would hope. How about writing a slightly less automated service alternative that’s easy to adjust and try to get the issue surfaced to someone or just try multiple things [Did someone just say “Workflow”?] – and hook that straight up to where all the bad stuff lands: the poison queue.

Here’s the code. I just coded that up for illustrative purposes and hence there’s absolutely room for improvement. I’m going to put the project files up on wcf.netfx3.com and will update this post with the link. We’ll start with the boilerplate stuff and the “regular” service:

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.ServiceModel.Description;
using System.Workflow.Runtime;
using ServerErrorHandlingWorkflow;
using ServerData;

namespace Server
{
    [
ServiceContract(Namespace=Program.ServiceNamespaceURI)]
   
interface IApplicationContract
    {
        [
OperationContract(IsOneWay=true)]
       
void SubmitData(ApplicationData data);
    }


    [
ServiceBehavior(TransactionAutoCompleteOnSessionClose=true,
                     ReleaseServiceInstanceOnTransactionComplete=
true)]
   
class ApplicationService : IApplicationContract
    {
        [
OperationBehavior(TransactionAutoComplete=true,TransactionScopeRequired=true),
         System.Diagnostics.
DebuggerStepThrough]
       
public void SubmitData(ApplicationData data)
        {
           
throw new Exception("The method or operation is not implemented.");
        }
    }

Not much excitement here except that the highlighted line will always cause the service to tank. In real life, the path to that particular place where the service consistently finds its way into a trouble-spot is more convoluted and may involve a few thousand lines, but this is a good approximation for what happens when you hit a poison message. Stuff keeps failing.

The next snippet is our alternate service. Instead of boldly trying to do complex processing, it simply punts the message data to a Workflow. That’s assuming that the message isn’t completely messed up to begin with and can indeed be de-serialized. To mitigate that scenario we could also use a one-way universal contract and be even more careful. The key difference between this and the “regular” service is that the alternate service turns off the WCF address filter check. We’ll get back to that. 


    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
    class ApplicationErrorService : IApplicationContract
    {
       
public void SubmitData(ApplicationData data)
        {
           
Dictionary<string,object> workflowArgs = new Dictionary<string,object>();
            workflowArgs.Add(
"ApplicationData",data);
           
WorkflowInstance workflowInstance =
               
Program.WorkflowRuntime.CreateWorkflow(
                         
typeof(ErrorHandlingWorkflow),
                          workflowArgs);
            workflowInstance.Start();
        }
    }

So now we’ve got the fully automated middle-of-the-road default service and our “what do we do next” alternate service. Let’s hook them up.

    class Program
    {
       
public const string ServiceNamespaceURI =
               
"http://samples.microsoft.com/2007/03/WCF/PoisonHandling/Service";
       
public static WorkflowRuntime WorkflowRuntime = new WorkflowRuntime();

       
static void Main(string[] args)
        {
           
string msmqQueueName = Properties.Settings.Default.QueueName;
           
string msmqPoisonQueueName = msmqQueueName+";poison";
           
string netMsmqQueueName =
                
"net.msmq://" + msmqQueueName.Replace('\\', '/').Replace("$","");
           
string netMsmqPoisonQueueName = netMsmqQueueName+";poison";
           
           
if (!System.Messaging.MessageQueue.Exists(msmqQueueName))
            {
                System.Messaging.
MessageQueue.Create(msmqQueueName, true);
            }

First – and for this little demo only – we’re setting up a local queue and do a little stringsmithing to get the app.config stored MSMQ format queue name into the net.msmq URI format. Next …

            ServiceHost applicationServiceHost = new ServiceHost(typeof(ApplicationService));
           
NetMsmqBinding queueBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);
            queueBinding.ReceiveErrorHandling =
ReceiveErrorHandling.Move;
            queueBinding.ReceiveRetryCount = 1;
            queueBinding.RetryCycleDelay =
TimeSpan.FromSeconds(1);
            applicationServiceHost.AddServiceEndpoint(
typeof(IApplicationContract),
                                                      queueBinding,
                                                      netMsmqQueueName);

Now we’ve bound the “regular” application service to the queue. I’m setting the binding parameters (look them up at your leisure) in a way that we’re failing very fast here. By default, the RetryCycleDelay is set to 30 minutes, which means that WCF is giving you a reasonable chance to fix temporary issues while stuff hangs out in the retry queue. Now for the poison handler service:

      
           
ServiceHost poisonHandlerServiceHost = new ServiceHost(typeof(ApplicationErrorService));
           
NetMsmqBinding poisonBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);
            poisonBinding.ReceiveErrorHandling =
ReceiveErrorHandling.Drop;
            poisonHandlerServiceHost.AddServiceEndpoint(
typeof(IApplicationContract),
                                                        poisonBinding,
                                                        netMsmqPoisonQueueName);

Looks almost the same, hmm? The trick here is that we’re pointing this one to the poison queue into which the regular service drops all the stuff that it can’t deal with. Otherwise it’s (almost) just a normal service. The key difference between the ApplicationErrorService service and its sibling is that the poison-message handler service implementation is decorated with [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)].Since the original message was sent to the a different (the original) queue and we’re now looking at a sub-queue that has a different name and therefore a different WS-Addressing:To identity, WCF would normally reject processing that message. With this behavior setting we can tell WCF to ignore that and have the service treat the message as if it landed at the right place – which is what we want.

And now for the unspectacular run-it and drop-a-message-into-queue finale:

            applicationServiceHost.Open();
            poisonHandlerServiceHost.Open();
           
           
Console.WriteLine("Application running");

           
ChannelFactory<IApplicationContract> client =
              
new ChannelFactory<IApplicationContract>(queueBinding,
                                                        netMsmqQueueName);
           
IApplicationContract channel = client.CreateChannel();
            
ApplicationData data = new ApplicationData();
            data.FirstName =
"Clemens";
            data.LastName =
"Vasters";
            channel.SubmitData(data);    
            ((
IClientChannel)channel).Close();

           
Console.WriteLine("Press ENTER to exit");
       
           
Console.ReadLine();
        }
    }
}

The Workflow that’s hooked up to the poison handler in my particular sample project does nothing big. It’s got a property that is initialized with the data item and just has a code activity that spits out the message to the console. It could send an email, page an operator through messenger, etcetc. Whatever works.

Thursday, March 29, 2007 1:02:54 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0] - Trackback
MSMQ | WCF