A practical guide to integrating Line of Business systems with BizTalk Server 2010
We found that rather than repeating code in several BizTalk solutions when you need to retrieve data from the AIF Queue, it’s relatively simple to create a general solution to accomplish this. This solution will retrieve all data via the BizTalk Dynamics AX adapter by polling the Queue at a set interval of time. The minimum polling interval is 1 minute, thus any messages you put in the AIF Queue will not be immediately consumed by BizTalk. The complete solution (Chapter9-AXMessageOutflow) is included with the source code.
We’ll start by creating a new BizTalk project, Chapter9-AXMessageOutflow, in Visual Studio. Add in a new orchestration, ProcessOutboundAXMessage.odx, which will be the only orchestration required for this example. Also, we’ll need to add reference to the Microsoft.Dynamics.BizTalk.Adapter.Schemas assembly and sign the project with a strong name key.
Next, we’ll add two messages to our orchestration: msgAxOutboundMessage and msgAXDocument. These will be the only two messages required in this example.
The first message, msgAXOutboundMessage, is of type DynamicsAX5.Message.Envelope. The schema is located in the referenced Microsoft.Dynamics.BizTalk.Adapter.Schemas assembly.
(Move the mouse over the image to enlarge.)
All outbound messages from the AIF Queue are of this type. As you can see from the sample screenshot below, we have some metadata in the header node but what we are really interested in is the XML contents of the Body node. The contents of the MessageParts node in the Body node will be of type ExchangeRatesService_ExchangeRates.xsd. Thus, all the schemas we require for both inbound and outbound transactions can be generated using the adapter.
For the second message, since we don’t want to specify a document type, we will use System.Xml.XmlDocument for the Message Type.
Using the System.Xml.XmlDocument message type allows for great flexibility in this solution. We can push any message to the AIF queue, and no changes to this BizTalk application are required. Only changes to consuming applications may need to add the AX schema of the message in order to process it.
Next, we create a new a logical port that will receive all messages from Dynamics AX via the AIF Queue with the following settings:
Port NameReceiveAXOutboundMessage_PortPort Type NameReceiveAXOutboundMessage_PortTypeCommunication PatternOne-WayPort direction of communicationI’ll always be receiving messages on this portPort BindingSpecify Later
Also, create a new send port. For this example, we’ll just send to a folder drop using the FILE adapter so that we can easily view the XML documents. In practice, other BizTalk applications will most likely process these messages, so you may choose to modify the send port to meet your requirements. Send port settings:
Port NameSendAXDocument_PortPort Type NameSendAXDocument_PortTypeCommunication PatternOne-WayPort direction of communicationI’ll always be sending messages on this portPort BindingSpecify Later
Next, we will need to add the following to the orchestration:
- Receive shape (receive msgAXOutboundMessage message)
- Expression shape (determine the file name for msgAXDocument)
- Message assignment (construct msgAXDocument message)
- Send shape (send msgAXDocument message)
We’ll also add two variables (aifActionName and xpathExpression) of type System.String and xmlDoc of type System.Xml.XmlDocument.
In the expression shape, we want to extract the AIF Action so that we can name the outbound XML documents in a similar fashion. This will allow us to easily identify the message type from AX.
Next, we’ll put the following inside expression shape below receive to extract the AIF action name.
aifActionName = msgAXOutboundMessage(DynamicsAx5.Action); aifActionName = aifActionName.Substring(55,aifActionName. LastIndexOf('/') - 55);
Now, we need to extract the contents of the body message, which is the XML document that we are interested in. Inside the message assignment shape, we will use XPath to extract the message. What we are interested in is the contents of the Body node in the DynamicsAX5.Message.Envelope message we will receive from AX via the AIF Queue. Add the following code inside the assignment shape to extract the XML, assign it to the message we are sending out, and set a common name that we can use in our send port:
// Extract Contents of Body node in Envelope Message xpathExpression = "/*[local-name()='Envelope' and namespaceuri()='
http://schemas.microsoft.com/dynamics/2008/01/documents/Message']/*[local-name()='Body' and namespace-uri()='http://schemas.microsoft.com/dynamics/2008/01/ documents/Message']"; xmlDoc = xpath(msgAXOutboundMessage, xpathExpression);
// Extract the XML we are interested in
// Set the message to the XML Document
msgAXDocument = xmlDoc;
// Assign FILE.ReceivedFileNameproperty
msgAXDocument(FILE.ReceivedFileName) = aifActionName;