Author: Richard Seroter

  • I, For One, Welcome our New Cloud Overlords

    I’m trying really hard to not pay attention to PDC today, but, damn them and their interesting announcements!  The “Cloud OS” turned out to be Azure.  Good stuff there.  “BizTalk Services” are dead, long live .NET Services.    Neat that you have both Java and Ruby SDKs for .NET Services.

    Also, we got a full release of the Microsoft Federation Gateway (whitepaper here) and a preview of the Microsoft Service Connector (announcement here).  For companies tackling B2B scenarios with a myriad of partners, these technologies may offer a simplified route.

    Ok, back to real work.  Stop distracting me with your sexy cloud products.

    Technorati Tags: ,

  • Reason #207 Why the BizTalk WCF Adapter is Better Than the SOAP Adapter

    In writing my book, I’ve had a chance to compare the two BizTalk service generation wizards, and I now remember why the BizTalk Web Services Publishing Wizard (ASMX) drove me nuts.

    Let’s look at how the WCF Wizard and ASMX Wizard take the same schema, and expose it as a service.  I’ve purposely included some complexity in the schema to demonstrate the capabilities (or lack thereof) of each Wizard.  Here is my schema, with notations indicating the node properties that I added.

    Now, I’ve run both the BizTalk Web Services Publishing Wizard (ASMX) and the BizTalk WCF Service Publishing Wizard (WCF) on this schema and pulled up WSDL of each.   First of all, let’s look at the ASMX WSDL.  Here is the start of the schema definition.  Notice that the “Person” element was switched back to “sequence” from my XSD definition of “all.”  Secondly, see that my regular expression no longer exists in the “ID” node.

    We continue this depressing journey by reviewing the rest of the ASMX schema.  Here you can see that a new schema type was created for my repeating “address” node, but I lost my occurrence boundaries.  The “minOccurs” is now 0, and the “maxOccurs” is unbounded.  Sweet.  Also notice that my “Status” field has no default value, and the “City” node doesn’t have a field restriction.

    So, not a good story there.  If you’ve thoughtfully designed a schema to include a bit of validation logic, you’re S.O.L.  Does the WCF WSDL look any better, or will I be forced to cry out in anger and shake my monitor in frustration?  Lucky for me (and my monitor), the WCF wizard keeps the ENTIRE schema intact when publishing the service endpoint.

    There you go.  WCF Wizard respects your schema, while the ASMX Wizard punches your schema in the face.  I think it’s now time to take the ASMX Wizard to the backyard, tie it to a tree, and shoot it.  Then, tell your son it “ran away but you got a brand NEW Wizard!”

    Technorati Tags:

  • That’s "MR" Skeptical Blogger to You!

    A couple weeks back I answered some interview questions regarding my impressions of Microsoft’s Oslo.  One of my answers found its way into an article you can read on ComputerWorld entitled Microsoft eyes Oslo as game-changer for application development.   It’s a good article with some interesting perspective.  You’ll find my quote on page three.  I wouldn’t say that I’m skeptical of the intentions of Oslo, but I AM just curious to see how they pull it off.  So, maybe I’m skeptical of their implementation!  The point I was trying to make is that expansive models aren’t easy to either design or maintain, and attempts that I’ve seen so far to synchronize the model with the implementation have been lacking.  We’ll see if the Oslo repository and “M” language are actually game changers.  Here’s hoping.

    I’m not making it to PDC this year, but since I live close by, I hope to pop in on some extracurricular events.

  • In-Memory BizTalk Resequencer Pattern

    I was asked a couple days ago whether it was possible to receive a related but disjointed set of files into BizTalk Server and both aggregate and reorder them prior to passing the result to a web service.  Below is small sample I put together to demonstrate that it was indeed possible.

    You can find some other resequencer patterns (most notably, in the Pro BizTalk Server 2006 book), but I was looking for something fairly simple and straightforward.  My related messages all come into BizTalk at roughly the same time, and, there are no more than 20 in a related batch.

    Let’s first take a look at a simplified version of the schema I’m working with.

    I’ve highlighted a few header values.  I know the unique ID of the batch of related records (which is a promoted value), how many items are in the batch, and the position of this individual message in the batch sequence.  These are crucial for creating the singleton, and being able to reorder the messages later on.  The message payload is a description of a document.  This same schema is used for the “aggregate” message because the “Document” node has an unbounded occurrence limit.

    I need a helper component which stores, sorts and combines my batch messages.  My class starts out like this:

    Notice that I’m using a SortedDictionary class which is going to take the integer-based sequence number as the “key” and an XML document as the “value.”  The SortedDictionary is pretty cool in that it will automatically sort my list based on the key.  No extra work needed on my part.  I’ve also got a couple member variables that hold values universal to the entire batch of records.  I accept those values in the constructor.

    Next, I have an operation to take an inbound XML document and add it to the list.

    You can see that I yank out the document-specific “SequenceID” and use that value as the “key” in the SortedDictionary.

    Next I created an “aggregation” function which drains the SortedDictionary and creates a single XML message that jams all the “Document” nodes into a repeating collection.

    As you can see, I extract values from the dictionary using a “for-each” loop and a KeyValuePair object.  I then create a new “Document” node, and suck out the guts of the dictionary value and slap it in there.

    Now I can build my BizTalk singleton.  Because we promoted the “BatchID” value, I can create a correlation set based on it.  My initial receive shape takes in a “BatchRecord” message and initializes the correlation set.  In the “Set Variables” Expression Shape, I instantiate my loop counters (index at 1 and maximum based on the “BatchCount” distinguished field), and the helper class by passing in the “BatchID” and “BatchCount” to the constructor.  In the “AddDocToBatch” Expression Shape, I set my message equal to a variable of type “XmlDocument”, and pass that variable to the “AddDocumentToDictionary” method of my helper class.

    Next, I have a loop where I receive the (following correlation) “BatchRecord” message, once again call “AddDocumentToDictionary”, and finally increment my loop counter.

    Finally, I create the “BatchResult” message (same message type as the “BatchRecord”) by setting it equal to the result of the “GetAggregateDocument” method of the helper class.  Then, I send the message out of the orchestration.

    So, if I drop in 5 messages at different times and completely out of order (e.g. sequence 3, 5, 4, 2, 1), I get the following XML output from the BizTalk process:

    As you can see, all the documents show up in the correct order.

    Some parting thoughts: this pattern clearly doesn’t scale as the number of items in a batch increases.  Because the batch aggregate is kept in memory, you will run into issues if either (a) the batch messages come in over a long period of time or (b) there are lots of messages in a batch.  If either case is true, you would want to consider stashing the batch records in an external storage (e.g. database) and doing the sorting and mashing at that layer.

    Any other thoughts you wish to share?

    Technorati Tags:

  • Splitting Delimited Values in BizTalk Maps

    Today, one of our BizTalk developers asked me how to take a delimited string stored in a single node, and extract all those values into separate destination nodes.  I put together a quick XSLT operation that makes this magic happen.

    So let’s say I have a source XML structure like this:

    I need to get this pipe-delimited value into an unbounded destination node.  Specifically, the above XML should be reshaped into the format here:

    Notice that each pipe-delimited value is in its own “value” node.  Now I guess I could chained together 62 functoids to make this happen, but it seemed easier to write a bit of XSLT that took advantage of recursion to split the delimited string and emit the desired nodes.

    My map has a scripting functoid that accepts the three values from the source (included the pipe-delimited “values” field) and maps to a parent destination record.

    Because I want explicit input variables  to my functoid (vs. traversing the source tree just to get the individual nodes I need), I’m using the “Call Templates” action of the Scripting functoid.

    My XSLT script is as follows:

    <!-- This template accepts three inputs and creates the destination 
    "Property" node.  Inside the template, it calls another template which 
    builds up the potentially repeating "Value" child node -->
    <xsl:template name="WritePropertyNodeTemplate">
    <xsl:param name="name" />
    <xsl:param name="type" />
    <xsl:param name="value" />
    
    <!-- create property node -->
    <Property>
    <!-- create single instance children nodes -->
    <Name><xsl:value-of select="$name" /></Name>
    <Type><xsl:value-of select="$type" /></Type>
    
    <!-- call splitter template which accepts the "|" separated string -->
    <xsl:call-template name="StringSplit">
    <xsl:with-param name="val" select="$value" />
    </xsl:call-template>
    </Property>
    </xsl:template>
    
    <!-- This template accepts a string and pulls out the value before the 
    designated delimiter -->
    <xsl:template name="StringSplit">
    <xsl:param name="val" />
    
    <!-- do a check to see if the input string (still) has a "|" in it -->
    <xsl:choose>
      <xsl:when test="contains($val, '|')">
       <!-- pull out the value of the string before the "|" delimiter -->
       <Value><xsl:value-of select="substring-before($val, '|')" /></Value>
         
         <!-- recursively call this template and pass in 
    value AFTER the "|" delimiter -->
         <xsl:call-template name="StringSplit">
         <xsl:with-param name="val" select="substring-after($val, '|')" />
         </xsl:call-template>
    
      </xsl:when>
      <xsl:otherwise>
          <!-- if there is no more delimiter values, print out 
    the whole string -->
          <Value><xsl:value-of select="$val" /></Value>
       </xsl:otherwise>
    </xsl:choose>
    
    </xsl:template>
    

    Note that I use recursion to call the “string splitter” template and I keep passing in the shorter and shorter string into the template.   When I use this mechanism, I end up with the destination XML shown at the top.

    Any other way you would have done this?

    Technorati Tags:

  • Interview Series: Four Questions With … Matt Milner

    I’m continuing my series of interviews where I chat with a different expert in the Connected Systems space and find out their thoughts on technology.

    This month, we’re having a powwow with Matt Milner.  Matt’s a Microsoft MVP, blogger, instructor and prolific author in MSDN Magazine.  Matt’s a good sport who was subjected to my stupidest stupid question so far and emerged unscathed.

    Q: You’ve recently delivered a series of screencasts for Microsoft that explain how to get started with WCF and WF. What has the reaction to these offerings been so far? Do you believe that these efforts make development in WCF and WF more approachable? Why do you think that uptake of these technologies has seemed a been a bit slower than expected?

    A:  The response to the screencasts has been great; with a lot of positive comments from developers who have viewed them.  I think the smaller bits of information are easily digestible and the goal is definitely to make the technologies more accessible to .NET developers.  I think uptake on Windows WF is slower than hoped because many developers have not seen the “killer application” of the technology to really help them understand how it can save them time. 

    Q: There are a wide range of technologies that you’ve written about and researched (e.g. BizTalk Services, WCF, WF, BizTalk Server).   Which technology are you truly excited to work with and learn more?  For the traditional BizTalk developer, which technology would you recommend they spend free time on, and why?

    A:  For me, the combination of WF and WCF is going to be huge moving forward.  These are primary underlying technologies for BizTalk Services and other platform plays coming from Microsoft.  Both technologies will be used in many different products from Microsoft and other vendors as they are key enabling technologies.  Understanding these two technologies on top of the core .NET language fundamentals will provide developers with a solid base for developing in the next generation Microsoft application platform.

    Q: In addition to your day job, you’re also an instructor for Pluralsight (with a course coming up in Irvine, CA) which means that you are able to watch many folks grasp BizTalk for the very first time.    What are some common struggles you see, and what sort of best practices do you teach your students that you wish seasoned, self-taught BizTalkers would adhere to?

    A:  One of the biggest struggles for most students new to BizTalk is getting your head wrapped around the message oriented approach.  Most .NET developers focus on objects with methods and parameters and BizTalk doesn’t work that way.  The other two key things that trip people up are a lack of knowledge around programming XML, schemas and XSLT which are important technologies in BizTalk Server; and the sheer number of tools and concepts that surround BizTalk Server and make it an extremely powerful server platform.

    Q [stupid question]: In addition to being an instructor, you also are a consultant.   This means that there are countless opportunities to introduce yourself to new people and completely fabricate a backstory which baffles and intrigues your audience.  For instance, you could walk onto a brand new project and say “Hi, before doing IT consulting, I toiled in the Bolivian underground as an oil wrestler with a penchant for eye gauges.   I currently own a private farm where I raise boneless chickens and angry ferrets who provide inspiration for a romantic thriller I’m writing on weekends.”  Ok, give me your best fake back-story that you could use for your upcoming BizTalk class. 

    A:  Over the summer I lived my dream of opening a booth at the Minnesota State Fair where food “on-a-stick” is a common theme.  My family and I perfected the Peanut Butter and Jelly sandwich-on-a-stick, pancakes on-a-stick, and deep-fried huevos rancheros on-a-stick.  The whole family worked at the booth and got to meet people from all over Minnesota including celebrities Al Franken and Jesse “the body” Ventura.

    Stay tuned for next month’s interview where we can digest some of the announcements and information from the upcoming PDC.

    Technorati Tags:

  • "Gotcha" When Deleting Suspended BizTalk Messages

    Today I’m sitting in a “BizTalk Administration” class being taught to 20 of my co-workers by my buddy Victor.  I’ve retired from teaching internal training classes on BizTalk, so the torch has been passed and I get to sit in the back and heckle the teacher.

    One thing that I finally confirmed today after having it on my “todo” list for months was the behavior of the BizTalk Admin Console when terminating messages.  What I specifically wanted to confirm was the scenario presented below.

    Let’s say that I have 10 suspended messages for a particular receive port.

    What happens if while I’m looking at this, another 5 suspended messages come in for this service instance?  I’ll confirm that 5 more came in via another “query” in the console.

    So we know for sure that 5 more came in, but, let’s say I was still only looking at the “Suspended (resumable)” query tab.  If I choose to”terminate” the 10 suspended messages, in reality, all suspended messages that match this search criteria (now 15) get terminated.

    So even though the default query result set showed 10 suspended messages, the “terminate” operation kills anything that matches this suspension criteria (15 messages).   How do we avoid this potentially sticky situation?  The best way is to append an additional criteria on your Admin Console query.  The “Suspension Time” attribute allows you to put a date + time filter on your result set.  In the screenshot below, you can see that I’ve taken the greatest timestamp in my visible result set and used that.  Even though additional failures have occurred, then don’t get absorbed by this query.

    So, if you are a regular BizTalk administrator, and don’t already do this (and maybe I’m the only sap who didn’t realize this all along), make sure that your suspension queries always have a date restriction prior to terminating (unless you don’t care about messages that have arrived since the query last executed).

    Technorati Tags:

  • Differences in BizTalk Subscription Handling for SOAP and WCF Adapter Messages

    I recently encountered a bit of a “gotcha” when looking at how BizTalk receives WCF messages through its adapters.  I expected my orchestration subscription for messages arriving from either the SOAP adapter or WCF adapter to behave similarly, but alas, they do not.

    Let’s say I have two schemas.  I’m building an RPC-style service that takes in a query message and returns the data entity that it finds.  I have a “CustomerQuery_XML.xsd” and “Customer_XML.xsd” schema in BizTalk.

    Let’s assume I want to be very SOA/loosely-coupled so I build my web service from my schemas BEFORE I create my implementation logic (e.g. orchestration).  To demonstrate the point of the post, I’ll need to create one endpoint with the BizTalk Web Services Publishing Wizard and another with the BizTalk WCF Service Publishing Wizard (using the WCF-BasicHTTP adapter).  For both, I take in the “query” message and return the “entity” message through a two-way operation named “GetCustomer.”

    Now, let’s add an orchestration to the mix.  My orchestration takes in the query message and returns the entity message.  More importantly, note that my logical port’s operation name matches the name of the service operation I designated in the service generation wizards.

    Why does this matter?  Once I bind my orchestration’s logical port to my physical receive location (in this case, pointing to the ASMX service), I get the following subscription inserted into the MessageBox:

    Notice that it’s saying that our orchestration will take messages if (a) they come from a particular port, are of a certain type, and not using a SOAP transport, or (b) they come from a particular port and has a specific SOAP method called.  This is so that I can add non-SOAP receive locations to this particular port, and still have them arrive at the orchestration.  If I picked this up from the FILE adapter, I clearly wouldn’t have a SOAP method that matches the orchestration’s logical port operation name.

    For comparison purposes, note that the subscription created by binding the orchestration to the WCF receive location looks identical (except for a different port ID).

    Let’s call the SOAP version of the service (and assume it has been bound to the orchestration).  If we “stop” the orchestration, we can see that a message is queued up, and that it’s context value match one part of our subscription (receive port with a particular ID, and the SOAP method name matching our subscription).  Note that because the InboundTransportType was “SOAP” that the first part of the subscription was followed.

    If I rebuild this orchestration with a DIFFERENT port operation name (“GetDeletedCustomer”) and resubmit through the SOAP adapter, I’ll get a subscription error because the inbound message (with the now-mismatched operation in the client’s service proxy) doesn’t match the subscription criteria.

    You can see there that we still apply the first port of the subscription (because the inbound transport type is SOAP), and in this case, the new method name doesn’t match the method used to call the service.

    Can you guess where I’m going?  If I switch back and bind the orchestration to the WCF receive location, and call that service (with now-mismatched operations still in place), everything works fine. Wait, what??  How did that work?  If I pause the orchestration, we can see how the context data differs for messages arriving at a WCF endpoint.

    As you can see, my InboundTransportType for this receive location is “BasicHttpRLConfig” which means that the subscription is now evaluated against the alternate criteria: port ID, message type and !=SOAP.

    Conclusion

    So, from what I can see, the actual operation name of the WCF service no longer corresponds to the orchestration logical port’s operation name.  It doesn’t matter anymore.  The subscription treats WCF messages just like it would FILE or MSMQ messages.  I guess from a “coupling” perspective this is good since the orchestration (e.g. business logic) is now even more loosely coupled from the service interface.

    Technorati Tags: ,

  • Building Enterprise Mashups using RSSBus: Part IV

    We conclude this series of blog posts by demonstrating how to take a set of feeds, and mash them up into a single RSS feed using RSSBus.

    If you’ve been following this blog series, you’ll know that I was asked by my leadership to prove that RSSBus could generate a 360° view of a “contact” by (a) producing RSS feeds from disparate data sources such as databases, web services and Excel workbooks and (b) combining multiple feeds to produce a unified view of a data entity.  Our target architecture looks a bit like this:

    In this post, I’ll show you how to mash up all those individual feeds, and also how to put a friendly HTML front end on the resulting RSS data.

    Building the Aggregate Feed

    First off, my new aggregate feed asks for two required parameters: first name and last name of the desired contact.

    Next, I’m ready to call my first sub-feed.  Here, I set the input parameter required by the feed (“in.lastname”), and make a call to the existing feed.  Recall that this feed calls my “object registry service” which tells me every system that knows about this contact.  I’ve taken the values I get back, and put them into a “person” namespace.  The “call” block executes for each response value (e.g. if the user is in 5 systems, this block will execute 5 times), so I have a conditional statement (see red box) that looks to see which system is being returned, and setting a specific feed value based on that.

    I set unique feed items for each system (e.g. “person:MarketingID”) so that I can later do a check to see if a particular item exists prior to calling the feed for that system.  See here that I do a “check” to see if “MarketingID” exists, and if so, I set the input parameter for that feed, and call that feed.

    You may notice that I have “try … catch” blocks in the script.  Here I’m specifically catching “access denied” blocks and writing a note to the feed instead of just blowing up with a permission error.

    Next, I called the other data feeds in the same manner as this one above.  That is, I checked to see if the system-specific attribute existed, and if so, called the feed corresponding to that system.   My “reference data” feed which serves up Microsoft Excel data returns a data node that holds the blog feed for the contact.  I took that value (if it exists) and then called the built-in RSSBus Feed Connector’s feedGet operation and passed in the URL of my contact’s blog feed.  This returns me whatever is served up by my contact’s external blog.

    Neat.  So, now I have a single RSS feed that combines data from web services, Google web queries, Excel workbooks, SQL Server databases, and external blog feeds.  If I view this new, monster feed, I get a very denormalized, flat data set.

    You can see (in red) that when data repeating occurred (for example, multiple contact “interactions”), the related values, such as which date goes with which location, isn’t immediately obvious.  Nonetheless, I have a feed that can be consumed in SharePoint, Microsoft Outlook 2007, Newsgator, or any of your favorite RSS readers.

    Building a RSSBus HTML Template

    How about presenting this data entity in a business-friendly HTML template instead of a scary XML file?  No problem.  RSSBus offers the concept of “templates” where you can design an HTML front end for the feed.

    Much like an ASP.NET page, you can mix script and server side code in the HTML form.  Here, I call the mashup feed in my template, and begin processing the result set (from the “object registry service”).  Notice that I can use an enumeration to loop through, and print out, each of the systems that my contact resides in.  This enumeration (and being able to pull out the “_value” index) is a critical way to associate data elements that are part of a repeating result set.

    To further drive that point home, consider the repeating set of “interactions” I have for each contact.  I might have a dozen sets of “interaction type + date + location” values that must be presented together in order to make sense.  Here you can see that I once again use an enumeration to  print out each date/type/location that are related.

    The result?  I constructed a single “dashboard” that shows me the results of each feed as a different widget on the page.   For a sales rep about to visit a physician, this is a great way for them to get a holistic customer view made up of attributes from every system that knows anything about that customer.  This even includes a public web (Google) query and a feed from their personal, professional, or organization’s blog.  No need for our user to log into 6 different systems to get data, rather, I present my own little virtual data store.

    Conclusion

    In these four blog posts, I explained a common data visibility problem, and showed how RSSBus is one creative tool you can use to solve it.  I suspect that no organization has all their data in an RSS-ready format, so applications like RSSBus are a great example of adapter technology that makes data extraction and integration seamless.  Mashups are a powerful way to get a single real-time look at information that spans applications/systems/organizations and they enable users to make more informed decisions, faster.

    Technorati Tags: ,

  • New Microsoft KB Article on BizTalk Database Support

    If you have any responsibility for planning or maintaining BizTalk Server databases, I highly encourage you to check out the brand new Microsoft Knowledge Base article entitled How to maintain and troubleshoot BizTalk Server databases

    The article contains details on SQL Server instance settings, the SQL Server Agent jobs, handling deadlocks, how to delete data from BizTalk databases, and how to troubleshoot database-related issues.

    Much of this data is floating around elsewhere, but it’s a useful bookmark for a consolidated view.

    On a completely unrelated note, I’ve enjoyed poking around the newly opened up Stack Overflow site and learning a few new C# language things and seeing some nice tool recommendations.  I suspect that this site will be added to my daily web browsing cycle.

    Technorati Tags: