Biztalk message agnostic orchestration - biztalk

After moving away from Biztalk since BT2006, we're looking at bringing it back into the organization. One of the frustrations I had early on was when dealing wht HL7 and orchestrations, we needed to have a seperate orchestration for each ADT message type, even though the schema for each type is essentially the same, and each orchestration did exactly the same thing. Moving forward into the world of BizTalk 2010, has anything improved here? Is there a pattern I can utilize to use a single orchestration for all ADT types?

HL7 messaging in BizTalk has remained roughly unchanged since the 2006 release. Because BizTalk defines a schema for each message and event type (e.g. ADT^A01, ADT^A03, ADT^A08) and not just for each message type (e.g. ADT, BAR, MDM), your mapping and orchestrations quickly become a mess.
Here is what I have done in the past to get around this limitation:
Allow messages to come in untyped to the orchestration. That is set the MessageType = System.Xml.XmlDocument. I found that generally, I am only interested in parsing out or updating a few elements, so I would just write a helper library with a few generic linq statements to get to the data that I needed. This way, I could write a linq statement that gets to PID-3 (Patient Id Number) and I would be able to use it consistently over any message or event type because PID remains the same. Likewise, I would use the same technique to update the message as well. This technique does not work great if there are large structural differences in the fields that you are looking to update or if you are looking to read/update a large amount of data.
Create master/canonical HL7 message type schemas. This takes a bit more work, but depending on how many message types you are looking to process, this can really pay off and is more consistent with how healthcare organizations think of their HL7 interfaces. In order to do this, you would need to define a new schema for a message type and include all possible segments for this message. So, instead of having multiple ADT types defined, you would roll all the possible variations for A01, A03, A04, etc. under one master schema. This will allow you greatly reduce the amount of mapping and parsing logic needed. Unfortunately, since this is not the HL7 accelerator's default behavior and will require some custom pipelines and orchestration logic to achieve. Basically, you will need to modify some properties to get the Accelerator to think that your new master message is valid.
For mostly pass-through interfaces, I would recommend technique #1. Otherwise, if you will be generating or needing to consume basically any message event in a canonical fashion, technique #2 can pay off in the long run.

As I see it you have two possibilities here.
Treat the message as anonymous. This means your message is "un-typed" (you declare it as a System.Xml.XmlDocument type). Then your orchestration can interrogate the message to decide what type it is.
Create an envelope message whose body can be all of your possible message types (using the xsd choice group selector). Your orchestration then handles the envelope message type. With this approach you can declare the type contained in the body of the envelope by setting a value in the envelope header.
I would prefer the second one; while it is certainly more work (you need to wrap all your inbound messages in an envelope) it allows you to understand the what the message is by just looking at the envelope header. This means you can still route by message type if you need to.

Related

viewing data from Exceptions in ExceptionTelemetry

After logging ExceptionTelemetry, is there a way to see the Exception.Data content in the logs? I am using Exception.Data to capture informative data about the environment when the exception occured.
It appears that ExceptionTelemetry has its own kvp for properties and metrics.
If not supported, then the plan is to wrap ExceptionTelemetry in code that walk through the exception/innerexception tree and add any data KVP entries it finds to these dictionaries. I was hoping not to have to do that myself...
the AI sdk does not walk through the Exception.Data structure itself. the items in exception data could be any type, complex structures, etc, and could literally contain anything.
The AI SDK allows you to send custom properties (strings), of limited size and custom metrics (doubles). There are also some limitations on the number of distinctly named properties for the lifetime of the AI application (though these limitations are always changing).
So you might not want to walk through and send ALL data in exception data, you might want to grab only the things you know you'll need, in order not waste custom properties?

BizTalk EDIFACT sub document splitting

Our partner sends a EDIFACT which has some custom segments. I have updated one of the existing edifact schemas to have these custom segments. The happy day scenarios are working. We are now trying to implement negative scenarios. The business wants BizTalk to process the successful message within the interchange and raise an error for the failed ones. I am not using partner agreement. In the EDIFACT fallback settings, I have set the inbound batch processing option to split the interchange as Transaction sets - suspend transaction set on error.
Issue:
My partner will send multiple data (in our case, multiple S01Loop) within the same transaction set i.e. within UNH-UNT. If I apply the above logic, the entire interchange is failing.
Requirement:
We want the particular Loop data to fail and the remaining positive ones should pass.
What I have tried:
For HIPAA based edifact file, there is a concept called subdocument_break. I applied those annotations in the XSD. Unfortunately it didnt work.
If there is no out of the box solution, I am planning to write a EDI splitter pipeline component which will be custom flat file disassembler component which will split the multiple data into separate instances. I will then use the EDI disassembler to parse the data.
Let me know if anyone has got a out of the box feature available in BizTalk to do this.
In this case, Sub Document Splitting will not help because if there is an syntactical error, the entire Transaction Set will fail anyway.
There is a reason for this. If segments are out of order, the parser cannot reliably determine it's place.
The correct way to handle this is to move such validation to later in the process so the invalid messages are detected after parsing. If the Trading Partner is sending truly invalid EDI, they really need to fix that on their end.

BizTalk 2010 Prevent output of Property Schema

I have an orchestration which is receiving messages from the message box of type XmlDocument. The messages have promoted properties and I am including the property schema in my project so that I may filter on them (a separate application is creating these messages). I am then assigning the untyped message to a typed message (I am not altering the name space) via a standard message assignment shape e.g.
MsgAgressoNewStarters = MsgXmldoc;
I am then outputting the message to a file location. However when I do this the property schema is also outputted.
How can I prevent this? I have tried filters etc.
Thanks
10th May 2012
I think I am possibly going about this the wrong way perhaps if I describe the full scenario you may be able to spot my deliberate mistake ;)
We are using BizTalk 2010.
I have a BizTalk application which talks to a 3rd party generic webservice that returns reports from one of our systems. This application is activated via the scheduled adapter which sends an XML document containing two values, the report name and the interface it is for. The web service returns the report as a string on a single XML node, this string in its self is an XML document. I then load this string into a message of type System.Xml.XmlDocument. There is no way of telling from the format of the data what report or for what interface this message is for. I need to send this message to the messagebox for it to be picked up by any number of related biztalk applications. So far I have tried creating a correlation set with the two values (from a property schema) & used that as the initialising correlation set on the send shape. I have then used the same property schema on another BT application to filter the message. This works but for some reason I get two messages, one being the XML which activities the orchestration which has the same fields as the property schema & correlation set. BizTalk doesn't seem to be able to tell the difference between them although they are structurally different and this is where my problem starts.
I am now thinking of creating a multipart message in the report application one part being the XmlDocument and the other being a header with the values I wish to route on.
Hope that makes some kind of sense.
I've actually now answered my own question, because both messages have the same properties I am inadvertently subscribing to both, d'oh!

Where should I do message resolution in Biztalk?

Let's say I have a flat file containing incoming messages. Where would the appropriate place be to inject the logic that takes identifying information from the message and sets primary key properties to link it to internal record IDs. For example, to map a customer's version of order ID into our internal order ID.
Sounds like you are looking to do a conversion of the incoming id to the internal id before sending the further along.
There are multiple places to do this.
You could do it in a pipeline component that either reads directly from its run-time configuration or from a database. You could also do it in a orchestration.
The easiest and most suitable place to do is probably however in a transformation map. Just make sure not to hard-code the transformation table (what id maps to one of you internal ids) as these usually change a lot. Have the map do a lookup ion a database for example to find the matching id.
Doing these kind of tasks in a map compared to the other options gives you a bit more flexibility as you can then apply the map directly in receive or send port. So if you don't need to do any workflow based logic you can use a messaging pattern and skip any orchestrations (always preferable).
I would consider doing this type of conversion in a map.

BizTalk Flat File Failed Message Routing

I have found some broken threads across the web where people claim to be able to use receive shapes in an orchestration with XLANGMessage types to receive flat file schema files that could not be assembled into a specific xsd.
I've attempted to set the messagetype in the receive shape as Microsoft.XLANGS.BaseTypes.XLANGMessage, but this basetype is not serializable. This then causes a build error.
Is there an object type that can capture both XmlDocuments of well formed xml messages as well as malformed xml and non-assembled flat files?
In answer to your direct question in bold - yes, the type you are after is System.Xml.XmlDocument.
What you need to do is create a new message and when selecting its type, select the above type from the .NET Classes section.
This message when assigned to a receive shape can then receive any payload, for example, I've often used this to pass formats such as .pdf files through BizTalk where I had no need to parse them. Do be aware, however, that despite the name, what you have here is not Xml and will cause you all sorts of issues if you try and treat is as such.
To dig a little further into your question - are you trying to make some sort of error handling orchestration?
If you are then in your error handling code you can just have a recieve shape that receives a message of type XmlDocument with its filter expression set to ErrorReport.ErrorType == "FailedMessage" that is bound to a direct bound port attached to the Message Box.
I've often found it handy to have two receive shapes, one to catch routing failures, when we have any possible payload, and another to subscribe to a strongly types fault wrapper envelope that you define and pass out of your other orchestrations from their CatchException shapes.
This means that you can then build one centralised place to handle all exceptions.
If you haven't seen it, there is a nice post by Charles Young that may describe something similar to what you are trying to do.

Resources