Tag Archive: Dynamics AX


This blog post will be focused on the BizTalk development required to call on a Dynamics AX AIF.  Please take a look here if you missed Part 1 which covered the setup work required in Dynamics AX to actually expose a specific AIF to your BizTalk server.

The AIF service we are going to be calling on in this exercise is CustCustomerService.find which is used to retrieve customer details using the customer’s account number as a the search criteria.  We’ll set up an orchestration which is activated with a CustomerRequest message, which is then mapped to the AIF request message, the request will be made, and the response will be used to map to a CustomerResponse message.   Please keep in mind that for simplicity’s sake, this example will portray all the components being in a single project.  I will cover at the end what practices I believe should be applied in a real life application.

After creating a Visual Studio BizTalk project (do all the normal stuff like signing it with a strong name key and setting what application it deploys to etc…) the first thing we will need to do is to create the CustomerRequest and CustomerResponse schemas.  I’ll keep it quite simple for this example, see the below screenshots for the schema structure.

The next thing we’ll want to do is to add in the required AX schema files.  When calling on a .Find type AIF service, the request message will always be a generic message with a root node named QueryCriteria.  This schema exists in the Microsoft.Dynamics.BizTalk.Adapter.Schemas dll, so add a reference to it in your project, you’ll typically find it in the C:Program Files (x86)Microsoft Dynamics AX50Client directory.

You will need to open AX to get the schema for the response message from AX.  Theres a few ways you can get to the schema but I’ll give you one method.  Once again you want to Application Integration Framework section under the Basic menu option (we covered this in the last blog post but here’s a screenshot to remind you).

You want to navigate to the endpoint menu, click on the Remote endpoint record that you set up as per the previous blog post, and click on Action Policies.  You will now have a list of all the AIF services that are exposed to our remote endpoint, click on CustCustomerService.Find and click on parameter schema.  This is the complete schema that represents a customer, which you can save and add to your visual studio project.

Next step is to add a map to your project from the CustomerRequest schema to the QueryCriteria schema.  You’ll want to map a value of CustTable to the DataSourceName since that’s the name of the table we are querying againt.  We want a value of AccountNum in the FieldName element since that is going to be our search criteria.  The Operator element should be given a value of Equal since we are trying to find a record where the account number equals the value which we are going to provide.  I’ve used String Concatenate functoids to provide values to these three elements.  Lastly you will want to map the AccountNumber from your CustomerRequest schema to the QueryCriteria schema’s Value1 element.  We’re going to leave Value2 unpopulated since it isn’t applicable in cases where the Operator is set to Equal.  Your map should look somewhat like the below.

We’ll now want to add a second map which will be from the AX Customer schema to your CustomerResponse schema.  This one is quite straightforward, your end result should look like the below (notice that I am making use of Visual Studio 2010’s relevance tree view feature on the source schema to hide all the elements in the source schema that aren’t relevant to my map, it definitely makes it easier to study maps).

Now that our maps are in place, next step is the orchestration.  Again we’ll keep this pretty straightforward.  Create an orchestration and declare messages of type CustomerRequest, CustomerResponse, QueryCriteria, and Customer (AX).  Create a port type which has a request-response operation on it,one with QueryCriteria as the request and Customer (AX) as the response (lets call this the AX operation).  Create one send port of this type (you can set the binding for these ports to be specify-later to keep this exercise simple).  Next create a port type which has two one way operations in it, one having CustomerRequest as the request and the second having CustomerResponse as the request.  Create a receive and a send port of this type (you can set the binding for these ports to be specify-later to keep this exercise simple).

You should now follow the below steps to get your orchestration to look like the above screenshot.

  • Drag a receive shape onto the orchestration designer surface and set the message to be the CustomerRequest message, and set it to be an activating receive.  Set the operation to the request on the CustomerRequest operation in your receive port.
  • Next, add in a construct shape and set it to construct the QueryCriteria message
    • Insert a transform shape into the construct shape and use the CustomerRequest to QueryCriteria map, set up the map parameters appropriately
    • Next, insert a message assignment shape.  Let’s leave the expression blank for now but we’ll come back to it with some further explanation later
  • Next, add a send shape and set the message to be your QueryCriteria message and connect it to the request in the operation on your AX send port
  • Next add in a receive shape and set the message to your Customer message and connect it to the response in the operation on your AX send port
  • Next add in a construct shape and set it to construct the CustomerResponse message
    • Insert a transform shape into the construct shape and use the Customer To CustomerResponse map, set up the map parameters appropriately
  • Insert a send shape, set the message to be your CustomerResponse message and set it to the CustomerResponse operation on your one way send port

