Windows Communication Foundation (WCF) LOB Adapter SDK and the BizTalk Adapter Pack Microsoft Corporation Published: March 2009 Authors: Aaron Skonnard, Pluralsight, and Matt Milner, Pluralsight Summary This whitepaper discusses how the worlds of Windows Communication Foundation (WCF) and BizTalk Server 2006 are fully converging through the WCF LOB Adapter SDK and the BizTalk Adapter Pack. Note The content in this document applies to BizTalk Server 2009 as well as BizTalk Server R2. Table of Contents Overview ....................................................................................................................................................... 4 BizTalk Server and WCF................................................................................................................................. 4 BizTalk and Service Orientation ................................................................................................................ 5 WCF Adapters in BizTalk Server ................................................................................................................ 5 Exposing LOB Applications as Services ..................................................................................................... 6 WCF LOB Adapter SDK .............................................................................................................................. 7 BizTalk Adapter Pack ................................................................................................................................. 8 Consuming WCF LOB Adapters ................................................................................................................. 8 Implementing WCF LOB Adapters ............................................................................................................ 9 BizTalk Adapter Pack & SDK Poster......................................................................................................... 10 WCF Architecture and Programming Model............................................................................................... 11 WCF Architecture .................................................................................................................................... 11 Understanding Channels ......................................................................................................................... 12 Understanding Bindings .......................................................................................................................... 13 Understanding Endpoints ....................................................................................................................... 14 Custom Bindings ..................................................................................................................................... 16 Custom Channels .................................................................................................................................... 20 BizTalk Adapters as WCF Channels ......................................................................................................... 21 Introducing the BizTalk Adapter Pack ......................................................................................................... 21 BizTalk Adapter for Oracle Databases..................................................................................................... 22 BizTalk Adapter for mySAP Business Suite.............................................................................................. 22 BizTalk Adapter for Siebel eBusiness Applications ................................................................................. 22 BizTalk Adapter for Oracle E-Business Suite ........................................................................................... 23 BizTalk Adapter for SQL Server ............................................................................................................... 23 Which adapter should I use? .................................................................................................................. 23 Consuming WCF LOB Adapters ................................................................................................................... 24 Consuming WCF LOB Adapters in .NET Applications .............................................................................. 24 Consuming WCF LOB Adapters in SharePoint......................................................................................... 29 2 Consuming Adapters in BizTalk Server ................................................................................................... 32 Consuming Adapters from SQL Server Integration Services ................................................................... 33 Hosting LOB adapters.................................................................................................................................. 34 Client Process Outbound Hosting ........................................................................................................... 35 Client Process Inbound Hosting .............................................................................................................. 35 Server Process Hosting............................................................................................................................ 36 Choosing a Hosting Model ...................................................................................................................... 38 When Should I Write a Custom LOB Adapter? ........................................................................................... 39 Building Custom Adapters with the WCF LOB Adapter SDK ....................................................................... 40 Steps for Building a Custom Adapter ...................................................................................................... 41 Using the WCF LOB Adapter Development Wizard ................................................................................ 42 Implementing the Connection and Binding Classes ............................................................................... 45 Implementing the Metadata Classes ...................................................................................................... 45 Implementing the Remaining Runtime Classes ...................................................................................... 47 Summary ..................................................................................................................................................... 47 References .................................................................................................................................................. 48 3 Documentation Feedback Microsoft values your feedback. To send feedback and comments about this topic to the documentation team, click here. For more information about adapters, go to the Adapters in BizTalk Server page on MSDN. Note To download a copy of this document, go to http://go.microsoft.com/fwlink/?LinkId=147581. Overview When building applications today, it’s hard to consider building something that doesn’t involve connectivity of some sort. Applications require business data and logic that is distributed across several applications or servers. Unfortunately, not all systems provide the same interface to their data and business logic which ultimately forces developers to figure out how to talk to each of those systems. Connecting to a system doesn’t just involve opening up a port on a network address either; we have to work with different message formats, varying security mechanisms, and in many cases custom libraries that rely on proprietary mechanisms. In the end, it’s common for developers to struggle with learning a variety of different programming interfaces, communication protocols, and messaging semantics. Windows Communication Foundation (WCF) promises to change all of that. WCF provides a unified programming model for building distributed applications using the .NET Framework. WCF was designed to provide a single unified programming model for writing either clients or services while also providing a flexible framework for different styles of communication on the wire. This approach allows developers to focus on writing code in their business domain rather than on learning new networking interfaces or object models. The code you write with WCF always looks the same but you can configure your apps to use different transport protocols like TCP, HTTP, and MSMQ; different message encodings like XML, MTOM, and binary; and varied security options including certificates, passwords, and security tokens. The goals addressed by WCF are also very similar to the integration goals of Microsoft® BizTalk® Server. Ultimately BizTalk Server is primarily focused on providing an easy-to-manage model for connecting disparate, heterogeneous systems using a variety of different protocols, message formats and security mechanisms without requiring much, if any, code. This whitepaper discusses how the worlds of WCF and BizTalk Server 2006 are fully converging through the WCF LOB Adapter SDK and the BizTalk Adapter Pack. BizTalk Server and WCF Prior to the release of WCF, Microsoft was not without a solution to these integration and connectivity complexities thanks to an excellent product in their portfolio called BizTalk Server. BizTalk Server 2004, the third release of the product and the result of a significant redesign, provided a similar solution in its underlying adapter model. Like WCF, BizTalk Server separated the business process and the logical 4 process of sending and receiving of messages from the technical details of the underlying networking communication, message formatting, and security mechanisms. In BizTalk Server, the sending and receiving of messages is handled by adapters. The job of an adapter is to “adapt” to the communication requirements of a specific external system that may have very custom and proprietary requirements. Encapsulating the code specific to each external system within an adapter greatly simplifies the programming experience for developers inside of BizTalk Server because the way you work with one adapter is the same as any other adapter despite their inherent differences. BizTalk Server ships with a bunch of built-in adapters for the most common communication scenarios but anyone can write custom BizTalk adapters through the BizTalk adapter framework. Because BizTalk Server has been around for a while, there a large number of BizTalk adapters that not only provide transport connectivity (e.g., HTTP, FTP, WebSphere MQ. etc), but also some that provide connectivity to common line-of-business (LOB) applications such as SAP, Siebel, and PeopleSoft to name a few.1 BizTalk and Service Orientation Service orientation was a large consideration in the design around how to expose all of these different types of adapters through a unified programming model that provides a consistent experience. Each adapter in BizTalk Server exposes its functionality as a service by providing WSDL and XSD metadata documents that describe the adapter’s messaging contracts. The idea being that these metadata documents can be consumed in a standard way to provide a standard experience. The BizTalk adapter framework allows any application or communication protocol to be exposed as a service, a fact that has helped thousands of enterprises connect their heterogeneous systems and LOB applications into higher-level, manageable business processes. When an adapter doesn’t exist for a particular LOB application, developers can use the BizTalk adapter framework to create a custom adapter that can be consumed in BizTalk on equal footing with the rest of the existing BizTalk adapters through a consistent, service-oriented, model that relies on WSDL and XSD metadata artifacts. While the BizTalk adapter framework can provide tremendous business value in complex environments, the current adapter model only allows adapters to be consumed within BizTalk Server. In other words, you cannot consume a BizTalk adapter from traditional .NET code. In some simpler environments, where a client application needs to communicate directly with a single LOB system, using BizTalk Server can be overkill. What we need is a way to consume these LOB applications directly, as if they were traditional WCF services, by simply generating a client proxy and writing code like you would for any other service. WCF Adapters in BizTalk Server With the release of WCF, Microsoft realized there was great synergy between BizTalk Server and the new WCF programming model so they quickly began work on providing some integration between the two communication models. As a result, one of the biggest features found in the BizTalk Server 2006 R2 release was the introduction of the new WCF adapters. The WCF adapters, in a nutshell, make it possible to both consume and expose services using WCF within the BizTalk port architecture. With the 1 All in all, R2 ships with more than 80 adapters to existing technologies and LOB applications. 5 WCF adapters, you can easily configure a send port to transmit messages using a WCF channel. And you can configure a receive location to expose a WCF service for receiving incoming messages. Completing the bridge between BizTalk Server and WCF provides two key benefits for developers. First, BizTalk developers can take advantage of the many communication features of WCF for service oriented communication including support for the latest WS-* security models, distributed transaction support, and a richer “pipeline” model for manipulating messages as they move in and out of the server. The second, and perhaps more significant benefit, is that WCF compatible services can be consume from any .NET application (in other words, they aren’t restricted to BizTalk Server like BizTalk adapters have been to date). Developers using WCF to connect to a service, whether in ASP.NET, desktop applications, SharePoint, or BizTalk Server can use the same service interface to communicate with that service. Within BizTalk Server, the various WCF communication options are exposed as a set of adapters to simplify the configuration experience for specific scenarios. For example, the WCF-WSHttp adapter targets the latest WS-* specifications over HTTP, whereas the WCF-NetTcp adapter targets crossmachine communication between different WCF applications. These specialized adapters make it easier for BizTalk developers and IT professionals to configure things even if they have not yet become completely familiar with the WCF configuration model. In addition to the specialized adapters, the WCFCustom adapter allows for complete customization of the underlying WCF configuration when you need complete control for interacting with external systems.2 Exposing LOB Applications as Services With the WCF adapters in BizTalk Server 2006 R2, you can now consume any LOB application that has been service-enabled. This means that someone has already gone to the effort to expose the LOB functionality through a service façade that provides WSDL and XSD metadata to simplify client consumption. Assuming this is the case, you can easily use the built-in WCF adapters to consume the service-enabled LOB application. If not, you’ll first need to service-enable the LOB application before you’ll be able to consume it. The process of service-enabling is becoming a more common task throughout enterprises today. One of the challenges many organizations run into while service-enabling applications is figuring out how to effectively expose metadata to the consumer. Some applications expose such a vast underlying data source, it would be impossible to serve up a single WSDL definition describing everything it can do (e.g., think about what it would be like to write a WSDL definition for everything found in your SQL Server databases). In situations like this, it probably makes more sense to ask the consumer “what data” they’re interested in up front and generate specialized metadata files for that particular usage. The other problem with service-enablement is how traditional techniques can potentially impact the performance and throughput of the system. For example, making everything go through HTTP and XML can have a dramatic negative effect. For many types of applications, this would be unacceptable, so instead they must stick with the LOB application’s native protocols and message formats. Luckily, WCF 2 For more detailed information on the WCF adapters in BizTalk Server, see the related whitepaper entitled WCF Adapters in BizTalk Server 2006 R2. 6 allows for this type of flexibility but it requires writing custom channel components (e.g., custom transport channel, custom message encoder, etc), which is not a trivial task in the least. Because these service-enablement challenges are so common throughout enterprises, Microsoft decided to take the marriage between traditional BizTalk adapters and WCF one step further by introducing what’s now called the WCF LOB Adapter SDK. The WCF LOB Adapter SDK was introduced to provide a simplified and unified model for creating custom BizTalk adapters that can be used from any WCF client application including, but not limited to, BizTalk Server. The SDK makes it much easier to provide metadata-driven adapters that can embrace native LOB protocols and formats when necessary. WCF LOB Adapter SDK In a nutshell, the WCF LOB Adapter SDK is a set of tools and components for creating adapters based on the WCF channel programming model.3 The SDK includes a set of runtime components as well as designtime tools and interfaces that simplify the process of hosting or consuming adapters built with the SDK. By using the SDK to build an adapter, any LOB system can be exposed as a WCF service and consumed by any WCF client application as if it were a traditional WCF service found on the network somewhere. Much like the BizTalk adapter programming model that preceded it, the WCF LOB Adapter SDK provides a programming model that allows developers to focus primarily on the issues specific to communicating with a given application without having to worry about all the details of writing WCF components. Instead of programming against the WCF channel model, developers write their adapters against a simpler set of API’s that focus on connecting to and interacting with the target system. An adapter built with the SDK is packaged and exposed to WCF as a binding that can be configured for a given client or service endpoint. This provides a very simple abstraction for developers to use when using the adapter. Before moving on, let’s briefly review how WCF bindings work. A binding in WCF is responsible for “binding” the logical messages used within the service layer to the underlying channel layer. Ultimately, a binding defines all of the details around how a message will be processed between your .NET service code and the underlying network or communication medium that’s used to transmit the message. For example, a binding might specify security processing, message encoding, and a transport channel details. However, with the adapter SDK, instead of using a transport channel like TCP, the final WCF channel will be one that incorporates the adapter code to interact with the target system. Figure 1 depicts how the actual adapter logic fits into the WCF binding model. 3 Information about where to obtain the WCF LOB Adapter SDK can be found in the References section at the end of this document. Version 1 of the SDK requires the .NET Framework 3.0 and Visual Studio® 2005. With the release of Service Pack 2, the SDK supports Visual Studio 2008 and .NET 3.5 is required. 7 Figure 1: WCF LOB Adapter SDK as a WCF binding The WCF LOB Adapter SDK comes with a new Visual Studio project template that walks developers through the process of creating the basic structure for a custom adapter. Included in the project are the classes needed to implement both the runtime and design-time behavior as well as the classes that enable packaging the adapter code into a custom WCF binding as illustrated in Figure 1. BizTalk Adapter Pack Microsoft has built and shipped a suite of WCF LOB adapters using the SDK we just described. This suite of LOB adapters is referred to as the BizTalk Adapter Pack. The BizTalk Adapter Pack contains several WCF LOB adapters for some of today’s most popular LOB systems including Oracle, Oracle E-Business Suite, mySAP Business Suite, Siebel eBusiness Applications, and even Microsoft SQL Server.4 These adapters make it possible to integrate with these LOB systems from any .NET application. We’ll provide more details on these individual adapters, and how to use them, later in the whitepaper. Consuming WCF LOB Adapters In addition to the runtime programming model, the WCF LOB Adapter SDK provides a rich metadata driven approach to consuming LOB systems that expose large amounts of data. In a typical service, the service exposes a variety of operations that client applications can call. These definitions are relatively static and can therefore be exchanged using static WSDL and XSD files. However, consider a typical LOB application such as PeopleSoft which may have thousands of operations and datasets that could be exposed from the different functional areas of the product. It is unrealistic and undesirable to create a single service definition containing the plethora of possibilities. A typical client application is only going to be interested in a subset of the possible operations for a particular use case. Hence, the SDK provides a programming model that makes it possible for adapter developers to expose custom metadata from the adapter, so when the adapter is being consumed, a developer can choose 4 Version 1 of the BizTalk Adapter Pack contains three adapters: Oracle Database, mySAP Business Suite and Siebel eBusiness Applications. Version 2 of the BizTalk Adapter Pack adds two additional adapters: Oracle E-Business Suite and SQL Server. 8 which operations are important and only receive metadata for the chosen operations. Adapters can support browsing or searching through the metadata in order to find the operations of interest. The WCF LOB Adapter SDK comes with two options for consuming adapters in Visual Studio: the Add Adapter Service Reference plug-in (see Figure 2) and the Consume Adapter Service Reference plug-in. Figure 2: Add Adapter Service Reference The former can be used when building any .NET client application to create a client proxy to interact with a LOB system as simply as adding a reference to WCF service. Figure 2 shows the Add Service Reference dialog where the adapter-generated metadata is being used to define the specific operations that will be used by this client. The metadata will then be used to build a client proxy that can be programmed against to interact with the LOB system. The Consume Adapter Service Reference plug-in provides the same functionality when the application being built is a BizTalk Server application. Both developers and businesses gain benefits because the SDK is built upon WCF. The experience for developers who are adapter consumers will be similar in nature to communicating with any WCF service. And most developers are already familiar with the concept of adding a service reference to generate a local proxy which can be used to communicate with a remote system. Using this familiar model improves developer productivity, which thereby reduces short-term business costs and improves the business’s long-term ability to quickly “adapt” to a variety of different integration scenarios. Implementing WCF LOB Adapters For adapter developers the SDK simplifies the job of encapsulating the communication semantics for a particular LOB system. The goal of the adapter model has always been to write the adapter once and 9 enable a broad range of processes to interact with the target system. The main difference now is the use of WCF as the underlying implementation framework. In addition, the SDK greatly simplifies the process of exposing metadata to client applications so developers don’t have to understand WSDL very deeply. Because the SDK builds on WCF, the resulting adapters become incredibly flexible because they can be further composed with other WCF channels including those shipping in WCF and custom or third party channels. This flexibility allows for scenarios where messages being sent to or received from an adapter need to have additional processing applied between your .NET code and the adapter processing code. All of these advances boil down to more developer productivity and increased integration flexibility. Thanks to the WCF LOB Adapter SDK, developers can more quickly consume adapters that talk to LOB systems from any .NET application including SharePoint, BizTalk and custom applications. And by having adapters expose systems as WCF services, developers get to choose whether to embrace BizTalk Server for complex integration scenarios or eliminate it when simple point to point interaction will suffice. BizTalk Adapter Pack & SDK Poster Microsoft has provided a helpful poster that illustrates the architecture of the WCF-based adapters, the various usage and hosting scenarios, and the overall adapter landscape (see Figure 3). You can download the BizTalk Adapter Pack 2.0/WCF LOB Adapter SDK Poster from Microsoft Download Center.5 This poster provides some helpful context as we describe the different aspects of working with the WCF LOB Adapter SDK and the corresponding BizTalk Adapter Pack. You may want to download the poster now and refer to it as you read through the rest of the whitepaper. 5 Search for the “BizTalk Adapter Pack Poster” if this link no longer works. 10 Figure 3: BizTalk Adapter Pack & SDK Poster WCF Architecture and Programming Model The WCF LOB Adapter SDK works by taking the existing WCF framework and extending certain components to provide connectivity and interaction with a LOB application instead of the typical connection to a SOAP-based web service over a network protocol such as HTTP or TCP. Before getting into the details of the SDK itself, a brief review of the WCF programming model is necessary. WCF Architecture The WCF programming interfaces can be broken down into two logical layers: you write code in the service layer and WCF provides the underlying messaging layer to handle the complexities of transmitting, receiving, and processing messages on the wire. Figure 4 depicts the WCF architecture.6 6 These layers are also often referred to as the “service model” and “channel model” layers. 11 Figure 4: The WCF Architecture The service layer provides the programming model that developers most commonly use to build services and clients – it includes the attributes used to define service and message contracts, for example. This programming model is almost exclusively based on programming against .NET classes and interfaces representing the various messages and operations supported by the service. When messages move between the service layer and the channel layer, a WCF runtime component handles the transition. On the client side, we refer to this runtime component as the proxy. And on the service-side, we refer to it as the dispatcher. Ultimately, these runtime components are responsible for translating between .NET objects and logical WCF Message objects that are further processed by the underlying messaging layer. The messaging layer is basically made up of a collection of “channels”. The collection of channels is often referred to as the channel stack. The channel stack contains one transport channel, one message encoder, and zero or more layered protocol channels.7 Protocol channels can provide additional messaging functionality such as features related to security, transactions and reliable messaging. Understanding Channels As an example, consider a simple interaction between a client and a service. First the client application would use the .NET classes that represent the data of interest and a service contract to formulate a specific request. Using the generated proxy class, which derives from a base class included in the 7 If you want to get technical, the message encoder isn’t officially considered a “channel”. The message encoder is actually a different type of component that is managed by the transport channel to process incoming/outgoing bytes but it doesn’t hurt to think of it this way. 12 framework, the client application invokes an operation. The proxy class then converts the supplied .NET objects into a Message object and passes it to the first channel in the stack (top in the figure). The message then proceeds through a number of protocol channels, where each channel can read and augment the message, usually by inspecting and manipulating headers in the Message object. The message then proceeds through the message encoder, which convert the message into a specific format such as XML, MTOM, or binary. And finally, the message reaches the last channel in the stack – the transport channel – responsible for sending the encoded bytes to the destination service. On the server side, the message is first received into the messaging layer by a transport channel that is listening for requests. The message is then processed by the message encoder which decodes the raw bytes into a Message object, which proceeds up through the protocol channels where it can be processed. At this point, a security channel might process the credentials sent by the client, decrypt the message, and validate the signature. Ultimately, the Message object passes through messaging layer and into the dispatcher, where it’s converted into the appropriate .NET objects required by the method. Finally, the dispatcher invokes the service method supplying the .NET objects it harvested from the message. The reply message passes back through the same channel stack, following the same process, and the calling application can consume the response message in the form of .NET objects once again. It’s important to note that the client and service must be configured correctly to use the same channel stack configuration. If there’s any disagreement in the security configuration, for example, security errors will result. More obviously, if the transport channels don’t match, at the lowest level, WCF will not be able to successfully deliver messages at all. In order to simplify the configuration of the channel stack, WCF provides the notion of a “binding” which defines a clear recipe for building a channel stack. Understanding Bindings A binding is simply a recipe for how to build a channel stack. For example, you can define a binding that uses HTTP for communication and simple XML messages in order to maximize interoperability. Anyone who uses the same binding will end up with the same underlying channel stack configuration. In order to simplify things further (and to facilitate interoperability), WCF comes with a set of predefined bindings that address the most common communication scenarios today. These bindings define the how to create and configure different types of channel stacks meant for different communication scenarios. They’ll each be configured with different communication features and reasonable default values but you can easily configure the built-in bindings to better fit your specific scenarios. Figure 5 describes some of the most commonly used WCF bindings and the features they support.8 Figure 5: WCF Binding Comparison Binding Class Name 8 Transport Message Encoding Message Version Security Mode RM Tx Flow* This list is not exhaustive – WCF comes with other built-in bindings that we’ve omitted from the discussion. 13 BasicHttpBinding HTTP Text SOAP 1.1 None X X WSHttpBinding HTTP Text SOAP 1.2 WS-A 1.0 Message Disabled WS-AT NetTcpBinding TCP Binary SOAP 1.2 Transport Disabled OleTx NetNamedPipesBinding Named Pipes Binary SOAP 1.2 Transport X OleTx NetMsmqBinding MSMQ Binary SOAP 1.2 Message X X CustomBinding You decide You decide You decide You decide You decide You decide Notes: X = Not Supported, WS-A = WS-Addressing, WS-AT = WS-AtomicTransactions, OleTx = OleTransactions * Transaction flow is always disabled by default, but when you enable it, these are the default protocols The BasicHttpBinding provides an interoperable channel stack because it only requires basic XML text messaging using SOAP 1.1 over HTTP, which pretty much everyone supports. For developers requiring WS-* support, the WSHttpBinding provides a recipe for configuring each of the WS-* protocols while still using the interoperable XML text encoding and SOAP messaging over HTTP. This binding can be used for interacting with services built on other platforms that also support the same WS-* specifications. Finally, there are a suite of bindings that can be used when WCF is used to create both the client and server components – these build on a proprietary binary encoding for efficiency and more efficient/reliable transports like TCP, Named Pipes, and MSMQ. These bindings also support security, transactions and reliable messaging albeit not always through interoperable standards, rather with the most appropriate Windows® technologies such as Windows integrated security or OleTx. When one of the predefined bindings does not meet your needs you can also use the built-in CustomBinding class to define a completely custom channel stack from scratch. With a custom binding you specify and configure each of the channels that will be included in the stack and add them into the binding in a specific order. This method gives you the most control over the individual channels and allows for adding custom or third party channels as you’ll see shortly. Understanding Endpoints When communicating with WCF both the client and the service use endpoints to represent their respective communication ports. A service exposes one or more endpoints where it can respond to messages.9 A client chooses one of the service’s endpoints to use for communicating with the service. Each endpoint is configured with an address, a binding, and a contract. The address defines the actual network address to be used in most cases, while the contract defines the service contract definition 9 If you forget to configure a WCF service with any endpoints, you’ll receive a runtime error when you try to load it into a host. This is reasonable since a service without any endpoints is useless. 14 describing the structure of the interactions. And, of course, the binding defines the mechanics around how that message moves between the service layer and messaging layer like we just discussed. Endpoints, and therefore bindings, can be configured in an application configuration file or directly within application code. For example, we can configure a service with a single endpoint (using the BasicHttpBinding) with the following application configuration file: <configuration> <system.serviceModel> <services> <service name="ChatService"> <endpoint address="http://localhost:8080/chat" binding="basicHttpBinding" contract="ChatLibrary.IChat" /> ... </service> </services> </system.serviceModel> </configuration> And we can accomplish the same thing within the following host application code10: BasicHttpBinding basicHttpBinding = new BasicHttpBinding(); host.AddServiceEndpoint(typeof(IChatService), basicHttpBinding, "http://localhost:8080/chat"); In addition to simply specifying the binding to use, most bindings provide properties that allow you to configure the underlying channel components. For example, the BasicHttpBinding provides a property called MessageEncoding that allows you to specify “Text” or “MTOM” to control which model is used to encode the messages. The BasicHttpBinding also provides a property called “TextEncoding” which allows you to choose between different text encoders such as UTF-8 or ASCII. These properties make it easier to use this binding in a variety of scenarios by allowing the message processing to be modified slightly on a case-by-case basis to meet your varying requirements. The following configuration file illustrates how you can configure this binding to use the MTOM message format along with SSL: <configuration> <system.serviceModel> <services> <service name="ChatService"> <endpoint address="http://localhost:8080/chat" binding="basicHttpBinding" bindingConfiguration="basicConfig" contract="ChatLibrary.IChat" /> ... </service> </services> <bindings> <basicHttpBinding> 10 One of the nice things about the WCF architecture is that anything you can do in code, you can also do in configuration, and vice-versa. 15 <binding name="basicConfig" messageEncoding="Mtom"> <security mode="Transport"/> </binding> </basicHttpBinding> ... </bindings> </system.serviceModel> </configuration> When you need to configure properties on an underlying channel that are not exposed by and existing binding, or when you need to add channels that are not part of an existing binding, you can always use the CustomBinding class as discussed previously.11 Custom Bindings When using the CustomBinding, or any binding for that matter, you do not actually create instances of a channel directly. Instead each channel is represented by a BindingElement. You add a BindingElement to a binding and then at runtime it’s used to create and configured the corresponding channel. When a developer uses the CustomBinding on an endpoint, the associated binding configuration will define the various binding elements that make up the binding and thus define the configuration of the channel stack. The following shows a sample binding configuration using CustomBinding: <configuration> <system.serviceModel> <services> <service name="ChatService"> <endpoint address="custom" binding="customBinding" bindingConfiguration="myBasicHttpBindingConfiguration" contract="IChat" /> </service> </services> <bindings> <customBinding> <binding name="myHttpBindingConfiguration"> <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004"/> <httpTransport useDefaultWebProxy="true" transferMode="Streamed"/> </binding> </customBinding> </bindings> </system.serviceModel> </configuration> 11 Bindings do not surface all of the properties for each of the underlying channels that will ultimately end up in channel stack. Instead the developer of the binding gets to choose which properties are most appropriate to surface for the binding. 16 While the CustomBinding class is extremely useful and provides great flexibility in defining custom channel stacks, it doesn’t provide for reuse beyond cut & paste. When you want to reuse a binding configuration across applications, you can go one step further and create your own custom binding class and configuration elements that will make your binding as easy to use as the built-in bindings. In order to create a reusable binding, we first need to define the new binding class. In this example we will create a binding that includes the HTTP transport but uses binary encoding instead of text to provide better performance for WCF clients and services. The first step is to create a binding class as shown in Figure 6 which returns a collection of the binding elements to be included in the binding. In addition, we can add properties to the binding to allow a consumer to configure various aspects of the channels. In this example we have added a few properties to allow the consumer to specify the transfer mode and whether to use the default web proxy. Figure 6: Implementing a Custom Binding Class public class NetHttpBinding : Binding { private BinaryMessageEncodingBindingElement binary = new BinaryMessageEncodingBindingElement(); private HttpTransportBindingElement http = new HttpTransportBindingElement(); public override BindingElementCollection CreateBindingElements() { return new BindingElementCollection( new BindingElement[] { binary, http }); } public TransferMode TransferMode { get { return http.TransferMode; } set { http.TransferMode = value; } } public bool UseDefaultWebProxy { get { return http.UseDefaultWebProxy; } set { http.UseDefaultWebProxy = value; } } public override string Scheme { get { return "http"; } } } Developers can now use this binding in code by simply instantiating an instance of the binding class and using it in a service endpoint like they would with one of the standard bindings. In order to use the binding in the application configuration file, a binding element class must be created to handle mapping the configuration settings to the actual binding class. We’ve provided a complete example in Figure 7. 17 As you can see, the NetHttpBindingElement class derives from StandardBindingElement and defines the various properties available in the configuration file. Figure 7: Implementing a Custom Binding Configuration Element public class NetHttpBindingConfigurationElement : StandardBindingElement { public NetHttpBindingConfigurationElement(string configurationName) : base(configurationName) { } public NetHttpBindingConfigurationElement() : this(null) { } protected override Type BindingElementType { get { return typeof(NetHttpBinding); } } [ConfigurationProperty("transferMode", DefaultValue = TransferMode.Buffered)] public TransferMode TransferMode { get { return ((TransferMode)(base["transferMode"])); } set { base["transferMode"] = value; } } [ConfigurationProperty("useDefaultWebProxy", DefaultValue = false)] public bool UseDefaultWebProxy { get { return ((bool)(base["useDefaultWebProxy"])); } set { base["useDefaultWebProxy"] = value; } } protected override ConfigurationPropertyCollection Properties { get { ConfigurationPropertyCollection properties = base.Properties; properties.Add(new ConfigurationProperty("transferMode", typeof(TransferMode), TransferMode.Buffered)); properties.Add(new ConfigurationProperty("useDefaultWebProxy", typeof(bool), true)); return properties; } } protected override void InitializeFrom(Binding binding) { base.InitializeFrom(binding); NetHttpBinding netHttpBinding = ((NetHttpBinding)(binding)); this.TransferMode = netHttpBinding.TransferMode; this.UseDefaultWebProxy = netHttpBinding.UseDefaultWebProxy; } protected override void OnApplyConfiguration(Binding binding) 18 { if (binding == null) { throw new System.ArgumentNullException("binding"); } if (binding.GetType() != typeof(NetHttpBinding)) { throw new System.ArgumentException( "Invalid binding type – expected NetHttpBinding"); } NetHttpBinding netHttpBinding = ((NetHttpBinding)(binding)); netHttpBinding.TransferMode = this.TransferMode; netHttpBinding.UseDefaultWebProxy = this.UseDefaultWebProxy; } } public class NetHttpBindingSection : StandardBindingCollectionElement<NetHttpBinding, NetHttpBindingConfigurationElement> { } Before you can use this custom binding element in the configuration file, you must first tell WCF about it. This is accomplished by adding a BindingExtensions configuration entry identifying the name that will be used to refer to this binding element and the type that corresponds to that name. The following example illustrates how to accomplish this using a new element name (<netHttpBinding>): <configuration> <system.serviceModel> <services> <service name="ChatService"> <endpoint address="nethttp" binding="netHttpBinding" bindingConfiguration="myNetHttpBindingConfiguration" contract="ChatLibrary.IChat" /> </service> </services> <bindings> <netHttpBinding> <binding name="myNetHttpBindingConfiguration" transferMode="Streamed" useDefaultWebProxy="true"/> </netHttpBinding> </bindings> <extensions> <bindingExtensions> <add name="netHttpBinding" type="NetHttpBindingSection, NetHttpBindingLibrary" /> </bindingExtensions> </extensions> </system.serviceModel> </configuration> 19 For more detailed information on WCF bindings and creating custom bindings see the MSDN Magazine article WCF Bindings in Depth. Custom Channels Up to this point the focus has been on customizing the channel stack through custom binding configurations. But this assumes that there are channel components available that fit all of your communication needs. A custom binding can only take you as far as the available suite of channels can. What if you need a transport channel that knows how to use some proprietary home-grown communication protocol? This is where custom channels come in. Creating custom channel components involves deriving from the appropriate base classes and implementing the interfaces that are required to support the possible message exchange patterns including request/reply, one-way messaging, sessions, and duplex communication. Creating custom channels is not a trivial undertaking – it’s definitely considered an advanced WCF topic.12 However, once you have a custom channel, you can make it easy for everyone to use by defining a corresponding BindingElement class and perhaps even a custom Binding class that provides a default configuration. In order to use a custom channel in configuration, you need to use a process similar to the one we showed earlier for using a custom binding class. In the case of an individual binding element, you need to create a class derived from BindingElementExtensionElement which maps the configuration of a specific binding element to its matching implementation class. Then you can register the binding element extension within the <extensions> element and use it in a binding as illustrated here: <configuration> <system.serviceModel> <bindings> <customBinding> <binding configurationName="UdpCustomBinding"> <udpTransport/> </binding> </customBinding> </bindings> <extensions> <bindingElementExtensions> <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport /> </bindingElementExtensions> </extensions> </system.serviceModel> </configuration> 12 For more in-depth information on building custom channels, check out the resources available at http://wcf.netfx3.com/content/BuildingCustomChannels.aspx 20 BizTalk Adapters as WCF Channels When you build LOB adapters with the WCF LOB Adapter SDK, you are actually building a custom transport channel for WCF (like the UDP example we just showed you). However, the WCF LOB Adapter SDK extends and abstracts the WCF messaging layer and makes this much easier to accomplish. It provides a simplified set of interfaces focused on creating connections and handling messages, shielding you from most of the nasty channel details. This abstraction helps developers focus primarily on the issues of connecting to the LOB system and translating between WCF messages and LOB API calls. You expose your custom adapter (transport channel) like you would any custom transport channel – by creating custom binding and binding element implementations for others to use. After the adapter is packaged, any WCF client can create a client proxy using the binding you’ve provided and invoke operations on it without worrying about the underlying communication details. However, in order to generate a client proxy that provides an appropriate contract, the client needs a mechanism to retrieve metadata from the adapter as well. This is where the WCF LOB Adapter SDK provides an extremely rich model for exposing metadata from LOB systems without having to manipulate or work with WSDL. The BizTalk Adapter Pack contains a suite of BizTalk adapters developed by Microsoft using the WCF LOB Adapter SDK. It provides solutions for today’s most common LOB systems so you don’t have to. We’ll cover the BizTalk Adapter Pack in the following sections, and then towards the end of whitepaper, we’ll show you how to use the SDK to implement your own custom LOB adapter when necessary. Introducing the BizTalk Adapter Pack One of the most valuable aspects of BizTalk Server today is the sheer number of adapters that are available for common LOB applications. Most of these adapters were written using the existing BizTalk adapter framework and are therefore not usable outside of BizTalk Server. Now, the focus of future BizTalk adapter development is moving towards the WCF LOB Adapter SDK model, which enables all future adapters to be used with or without BizTalk Server. Microsoft has already begun producing a suite of WCF LOB adapters for common LOB applications known as the BizTalk Adapter Pack. The BizTalk Adapter Pack is a set of installable adapters that were built using the same WCF LOB Adapter SDK available to you as a developer. Version 1 of the BizTalk Adapter Pack contains three adapters: Oracle Database, mySAP Business Suite and Siebel eBusiness Applications. Version 2 of the BizTalk Adapter Pack adds two additional adapters: Oracle E-Business Suite and SQL Server. Figure 8 (from the poster) illustrates the new BizTalk adapter landscape as shaped by new the BizTalk Adapter Pack. 21 Figure 8: The BizTalk Adapter Landscape In the following sections we’ll provide a brief description of each of these WCF LOB adapters found in the BizTalk Adapter Pack and we’ll highlight their primary features. BizTalk Adapter for Oracle Databases The Oracle Database adapter supports a request/response mode where a client application can specifically execute a SQL statement or stored procedure and get the results of the statement. In addition, the adapter supports a polling receive model, where the adapter can be configured to execute a particular polling query at a given interval and notify the adapter consumer with the results of that query. Internally, the Oracle Database adapter uses the Oracle Data Provider for .NET 2.0 (ODP.NET) to execute the specific operations against the target database. BizTalk Adapter for mySAP Business Suite The mySAP adapter supports RFC, IDOC and BAPI programming interfaces to allow client applications to execute functions. Interactions can be client initiated using any of the three programming interfaces, though BAPI calls will always be executed using RFC. In addition to initiating calls to the mySAP system, the mySAP adapter can act as an RFC server to receive calls from the mySAP system or to receive IDOCs sent out by the system. The mySAP adapter, through a custom RFC installed on the SAP server, can also surface data as an ADO.NET data provider. This allows clients to query data directly in code or as part of a SQL Server Integration Services (SSIS) package when simple data access is all that is required. BizTalk Adapter for Siebel eBusiness Applications The Siebel adapter supports working with Siebel Business Components and Business Services through the COM Data Control that ships with the Siebel Web Client. The support for Business Components includes query, insert, update and delete and Picklist fields while the Business Services support allows for executing operations exposed on the various services found in the Siebel system. Like the mySAP 22 adapter, the Siebel adapter provides an ADO.NET data provider which can be used in client applications or SSIS to query Business Components or return the results of executing a Business Service operation. BizTalk Adapter for Oracle E-Business Suite The Oracle E-Business adapter supports interactions using interface tables and views, PL/SQL statements and procedures as well as support for concurrent programs in the Oracle E-Business Suite. The adapter can be configured to poll the E-Business Suite using a query and to notify the client when data is returned by the query. To support the need to execute multiple operations with a single message, the Oracle E-Business adapter also supports composite operations where the client can send a message with a “batch” of operations to perform and the adapter will execute all of the operations in order. BizTalk Adapter for SQL Server The SQL Server adapter is an evolution of the existing SQL Server adapter that came with BizTalk Server 2004. The new adapter supports operations on tables, views and stored procedures in SQL Server. Like several other adapters, the SQL Server adapter supports composite operations and polling the database for changes. In addition, the SQL Server adapter can take advantage of SQL Server’s notification architecture to be notified when the data of interest changes. By using the notification approach, SQL Server will actually contact the adapter when changes occur, which means the notification is immediate and the client does not have to consistently poll the database like it normally would. Which adapter should I use? In the case of the SQL Server, SAP, Siebel and Oracle Database adapters there are existing BizTalk adapters that shipped with BizTalk Server 2006. The question often arises about which adapter to use and whether to update existing solutions to use the new adapters found in the new BizTalk Adapter Pack. For deployed applications that are already using one of the existing adapters, upgrading to the newer adapter would only provide value if you can take advantage of new features found in one of the adapters or the WCF LOB Adapter SDK (the features we’ve been discussing in this whitepaper). For new applications, your first choice should be the adapters in the BizTalk Adapter Pack since they provide more flexibility in client applications and they will be the focus of future enhancements and improvements moving forward. And since these new adapters support BizTalk Server as a client application, they will continue to provide a solution for integration projects requiring the message routing and process management capabilities found in that product. 23 Figure 9: Usage and Hosting Scenarios Consuming WCF LOB Adapters Adapters, either custom or those included in the BizTalk Adapter Pack, can be consumed from a number of environments broadening the reach of the adapter technology. In each of the client applications there are appropriate tools for creating proxies and different considerations based on the varied hosting models. In this section we’ll discuss four common scenarios for consuming the LOB adapters: traditional .NET applications, SharePoint, BizTalk Server, and SSIS. All of these scenarios are depicted in Figure 9 (from the poster). While the focus here is on the BizTalk Adapter Pack, the core concepts we’re about to discuss apply to all adapters built with the WCF LOB Adapter SDK, including your own. Consuming WCF LOB Adapters in .NET Applications When consuming WCF LOB adapters, .NET developers can use the familiar experience of “adding a service reference.” However, instead of using the Add Service Reference command that creates client 24 proxies for regular WCF services, developers use the Add Adapter Service Reference command to invoke the SDK-provided wizard. The wizard uses the metadata capabilities of the adapter to allow browsing, and if supported, searching the metadata exposed by the LOB application. The wizard allows the developer to choose only those operations that are appropriate for the current application and add those into a service definition which then is used to generate a client proxy and the related data types necessary to invoke operations. Figure 10 shows an example of using the Add Adapter Service Reference dialog to create a client proxy for talking to an SAP system. Figure 10: Adding an Adapter Service Reference to SAP When adding an adapter service reference the first two things a developer has to do is choose the appropriate adapter and then configure the URI to point to valid instance of the system. Remember, the adapter will dynamically generate the metadata by accessing the LOB system at runtime, so the adapter wizard must be running in a context that will allow it to connect to the appropriate LOB server instance. The Configure button opens a shared, consistent dialog that provides three tabs for configuring the LOB connection: Security, URI Properties, and Binding Properties. The Security tab provides options for setting client credentials (see Figure 11). The other two provide property grids that are driven from the binding and URI objects created when the adapter was developed (see Figure 12 and Figure 13). They allow all adapters to have a consistent configuration experience to identify the connection URI. 25 Figure 11: Configuring the SAP Adapter (Security) Figure 12: Configuring the SAP Adapter (URI Properties) 26 Figure 13: Configuring the SAP Adapter (Binding Properties) After the adapter and URI have been specified through these dialogs, clicking the Connect button causes the adapter to query the LOB system and to generate the metadata browsing tree. It’s important to note that for most LOB systems a client library of some sort must be present on the client computer at this point. For example, to communicate with Oracle eBusiness Suite the client must have the appropriate client library installed in order to execute the wizard and query for metadata. Figure 14: Browsing and Querying Adapter Metadata 27 At this point the developer can browse and select operations or categories then add them to the list of added categories and operations. If a category is selected, all operations in that category will be added to the client proxy. While a particular node or category is selected, the developer can also search for operations using the search box if the adapter support metadata search (see Figure 14). 13 After you’ve completed the wizard, the .NET project will include code files with all of the appropriate interfaces, proxy classes, and data structure types needed to use the selected SAP operations (the ones you selected in the dialog), and the application configuration file will be updated with appropriate WCF client endpoints for using the SAP adapter through the custom SAP binding. Figure 15 shows what the application configuration file looks like for the SAP adapter example shown in the wizards. Figure 15: Client Configuration Generated by the Add Adapter Service Reference Wizard <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.serviceModel> <bindings> <sapBinding> <binding name="SAPBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" enableBizTalkCompatibilityMode="false" receiveIdocFormat="Typed" enableSafeTyping="true" generateFlatFileCompatibleIdocSchema="true" maxConnectionsPerSystem="50" enableConnectionPooling="true" idleConnectionTimeout="00:15:00" flatFileSegmentIndicator="SegmentDefinition" enablePerformanceCounters="false" autoConfirmSentIdocs="false" enableBusinessObjects="true" acceptCredentialsInUri="false" padReceivedIdocWithSpaces="false" sncLibrary="" sncPartnerName="" /> </sapBinding> </bindings> <client> <endpoint address="sap://CLIENT=000;LANG=EN;@a/ABTSSRV01/00?RfcSdkTrace=False&amp; AbapDebug=False" binding="sapBinding" bindingConfiguration="SAPBinding" contract="BapiSFLIGHT" name="SAPBinding_BapiSFLIGHT" /> </client> </system.serviceModel> </configuration> 13 If the adapter does not support metadata search, the search box will be disabled in the user interface. 28 At this point, it’s pretty easy to write .NET code to consume the adapter. The developer simply creates an instance of the correct proxy class, specifying the “SAPBinding_BapiSFLIGHT” endpoint found in the configuration file, and then invokes operations on the proxy supplying any required data structure objects. The messages then pass through the WCF client side messaging layer to the adapter loaded in the transport channel. But instead of invoking a remote WCF service, the adapter code interacts directly with the LOB system and the reply, if any, is returned back through the messaging layer to the client code. Figure 16 shows some sample code that calls through the proxy generated for the SAP adapter. Figure 16: Client Code for Calling the SAP Adapter //declare reference parameters microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDAT[] flightData = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDAT[0]; microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDRA[] dateRange = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDRA[]{ new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDRA{ HIGH ="20060606", LOW="20060606"}}; microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIPAREX[] extensionsIn = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIPAREX[0]; microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIPAREX[] extensionsOut = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIPAREX[0]; microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIRET2[] returnData = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIRET2[1]; using(BapiSFLIGHTClient sapClientProxy = new BapiSFLIGHTClient("SAPBinding_BapiSFLIGHT")) { sapClientProxy.GETLIST("ABC", new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDST{ AIRPORTID= "SEA"}, new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISFLDST{ AIRPORTID="ORD"}, 20, ref dateRange, ref extensionsIn, ref extensionsOut, ref flightData, ref returnData); } Console.WriteLine(flightData[0].AIRLINE); In the end, consuming adapters in .NET applications should be a familiar experience for .NET developers. It works like consuming any other service – the only difference is how you add the service reference. Consuming WCF LOB Adapters in SharePoint Microsoft Office SharePoint Server 2007 provides a platform for building rich web applications for internet and intranet scenarios. When building intranet applications, it is often a requirement to expose 29 data and operations from existing LOB systems inside the web pages of the portal. And since SharePoint is a product targeted at end user collaboration and productivity, it allows users to customize and create content within the portal. In order to enable users in this environment, SharePoint comes with many features designed to make it easier for users to consume enterprise systems. Two technologies relevant to consuming WCF LOB adapters are the Business Data Catalog (BDC) and Web Parts. The Business Data Catalog is a feature of SharePoint that allows a developer to take existing Web services or database systems and expose them to business users. By creating a catalog of business data, you can enable users to search and query over a data source without having to know how to program or access the data source directly. In addition to defining the business data into an application definition, security can be configured to use the SharePoint Single Sign On service so that when a portal user accesses the back end system, they do so with their credentials for that system as well. Web parts, on the other hand, provide the building blocks for the overall SharePoint portal experience by defining discrete user interface elements that can be added to a Web page dynamically. Developers can create Web parts using familiar ASP.NET programming skills to add functionality to a SharePoint site. In addition, SharePoint ships with many built-in Web parts including several related to the Business Data Catalog. Combining the Business Data Catalog functionality with the appropriate Web part interfaces provides a foundation for exposing your LOB information through your SharePoint portal. The recommended approach for exposing LOB adapters to a SharePoint client is to host the adapter in IIS as a WCF service endpoint and then to use the Business Data Catalog to create an application definition based on the published service. This pattern provides the best experience for SharePoint developers and ultimately the end-users accessing the functionality in the LOB system. The process of hosting an LOB adapter is covered in a bit more detail in the next section; for now it’s enough to know that a developer uses a wizard with a similar metadata browsing experience as in the .NET client scenario, but the output is an ASP.NET website containing a WCF service for hosting the LOB adapter. As an example, a business may want to expose some functionality in their SAP system to SharePoint users. The first step is to generate the WCF service as just mentioned, followed by creating the Business Data Catalog definition of the service. The SharePoint Server 2007 SDK contains a tool called the Microsoft Business Data Catalog Definition Editor which provides a user interface to consume services or databases and create the necessary XML files to add an application definition to SharePoint. For this example, we’ll get flight information from SAP by exposing two operations that allow for searching for flights and getting flight details. Figure 17 shows the BDC editor being used to add several operations found in a Web service hosted adapter into a SharePoint application definition. After the application definition is created and added to SharePoint, we can then use Web parts to consume the BDC application and thus the adapter. The BDC List Web part allows you to filter the list items by parameters. These parameters are essentially inputs to a service operation that returns a list of items, in our case flights that match some criteria. We can connect the BDC List Web part to the BDC Items Web part so that when a user clicks on a flight in the list, the identifier for the flight can be passed to the BDC Items Web part. It can then invoke another service operation on the adapter (via the WCF 30 service shim) to get individual flight details from our SAP system. Figure 18 shows the BDC List Web part being used in a SharePoint page to expose the underlying adapter functionality. Figure 17: Using the Business Data Catalog Definition Editor Figure 18: Business Data Catalog Web Parts Interacting with a WCF LOB Adapter 31 Consuming Adapters in BizTalk Server BizTalk Server has an existing adapter framework that defines the connectivity between BizTalk and other systems. With the introduction of the WCF adapters in BizTalk Server 2006 R2, BizTalk ports are now able to act as both WCF clients and services. Consuming LOB adapters in BizTalk Server is a two step process: 1) metadata retrieval and artifact creation, and 2) port configuration.14 For example, to call some business functions in a Siebel system, the first step would be to create a new BizTalk project or open an existing one. BizTalk has a slightly different model for adding adapter references and consuming metadata so instead of the Add Adapter Service Reference command, developers use the Add Generated Items command from the context menu in the solution explorer. In addition to the previously available commands for adding adapter metadata, with the WCF LOB Adapter SDK installed, a developer will also see the Consume Adapter Service option (see Figure 19). Upon selecting this option, the same adapter dialog used by .NET clients to add an adapter reference is presented and after completing the operation selection the project is updated with the appropriate artifacts including schema and port definitions based on the metadata returned by the adapter wizard. Figure 19: BizTalk Add Generated Items – Consume Adapter Service The second step is to configure the physical send port. For the Siebel LOB adapter, configuration involves using the WCF-Custom adapter in BizTalk and specifying the binding directly. The WCF-Custom adapter allows you to define the binding and behaviors that need to be included in the WCF configuration, including the BindingElement and BindingElementExtensionElement that were created by the adapter. Figure 20 shows how to configure the WCF-Custom adapter to use the Siebel binding. 14 This is similar to the process of using any application adapter in BizTalk Server 2004 or 2006. 32 Figure 20: Configuring the WCF-Custom Adapter with the Siebel Binding After the metadata exists in the project, you can create orchestrations built around the port and message types extract from the adapter. Later the orchestrations can be bound to the physical ports configured to use the adapter (like the one shown in Figure 20).15 At runtime the messages will get delivered to the send port and the WCF channel will be invoked resulting in a call to the LOB system. Response messages will come back through the WCF messaging layer into the BizTalk message box, at which point they’ll be routed back to the orchestration instance for processing. In version 2 of the BizTalk Adapter Pack, several of the adapters (SAP, SQL, Oracle EBS, and Oracle Database) have been updated to allow them to appear as native adapters in BizTalk. This means that instead of having to choose the WCF-Custom adapter and configure the binding like we just showed you, you’ll be able to choose the WCF-SQL or WCF-SAP adapter, for example, as the transport and get a slightly customized configuration experience for the adapter. The biggest advantage includes a Configure button to help create the address or URI for the adapter and simplified configuration of the binding since the user interface contains only information relevant to the specific adapter being used. Consuming Adapters from SQL Server Integration Services There are times when the goal of interacting with an LOB system is not necessarily to take advantage of business rules or processing functionality but rather to consume raw data from the system. The .NET model for working with data is based on ADO.NET and the concept of data providers. There are providers that exist for many databases including SQL Server and Oracle. Even the Siebel and SAP adapters in the BizTalk Adapter Pack provide ADO.NET providers for consuming data from their systems. 15 This is similar to the process today for building orchestrations that consume Web services or the SQL adapter. 33 ADO.NET data providers can obviously be used in different tools and applications; however, SQL Server Integration Services is one key application that can take advantage of extracting and processing data from an LOB system along with the other data available to it. For example, you may wish to extract all of your customer information from the SAP system and load it into a SQL Server instance in order to do analytics on the customer data or by combining that data with other data available in various systems. In SSIS, you can create a connection manager and configure it to use the SAP data provider. You need to configure the various connection properties for the provider to connect to the SAP instance and run a query. Figure 21 shows the configuration dialog to configure the data provider connection for SAP. Figure 21: Configuring the SAP Data Provider in SSIS The data provider for SAP works by calling a custom RFC installed on the SAP system. Before you’ll be able to query the system, you have to install the RFC on the SAP server. For more information on query syntax and installation, refer to the documentation for the SAP adapter in the BizTalk Adapter Pack. Hosting LOB adapters When using a LOB adapter, either a custom adapter or one from the BizTalk Adapter Pack, the first decision a developer needs to make is what process will host the adapter. The final decision will be based on several factors including the number and type of expected client applications, security, and message exchange patterns. There are three key patterns for hosting LOB adapters: client process outbound hosting, client process inbound or server process hosting. These different usage patterns are illustrated in Figure 9 (from the poster) and we’ll discuss each one in more detail below. 34 Client Process Outbound Hosting When the adapter is hosted in the client process, the client application creates an instance of a WCF proxy configured to use the adapter binding. The act of creating the proxy initiates the adapter in the client process. When the adapter is being used for request/response communications, the client application triggers the adapter logic by attempting to call an operation on the proxy, thus sending a message through the WCF binding to the adapter. Figure 22 illustrates the client hosting process model. Figure 22: Client Hosted WCF LOB Adapter Client Process Inbound Hosting When an adapter will be used in an inbound capacity, that is, when it will be receiving messages and delivering them to the client process, the adapter needs to be hosted in a listening mode. The solution is for the client process to use the ServiceHost class to create an instance of the generated proxy class and create an endpoint using the appropriate binding for the LOB System. After the LOB system contacts the client process, the implementation of the contract will execute in the client process (see Figure 23). Figure 23: Client Hosted WCF LOB Adapter in Listen Mode 35 Server Process Hosting In the server process hosting scenario, the adapter code is hosted on a server in IIS or Windows Process Activation Service (WAS) and is accessed by clients through WCF. Essentially, the client channel for the adapter is taken and exposed as a WCF service using standard bindings such as the BasicHttpBinding or WSHttpBinding to make it accessible to more clients and tools. Using this hosting model, the LOB adapter truly becomes just another WCF service that client applications can call and interact with. Figure 24 shows a LOB adapter hosted in IIS being called from a client application. Figure 24: WCF LOB Adapter Hosted in IIS Hosting adapters in IIS/WAS creates a WCF service endpoint that exposes a set of operations from the LOB system. In order to simplify this process, the WCF LOB Adapter SDK provides a project template in Visual Studio for creating the hosted adapter service. When you create a project using this template the wizard wraps the Add Service Adapter Reference user interface to guide you through selecting the desired operations (see Figure 25). When the wizard completes, it generates classes that act as proxies for the LOB adapter through the WCF messaging layer. These same proxy classes are then exposed as WCF services by the wizard, which generates .svc files and entries in the web.config file for each service. After completing the configuration of the specific LOB operations to be exposed, the wizard has two more steps to configure the WCF service shim. The first step involves configuring the WCF behaviors to be applied to the service primarily involving credentials of the service and how to handle the credentials of the user. Figure 26 shows the dialog with these two behavior settings. The final step in the wizard is to configure the endpoints used in the WCF service shim. This step shows the various WCF contracts that will be exposed and allows you to configure the endpoint for each contract focused primarily on providing a name and binding configuration. 36 Figure 25: WCF Adapter Service Wizard Figure 26: WCF Adapter Service Wizard Behavior Configuration 37 Figure 27: WCF Adapter Service Endpoint Configuration Choosing a Hosting Model As mentioned, choosing the hosting model depends on several factors. Starting with client hosting, this model works very well for point to point communication where a specific client application will be communicating with a LOB application and using a particular set of operations on the service. Keep in mind that even though an adapter can expose thousands of operations from a LOB system, a given consumer of that adapter will select the operations that are relevant in the context of the client application. Therefore while three different client applications might need to interact with the same LOB system, the operations and data they work with can be different. In that case, each client application should have its own proxy with the appropriate set of operations exposed. The power of the LOB Adapter SDK is that the same adapter can be used to generate different client proxy facades. Another use case where client hosting makes the most sense is when the adapter being used supports inbound messaging patterns. For example, a client application that uses the mySAP adapter from the BizTalk Adapter Pack can register as an RFC server so that the SAP system can call the adapter when a particular event occurs. In this model, the adapter needs to remain loaded in memory in order to receive the invocations from the SAP system. The ServiceHost class is used to host the adapter in a listening capacity just as would be done for any WCF service that needed to listen for inbound requests. And when you need to the widest reach possible for the LOB adapter, you should host it in a server process. After you’ve hosted an adapter in IIS/WAS, the adapter is accessible from any client application capable of making basic Web service requests. For example, if the adapter is hosted as a WCF service 38 using the BasicHTTPBinding, even .NET 2.0 client applications would be able to call the service, thereby invoking the adapter operations, and retrieve the results.16 Using WCF as the hosting model for the adapter enables the LOB system to be exposed to a wide variety of clients. Also, as mentioned earlier, most LOB adapters require some sort of library on the client computer for interacting with the LOB system. Hence, another good reason to host your LOB adapters in IIS/WAS is that it reduces the need to distribute those client components. This might simply reduce administration and maintenance costs, but in some cases, it could also result in savings due to licensing issues. When Should I Write a Custom LOB Adapter? When deciding to build a custom adapter with the WCF LOB Adapter SDK it is important to make sure you are using the right tool for the job. The main things to consider include: Does a Web service façade already exist for the target LOB system? Does an adapter already exist for the target LOB system (perhaps in the BizTalk Adapter Pack)? If the answer to either of these questions is “yes,” you probably don’t need to build a custom LOB adapter. Otherwise, the next thing you need to consider is would it be better to service-enable the LOB application (through a service façade) or would it be better to implement a custom LOB adapter. The main factors you should consider on this front include: Does your LOB application expose multiple operations and a wide variety of data that would benefit from the rich metadata search and browsing support found in the SDK? Do different consumers need to consume your LOB application differently? Do you anticipate the adapter being used more than once, in different types of integration scenarios? Does your LOB application have native programming interfaces or protocols that you can use to connect to the application and execute business operations? If the answer to any of these questions is “yes,” you should definitely consider building a custom LOB adapter using the WCF LOB Adapter SDK. However, if your system only exposes a few operations, it may be simpler to create a simple wrapper on the functions you need. And in the case where the LOB system does not have an appropriate API to allow you to execute business functions or extract information, writing an adapter will not make that system easier to access – it will not change the fact that your system does not support those types of operations from external code. In addition, you should not use the WCF LOB Adapter SDK to build a custom adapter if you are wrapping an existing transport such as FTP or SMTP. These transport style adapters do not require the rich 16 This is possible because the client simply needs to be able to communicate with SOAP 1.1 messages using XML 1.0 text messages, which .NET 2.0 is capable of through the standard “Add Web Reference” command. 39 metadata support and connection oriented features of the SDK. Transport style connectivity is better handled by creating a new WCF transport channel and the binding implementations to support it.17 Building Custom Adapters with the WCF LOB Adapter SDK Now it’s time to turn our attention to towards implementing a custom WCF LOB adapter. Figure 28 (from the poster) depicts the overall architecture for WCF-based adapters that you build with the WCF LOB Adapter SDK. As illustrated here, there are three main areas you’ll need to focus on during the implementation process: metadata support, connection management and message handling. Adapters expose metadata so that client applications can choose the operations they require to interact with the LOB system and can build a client proxy that reflects only those operations. When building the adapter, it’s the responsibility of the developer to implement the metadata retrieval process. Adapters can support metadata browsing through a hierarchical representation of the exposed operations as well as metadata search functionality. Search functionality is especially important if your LOB system supports a larger number of operations and you want to make it easier for someone to find the specific operation they need. Finally, adapters must provide support for metadata resolution which involves handling requests to resolve type names to metadata describing the types. As for the runtime components, there are two primary functions developers must implement in an adapter: connection management and message handling. Connection management involves being able to create instances of an object that represents a connection to your LOB system. The connection class is responsible for managing the opening and closing of connections to the LOB system much like a SQLConnection instance is responsible for opening and closing connections to a database. The framework provides most of the supporting connection management infrastructure you’ll need (such as connection pooling) but it relies on the adapter to manage the LOB-specific connection object. Message handlers provide the actual processing of runtime messages and how they translate to calls in the LOB application. When creating an adapter, the developer chooses the message exchange patterns that will be supported by the adapter and the appropriate synchronous/asynchronous interfaces required to support them. Message handlers include both inbound and outbound handlers. Let’s walk through an example of building a custom adapter to illustrate these concepts in action. 17 A common misconception is that the WCF LOB Adapter SDK can or should be used to simplify the process of developing custom WCF transport channels but that is not the purpose of the SDK. 40 Figure 28: The Architecture of WCF-Based Adapters Steps for Building a Custom Adapter The following steps outline the process to follow when building a custom adapter using the SDK: 1. 2. 3. 4. 5. 6. 7. Choose a protocol scheme for the custom adapter (e.g., “myhttp://…”) Decide on the directionality (outbound vs. inbound) and whether it needs to be asynchronous. Decide on the metadata options your custom adapter will provide. Identify any adapter properties you’ll want to expose for end-user customization. Run the WCF LOB Adapter Development Wizard and specify your choices (see 1-4). Familiarize yourself with the generated Visual Studio solution. Finish implementing the provided connection, metadata, and runtime classes. 41 The first four steps in building a custom adapter focus on the design of the adapter. For example, it’s important to decide what protocol scheme you’re going to use and whether the adapter will support inbound and outbound messages, and whether those interactions need to be synchronous or asynchronous. It’s also important to identify what metadata behavior your adapter will provide (e.g., browse, search, both?). And finally, you need to identify any properties that will be required for a user of your adapter to configure the adapter’s behavior or to build an underlying LOB connection – users will be able to configure these through the WCF configuration when consuming your adapter. Answering these questions is often the most difficult aspect of building a custom adapter, because once you do, the wizard generates a complete solution that fulfills your specified requirements. Using the WCF LOB Adapter Development Wizard The WCF LOB Adapter SDK includes a Visual Studio project template for creating new adapters (see Figure 29). The template uses a wizard to ask you for some basic information about the new adapter and then it creates the project and classes based on that information. This provides a significant jump-start. Figure 29: The WCF LOB Adapter Project Template 42 Figure 30: Adapter Wizard – Configuring Scheme and Namespaces Figure 30 shows the first input screen of the wizard which collects information on namespaces and the protocol scheme that will be used in endpoint addresses. The next step is to specify the message exchange patterns (MEPs) and the type of metadata support that the adapter will provide. Figure 31: Adapter Wizard – Choosing Message Exchange Patterns and Metadata Support For metadata you can choose to support browse and/or search and you will have to implement resolve. There are a few different message exchange pattern options including inbound versus outbound and synchronous versus asynchronous (see Figure 31). 43 In the final two steps, the wizard allows you to specify properties that will be available on the adapter (the binding really) and properties needed to implement the connection such as a server name, port, etc (see Figure 32 and Figure 33). Figure 32: Adapter Wizard – Defining Adapter Properties Figure 33: Adapter Wizard – Defining Connection Properties After you’ve completed the wizard, the project template generates a generous number of classes to support the choices you selected. Figure 34 shows an example project and the various files that were 44 added to the project by the wizard. Some the classes defined in the solution are complete and ready to use straight-away while others are left to the developer to fill in the implementation. Figure 34: Adapter Wizard – Initial Project Structure Implementing the Connection and Binding Classes The generated project contains three classes related to connection management. The connection factory class18 has a default implementation that will create connections when requested by the Adapter SDK runtime – you don’t have to do anything with this one. The connection URI class requires you to implement Uri parsing logic to move between the typed properties for your connections and the way those properties are formatted into the Uri string. The connection class itself is where most of the connection management takes place, and where you’ll write the LOB-specific connection code. In the connection class, you’re responsible for managing the opening and closing of connections to the LOB system. In addition, the connection class has a ClearContext method that can be implemented to prepare a connection object to be put back in the pool. Finally, you can implement the IsValid method to return a status indicating whether the open connection is in a valid state or not. The four binding-related classes provide the WCF packaging that makes the adapter easy to use. It provides a binding class, a binding element, and a binding element extension that make it easy to use the new custom adapter. These binding classes are preconfigured to expose the adapter properties supplied in the new project wizard all the way from the configuration up to the adapter class itself. Implementing the Metadata Classes Metadata support is found in three files including one for browsing support, one for search support, and a final class for resolving metadata types. The browse and search classes each have one method to implement returning an array of MetadataRetrievalNode objects representing the operations that can be performed on the adapter. These nodes are simply definitions of named items that can be shown to 18 In this case the class name is TrainingCourseSystemAdapterConnectionFactory, but since these class names are so long, we’re going to abbreviate and leave the mental mapping to you. 45 a developer using the adapter – this is where you’ll need to do your mapping to the LOB system. The metadata resolver is responsible for resolving metadata identifiers to operation descriptions. For example, Figure 35 shows a simple static implementation of a metadata browse handler which returns a single operation with two parameters. Figure 36 shows the corresponding code in the metadata resolver class that returns more detailed metadata for a particular operation so that it can be used by consumers to generate client-side proxy classes. Figure 35: Implementing Metadata Retrieval public MetadataRetrievalNode[] Browse(string nodeId, int childStartIndex, int maxChildNodes, TimeSpan timeout) { MetadataRetrievalNode node = new MetadataRetrievalNode("ops/GetCourses"); node.Direction = MetadataRetrievalNodeDirections.Outbound; node.DisplayName = "GetCourses"; node.IsOperation = true; node.Description = "Gets all courses scheduled for the given time window"; return new MetadataRetrievalNode[] { node }; } Figure 36: Implementing Metadata Resolution public OperationMetadata ResolveOperationMetadata(string operationId, TimeSpan timeout, out TypeMetadataCollection extraTypeMetadataResolved) { extraTypeMetadataResolved = null; switch (operationId) { case "ops/GetCourses": ParameterizedOperationMetadata opMeta = new ParameterizedOperationMetadata("ops/GetCourses", "GetCourses"); OperationParameter prmStartTime = new OperationParameter("startDate", OperationParameterDirection.In, QualifiedType.DateTimeType, false); OperationParameter prmEndTime = new OperationParameter("endDate", OperationParameterDirection.In, QualifiedType.DateTimeType, false); opMeta.Parameters.Add(prmStartTime); opMeta.Parameters.Add(prmEndTime); opMeta.OperationResult.QualifiedType = new ComplexQualifiedType("Types/Course"); return opMeta; default: throw new InvalidOperationException("No operation with that ID exists"); } } In addition to resolving operation metadata, the resolver class is responsible for handling generation of metadata for types that will be exposed from the system. For a given operation, there may complex types that make up the parameters or the return types. These types must also be resolved and 46 described using the metadata classes so they can be used in the generation of WSDL and consumed by users. In the examples shown here, the metadata generation is very static but in a real system the metadata would be harvested from the LOB system in a more robust and dynamic way. Implementing the Remaining Runtime Classes Finally, the remaining classes represent the core of the adapter runtime development. The outbound handler simply has an execute method on it which receives a WCF message object and is expected to return the same. The execute method is where the adapter runtime behavior is focused and where the real communication happens. In order to complete the execution there are two key things the handler might need: a connection and metadata to provide information about a specific operation. Fortunately, the base class for the handler provides the connection and a MetadataLookup object that can be used to query for metadata (e.g., using the SOAP action). With a message, the connection and the metadata about the operation to be invoked, it’s up to you to decide how to translate that information into an LOB API call, and how to translate the result back into a WCF Message object. The inbound handler is slightly more complicated as it must begin listening for messages and get them into the system when they arrive. For inbound handlers, you implement StartListener and StopListener to control when the adapter should start or stop whatever specific mechanism it has for receiving messages. The other two operations on the inbound handler are WaitForMessage and TryReceive. It’s beyond the scope of this whitepaper to discuss the precise implementation details for these runtime components, however, the SDK documentation and samples will be able to fill in the remaining gaps. While the sheer number of files generated by the adapter wizard can seem overwhelming at first, keep in mind that many of them are completely implemented, providing boilerplate logic, and once you group the rest together each development task becomes clear. After you’ve implemented all of the classes, you simply install your adapter into the Global Assembly Cache (GAC) and add the appropriate configuration to machine.config to make your adapter accessible to all applications on the machine. Summary The WCF LOB Adapter SDK and the BizTalk Adapter Pack promise to increase overall integration flexibility by making it possible to integrate directly with LOB applications outside of BizTalk Server, from a variety of different .NET applications, including Windows SharePoint, SSIS, or your own. Through the WCF LOB Adapter SDK, anyone can create custom LOB adapters that can be easily consumed like typical WCF services. These adapters can then be hosted and consumed in a variety of different scenarios. This is particularly useful when you need to expose LOB applications that expose a vast set of operations and data sets (like a database system). The BizTalk Adapter Pack provides a suite of LOB adapters (built with the SDK) for some of today’s most common LOB applications including SAP, Oracle, and Siebel. For additional information and downloads, see the References section below. 47 References WCF LOB Adapter SDK (download) BizTalk Adapter Pack (download) BizTalk Adapter Pack SDK Poster WCF Adapters in BizTalk Server 2006 R2 WCF Bindings In-Depth 48 Copyright Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted in examples herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. © 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, BizTalk, and Visual Studio are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. All other trademarks are property of their respective owners. 49