Feb 18, 2016 by Dick Wenning Category: AX2012 1 comment Tags: AX2012, integration

As we all know, communication these days is still changing. We might think that the whole world is Microsoft and .Net. Well last month I have seen again that this is not the case. We had a customer who had a website running on Linux and programmed in Java, which we had to integrate with AX. This meant that WCF inbound messages could have been a solution, since they already had XSD available on the java website. Generating XSLT and AIF in and outbound could be a suitable option in this case.  But suddenly I started thinking… why do we always map external XSD on Microsoft Dynamics AX XSD? Why not consume their XSD straightaway?

This is quite possible, but more items need to be taken into consideration.For example security: why should the customer have to open their firewall at company site to provide access to AX from the external website’s point of view?  One might ask why not use the azure bus adaptor from AX? In my opinion, there are too many external obstacles to get this one up and running quickly. One has to understand additional topics like Microsoft ADFS and Claim based authentication. All these points make you think that we are on the wrong track.

After quite some experiments, we came with the following solutions.

Azure Service bus

The next diagram describes the global architecture. The Service Bus acts like a message queue somewhere out there in the world. Dynamics AX is just an App that can push and pull messages to this service bus. If all those apps also use the same data format structure, life becomes easy. That is why we decided to use JSON.

1

JSON

I will outline how JSON works. Basically this is similar to XML, being just a format style of data

2

Above screenshot taken from http://www.service-architecture.com/articles/web-services/javascript_object_notation_json.html

The next screenshot is a visual studio project where I included three special libraries (see the red box). The rest of the project are my contracts and a JSON class. This class is used in my X++ code. The libraries are easy to integrate in visual studio. For more details one can have a look at http://docs.nuget.org/consume/installing-nuget

3

The contract classes are not very different from the SysOperation classes we create in X++. One creates classes that define the contract. In the next example I created three classes. The first class is named JsonEnvelop and it has 2 related classes JsonHeader and JsonBody (Note the JsonBody is similar to the JsonHeader class)

using System.Runtime.Serialization;

namespace Json

{

[DataContract]

public class JsonEnvelop

{

public JsonEnvelop()

{

}

[DataMember]

public JsonHeader Header { get; set; }

 

[DataMember]

public JsonBody Body { get; set; }

}

}

using System.Runtime.Serialization;

namespace Json

{

[DataContract]

public class JsonHeader

{

public JsonHeader()

{

}

[DataMember]

public string TimeStamp { get; set; }

[DataMember]

public string MessageType { get; set; }

[DataMember]

public string MessageVersion { get; set; }

[DataMember]

public string MessageId { get; set; }

[DataMember]

public string CorrelationId { get; set; }

}

}

After that I created two methods for sending and receiving the message. If you look closely, you can see that the trick is the DataContractJsonSerializer class. This class wraps my classes to the content that we call JSON.

public void SendMessages(Json.JsonEnvelop envelop)

{

MemoryStream stream = null;

try

{

stream = new MemoryStream();

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Json.JsonEnvelop));

StreamReader sr;

ser.WriteObject(stream, envelop);

QueueClient = QueueClient.CreateFromConnectionString(connectionstr, QueueName);

List<BrokeredMessage> messageList = new List<BrokeredMessage>();

stream.Position = 0;

sr = new StreamReader(stream);

messageList.Add(new BrokeredMessage(sr.ReadToEnd().ToString()));

foreach (BrokeredMessage messages in messageList)

{

queueClient.Send(messages);

}

}

finally

{

if (stream != null)

{

stream.Close();

}

}

}

 

public void ReceiveMessages()

{

QueueClient = QueueClient.CreateFromConnectionString(connectionstr, QueueName);

Message = queueClient.Receive(TimeSpan.FromSeconds(2));

if (Message != null)

{

var bodyJson2 = Message.GetBody<string>();

Envelop = JsonConvert.DeserializeObject<Json.JsonEnvelop>(bodyJson2);

Message.Complete();

}

 

queueClient.Close();

}

Now all we have to do is the actual send and receive method, which also needs some configuration stuff. This is added in the next part.

private static string QueueName = “Demo”;

const Int16 maxTrials = 4;

private static string connectionstr = “Endpoint=sb://X.servicebus.windows.net/;SharedAccessKeyName=testUser;SharedAccessKey=*”;

public BrokeredMessage Message { get; set; }

public Json.JsonEnvelop Envelop { get; set; }

Example of x++ code (pseudo code)

static void Json (Args _args)

{

Json.OnBoardingMessage msg = new Json.OnBoardingMessage();

Json.Header header = new Json.Header();

Json.Member body   = new Json.Body();

Json.Handler test     = new Json.Handler();

str dummy;

msg.set_Header(header);

msg.set_Member(member);

member.set_CompanyName(‘kaya’);

try

{

test.SendMessages(msg);

test.ReceiveMessages();

msg = test.get_contactHander();

header = msg.get_Header();

body = msg.get_Body();

dummy =body.get_CompanyName();

info(dummy);

}

Catch

{

SyncSetup::processCLRErrorException();

}

}

Conclusion:

  • YES it works!
  • Because we use a special library like JSON and azure bus, you cannot hook in the visual studio project directly in the AOT. At compilation time, Dynamics AX cannot resolve it. So you have to do it old school and copy all DLL files to the server Bin map of their AOS.

 

5

Subscribe to our newsletter and get our latest blogs straight to your inbox and if you have any questions, don`t hesitate to contact us.

Subscribe to our newsletter

Comments1

Leave a Comment!

Your email address will not be published. Required fields are marked *