BizTalk Application: Dynamics AX Message Outflow

A practical guide to integrating Line of Business systems with Microsoft BizTalk Server 2010 in this book and eBook


Microsoft BizTalk 2010: Line of Business Systems Integration

Microsoft BizTalk 2010: Line of Business Systems Integration

A practical guide to integrating Line of Business systems with BizTalk Server 2010

        Read more about this book      

(For more resources on BizTalk, see here.)

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.


Message setup

Next, we'll add two messages to our orchestration: msgAxOutboundMessage and msgAXDocument. These will be the only two messages required in this example.

Microsoft BizTalk 2010: Line of Business Systems Integration

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.

Orchestration setup

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 Name ReceiveAXOutboundMessage_Port
Port Type Name ReceiveAXOutboundMessage_PortType
Communication Pattern One-Way
Port direction of communication I'll always be receiving messages on this port
Port Binding Specify 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 Name SendAXDocument_Port
Port Type Name SendAXDocument_PortType
Communication Pattern One-Way
Port direction of communication I'll always be sending messages on this port
Port Binding Specify 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()='
and namespace-uri()='
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;



        Read more about this book      

(For more resources on BizTalk, see here.)


Port configuration

Create a new receive port, ReceiveAxOuboundMessage_ReceivePort, and a new receive location, ReceiveAxOuboundMessage_ReceiveLocation. Set the type to Microsoft Dynamics AX 2009, and we need to select a PassThruReceive for the Receive pipeline.

Microsoft BizTalk 2010: Line of Business Systems Integration

Click Configure to bring up the Microsoft Dynamics AX 2009 Transport Properties window. Here, we'll set the Authentication Type to Host User, set the Gateway User to the Active Directory account that our BizTalk Host Instance is running under, AOS Port to 2712, and AOS Server to our AX server name (AX 2009-SHARED). Also, we set the Polling interval to 1 minute, and finally, we must set the Pass Through to True. This allows our solution to use the adapter without parsing the message. If we set this to False, the adapter will attempt to resolve the message type in the AIF queue before removing it and set it to an error status if it's unsuccessful.

Microsoft BizTalk 2010: Line of Business Systems Integration

Next, we'll create a Static One-way Send Port with Name set to SendAxDocument_SendPort to bind to our logical send port. Set the Type to File, and Send pipeline to PassThruTransmit as we'll perhaps be sending different message types out as XML documents.

Microsoft BizTalk 2010: Line of Business Systems Integration

Click Configure to bring up the FILE Transport Properties window. Set the Destination folder to C:\LOBIntegration\Chapter09\Chapter9-AXMessageOutflow\AXOutboundDocuments and File name to %SourceFileName% - %datetime% - %MessageID%.xml. The SourceFileName for each message type will be identical as it was set in our orchestration above to the Dynamics AX action name. The datetime is added to the file name property because we often find it helpful in troubleshooting errors or sometimes it is required for future integration logic.

Microsoft BizTalk 2010: Line of Business Systems Integration

Now, we bind the two ports to the orchestration and start the BizTalk application. Since there's nothing in the AIF Queue for us to pick up, we won't see anything much on the BizTalk server side. However, if you log into Dynamics AX, go to Online users (Administration | Online users) and you can verify that your BizTalk application is indeed connected. There will be one connect, with Session type of Worker that will verify your connection. Click the refresh button continuously, and you will see the Session type of Business Connector appear every minute (our application polling interval set on the port).

Now that we have verified that we have connectivity, we need to send a message to the AIF Queue in order to run a test. Disable the receive location for now so that we can see what's happening inside AX before it's removed from the Queue.

There are many forms in Dynamics AX (Exchange Rates for example) where you'll see a Send Electronically button. Click on the button from the Exchange Rates table and you'll see the Send document electronically window pop up. You need to select an Endpoint ID and can put filter criteria from the Select button if you wish. Notice that only Endpoints that have the LedgerExchangeRates AIF service actions enable will appear in the drop-down list.