This all seems pretty straightforward.  You might be wondering why we put in the Message Assignment shape in the construct for the QueryCriteria message.  This is because when calling Dynamics AX AIF services, you need to set a few properties on your request message that would then get added into the header of the message by the Dynamics AX adapter.  Your message assignment should look like the below.

  • The SourceEndPoint is equivalent to the Remote Endpoint name that you setup in the part 1 of this blog entry.
  • The DestinationEndPoint is equivalent to the Local Endpoint name that you setup in part 1 of this blog entry.
  • The Action appears to be (I am not 100% sure of this, but it makes logical sense, please let me know if you believe otherwise) a combination of <the NameSpace of the service>/<the external name of the service>/<the specific operation on the service you are calling on, ex. find / create etc…).
  • The MessageID is a UniqueIdentifier for this transaction.  I believe that this is intended for correlation purposes but doesn’t serve much purpose for this example since we’ll be using a solicit-response synchronous adapter.  Just create a GUID and set it to be the value for the MessageID property.

That is pretty much all there is to the development side of things.  You should now be able to deploy the project to your development BizTalk environment.  Create a file receive and send port which you will use to receive the CustomerRequest and send the CustomerResponse messages to and bind them to the orchestration.  Make sure the the receive pipeline for the receive file location is set to XMLReceive.

Next create a static solicit-response send port and set the adapter type to Microsoft Dynamics AX 2009 adapter.  I believe that you must set the Send Pipeline to be XMLTransmit (I will try to set it to PassThroughTransmit on the next opportunity I have to see if this works).  In the adapter settings you need to apply settings as below.

There are a few options for the authentication type, I choose host user as we have previously given access to our host user for this remote endpoint while working through part 1 of this blog entry.  I would recommend that you read this Technet Article to get a better understanding of AIF security concepts.  If you choose host user then you shouldn’t have to fill in any more authentication settings.

Under the connection settings, set the AOS Port appropriately (default in 2712 but if you have multiple AX instances installed on the same server then it might be another port number as in the above screenshot), enter your server’s DNS name in the AOS Server section, and a timout in minutes for synchronous transactions.

You should now bind this send port to the orchestration appropriately.  If you drop a message of type CustomerRequest into the file receive location then it should result in the AIF service being called and the response being mapped back to your CustomerRequest type and a file created in the file send location.  Well done 🙂

Here’s a list of things I would do differently in a real life application of AX (I wont mention the non-AX related practices that I would do differently).

  • I would write a custom pipeline component that promotes the required AX properties to a message instead of writing them in a Message Assignment shape in orchestration.  The custom pipeline component would write these properties based on parameters (in which case there would have to be a seperate send port for every AIF since the action property is specific to each AIF) or you could take it one step further and provide a mechanism to dynamically set the Action property (in which case you will only need one send port).
  • I would always put AX schemas into an AX specific project, and in fact in a seperate solution and deployed to a seperate BizTalk application.  Remember that these are pretty generic services and it is likely that there will be more BizTalk solutions in the future that will need to call on these messages.
  • I would create Canonical versions of the AX schemas, and use these in my orchestrations so that they don’t have to be exposed to the actual implemenations.  This protects you in case Microsoft releases changes to their components and you wont have to change and redeploy your orchestrations, and of course also protects you in case your company decides to change to use a system other than Dynamics AX in the future.  You would of course also need to create maps from the canonical schemas to the AX schemas and vice versa, which you could apply on the send ports.  These schemas and maps would be deployed to the same BizTalk application as the AX schemas.
  • I would make an orchestration project which contains public multi-part message types and port types based on the canonical schemas mentioned above.  I would deploy this to the same BizTalk application as the AX schemas.
  • I would create an AX send port(s) in the BizTalk application where the AX schemas were deployed, and set up filters on it such that canonical messages which are representing AX requests are directed here.  I would have the canonical->AX maps setup on the outbound maps section of the port and the AX->Canonical maps setup on the inbound maps section of the port.  Because we setup subscription filters on this send port(s), there is no need to bind orchestrations to this port(s) and they can use direct binding.
  • I would bypass orchestration altogether and implement a messaging type solution unless orchestration was really warranted.

I have had two recent projects which required me to call on Dynamics AX AIF operations from BizTalk, one of them being a BizTalk 2009 project, and another being a BizTalk 2010 project which required me to install the Dynamics adapters as well since it was a relatively new environment.  After this experience, I can only say that I am so glad that Microsoft have decided to streamline the way AX integrates with the rest of the enterprise from Dynamics AX 2012 onwards and is depending on WCF rather than a proprietary means of communication, see http://technet.microsoft.com/en-us/library/hh352300.aspx.  For now though you will need to wrap your head around AIF (Application Integration Framework).

