AMQP.NET Lite
AMQP.NET Lite is an AMQP 1.0 client library written in pure .NET. It can be downloaded from https://github.com/Azure/amqpnetlite - version 1.1.2 or newer is required to connect to Eurex Clearing interfaces.
Environment setup
AMQP.NET Lite client is using Windows certificate store as the main source of certificates. The Eurex Clearing public key has to be present in the "Trusted Root Certification Authorities" store and the member’s private key has to be stored in the “Personal” store. To import the public / private keys, the Windows Certificate Manager utility can be used (certmgr.msc).
Additionally to the certificates stored in the Windows Certificate Store, the public key belonging to the member certificate has to be stored in a file. This file will be loaded by the client application and used to tell the client library which private key should be used.
Preparing Connection and Session
The connection is created using the ConnectionFactory. Before opening the connection, the factory has to be configured to support SSL.
ConnectionFactory factory = new ConnectionFactory();
The public key of the member certificate has to be added to the ClientCertificates. It will use the file which was prepared in previous chapter:
factory.SSL.ClientCertificates.Add(X509Certificate.CreateFromCertFile("c:\path\to\certificate\ABCFR_ABCFRALMMACC1.crt"));
By default, the library would select the SSL certificate for the client authentication based on the list of supported certification authorities as published by the AMQP broker. This would not work on the Eurex Clearing interfaces because only self-signed certificates are used. The LocalCertificateSelectionCallback has to be used to select the proper certificate.
factory.SSL.LocalCertificateSelectionCallback = (a, b, c, d, e) => X509Certificate.CreateFromCertFile("c:\path\to\certificate\ABCFR_ABCFRALMMACC1.crt");
To validate the broker certificate, the RemoteCertificateValidationCallback should be configured. A new method for the server certificate validation has to be created:
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None
{
return true;
}
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
return false;
}
This method would let the server certificate validation pass only in case there were no errors. The method has to be used in the callback:
factory.SSL.RemoteCertificateValidationCallback = ValidateServerCertificate;
Additionally to the SSL settings, the maximal frame size should be set to 64kB and the SASL mechanism has to be set to EXTERNAL.
factory.AMQP.MaxFrameSize = 64 * 1024;factory.SASL.Profile = SaslProfile.External;
When the factory is properly configured, it can be used to create the connection. The broker address is in the format “amqps://<hostname>:<port>”, for example “amqps://ecag-fixml-simu1.deutsche-boerse.com:10170”.
Address brokerAddress = new Address("amqps://ecag-fixml-simu1.deutsche-boerse.com:10170");Connection connection = await factory.CreateAsync(brokerAddress);
With the connection ready, the session can be opened:
Session session = new Session(connection);
Receiving / Sending messages
Creating receiver / sender
ReceiverLink and SenderLink classes represent the message receiver and sender. They both accept three different parameters:
- The AMQP session
- The name of the receiver / sender link
- The address where the messages should be received from / sent to
The address is always the queue name, for example:
SenderLink sender = new SenderLink(session, "request-sender", "request.ABCFR_ABCFRALMMACC1");ReceiverLink receiver = new ReceiverLink(session, "response-receiver", "response.ABCFR_ABCFRALMMACC1");
Using filters
The ReceiverLink can be configured to use AMQP filters. The FilterSet has to prepared containing all filters which should be used when creating the receiving link. To use filters, different ReceiverLink constructor has to be used, which allows passing the whole message source and not only the address:
Map filters = new Map();filters.Add(new Symbol("apache.org:selector-filter:string"), new DescribedValue(new Symbol("apache.org:selector-filter:string"), "amqp.correlation_id='123456'"));ReceiverLink receiver = new ReceiverLink(session, "response-receiver", new Source() { Address = "response. ABCFR_ABCFRALMMACC1", FilterSet = filters}, null);
Preparing a request message
The Message class is used to create a new message. Additionally to the message payload, the ReplyTo property has to be set to “response/response.ABCFR_ABCFRALMMACC1” so that the response message can be routed back to the client.
Message request = new Message("Hello world!");request.Properties = new Properties();request.Properties.ReplyTo = "response/response.ABCFR_ABCFRALMMACC1";
Sending a request message
The message can be sent using the Send method:
sender.Send(request);
The Send method will send the message synchronously. There is additional method SendAsync to send messages asynchronously.
Receiving a message
Messages can be received using the Receive method of the ReceiverLink object. The parameter defines the timeout for which the receiver will wait for new message to arrive.
Message response = receiver.Receive(60000);
In case no message is received during the timeout interval, null value will be returned.
Message Processing
The messages received from Eurex have the payload encoded as single binary data section. To decode it, the BodySection has to be first converted to the Amqp.Framing.Data and afterwards to UTF string:
Amqp.Framing.Data payload = (Amqp.Framing.Data)response.BodySection;String payloadText = Encoding.UTF8.GetString(payload.Binary);
Closing the connection
To close the connection, call the Close method:
connection.Close();
Logging
The client can trace the AMQP protocol frames. To switch it on, the trace level and the listener have to be configured:
Trace.TraceLevel = TraceLevel.Frame;
Trace.TraceListener = (f, a) => Console.WriteLine(String.Format(f, a));