Generating ACKs from BizTalk – Two Approaches

A recent question on the HL7 forum was how to manually create an acknowledgment from within BizTalk and send it out on a Request/Response port.

There are two approaches to this:

1. Manually create the acknowledgment within the orchestration

2. Have the pipeline create the acknowledgment

Taking advice from a good friend EricI am going to try to explain why you would use both approaches and the benefits and drawbacks.

1. The manually creating of an acknowledgment is a sure fire way of getting an acknowledgment. If you want a ‘true’ application acknowledgment, this is the approach you will want to implement, as once your business process completes, you will want to send back an acknowledgment instead of having the pipeline component generate the acknowledgment automatically before the application (BizTalk) actually processes the message.

Note: This same approach will be used for an ORM/ORR situation.

2. Come on, we are in the computer field for one of two reasons

  1. Because of forces beyond our control, we ended up here sitting in front of a computer: training 0s and 1s to follow a particular path from one computer to another; instead of being the astronaut, firefighter, or ballerina that we put on our 3rd grade paper of what we wanted to be when we grew up.
  2. Or, we are lazy, and manually typing out Lab orders, Patient Admittance forms just does not appeal to us, so we, or our manager, wants us to automate the process

So laziness seems to be the underlying reason. You can have the pipeline component will do most of the work. But I will explain how to accomplish this also.

Okay, so lets get to it.

Regardless of the approach, it will all start off at the same point. We are going to be using the ADT^A03 (again, since I am lazy and going to use the message in the SDK folder)

  1. I created the BTAHL7V231Common project
  2. I created the BTAHL72XCommon project and added a new schema called Z_24_GLO_DEF and made the namespace BTAHL7Schemas for the definition of the Z Segments (more about that later)
  3. I then created the BTAHL7ADTA03 project added the above project references along with the BTAHL7.Schemas dll

Okay so lets add a new orchestration to the BTAHL7ADTA03 project called ManualACK.

We want to define both a ADT^A03 and ACK multi-part message, along with creating a two way port type called ADTA03PortType as shown below (request: ADT_A03Type response: ACKType). Notice that the ZSegments part is pointed to the new schema in the BTAHL72XCommon project.

Next lets make the port and the messages, create a port manually called VendorPort and choose specify later binding, recieve-send direction,and use the ADTA03PortType. Create a message and call it ADTA03Msg and point to the ADT_A03_Type, create ACKMsg and point to the ACKType

Now lets manually create the acknowledgment. Add a receive shape which will accept the ADTA03Msg and then the transform that creates the ACKMsg.

In the map definition we want the source to be the ADT_A03_Type.MSHSegment and since we need the information from the ADT^A03 MSH segment to populate the ACK MSH and MSA segment.

The reason I can access the message parts directly from within this dialog box is that all parts of the multi part message are defined as schemas, contrary to what is specified in the tutorial (System.String).

Also, we will make a seperate map that just creates the ZSegments body part. BizTalk seems to get ‘confused’ when you try to map all three parts in the same map.

Here is the map that creates the MSH and MSA segment, for the new control number I have the following code in the scripting functiod:

public string ReverseControlNumber(string input)

{

char[] charArray=new char[input.Length];

int len=input.Length-1;

for(int i=0;i<len;i++)

charArray[i]=input[len-i];

return new string(charArray);

}

Then I created a seperate map for theZSegment, the input is theADT^A03, and the output is the ACKZSegment, and I hard coded a space

I added a message assignment shape called Add ContextData and the follow code is included:

ACKMsg(BTAHL7Schemas.MSH1)=124;

ACKMsg(BTAHL7Schemas.MSH2)=”^~\\&”;

ACKMsg(BTAHL7Schemas.ParserError)=false;

ACKMsg(BTAHL7Schemas.ZPartPresent)=false;

ACKMsg(BTAHL7Schemas.SegmentDelimiter2Char)=true;

Then we send the message back to the request/response port.

The final orchestration looks like this:

You are completed! What you would want to do at this point is to put your processing logic between the Recieve ADTA03 and the Construct ACK shape.


