More Detail on BizTalk Services and Hosting WF Workflows in BizTalk

Seems like there’s no shortage of new and exciting topics to stay up to date on!


 John Udel has just posted a conversation with John Schewchuck exploring how BizTalk Services plays an integral role in the evolution towards an Internet Service Bus. And, Paul Andrew, product manager for Windows Workflow Foundation, has posted on a new project that demonstrates how to host WF workflows in BizTalk Server! This give you the best of both worlds, WF’s cutting edge programming model coupled with BizTalk’s enterprise scale hosting capabilities.


-Kris

Hanselman joins Microsoft

I

opened my newsreader last night and there on the top of my “Must Read” folder was

a post from Hanselman entitled

“Blue Badge”. Apparently Scott has decided to take the jump and join Microsoft

in ScottGu’s division. According to him, this is what he’ll be doing:

The HR title is a nice generic one like “Program Manager” (I was thinking to get this

on my business card – Scott Hanselman – progman.exe,

what do you think? 😉 ) but in essence I’m going to talk about .NET and Visual Studio

– the whole of DevDiv, including ASP.NET, WinForms, WPF, Silverlight, CLR, LINQ, IIS,

DLR, .NET CF, everything. This means videos, screencasts, podcasts, maybe some Channel

9 stuff, doing articles, wikis, speaking at conferences and large events (invite me!),

creating starter kits, samples, as well as my regular hobby of plugging things into

other things. I’ll also be working on understanding our community (that means

you, Dear Reader)thr ough conversations, visits, and trying to bring

some big picture analysis (the kind of stuff I do now, again) to the .NET 3.5 and

.NET Futures stack. I am also obsessed with getting my new Apple Newton Messagepad

2000 to sync with Outlook 2007, so watch for that.

Personally I’m absolutely thrilled to hear this, because Scott is so very good at

communicating things about the .NET Framework and things developer. I also find

it funny that he created the image above because he knew that the Borg joke would

be made. He’s right of course, people will say he’s going to become faceless,

nameless, and simply join the “Evil Empire” but in reality shouldn’t we be thrilled

that Microsoft wants to hire someone who is so community focused as Scott?

I often give the Linux community crap about hating Microsoft and a reflex, no basis

just a reflexive “Microsoft == Evil” embedded in their psyche. Yet most (certainly

not all) of Scott’s readership are Microsoft .NET developers, because that and gadgets

are what he talks about most often, and yet I expect that many of his own readers

will relate this to the Borg as he did. Why is this?

Upcoming Speaking Events

I’ve been a busy camper the last several months, having spoken at:

  • Microsoft TechEd 2007 – Birds of a Feather : BizTalk, WCF and WF

  • Little Rock .NET User Group – All Day Training Event : WCF Deep Dive

  • Northwest Arkansas .NET User Group – Introduction to C# 3.0

But now there are several more coming up over the next several months I want to make

you aware of:

  • Oklahoma City Code Camp (www.okcodecamp.com)

    : Introduction to C# 3.0 on July 28th, 2007

  • Houston TechFest (www.houstontechfest.com)

    : Introduction to BizTalk Server and Introduction to C# 3.0 on August 25th,

    2007

  • Memphis .NET User Group : Practical Test Driven Development on October 16th,

    2007

  • Little Rock .NET User Group : Introduction to C# 3.0 on November 8th, 2007

  • VSLive! Austin : Introduction to C# 3.0 on November 13th, 2007

In all likelihood I’ll also be speaking at least twice at the Dallas BizTalk User

Group between now and the end of the year as well. Looking like a busy season,

and I look forward to meeting as many of you as I can while I’m out and about.

Memphis, take note : I’ll be in Memphis the weekend before the user

group, and it will be my birthday so if you’ve got recommendations of where I should

go, or just tourist recommendations in general then drop a comment! This will

be my first time in Memphis not going 50+ MPH the whole time.

Retrieving error information from HIPAA accelerator

A recent request I got was for information regarding retrieving error informaiton in a morereadable format:

We have several clients submitting valid X12 documents but recently we started receiving X12 from a client which is not conforming to the standard. For these messages BizTalk is throwing an error into eventlog and does nothing. Unless some one monitors the eventlog there is no way we could identify that a message failed. At the same time we want to report to client in a nice way that the message they sent us is invalid. Something similar to EDIFECS or FREDI. We cannot find a simpler way to do that. Do you have any information about how we can validate X12 and reject in BizTalk in a better way?

I actually have, what I have is an orchestration that picks up the file, interrogates the sender/reciever id and then drops the file off for the HIPAA accelerator to validate. It then queries the HIPAA database and extracts the information and sends out an email. It has a delay before it runs the stored procedure that is determined by the Xref table (around 10 minutes) and then if it does not receive the XML version in the correlation set, it runs the following logic.

Here is the stored procedure that is on the HIPAA_EDIDb

CREATE PROCEDURE dbo.captureDetails
@senderQual varchar(2),
@senderId varchar(15),
@controlNumber varchar(9)
AS
SELECT errtxt.descrp AS description, errors.descrp1+errors.descrp2 AS details
FROM audin INNER JOIN
errors ON audin.icin = errors.msgnr INNER JOIN
errtxt ON errors.etc = errtxt.etc
WHERE (audin.sid = @senderId)
AND (audin.icr = @controlNumber)
AND (audin.sidcdq =@senderQual)
AND (errors.inout = ‘2’)
for xml raw–, xmldata
GO

Here is the schema that is created by this stored procedure:

<?xml version=”1.0″?>
<xs:schema attributeFormDefault=”unqualified” elementFormDefault=”qualified” targetNamespace=”http://captureErrors” version=”1.0″ xmlns:xs=”http://www.w3.org/2001/XMLSchema”>
<xs:annotation>
<xs:appinfo>
<msbtssql:sqlScript value=”exec [captureDetails] @controlNumber=&quot; &quot;, @senderId=&quot; &quot;, @senderQual=&quot; &quot;” xmlns:msbtssql=”http://schemas.microsoft.com/BizTalk/2003″ />
</xs:appinfo>
</xs:annotation>
<xs:element name=”Request”>
<xs:complexType>
<xs:sequence>
<xs:element name=”captureDetails”>
<xs:complexType>
<xs:attribute name=”controlNumber” type=”xs:string” />
<xs:attribute name=”senderId” type=”xs:string” />
<xs:attribute name=”senderQual” type=”xs:string” />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name=”Response”>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs=”0″ maxOccurs=”unbounded” name=”row” xmlns:q1=”http://captureErrors” type=”q1:rowType” />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name=”rowType”>
<xs:attribute name=”description” type=”xs:string” />
<xs:attribute name=”details” type=”xs:string” />
</xs:complexType>
</xs:schema>

I have a flat file schema

