Implementing Service Contracts with BizTalk Server 2004
Aaron Skonnard, Pluralsight
Published: November 2005
Applies to: Microsoft BizTalk Server 2004
Summary: The Implementing Service Contracts with BizTalk Server 2004 document discusses some of the issues surrounding BizTalk Server's support for Web services, while providing helpful guidance and some practical techniques for implementing existing WSDL contracts in your BizTalk orchestrations. (11 printed pages)
Microsoft BizTalk Server 2004 offers development tools for designing and implementing business processes as orchestrations. Once you've implemented a BizTalk orchestration, you can publish the orchestration as a Web service through the built-in Web Services Publishing Wizard. The wizard generates an ASP.NET Web services (ASMX) endpoint based on the schema types used in the orchestration. Then consumers can query the generated ASMX endpoint to retrieve the Web Services Description Language (WSDL) definition representing the orchestration's service contract. Once the WSDL contract is accessible, any Web services-enabled consumer can integrate with the orchestration.
This general development process assumes that the service contract is typically an orchestration byproduct defined by the BizTalk Server developer. The reverse scenario, however, is also important—where a pre-existing service contract (in the form of a WSDL definition) must be implemented and adhered to by a new BizTalk orchestration. This article discusses some of the issues surrounding BizTalk Server's support for Web services, while providing helpful guidance and some practical techniques for implementing existing WSDL contracts in your BizTalk orchestrations.
BizTalk Server, at its core, processes XML messages. In order to process XML, however, BizTalk Server must know about the message's structure and types. Developers provide this information to BizTalk Server in the form of XML Schema (XSD) definitions. Developers also model how these XSD types flow through BizTalk orchestrations using logical ports. Developers bind the logical ports to physical ports, which specify concrete transport details and locations. The information provided by the logical and physical ports together defines the external contract of a BizTalk Server system. What happens behind the port boundary is completely hidden from you (see Figure 1). As you can see, the BizTalk Sever development approach is very service-oriented and contract-driven by nature.
The information in an orchestration's logical ports is informative not only to external users, but also to BizTalk Server internally. The logical port information drives the way BizTalk Server's publish and subscribe architecture routes messages. When you enlist an orchestration, the logical port information is used to create BizTalk MessageBox subscriptions for the particular XSD type. When you publish messages to the MessageBox at run time, BizTalk Server uses the subscription information to route messages to the target orchestrations. Applications that wish to interact with a given orchestration only need to know about the XML types it uses along with where and how to send them.
Figure 1 BizTalk Server messages, ports, and orchestrations
When building service-oriented systems in general, the only artifact shared among parties is the service contract. Today service contracts are expressed and shared using WSDL—a language virtually all platforms and frameworks support. When numerous parties work together on large service-oriented systems, they often collaborate on the shared service contracts. This allows both consumers and implementers to provide valuable input during contract design, well before the implementation begins. Doing so increases interoperability success by bringing more expertise to the table (especially regarding local implementation environments) during the early design stages. Such shared contracts are not always controlled by a single party, but perhaps by a team or central body of sorts.
This type of collaboration is common in large organizations where developers from multiple departments participate in defining the service contracts surrounding business process integration scenarios. It's also common in business partner scenarios where business agreements and contracts are established well in advance, before any implementation, and then simultaneous development ensues against the predefined service contracts. It's even common in some industry verticals where contracts might be promoted or controlled by official standard bodies or consortiums (e.g., HL7 in the healthcare sector). Many of these scenarios are common for BizTalk Server developers.
If you find yourself in any of these scenarios, you'll need to implement an existing WSDL contract in your service implementations. How you accomplish this depends on the framework you're using to implement the services. The most commonly used frameworks among .NET developers are ASP.NET Web services (ASMX) or Web Services Enhancements (WSE) 2.0—these are a good fit for implementing fine-grained services that don't require much in the way of state management or long-running transactions. BizTalk Server is emerging as the preferred framework for implementing coarse-grained business services that typically deal with these more complex issues. The techniques to implement existing service contracts differ greatly across these different frameworks. Implementing existing contracts using BizTalk Server requires developers to understand the mapping between orchestrations and Web services along with the available tool support.
When you compare the characteristics of BizTalk orchestrations relative to today's Web services stack, you'll notice many similarities. For example, both orchestrations and WSDL definitions reference XSD types to define the messages that flow in and out of their systems. Both define the concept of a port type, a logical interface that defines groups of operations consisting of message exchanges. Both rely on "bindings" to specify the transport and protocol information used to communicate over a particular port type. Table 1 highlights the mapping between these central concepts.
Table 1 Comparing WSDL definitions to BizTalk orchestrations
WSDL documents import XSD types in order to define the messages that will in turn define the service inputs and outputs.
BizTalk orchestrations reference XSD types in order to define the input and output messages bound to send/receive ports.
WSDL message elements define the particular elements from the imported XSD that will flow in and out of the service.
BizTalk Server message variables specify exactly which public element from the referenced XSD will be used by the send/receive ports.
WSDL portType elements define groups of logical operations, which consist of input and output messages—effectively an interface definition.
BizTalk PortTypes define groups of logical operations, which consist of input and output messages—effectively an interface definition.
WSDL binding elements define additional transport and protocol details relative to a portType.
BizTalk orchestrations are "bound" to physical ports, which the BizTalk Server messaging engine renders using adapters (to encapsulate communication transports) and enhances the messages through the ports using pipeline components.
WSDL service elements define ports. WSDL ports define the physical endpoints (addresses) used to communicate with the service. Each port is associated with a portType/binding.
BizTalk orchestrations define ports. BizTalk Server ports define the logical and physical I/O mechanisms of an orchestration, Each logical port is associated a portType and is later bound.
Table 1 illustrates a direct correlation between the information conveyed by BizTalk orchestrations and WSDL definitions. Therefore, it's logical to assume an automatic mapping between the two worlds is possible, in either direction. In other words, it should be possible to publish an orchestration as a Web service endpoint using WSDL, and it should be possible to automatically generate an orchestration skeleton starting from an existing WSDL definition. BizTalk Server automates these mappings through a variety of different tools.
BizTalk Server provides the Web Services Publishing Wizard (along with a WSE-specific version) to automatically publish orchestrations as Web service endpoints described by WSDL. The publishing wizard also provides an option for publishing schemas as Web service endpoints, which doesn't require an orchestration as a starting point. This option requires you to provide more information about the service contract but also gives you more flexibility in terms of how BizTalk Server uses the service endpoint. In general, the publishing wizard assumes you're starting with BizTalk Server artifacts and publishing them as services.
The publishing wizard does not support the reverse direction, where you need to generate an orchestration from an existing WSDL definition. This is where BizTalk Server's BPEL Import Wizard comes into play. When provided a full Business Process Execution Language (BPEL) definition, the BPEL importer can generate a complete orchestration. However, you can also generate a skeleton orchestration from a WSDL starting point, providing you with the BizTalk Server representation of the service contract needed to get started. However, the BPEL Import Wizard doesn't provide the Web services layer needed to interact with the generated orchestration. Hence, to complete the implementation, you must still figure out a way to produce the orchestration's Web service front end that also conforms to the existing WSDL contract.
These tools make BizTalk Server a compelling framework for implementing Web services, unbeknownst to many developers. Let's discuss how each of these tools work before walking through how to implement existing service contracts using BizTalk Server.
The publishing wizard comes with two main options (see Figure 2):
Publish BizTalk orchestrations as Web services.
Publish schemas as Web services.
Both options produce ASMX code that integrates with BizTalk Server.
Figure 2 Web Services Publishing Wizard
When you choose the first option, the wizard prompts you to select the BizTalk assembly containing the desired orchestration. Then you select the public ports you'd like to publish, along with some other Web service details (such as the WSDL target namespace, header processing, etc.), and the wizard subsequently generates the necessary ASMX code needed to integrate with the orchestration. The wizard also generates and configures the Internet Information Services (IIS) virtual directory needed to host the ASMX endpoint, along with the BizTalk Server receive locations if those options are specified.
The generated ASMX code contains a WebMethod for each operation in the selected BizTalk Server port, along with the supporting .NET class definitions that model the various XSD types used by the operations. Once published, you can query the ASMX endpoint using the "?wsdl" convention to retrieve the WSDL definition. The WSDL is generated from the ASMX code, which was itself generated from the original BizTalk Server port type details. At this point, you don't have much control over the WSDL contract – everything is simply derived from the orchestration details.
However, the wizard also has the "Publish schemas as Web services" option, which gives you more flexibility. This option requires you to build the WSDL definition manually using the provided builder (e.g., adding/naming services, operations, etc.). The WSDL builder then asks you to map the WSDL operations to your BizTalk Server schemas (see Figure 3). The wizard generates an ASMX endpoint based on the specified details, along with the supporting .NET class definitions that model the selected XSD types. Although this option offers greater WSDL flexibility, the tradeoff is pretty obvious—you have to build the entire definition by hand.
Figure 3 Publish schemas as Web services
The generated ASMX code performs the same task regardless of which option you use. The code simply processes the SOAP envelope and dispatches the payload (what's in <soap:Body>) to the BizTalk MessageBox. When using an orchestration, one of its logical ports must be bound to the SOAP adapter, specifying the address of the ASMX endpoint. This produces the necessary subscriptions for routing incoming messages to the orchestration.
In the case of "publish schemas," however, you again have more flexibility. You could simply use the generated ASMX to provide a public gateway to the BizTalk MessageBox and rely on subscriptions along with maps and adapters to pick up the messages, perform translation, and move the information around your network without ever using orchestrations. Alternatively, you could manually define orchestrations that subscribe to the incoming messages—it's your choice.
Although this tool provides a productive solution, the use of ASMX in this case comes with an issue worth mentioning. When the ASMX infrastructure receives a SOAP message, it must first translate the SOAP message into a .NET object graph in order to invoke the WebMethod. The WebMethod then takes the object graph and using a custom proxy object, passes the object to BizTalk Server. BizTalk Server, however, is expecting to receive an XML document. Hence, the custom proxy object must translate the object graph back into XML before presenting it to BizTalk Server. The translation occurring here can become troublesome in some situations due to the well-documented mismatch between the XSD and .NET type systems.
The fact is that clients send XML and BizTalk Server consumes XML. The ASMX translation can introduce overhead and risk in this scenario but it is also possible for you to automatically retrieve WSDL definitions from the strongly-typed signatures (using service.asmx?wsdl), which is the most likely reason for doing things this way. When you're implementing existing service contracts, this is the main area that can cause problems (more on this shortly).
The BizTalk Server Adapter for WSE 2.0 also provides a publishing wizard that generates WSE 2.0 code instead of ASMX. The same two options exist for publishing orchestrations or schemas as Web services—the main difference here is that you can also specify policy information to configure security (see Figure 4).
What's interesting about the wizard-generated WSE code is that it no longer uses the ASMX programming model. Instead, the WSE 2.0 messaging API is used through a new SoapService-derived class named Microsoft.BizTalk.Adapter.WseReceiver.WseReceiver. It generates a new class that derives from WseReceiver and adds a [SoapMethod] attributed method for each operation. The generated method signatures are defined in terms of SoapEnvelopes, which means .NET object serialization no longer occurs at run time. Now the WSE infrastructure performs all policy/security processing on the raw SoapEnvelope and the generated proxy code simply dispatches the envelope body directly to BizTalk Server.
The generated class is bound to an .ashx endpoint, which you can browse to retrieve the WSDL definition. You might wonder how it could possibly generate WSDL if the signatures are defined in terms of SoapEnvelope. Additional method attributes convey the input/output type information, used solely for WSDL-generation purposes. This solution gives you the best of both worlds.
Both publishing wizards are suitable when you're defining new service contracts and aren't concerned with conforming to an existing WSDL definition. Each provides equivalent functionality to code-first ASMX, where you start by authoring WebMethods and let the infrastructure generate the contract, only here the orchestration is the "code" and the wizard generates the contract. If you're looking for the "wsdl.exe /server" equivalent, you need to use the BPEL import wizard.
Figure 4 BizTalk Server WSE Web Services Publishing Wizard
The BizTalk Server BPEL Import Wizard provides tool support for contract-driven orchestration development today. You access this wizard when creating new BizTalk Server projects in Microsoft Visual Studio .NET. There is a BizTalk Server project template named BizTalk Server BPEL Import Project (see Figure 5). When you select this template, Visual Studio .NET launches the BPEL Import Wizard that walks you through specifying the contracts to generate the new orchestration.
You can specify complete BPEL definitions describing an entire orchestration or just WSDL and schema definitions for generating the orchestration's port types. Although the full-BPEL approach is quite compelling, it's not the most common scenario today. The scenario focused on here is how to handle dealing with a stand-alone WSDL definition that you've been given to implement.
A typical WSDL definition contains two main types of information:
The abstract interface (type, message, portType)
The concrete binding details (binding, service)
A Web service that dispatches to BizTalk Server is concerned with both types of information. Orchestrations, on the other hand, aren't concerned with concrete binding information – they're defined in abstract terms via logical ports. This is important to understand when looking at the BPEL Import Wizard because it only generates the orchestration, not the Web service layer.
Figure 5 BizTalk Server BPEL import project
Let's walk through an example while discussing how this process works. We'll assume that we have an existing WSDL definition that defines a single operation named Multiply. The WSDL definition imports two external schema files: DocIn.xsd and DocOut.xsd. DocIn.xsd defines an element named DocIn, which contains two input elements, Param1 and Param2, as illustrated here:
<xs:schema xmlns="http://example.org/docin" elementFormDefault="qualified" targetNamespace="http://example.org/docin" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="DocIn"> <xs:complexType> <xs:sequence> <xs:element name="Param1" type="xs:int" /> <xs:element name="Param2" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
DocOut.xsd contains an element named DocOut, which contains a Result element to hold the result of the Multiply operation:
<xs:schema xmlns="http://example.org/docout" elementFormDefault="qualified" targetNamespace="http://example.org/docout" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="DocOut"> <xs:complexType> <xs:sequence> <xs:element name="Result" type="xs:long" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Both of these schema files are imported and used by the WSDL definition. They are referenced by the WSDL messages, which are in turn referenced by the operation:
<definitions ... xmlns:s0="http://example.org/docin" xmlns:s1="http://example.org/docout" xmlns:s2="http://example.org/mathservices" targetNamespace="http://example.org/mathservices" xmlns="http://schemas.xmlsoap.org/wsdl/" > <import namespace="http://example.org/docin" location="DocIn.xsd" /> <import namespace="http://example.org/docout" location="DocOut.xsd" /> <message name="InputMessage"> <part name="parameters" element="s0:DocIn" /> </message> <message name="OutputMessage"> <part name="parameters" element="s1:DocOut" /> </message> <portType name="MathService"> <operation name="Multiply"> <input message="s2:InputMessage" /> <output message="s2:OutputMessage" /> </operation> </portType> ...
The rest of this WSDL file goes on to bind the portType to SOAP over HTTP using the document/literal style. However, as far as the orchestration is concerned, the important information is shown above. The types, messages, and portTypes are the constructs that generate the new BizTalk orchestration. In fact, the current BPEL Import Wizard is only capable of dealing with these constructs, which means you have to extract the binding/service elements from the WSDL definition before using it with the BPEL Import Wizard.
Once you have the WSDL definition ready to import, run the BPEL Import Wizard and specify it when prompted to "Select BPEL, WSDL, and XSD Files" to import (see Figure 6). Even though the WSDL file imports the XSD files, you must specify the required XSD files as well. Once you've finished, complete the wizard and the skeleton orchestration project is generated.
Figure 6 BPEL Import Wizard - Selecting Files to Import
Initially, the orchestration project looks deceivingly empty. However, upon closer inspection, you'll notice the following things occurred:
If you inspect Solution Explorer, you'll see an orchestration was created with the same name as the WSDL file.
The XSD files were automatically imported into the project.
The wizard generated several BizTalk Server types and messages for use within the orchestration that you'll find via the Orchestration View (see Figure 7) REF _Ref100857356 \h
Given our WSDL, a BizTalk PortType was generated with a name of MathService. The PortType contains a single operation named Multiply, which uses a request/response message exchange.
The Request message is mapped to InputMessage—a multipart message type also generated from the WSDL. InputMessage contains a single part named parameter, which maps to the DocIn element from the imported XSD. The same is true for the Response message.
In addition to the PortType, notice that the wizard also generated two message variables named Message_1 and Message_2 for use within the orchestration. These messages also map to the DocIn and DocOut XSD elements.
Figure 7 Orchestration view
Now all we need to do is define a new logical port based on the MathService PortType and our orchestration is guaranteed to conform to the interface defined in the original WSDL definition. To do this, create a new configured port and select MathService as the existing PortType. Once you finish the wizard, the new port appears containing all of the operations found in the PortType – in this case Multiply. Then you're simply left with the task of implementing the operations in the orchestration logic.
The completed orchestration for this example is shown in Figure 8. Next, we need to generate the Web services layer that implements the original WSDL contract and dispatches messages into our new BizTalk orchestration.
Figure 8 Port Configuration Wizard
Figure 9 Orchestration implementation from WSDL
When you expose an orchestration through a Web service, the generated ASMX/WSE code is the BizTalk Server SOAP adapter. The adapter's job is to perform the necessary SOAP and WS-* processing on incoming SOAP messages, extract the payload from the SOAP envelope, and dispatch the payload to the BizTalk MessageBox. When the payload hits the BizTalk MessageBox, the SOAPness is lost and it is no longer considered a Web service message—it's simply an instance of some XSD type that BizTalk Server knows about. Upon arrival, BizTalk Server routes the message to the target orchestration. In the case of request/response operations, the Web service layer must also capture the response message returned by the orchestration, and create an appropriate SOAP response for the client.
Implementing this layer while conforming to an existing WSDL contract is the trickiest step of the overall process, and there are a variety of ways to approach it. First, you could use the built-in ASMX publishing wizard against the new orchestration. Although the publishing wizard produces the code needed to dispatch to the BizTalk MessageBox, the code won't conform to the original WSDL definition. The names of the various WSDL constructs are modified after passing through the code generation processes. The generated code may also contain other incompatibilities with respect to the original contract, such as binding differences and the necessary ASMX parameter style (bare vs. wrapped) that direct serialization.
Another option is to use the "publish schema" option to more fully control the WSDL and avoid the name-mangling problem referred to previously. This option requires you to manually define the WSDL operations via the wizard. Although it seems kind of silly to redefine the WSDL contract via the wizard when we had it from the beginning, doing so gets you closer to the original WSDL contract and produces the correct BizTalk Server dispatching code. We say "closer" because you can specify the correct names for things in the wizard, but the builder still doesn't let you specify WSDL/ASMX binding details. This means the ASMX-generated WSDL can still inherit these potential incompatibilities.
Regardless of the path you take in the ASMX publishing wizard, you'll have to make some manual edits to the generated ASMX code to ensure conformance with the original WSDL contract. The easiest way to do this is to disable the default ASMX WSDL generation and return the original WSDL file when requested by clients. Then you simply need to make edits to each WebMethod to ensure the ASMX dispatching and serialization logic continues to work properly. The exact steps you need to follow are in the following section.
ASMX Publishing Wizard Steps
Use the following steps to use the ASMX publishing wizard:
Run the BizTalk Web Services Publishing Wizard to generate the ASMX code from the orchestration that implements the original WSDL contract.
Disable automatic WSDL generation by modifying the ASMX code. You can do this by specifying the location of the static WSDL file you started from (specify the Location property on [WebServiceBinding] and the name of the specified binding on [SoapDocumentMethod]).
Modify each [SoapDocumentMethod] attribute to use SoapParameterStyle.Bare and the same SOAPAction value specified in the original WSDL definition.
Making these changes makes most of the remaining details found in the generated ASMX code insignificant. Now when consumers request the WSDL for the ASMX endpoint (using "?wsdl"), ASMX returns a reference to the static WSDL file from which we started.
As long as the ASMX SOAPAction values match those found in the WSDL definition, ASMX routes incoming SOAP messages to the correct WebMethod implementations. And if ASMX isn't expecting "wrapper" elements during object serialization (which you disable by specifying SoapParameterStyle.Bare), the XML serialization process should continue to work. Using this approach gives you the best of both worlds—you remain in control of the WSDL contract while taking advantage of the publishing wizard to generate the necessary BizTalk Server dispatching code.
When using the WSE publishing wizard, similar issues exist. The main thing you need to worry about in this case is the SOAPAction for each operation. You no longer have to worry about serialization incompatibilities since the WSE-based methods are defined in terms of SoapEnvelope.
Nevertheless, you probably don't want to use the generated WSDL in this case either. However, with the WSE messaging API, you cannot disable automatic WSDL generation using the same technique described for ASMX. In order to do this with the WSE-generated code, you need to override the ProcessNonSoapRequest method (defined by SoapReceiver) on the generated WseReceiver-derived class. Then you can simply publish the static WSDL file on your Web server somewhere. The following section summarizes the exact steps you need to follow when using the WSE publishing wizard.
WSE Publishing Wizard Steps
Use the following steps to use the WSE publishing wizard:
Run the BizTalk Server WSE Publishing Wizard to generate the WSE code from the orchestration that implements the original WSDL contract.
Disable automatic WSDL generation by overriding the ProcessNonSoapRequest method to return an HttpException (404, not found). Instead, you can publish the static WSDL file in a virtual directory for clients to access directly.
Modify each [SoapMethod] attribute to specify the same SOAPAction value specified in the original WSDL definition.
You could choose to avoid the publishing wizards altogether and use "wsdl.exe /server" to produce your Web service layer. This guarantees the generated ASMX conforms to the original WSDL definition, but it obviously doesn't generate the BizTalk Server dispatching code needed within the WebMethod implementations. Although not for the faint of heart, you could manually insert the BizTalk Server dispatching code by copying what the wizard produces (from another wizard-generated project) and customizing it within your WebMethods. The generated code follows a standard template but every implementation differs slightly by parameter lists, names, types, etc.
Regardless of the approach you use to produce the Web services layer, the last thing you need to do is bind your orchestration's logical port to the SOAP adapter specifying the address of the ASMX endpoint you're using for the Web service layer. Doing so generates the appropriate MessageBox subscriptions for routing the incoming messages sent by the Web service layer to the deployed orchestration.
Although none of these solutions is likely to make you completely happy, it is possible to implement existing WSDL contracts using BizTalk orchestrations today. Doing so, you reap the many benefits offered by the BizTalk orchestration engine surrounding state management and long-running transactions. You just need to know what options are available for getting the job done.
BizTalk Server 2004 provides in-depth integration with Web services and productive tools such as the Web Services Publishing Wizard and the BPEL Import Wizard for mapping between the worlds of BizTalk orchestrations and WSDL. We've covered step-by-step techniques for implementing existing WSDL contracts in your orchestrations today, along with alternative mechanisms for implementing a conforming Web services layer.
Aaron Skonnard is a co-founder of Pluralsight, a premier Microsoft .NET training provider. Aaron is the author of Pluralsight’s Applied Web Services, Applied BizTalk Server 2004, and Introducing Indigo courses. As an extension to his column, Aaron’s blog serves as a frequent pit stop through the Service Oriented universe - http://pluralsight.com/aaron/.