Now off to connecting an orchestraton to a port that you are using the pipeline component to create the acknowledgment.

This is going to be somewhat similar, except it is going to be a one way port type that just has defined the ADT^A03, and we are not going to be creating the ACK.

Lets create the NonACK orchestration with the following one way port type

Now for the port definition, because the orchestration is connecting to a request/response port, in order for it to bind correctly we need a two way port. But the orchestration is not sending anything back. The pipeline is handling that piece. If we create a 1 way logical port in the orchestration, then it would not bind to a request response physical port.

We are stuck…

The only thing that we can do is create the one way port, but instead of choosing Specify Later as the binding, we choose Direct.

This means that the adapter is going to pick up the message, the pipeline is going to create the acknowledgment and send it back out fulfilling the request/response scenario, and the orignal message is going to show up in the message box. There is where the orchestration is looking for the ADT^A03, not directly from the recieve location.

The compressed orchestration looks like this:

Of course you might need to put some filters on the recieve shape because now all ADT^A03’s are going to be picked up regardless of what port it came in on.

I hope that this was a much fun to read as it was to write!

Through my contacts page, let me know if you would like this prototype.

BizTalker Volume 9: Making The Right Port Binding Choice

 

The latest edition of The BizTalker has been released. 

This issue headlines John Callaway from QuickLearn.  He talks about Specify Now, Specify Later, Dynamic, and Direct Port Binding options inside an Orchestration.  He goes into details about when to use what and the scenarios each works well for.

View this issue online or subscribe now to make sure you do not miss an issue. 

The BizTalker is published every month or so to over 1400 people worldwide.

MIME Message, SOAP Adapter, Web Service with multiple input arguments – BizTalk Messaging-Only (CBR) solution.

In my previous post we have seen how you can call a web service which expects a single argument using SOAP adapter with a .NET proxy client in a BizTalk messaging only scenario (aka Content based routing) without using any orchestration.

In Step 4 of my previous post I explained how the IBaseMessage from Biztalk is translated into corresponding Web Service arguments in the proxy class. Basically, when we submit the sample message (CustomerInfo) via a Receive Location, BizTalk creates an IBaseMessage as shown in the below figure and submits it into the Message Box, which is then routed to the SOAP Adapter send port (based on ReceivePortName Filter). Inside the SOAP Adapter the body part of the message (CustomerInfo) identified by the content-id is assigned to the web service argument CustomerInfo. Now the .NET client proxy got all the required parameters (only one in this example)to make the call to the web service.

WebService Signature:

ProductInfo GetProductInfo (CustomerInfo customer)

IBaseMessage:

Now, coming to our second web method definition as shown below, how are we going to construct the IBaseMessage.

ProductInfo GetProductInfoByAccountNumber (CustomerInfo customer, int accountNumber)

The IBaseMessage to call the above Web Method should be in the form as shown below:

One easy way to generate the IBaseMessage shown above is by creating an orchestration, Adding a Web Reference to our web service, Assign the web method parameters as shown below inside a message assignment shape

WS_REQUEST.accountNumber = 5;
WS_REQUEST.CustomerInfo = CUSTOMER_INFO;

and link to the web port. The final Orchestration will look like the one shown below.

But, our goal is to call the web service without using any Orchestration. In order to archive this, all we need is a properly constructed IBaseMessage as shown in Figure 2. The method we are going to see here is making use of MIME Decoder pipeline component that comes out of the box and submitting a MIME message (as shown below) with multiple parts.

1. Create MIME Message

MIME-Version: 1.0
Date: Wed 20 Dec 2006 00:12:58 +0000
Content-Type: multipart/related;
boundary=”———MIME-digitaldeposit.net————-”

———–MIME-digitaldeposit.net————-
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-ID: CustomerInfo
Content-Description: CustomerInfo
Content-Type: text/xml;
charset=”utf-8″

<CustomerInfo xmlns=”http://www.digitaldeposit.net/biztalk/samples/Customer”>
<CustomerID>string</CustomerID>
</CustomerInfo>

