Saturday, July 21. 2018
WS-AT interoperability between wildfly XTS and .NET (windows side)
This is the second entry about the interoperability between wildlfy and .NET using the WS-AT (Web Service Atomic Transactions). In the previous post I explained that there was an issue between both platforms which has been addressed in wildfly during the past months (mainly a different interpretation of the standard in which both sides think they are right and the other part is wrong). The wildfly XTS setup was also done using the new asynchronous implementation. In this new entry the windows side is going to be configured. I don't like to take screenshots so I will try to minimize the use of them but, this is windows, some images are going to be necessary.
As I commented before, I am not a specialist in Microsoft (better said, I am a complete disaster with it), so please take this information as a starting point or example. The steps to configure the WS-AT in windows 2016 are the following.
In the previous entry some certificates were created (ca, wildfly and win2016). Now those certs are going to be installed in the windows system. Copy the ca.crt, wildfly.crt and the win2016.p12 to the windows machine. And install them using the Certificate snap-in (follow this blog post to start the application). Import the three certificates in the following locations:
- Select Trusted Root Certification Authorities → Certificates. Right click → All Tasks → Import... And select the ca.crt.
- Select Personal → Certificates. Right click → All Tasks → Import... And select the wildfly.crt
- Select Personal → Certificates. Right click → All Tasks → Import... And select the win2016.p12 (the password is requested).
Once the certificates are installed the thumbprints for the last two will be needed (the certificates for each server). So please select the certificate and double click on it. In the second tab details you have the property Thumbprint with the number for each one (in my case wildfly cert is 8DA33E3DCD937777F1D307B58A3E6E103B8F31BB and win2016 is 1c54bd1932207b4e183e732a7e42ea757b471335).
The next step is installing the visual studio 2017 community edition. I selected the option .NET desktop development (Build WPF, Windows Forms and console applications using C#, Visual Basic and F#.)
With visual studio installed (which contains the developer framework) WS-AT transactions are available. For that the Microsoft Distributed Transaction Coordinator (MSDTC) should be configured.
Execute dcomcnfg and in Componment Services → Computers → My Computer → Distributed Transactions → Local DTC, click on the right Local → more actions and select Properties.
In the Security tab, tick Network DTC Access, Allow Remote Clients, All Inbound, Allow Outbound, No Authentication Required, and Enable XA Transactions.
Now it's the time to configure the WS-AT endpoint. This is done with the wsatconfig utility. Start the Developer Command Prompt for VS 2017 console (the wsatconfig is not exposed in a normal cmd console). And execute the following command:
wsatconfig -network:enable -port:443 -accounts: -endpointcert:1c54bd1932207b4e183e732a7e42ea757b471335 -accountsCerts:1c54bd1932207b4e183e732a7e42ea757b471335,8DA33E3DCD937777F1D307B58A3E6E103B8F31BB -traceLevel:ALL -restart
This command enables network access for WS-AT on port 443 and configures the previous certificates (remember the thumbprints) to be used and admitted to communicate with the endpoint. In my case the final configuration is the following.
Finally a console application is needed to use the wildfly endpoint and the transactions. Open Visual Studio 2017 and File → New Project → Select Console App (.NET Framework). My application name is wsat-simple-client and can be download from here.
Add a reference to System.Transactions (to be able to use WS-AT in the application).
Then import the wsdl using the add service reference and selecting the WSDL of the wsat-simple application deployed in wildfly. This will create the artifacts to call the remote endpoint.
Now there are two tricky steps needed (both are required to start a WS-AT transaction when calling the wildfly endpoint). The App.config should be modified to add the following stanza inside the imported binding RestaurantServiceATServiceSoapBinding (meaning that this binding requires WS-AT):
<transactionFlow transactionProtocol="WSAtomicTransaction11"/>
And the auto-generated Reference.cs of the service should also be modified, to add that the makeBooking() method needs transaction level as a mandatory requirement:
[TransactionFlow(TransactionFlowOption.Mandatory)] void makeBooking();
Finally the application Program.cs developed is as simple as the following.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Transactions; namespace wsat_simple_client { class Program { static void Main(string[] args) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; using (ServiceReference1.RestaurantServiceATClient client = new ServiceReference1.RestaurantServiceATClient()) { using (TransactionScope scope = new TransactionScope()) { Console.WriteLine("[Client] Invoking makeBooking() on WS"); client.makeBooking(); scope.Complete(); } } Console.WriteLine("[Client] Transaction completed OK. Click any key to finish..."); Console.ReadKey(); } } }
And everything is ready. This is the video executing the application. It calls to the wildfly endpoint but, before that, the program knows that a transaction is needed for that method and it starts a WS-AT transaction. When wildfly receives the request it registers (now asynchronously) to the transaction as a new parted and the full flow is completed. Everything works as expected and the full transaction is completed successfully performing all the calls between both sides without any issues.
The summary is that now there is a initial support for interaction between wildfly and .NET using WS-AT. Previously any try to execute a transaction starting it at the windows side (wildfly needed to register to the MSDTC endpoint) failed because one side executed the registration synchronously and the other part expected an asynchronous call. Now wildfly has added the asynchronous endpoints to receive the windows responses and implemented a simple logic to handle the flow. All of this will be on the next release of wildfly 14. I do not think that a lot of people is using or wanting this but I know that it was a headache for a few people in the last year. Let's see if now it starts working.
Asynchronous regards!
Comments