Article Source: http://geekswithblogs.net/michaelstephenson/Default.aspx
I’ve been wanting to take a deeper look at the WCF LOB SDK for a while. I’ve read a few things about it, but you can’t beat just getting stuck in and writing some code to figure out how it all works. My aims from this exercise were as follows:
- Start to get an understanding on how to write custom WCF Lob adapters
- Do something that has some relation to the real world and not just a hello world thing
- Identify how much further I want to take this subject in terms of exploring its capabilities
- Try to keep this first attempt simple to grasp the basics and maybe do more later
To begin with I had read a few things but quickly it became apparent there isn’t a simple walk through available on the process you go through to create a custom WCF Lob adapter. There is lots of information on the background of the SDK and there are a few samples which show a fully working adapter. I’m hoping that this article will help plug this gap.
I’m not going to go much into the background of the SDK as there are a number of existing resources which are very good and I will mention some of the ones I have used later in this article.
Setting the Scene
As mentioned already I didn’t want to just do the old Hello World sample. I wanted to do something which could have a real application so I would think about some of the design considerations you might come across when you are thinking of a Custom WCF Lob adapter. The scenario I chose to use was one from a project I have been involved with. I think I have blogged previously about a situation we had on this project where we had an old application which we wanted to integrate with. The application (which I will refer to as the socket application for this post) is exposed as a socket interface. On this project we had done a POC at one point to explore using the BizTalk TCPIP Socket Adapter to connect with it. While functionally this adapter worked fine we found that under load we would encounter some problems and strange errors. We ended up with a solution where we wrote a web service fa%u00e7ade in C# which encapsulated some C# code to do this socket interaction (I think we were able to reuse some existing code which did this). We then deployed this web service to the BizTalk servers and made BizTalk do a call to the web service to interact with the socket application. The results proved that this web service although there was the additional overhead, the latency was only slightly longer but the performance when under load was significantly better and the service was much more reliable than the custom adapter. The architecture looked like the below diagram.
At this point before I got into my custom adapter there were a few thoughts I wanted to consider.
- Why can’t I just use the netTcp Binding?
For completeness I did consider this and it is common that with non WCF applications if you try to use the NetTcp Binding you may get problems because the binding is not intended to be interoperable and is specifically for WCF. In the case of this application I think I got a .net Framing exception. There is a forum post which discusses this topic and discussed creating a custom binding to handle this.
- Can I reuse our custom code within the adapter
I don’t particularly want to go writing a bunch of socket code so my preference was to reuse our classes which had been implemented to encapsulate this code. I wanted to be able to plug them into the adapter in a tidy way.
- Would the adapter be an application specific adapter or a protocol adapter
I was considering if the adapter I would create would be specific to connecting to just this socket application or if it would be more generic and able to connect to most applications which support a socket connection. I had a look at our existing code and while it looks fairly generic I think there is a small bit of (dodgy poorly placed) code that does something specific to this application. I have decided to consider that this particular thing is really small and I will essentially ignore that for now and just consider the adapter to be a protocol adapter. It will essentially be a socket client adapter. The socket client class we will wrap has a bunch of settings which can be configured and I intend to make these configurable as a WCF binding element so the adapter could be used differently when consumed.
Before I go through the walk through I think its important to list a few things that the adapter will and wont do in relation to the WCF Lob SDK just to set your expectations correctly:
- The adapter will be a one way synchronous outbound adapter
- It will not handle inbound messages
- It will not perform asynchronous actions
- It will not perform meta data look ups
Most of the limitations above are mainly because this fits with the scenario above and it also allows me to keep the scope of this POC quite small and specific. Often I find if you try to do too much you can end up not making good progress. It will also give me future scope to do more posts about these other things.
Prerequisites
I developed this sample on a BizTalk 2006 R2 developer machine to which I added the following components:
- WCF LOB SDK SP1
- Windows Platform SDK
The Walk Through
To begin with I created a Visual Studio solution and added a windows forms application to test the adapter and a console application which would act as a stub of the socket server application.
The Socket Server Application
The socket server application is a console application which will when executed sit listening on the configured port for any messages and respond with a preconfigured response. The below picture shows a sample of the response message which is a delimited string.
Creating the Lob Adapter
This section will describe how I created the adapter itself.
Generating the Adapter Project
To begin with I chose to add a new project to the solution and picked the WCF LOB Adapter project type. I called the project SocketAdapter.
Next the WCF Lob Adapter Wizard opens and once past the welcome screen I was able to provide some information about my adapter like in the below picture. I supplied the scheme which I decided to be netSocket and also a namespace.
On the next screen I am able to choose the features my adapter will support. As mentioned earlier this adapter will be quite basic and will support only synchronous outbound messaging and will not support any meta data features. This can be seen in the below picture.
On the next screen I am able to supply some properties for my adapter. I have chosen that the properties will be the Maximum Buffer Size which will control the retrieval of data and the Protocol Type which will configure the socket client to determine which protocol it will use. While the Protocol type is a string property I will ensure in my adapter it is of type System.Net.Sockets.ProtocolType and I will mark the default value in this wizard to be Tcp.
The next screen allows you to configure the parts of the connection used by your adapter. I have determined my connection will need to include a server and a port.
The next screen provides a summary of your chosen options like in the below picture
When I finished the wizard the code for my adapter was generated. The below picture shows the code files which within my new project.
Adding the Custom Code to My Adapter
The next steps were to apply the manual steps including adding code to the adapter to turn this boiler plate code into a functioning adapter.
Strong Name
The first thing I did was to create a strong name key and amend my project so that it is strong named when it is compiled. I’m going to assume that you already know how to do this.
Amending the Adapter Project File
I wanted to amend the MsBuild for this C# project so that when it was compiled I would over ride the AfterBuild event and register the adapter in the GAC. To do this I added an xml file to the project called OverrideBuild.xml. The below picture shows this.
The next step is to amend the MsBuild xml in the .csproj file so that it will import my custom build target. The following picture shows this edited version of the SocketAdapter.csproj file.
Modify the SocketAdapterConnectionUri Class
One of the classes I needed to add code to is the class that manages the Uri for the adapter. The first thing I did was to amend the Uri property so that my class would correctly parse and create a Uri object based on my connection details. A well formed uri would be something like netSocket://{MachineName}:{PortNumber}
I also needed to modify the constructor of this class so that it would save the details of the passed in Uri when it was constructed.
Adding the Custom Socket Client Class
The next step was to copy across the couple of classes that get used with the SocketClient class. I did not amend these classes just copied them over as is into the adapter project. Remember from earlier the SocketClient class performs all of the stuff to interact with a socket and send a message to the socket application and receive a response. This is the class that we have already used elsewhere and which I want to just plug into the WCF Lob SDK framework to create an adapter. The below picture shows the outline of the classes.
Modifying the SocketAdapterConnectionFactory
I needed to make a couple of changes which are highlighted below in the picture to this class. Basically the change is to make the connection uri properties available to the connection object once it has been created by the factory.
Modifying the SocketConnection Class
The next step was to modify the SocketConnection class. I implemented the following changes.
Add a Field for the SocketClient
This field will store a reference to the SocketClient object. The below picture shows this.
Expose the SocketClient as a Property
The below picture shows how the SocketClient field was exposed as a property so it can be accessed by the outbound handler.
Update the Constructor
The below picture shows how the constructor was modified so that the SocketClient instance is created. The properties are extracted from the SocketConnectionUri and the binding information to configure the SocketClientArgs. One thing to notice in the below picture however is that I have missed a bit where I have not extracted the timeout values from the binding information and have still got them hard coded. You should look to get these from the binding info.
Modify the Implementation of IConnection
The below picture shows how I changed the implementation of some of the methods for this interface. In these methods I open and close the SocketClient connection.
Modifying the SocketAdapterOutboundHandler Class
The final class within the adapter to modify is the SocketAdapterOutboundHandler. This is the class which will send a message and handle a response. The below picture shows the implementation of this method.
There are a couple of assumptions that this method makes:
- The inbound message action will be “Submit”
- The inbound xml will have 1 element within the body and the content of that element is the data to send to the socket application. This essentially means we will need a contract with has 1 input parameter of type string.
- The outbound xml will be in the namespace defined in the code
- The outbound message will look something like:
<SendResponse xmlns:http://acme.wcf.lob.paymentapplication/>
<SendResult>{Value goes here}</SendResult>
</SendResponse>
Now all of the adapter code changes are complete.
Deploying the Adapter
The steps to deploy a WCF Lob Adapter are described in the MSDN documentation. Since we have already strong names and Gac’d the assembly the only thing left to do is to register the adapter in the machine.config to make it available to applications and services. This is also described in the above linked MSDN documentation, however the steps I took are as follows.
After opening the SvcConfigEditor.exe tool I browsed to the machine.config file and opened it with the Service Configuration Editor. I then selected the Binding Extensions node highlighted in the picture below.
The next step was to click the New button and then provide a name for my binding extension and choose the assembly and type from the GAC as shown below.
Once I had done this you can see in the below picture that my custom WCF Lob adapter is now registered.
The Client Application
Finally the adapter is available for use. In this demo I have chosen to keep things simple and to consume this adapter from a .net client rather than from BizTalk. In a future post I might extend this demo and use BizTalk. The steps I did to make the windows forms client be able to consume the netSocket custom WCF Lob adapter were as follows.
Defining a Contract
The first thing to do was to define a contract. I think with most custom WCF Lob Adapters if you implement the meta data features then you should be able to generate a contract, however in this demo I didn’t do that so needed to create a contract manually.
Remember the bit above where I implemented the OutBound Handler in the adapter I listed some assumptions about the message I would receive. Well those assumptions basically equate to a contract like I have defined below. The contract is a method which has input and return parameters which are both strings. Note the namespace and action properties also need to correlate.
Adding Code to the Form
The below picture shows the code I added to the form. You can see this code is really simple and does nothing more than the normal WCF style code for consuming a service.
Configuring the Client
The final step was to configure the client to be able to call the service. To do this I opened the App.config file using the Service Configuration Tool which I used above. This time I added a client endpoint which was a netSocket binding. See below picture.
The next step was to add a binding element for the netSocket adapter. This allows me to specify the properties for the binding we discussed much earlier such as MaximumBufferSize and ProtocolType.
I then supplied the settings for the client endpoint. You can see these below.
Once I saved the configuration I can look at the App.config file and would see the below xml. You can see that some of the properties such as ProtocolType aren’t configured because they are just using their default setting.
Running the Demo
We are now complete with development and can run the demo. Before we hit F5 we need to configure the solution so that it will start the socket server and client projects both at the same time. For those who may not know the below picture shows how to do this.
When we hit F5 both applications will pop up like below and we are ready to test.
Clicking the test button makes the client perform a call via the netSocket adapter to the socket server. You can see below the console application recorded that the server received a message, and the client popped up a message box displaying the response.
At this point you can see we have successfully made the call.
POC Summary
In summary I quite enjoyed this POC it was fun to play around with the WCF LOB SDK. Some of my thoughts after the POC are as follows:
- Hopefully the walk through shows what needs to be done to make a simple adapter work. Its not as difficult as you might first think when you generate the adapter project and then cant workout where to put your custom code.
- One of the things I didn’t quite get my head around is the relationship between a contract and how the adapter handles different types of messages. I think part of this was because I chose not to implement the meta data features. My assumption is my client could have generated the contract and it would have made more sense.
- It proved to be a pain writing the code to parse and create the response messages. I think some of this may relate to the above point, but I think it would be good to have some samples of best practices for doing this.
- I think I will look to consume this from BizTalk also just to see if there is much more required to do that
- It proved to be very easy to reuse our existing SocketClient code within the WCF LOB SDK framework without having to make any changes to the existing code
My final thought going back to the original problem domain I was looking at is that I do not think this WCF Adapter necessarily replaces the pattern we created originally where we created a fa%u00e7ade service on top of the socket application. While this adapter has its uses and functionally can do the job some other architectural considerations from our original problem domain are not solved.
One of the issues with the socket application was that it was consumed from a number of applications meaning that it was widely available. The application also didn’t implement a strong security mechanism so we had a vulnerability here. To address this when we implemented the fa%u00e7ade web service we secured this by restricting it to be only able to be called by users in certain windows groups and we signed and encrypted the message on the wire and passed identity within a Kerberos token. This allowed us to lock down the socket server with IPSec so that it could only be accessed from certain machines. The “other applications” would then either consume the web service directly or call BizTalk which would handle some of the security and transport requirements to allow the application to integrate with the socket application via the fa%u00e7ade web service as in the diagram right back at the start of the article. At this point we have mitigated a lot of this security risk.
If we allowed all of the clients to call the socket application with the netSocket adapter then it would require us to open up this security hole again. I think these considerations make it clear that implementing the service fa%u00e7ade has a lot of value in abstracting the consuming applications from the socket application, however where the WCF Lob adapter could have a place would either be behind the service fa%u00e7ade so that the web service uses the adapter to communicate with the socket application or if it was used by BizTalk and the service fa%u00e7ade logic was moved into BizTalk which then used the WCF Adapter (Note: on this point we would need to ensure that the original performance issue didn’t exist that we had with the BizTalk TCPIP Adapter).
I hope this article provides a lot of food for thought and helps people get started with the WCF LOB SDK and I’m sure ill post more on this soon.
The sample code for this article is available at the following place: http://www.box.net/shared/7xsvoe12zi