Condividi tramite


Outbound HTTP adapter for AIF in Dynamics AX 2012

There are lots of inbound integration adapters in AX2012 R3, including the File System, TCP, HTTP, Azure Service Bus and MSMQ, but just 2 outbound ones: File System and MSMQ. Both of them are asynchronous only and slow due to disc operations, very bad indeed in our brave cloud world.

Let me close this gap and introduce a small HTTP adapter written in X++, which uses the .NET HttpWebRequest API.

The core method is just 66 lines long:

 public void sendMessage(AifGatewayMessage gatewayMessage)
 {
 System.Net.HttpWebRequest httpWebRequest;
 System.Net.HttpWebResponse httpWebResponse;
 
 System.IO.Stream requestStream,
 messageStream,
 responseStream;
 System.IO.StreamReader responseStreamReader;
 
 System.Byte[] byteArray;
 System.Text.Encoding encoding;
 int msgLength;
 
 str response;
 
 if (! adapterIntialized)
 throw error("@SYS95134");
 
 httpWebRequest = System.Net.WebRequest::Create(transportAddress) as System.Net.HttpWebRequest;
 
 try
 {
 if (gatewayMessage.parmMessageStream() != null)
 {
 messageStream = gatewayMessage.parmMessageStream();
 messageStream.Read(byteArray, 0, int642int(messageStream.get_Length()));
 }
 else
 {
 encoding = System.Text.Encoding::GetEncoding(gatewayMessage.parmEncoding());
 byteArray = encoding.GetBytes(gatewayMessage.parmMessageXml());
 }
 msgLength = byteArray.get_Length();
 
 // Set HttpWebRequest properties
 httpWebRequest.set_Method("POST");
 httpWebRequest.set_ContentLength(msgLength);
 httpWebRequest.set_ContentType(strFmt("text/xml; charset=%1", gatewayMessage.parmEncoding()));
 
 requestStream = httpWebRequest.GetRequestStream();
 
 // Writes a sequence of bytes to the current stream
 requestStream.Write(byteArray, 0, msgLength);
 // Close stream
 requestStream.Close();
 
 // Sends the HttpWebRequest, and waits for a response.
 httpWebResponse = httpWebRequest.GetResponse();
 
 if (httpWebResponse.get_StatusCode() == System.Net.HttpStatusCode::OK)
 {
 // Get response stream into StreamReader
 responseStream = httpWebResponse.GetResponseStream();
 responseStreamReader = new System.IO.StreamReader(responseStream);
 response = responseStreamReader.ReadToEnd();
 }
 httpWebResponse.Close();
 }
 catch (Exception::CLRError)
 {
 messageId = gatewayMessage.parmMessageId(); // to re-send if needed
 
 throw error(strfmt("The HTTP adapter is unable to transmit the message to %1. Error: %2", transportAddress, AifUtil::getClrErrorMessage()));
 }
 }

Attached you may find an XPO file with the source code, as well as a tiny runtime listener in C# and a simple test routine to play with.

AIF_HTTP_Response.zip