Microsoft BizTalk 2010: Line of Business Systems Integration

Click Ok to send the message to the AIF Queue. Now, try and click on Send electronically on the Chart of Accounts table (General Ledger | Chart of Accounts) and notice the error message as shown in the following screenshot. Since we have not activated this AIF Service, nor added the services' actions to any Endpoints, Dynamics AX does not allow us to send out this message.

Microsoft BizTalk 2010: Line of Business Systems Integration

Next, we'll open up the AIF Queue manager form (Basic | Setup | AIF | Queue manager) and here we can see the message we just sent from the Exchange Rates tables. Notice that the log entry is missing Channel and Source Endpoint. This is because by default, the Send Electronically button is an asych process that requires a batch to be run in order to specify the Channel (BizTalk in our case) based on the configuration of the Destination endpoint.



        Read more about this book      

(For more resources on BizTalk, see here.)


Batch setup in Dynamics AX

Now we need to set up a batch in order to send this Outbound message through the BizTalk channel. If we had previously sent out messages from BizTalk in an asynchronous mode, it would also have appeared here and required a batch in order to be processed. Note it is also possible to customize methods in Dynamics AX that still write messages to the AIF queue, but do not require a batch in order to be picked up by our BizTalk application.

Dynamics AX 2009 allows for batch jobs to be run on the server; however, previous versions required an active client in order to run batch jobs. As you can imagine, keeping open an active client to run a continuous batch job, or manually starting a batch job when required can be very cumbersome in a live production environment. Even with server-side batch job capability, you opt to only do synchronous integration to eliminate the need for any batch job altogether.

So, we'll need to create a batch for this example. First, we'll create a new entry in the Batch job (Basic | Inquiries | Batch job) table. We'll type in Job description of AIF BATCH and hit Save.

Next, click on View Tasks button, which will bring up the Batch tasks form. Here, we need to add four new entries, one for each AIF class (AifOutboundProcesssingService, AifInboundProcessingService, AIFgatewaySendService, AIFGatewayReceiveService) from the drop-down list and set the Company accounts for each. Since the batch tasks are company specific, you can imagine this may add significant management overhead to your integration processes.

After configuring the batch tasks, save and close the window. Go back to the Batch Job form and click on the Recurrence button that will be the window below. Here, we can configure several parameters, but for our example simply set the Recurring pattern Count to 1 and select Minutes.

Microsoft BizTalk 2010: Line of Business Systems Integration

Click Ok. Again back on the Batch job form, click on the Functions button, which brings up the Select new status window.

Microsoft BizTalk 2010: Line of Business Systems Integration

Select Waiting to activate the batch job. Now, we go back to the AIF Queue manager form. Click refresh after approximately one minute and you'll see the same Outbound record we previously sent. However, you'll notice the Channel and Source endpoint have now been populated. Also note that the status is still set to Ready.

Now, we go back and enable the receive location on your BizTalk solution. You should see this record be removed from AIF Queue, and find the XML document in the folder specified on the send port.

Note that this record we just pulled from the AIF Queue will appear in the AIF Document history table. You can view the XML by selecting a record, clicking on Document logs, and then clicking on View XML.

If we have any errors, a detailed message will appear in the AIF Exceptions (Basic | Periodic | Application Integration Framework | Exceptions) form and the status of the outbound record in the Queue manager will change to Error. It's possible to fix the error and then change the status back to Ready.

For example, if we had not specified an outbound channel in our Endpoint configuration, the error seen above would have appeared when the batch job executed. Thus, we could go back, add in the BizTalk channel to the configuration, change the status of the message in the Queue to Ready; then, the next time the batch job executed, the message would be ready to be extracted by our BizTalk application.


In this article we created a generic solution to retrieve outbound message from Dynamics which demonstrated the set requirement for asynchronous integration including batch jobs.

Further resources on this subject:

Books to Consider

comments powered by Disqus

An Introduction to 3D Printing

Explore the future of manufacturing and design  - read our guide to 3d printing for free