<?xml version=”1.0″ encoding=”utf-16″?>
<xs:schema xmlns:ns0=”http://captureErrors” xmlns=”http://notificationEmail.email” xmlns:b=”http://schemas.microsoft.com/BizTalk/2003″ targetNamespace=”http://notificationEmail.email” xmlns:xs=”http://www.w3.org/2001/XMLSchema”>
<xs:import schemaLocation=”.\errorinfo.xsd” namespace=”http://captureErrors” />
<xs:annotation>
<xs:appinfo>
<b:schemaInfo count_positions_by_byte=”false” parser_optimization=”speed” lookahead_depth=”3″ suppress_empty_nodes=”false” generate_empty_nodes=”true” allow_early_termination=”false” standard=”Flat File” root_reference=”email” />
<schemaEditorExtension:schemaInfo namespaceAlias=”b” extensionClass=”Microsoft.BizTalk.FlatFileExtension.FlatFileExtension” standardName=”Flat File” xmlns:schemaEditorExtension=”http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions” />
<b:references>
<b:reference targetNamespace=”http://captureErrors” />
</b:references>
</xs:appinfo>
</xs:annotation>
<xs:element name=”email”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” sequence_number=”1″ child_order=”postfix” child_delimiter_type=”hex” child_delimiter=”0x0D 0x0A” />
<b:properties>
<b:property distinguished=”true” xpath=”/*[local-name()=’email’ and namespace-uri()=’http://notificationEmail.email’]/*[local-name()=’FileName’ and namespace-uri()=”]/@*[local-name()=’name’ and namespace-uri()=”]” />
<b:property distinguished=”true” xpath=”/*[local-name()=’email’ and namespace-uri()=’http://notificationEmail.email’]/*[local-name()=’Count’ and namespace-uri()=”]/@*[local-name()=’number’ and namespace-uri()=”]” />
</b:properties>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number=”0″ />
</xs:appinfo>
</xs:annotation>
<xs:element name=”Envelope”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” tag_name=”Sender (ISA06:ISA05:GS02): ” sequence_number=”1″ />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:attribute name=”id” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name=”ControlNumber”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” sequence_number=”2″ child_order=”infix” child_delimiter_type=”char” child_delimiter=”,” tag_name=”Control Number: ” />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:attribute name=”ControlNo” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name=”Count”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number=”3″ structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” tag_name=”Count: ” />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:attribute name=”number” type=”xs:int”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name=”FileName”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number=”4″ structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” tag_name=”Filename: ” />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:attribute name=”name” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element maxOccurs=”1″ name=”Data”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number=”5″ structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” child_order=”prefix” child_delimiter_type=”hex” child_delimiter=”0x0D 0x0A 0x0D 0x0A” />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number=”0″ />
</xs:appinfo>
</xs:annotation>
<xs:element maxOccurs=”unbounded” name=”Details”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” tag_name=”Error #” child_order=”infix” child_delimiter_type=”char” child_delimiter=”= ” sequence_number=”1″ />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number=”0″ />
</xs:appinfo>
</xs:annotation>
<xs:element maxOccurs=”1″ name=”Number” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element maxOccurs=”1″ name=”Information”>
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number=”2″ structure=”delimited” preserve_delimiter_for_empty_data=”true” suppress_trailing_delimiters=”false” child_order=”infix” child_delimiter_type=”char” child_delimiter=” ” />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number=”0″ />
</xs:appinfo>
</xs:annotation>
<xs:element maxOccurs=”1″ name=”Info” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”1″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element maxOccurs=”1″ name=”Detail” type=”xs:string”>
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number=”2″ justification=”left” />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

The orchestration runs and calls the stored procedure, maps the data, determines who gets it (based on a role link) and send out the email.

The email’s contents look like this:

Sender (ISA06:ISA05:GS02): 1234:ZZ:1234
Control Number: 166
Count: 0
Filename: c:\import\8371234564789.txt Error #1= The check condition has not been met. Contact the sender.; source format: [5 00401 ,X12-4010]
source document: [837 004010DEFAULT X X098A1,Health Care Claim: Professional]
source segment: [data#9945,def#22,tag=NM1 ,name=TS837Q1_2010BA_NM1_SubscriberName_A1>DEFAULT]
source element: [def#9,elm#9,comp#0,name=TS837Q1_2010BA_NM109__SubscriberPrimaryIdentifier_A1>DEFAULT],
value: []
undefined!
(((TS837Q1_2010BA_NM108__IdentificationCodeQualifier_A1>DEFAULT == [] AND TS837Q1_2010BA_NM109__SubscriberPrimaryIdentifier_A1>DEFAULT == [] ) OR

You have to be using the HIPAA recieve location, and not the pipeline component, for reason I have blogged about earlier.

Choosing Between WF Rules and BizTalk Business Rules Engine

If you’re still facing issues deciding which sort of workflow/rules technology from Microsoft to use (e.g. Windows Workflow vs. BizTalk), check out the latest well-written piece by Charles Young. He covers many of the specific differences to consider when deciding which Microsoft technology will work best for your given application.

Technorati Tags: BizTalk, Workflow, Business […]

BizTalk vs. WF/WCF Comparison (Smack Down) Article published

In the BizTalk Hotrod quarterly ezine. You can find a condensed version of the article at http://www.biztalkhotrod.com

The full version (huge!)can be found at http://biztalkhotrod.com/Documents/BizTalk%20Smack%20Down%20Full.pdf

The article was a ton of work but was well worth the effort. The intent was to have some fun comparing BizTalk and WF/WCF. Let me know if you have any feedback!