Introduction
Developers face the challenge of building services that interoperate across organizational and platform boundaries and connect to existing line-of- business (LOB) systems. At the same time, these services and LOB systems evolve independently of each other, making connecting applications and services a constant challenge.
Background
In the early days of BizTalk Server, Microsoft provided a set of adapters that handled the most common external entities such as FILE, SOAP, and HTTP, and when integration value became obvious to the world of business, a new set of adapters were introduced till we reached a point where there was much more than they could provide since the complexity differed from one business to another, and protocols differed too.
So they introduced a new SDK that could be used to develop custom adapters where the added value of this SDK compared to the classic one is that it uses Windows Communication Foundation to communicate with the adapter, which gives us the ability to bind our service to the adapter with not only just protocol and also it can be used in BizTalk and non-BizTalk applications.
Using the code
First you have to download and install WCF LOB Adapter SDK 2.0 from http://www.microsoft.com/downloads/en/details.aspx?FamilyID=56278fde-b708-469c-987e-ded9c6c5e580. Then open Visual Studio 2005 and click New project, click in Visual C#, and you will find a WCF LOB Adapter template. Select it and click OK. Then you have to go with the wizard shown below.
Click Next.
- Scheme: Consider it a unique name for the trace logs and prefix for the adapter connection.
- Project namespace: The actual namespace for the C# application.
The adapter SDK supports two main functionalities along with two sub categories for each functionality:
- Outbound: From BizTalk to an external location; supports sync and async communication.
- Inbound: BizTalk will be listening for incoming requests; supports sync and async communication.
By default, the framework supports connection pooling; to make it safer, we will add the enablePooling
parameter which will enable or disable the default connection pooling.
Our TCP adapter will have two connection parameters: IP address and port.
public class AdapterBindingCollectionElement :
StandardBindingCollectionElement<AdapterBindingObject,AdapterBindingElement>
{
}
public class AdapterBindingElement : StandardBindingElement
{
}
public class AdapterBindingElementExtensionElement : BindingElementExtensionElement
{
}
public class AdapterBindingObject : AdapterBinding
{
private void ApplyConfiguration(string configurationName)
{
BindingsSection bindingsSection = (BindingsSection)
System.Configuration.ConfigurationManager.GetSection(
"system.serviceModel/bindings");
AdapterBindingCollectionElement bindingCollectionElement =
(AdapterBindingCollectionElement)
bindingsSection["LOBTCPAdapterBinding"];
AdapterBindingElement element =
bindingCollectionElement.Bindings[configurationName];
if (element != null)
{
element.ApplyConfiguration(this);
}
}
}
ApplyConfiguration
has to be edited to insert the new custom binding name and location.
public class AdapterConnectionFactory : IConnectionFactory
{
private AdapterConnectionUri connection;
public AdapterConnectionFactory(ConnectionUri connectionUri,
ClientCredentials clientCredentials, AdapterCore adapter)
{
this.clientCredentials = clientCredentials;
this.adapter = adapter;
this.connection = connectionUri as AdapterConnectionUri;
}
public AdapterConnectionUri Connection
{
get
{
return this.connection;
}
}
}
public class AdapterConnectionUri : ConnectionUri
{
#region Custom Generated Fields
private string serverIP = "127.0.0.1";
private int serverPort = 0;
private UriBuilder uriBuilder;
#endregion Custom Generated Fields
public AdapterConnectionUri() { Initialize(null); }
public AdapterConnectionUri(Uri uri): base()
{
Initialize(uri);
}
public override Uri Uri
{
get
{
return BuildUri();
}
set
{
ParseUri(value);
}
}
}
public class AdapterCore : Adapter
{
public class AdapterCore : Adapter
{
internal static XmlDocument operationsRepository = null;
}
public AdapterCore(): base(environmentSettings)
{
Settings.Metadata.DefaultMetadataNamespace = SERVICENAMESPACE;
if (operationsRepository == null)
{
operationsRepository = new XmlDocument();
operationsRepository.Load(@"C:\Program Files\Test\" +
@"LOBAdapters\TCP\OperationsConfiguration.xml");
}
}
public AdapterCore(AdapterCore binding): base(binding)
{
this.Settings.ConnectionPool.EnablePooling = binding.EnableConnectionPolling;
this.Settings.Metadata.GenerateWsdlDocumentation = true;
if (operationsRepository == null)
{
operationsRepository = new XmlDocument();
operationsRepository.Load(@"C:\Program Files\" +
@"Test\LOBAdapters\TCP\OperationsConfiguration.xml");
}
}
}
public abstract class AdapterHandlerBase
{
protected virtual void Dispose(bool disposing)
{
}
}
public class AdapterMetadataBrowseHandler : AdapterHandlerBase, IMetadataBrowseHandler
{
}
public class AdapterMetadataResolverHandler : AdapterHandlerBase, IMetadataResolverHandler
{
}
public class AdapterMetadataSearchHandler : AdapterHandlerBase, IMetadataSearchHandler
{
}
public class AdapterConnection : IConnection
{
}
public class AdapterOutboundHandler : AdapterHandlerBase, IOutboundHandler
{
}
Deployment
To deploy the adapter, follow these steps:
- Drop the DLL into the GAC.
- Drop OperationsConfiguration.xml to "C:\Program Files\Test\LOBAdapters\TCP\".
- Open C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config.
- Register the adapter. (Configuration attached in the adapter source.)
Using the adapter in BizTalk
Once the deployment is done, deploy the BizTalk Test project and open the administration console, go to Send ports, and create a new Static Solicit-Response send port. In the transport type, choose WCF-Custom and click Configure.
First add the endpoint address.
Choose the LOBTCPAdapterBinding WCF binding.
Points of interest
Limitation: the TCP message size is limited to 7168 bytes.
This adapter can be called from outside BizTalk Server such as from a WCF service or WWF services.
History