———–MIME-digitaldeposit.net————-
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-ID: accountNumber
Content-Description: accountNumber
Content-Type: text/xml;
charset=”utf-8″

<?xml version=”1.0″?>
<int>5</int>

———–MIME-digitaldeposit.net—————

The MIME message shown above is quite straight forward, it has two parts. The first part contains our first web method argument CustomerInfo  and the second part contains our second web method argument accountNumber. The key aspect here is the Content-ID MIME header, which is used to identify the part and assign in to the web method argument in the SOAP Adapter.

2. Create a custom BizTalk Receive Pipeline with MIME Decoder.

Create a custom receive pipeline, drop the MIME/SMIME decoder component in the Decode stage (there is no settings to change). Build and Deploy it .

When the mime message is passed through the pipeline line eventually through the MIME/SMIME decoded a IBaseMessage (Multipart) will be constructed equivalent to the one shown in Figure 2, which is required for our web service call.

3. Configure the BizTalk Solution:

Now configure the BizTalk solutions as shown in the below figure. Refer to previous post for details on each port configuration.

We need to make two changes here, when compared to the previous post. On the Receive side change the pipeline from PassThru to MimeDecoder (our custom one), and select the appropriate web method on the SOAP Adapter configuration.

Download the sample solution here which got all the required files to support this blog post.

So, How did I construct the MIME Message

Unfortunately there is no support in .NET to create MIME messages, I created the MIME message manually in Notepad, its not hard as you can see.

Conclusion:

The only change we made in comparison to our previous post is changed the receive pipeline and changed the message to MIME message. This sample helps to understand 2 important things.

1. How to call a Web Service with the help of a MIME message and BizTalk

2. Also, how to call a web service without using an orchestration.

Nandri!

Saravana

Your opinion matters!

The BizTalk Server Documentation Team is looking for customer input on the documentation of the operations topics. Specifically they said they “want to know what is missing, incorrect, unclear, or just needs work in any of the Operations topics”. Go here for the survey:


http://www.surveymonkey.com/s.asp?u=32373055498



Be as explicit and clear as you possibly can. Don’t miss this opportunity to help improve the documentation!  Thank you!


 

Your opinion matters!

The BizTalk Server Documentation Team is looking for customer input on the documentation of the operations topics. Specifically they said they “want to know what is missing, incorrect, unclear, or just needs work in any of the Operations topics”. Go here for the survey:


http://www.surveymonkey.com/s.asp?u=32373055498



Be as explicit and clear as you possibly can. Don’t miss this opportunity to help improve the documentation!  Thank you!


 

Commerce Server 2007: Performance Guide Available

The Commerce Server team has just released their Commerce Server 2007 Performance Guide white paper. This is a must read for any Commerce Server developer or IT professional supporting Commerce Server. What's really amazing is how fast and scalable CS2007 really is given all the things going on behind the scenes and I can personally attest to how well it performs. I know the folks in Redmond that did all the testing described in this document and it's really a great read!

Have fun!

Technorati Tags: Commerce Server

Share this post: Email it! | bookmark it! | digg it! | reddit!| kick it!

Output validation error: Root element is missing….Biztalk Map

Recently while I was working on a map I constantly used to get this error


Error 3 Output validation error: Root element is missing


I thought that since I have not mapped few Destination fields it might be throwing such error.


I tried setting Output Validation False for the Map.


Still I was getting the same error.


The Map was a simple one to one link map.


I was confident that my input xml file was perfect and  I did confirm it by Validating it against the Input Schema again.


It got succeeded.No errors at all.


Now where could be the problem be.


So I just googled and got this link by Stephen.


http://geekswithblogs.net/sthomas/archive/2006/08/15/88094.aspx


And then I cross verified my Target namespace in the input Schema with the input xml file.


There was a blank space before and after the namespace in my Schema which was creating this problem for me.


Moral of the story:


” Validating the xml file against the Schema never assures that the two match each other”.


 


 


NISHIL is online…Click to Chat right now!

 










    Join BiztalkMumbai    
 MSN Groups