I highly recommend that you read Microsoft White Paper on integrating Dynamics AX 2009 with BizTalk to find out what AIF is all about – http://www.microsoft.com/download/en/details.aspx?id=17539.  That said, I will try to make your life a bit easier by giving you a head start in these blog posts, since it’s a lot quicker to read than a full white paper.

In this blog post, I will give you an overview of how to install the adapters for Dynamics AX 2009 in your BizTalk environment, and how to setup AX (please note that I am by no means an AX expert, but I will try my best) such that the specific AIF you are after is exposed to BizTalk.  In the second part of this post which I intend to publish towards the end of this week, I will walk you through calling on a simple AIF service which we will have already exposed in part 1.  I believe these posts should be applicable for BizTalk 2009 and BizTalk 2010, I’m not sure whether there would be any differences with prior versions.

First things first, you need to get a copy of the AX installer and run it on your BizTalk server(s).  Accept the terms and conditions, and choose to perform a custom installation.  Choose the BizTalk adapter (which will automatically select the .NET business connector as well) and hit next.

Choose to install the prerequisite software if required.

Next up we need to set up the connection information to the AX Server.  Put in the server name under the AOS name.  You should be able to leave the port at the default 2712 unless you are running multiple AOS instances (which probably implies you’re running multiple AX environments) in which case it might be 2713 or higher, you would need to check this with your AX administrator.

Beyond that, you should just be able to breeze through the rest of the installation by choosing next and install.

If you take a look in the Platform Settings -> Adapters section of the BizTalk Server Administration Console, you will now see the Dynamics AX 2009 adapter.  Woohoo 🙂  You might want to make sure that you are happy that the default send and receive handlers are against the appropriate host instances.  If you’re not happy with the default choices then you should make the appropriate changes.

Next up, we need to configure Dynamics AX to allow communication from our BizTalk server.  You will need administrator access in Dynamics to do the below, if you don’t have the required access levels then go grab your administrator and prepare to be a backseat driver.  Open up Dynamics AX, and you want to select the basic view from the bottom left of your screen (I’m not sure if Dynamics AX looks the same in all deployments, but here is a partial screenshot of how I enter the basic menu).

We are now interested in the options listed under Application Integration Framework over on the right hand side of the screen (see above screenshot).

Lets start by looking at the Local Endpoint.  What you want to see here is a record with your company code.  If there isn’t one already then click the new button (the top left button in this sub window), choose your company code using the drop down selector, and type in a name for your Local Endpoint.  You will want to remember this name.

Next up, you will want to visit the transport adapters section. You want to ensure that there is a record with the Adapter Class AifBizTalkAdapter.  If there isn’t one then create a new record and choose the AifBizTalkAdapter from the drop down selection.  You will want to mark the record as active and to set the direction to Receive and Response.  You can choose a name for this Adapter entry as well.

Next, you will want to visit channels.  You’ll want to configure it such that you have an entry like the one in the screenshot below.  The address field doesn’t really matter, you can put any value in here (this had me worried for awhile but Microsoft’s white paper confirms this).

While you’re still on the channels page, you’ll want to highlight your BizTalk channel record and choose configure on the right hand side of the screen.  You now need to enter the names of the BizTalk servers that will be communicating with Dynamics AX.

The next step is to select which services should be enabled.  For the rest of this post, let us assume that you are interested in the Find method on the CustCustomerService service.  Every out of the box service supports one or more generic methods, these methods being find, findkeys, read, update, create, delete (pretty self explanatory).  These services typically represent a table in the Dynamics AX database, I believe this service represents the CustTable table.  Click on the services option and ensure that the CustCustomerService record is enabled.

Next up we want to look at Endpoints.  You will want to create a new endpoint, giving it an ID and a Name, and choosing the Local Endpoint ID that we created a few steps ago.  It should look like the below.  You will then want to navigate over to the users tab and add in your BizTalk Host Instance identity (your AX administrator will need to set up an AX ID that is linked to this username and then you can select it on this screen).

While still on the endpoints screen, and while focusing on your remote endpoint, you will now want to click the Action Policies button.  If CustCustomerService.find isn’t listed here then select the new button and choose it from the drop down menu in the action ID column.  Make sure the status is enabled.

Highlight CustCustomerService.find and click on data policies.  You should get a popup window which has a single record with a direction of outbound (I’ll explain why you only see outbound over here in the next blog post).  Choose it and click on data policies again.  What you’re presented with here is a list of all the data elements that could be included in the response message for this method.  You can either leave it as it is or choose which elements you want to enable.

That should be everything you need to know to expose the CustCustomerService.find to your BizTalk environment.  In part 2 I will cover how you will develop a BizTalk solution which calls on and consumes the response from this service.

%d bloggers like this: