Geeks With Blogs
Paul's Petrov Whiteboard [BizTalk, Enterprise Application Integration, Business Process Automation, SOA, .NET]

In previous post describing features of BizTalk Web Services Publishing wizard I surfaced some thoughts suggesting that schema publishing option does not completely follow contract-first development principle. This post explains why I think so.

In a nutshell, according to contract-first approach one is supposed to produce service contract before trying to implement the service’s guts. After contract is done it can be published so the service consumers can start developing against it. On the other side, service provider is free to develop and bind any compatible service implementation to published contract. Service contract, when properly designed upfront, provides a great deal of decoupling between systems.

What goes into a service contract? Full blown service contract may include lots of things like functional description, message schemas, bindings, message exchange patterns, communication protocols, policies, quality of service, constraints, etc. If we are building web services, then at the very least we should create some WSDL as a standard way of describing services nowadays. We are about to check how BizTalk schema publishing handles this task. For guide how to publish schemas in BizTalk please refer to documentation and see articles by Aaron Skonnard and Richard Seroter.

Let’s design a simple service that does something banal, like weather reporting. I defined following simplistic schema:

<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://WeatherService.Schema" targetNamespace="http://WeatherService.Schema" xmlns:xs=http://www.w3.org/2001/XMLSchema attributeFormDefault="unqualified" elementFormDefault="qualified">

  <xs:simpleType name="ZipStruct">

    <xs:restriction base="xs:string">

      <xs:length value="5" />

    xs:restriction>

  <xs:simpleType>

    <xs:complexType name="WeatherInfoType">

      <xs:sequence>

        <xs:element minOccurs="1" maxOccurs="1" name="Temperature" type="xs:integer" />

        <xs:element minOccurs="0" maxOccurs="1" name="Humidity" type="xs:integer" />

        <xs:element minOccurs="1" maxOccurs="1" name="WindSpeed" type="xs:string" />

        <xs:element minOccurs="0" maxOccurs="1" name="Conditions" type="xs:string" />

      xs:sequence>

      <xs:attribute name="Zip" type="ZipStruct" />

    xs:complexType>

  <xs:element name="WeatherInfo" type="WeatherInfoType"/>

  <xs:element name="GetWeather">

    <xs:complexType>

      <xs:sequence>

        <xs:element minOccurs="1" maxOccurs="unbounded" name="Zip" type="ZipStruct" />

      xs:sequence>

    xs:complexType>

  <xs:element>

  <xs:element name="GetWeatherResponse">

    <xs:complexType>

      <xs:sequence>

        <xs:sequence>

          <xs:element minOccurs="1" maxOccurs="unbounded" ref="WeatherInfo" />

        xs:sequence>

      xs:sequence>

    xs:complexType>

  xs:element>

Although pretty basic, this example contains some common constructs and constraints found in real life schemas. It has global type definition of a simple type ZipStruct derived by restriction. There’s global complex type WeatherInfoType, and request/response messages declared as global elements. Take a close look at cardinality constraints on the elements. We’d like all those constraints to make into the service contract as part of our business requirements.

The first surprising thing after publishing schema using BizTalk Publishing wizard is that there’s no WSDL file created. Web directory contains WeatherReport.asmx that refers to WeatherReport.asmx.cs code file in the App_Code subfolder. Neither of three other subdirectories (bin, temp, and xsd) harbors our service description.

What we’ve got here essentially is a C# service stub generated from our schema. Let’s browse to the service URL and let .Net dynamically generate web service description for us. This will return a standard WSDL with common sections: types, messages, portTypes, bindings, services. So, what’s the problem? Let’s take a close look at the types section:

  <wsdl:types>

    <s:schema elementFormDefault="qualified" targetNamespace="http://WeatherService.Schema">

      <s:element name="GetWeather">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="unbounded" name="Zip" type="s:string" />

          s:sequence>

        s:complexType>

      <s:element>

      <s:element name="GetWeatherResponse">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="unbounded" name="WeatherInfo" type="s1:WeatherInfoType" />

          <s:sequence>

        s:complexType>

      s:element>

      <s:complexType name="WeatherInfoType">

        <s:sequence>

          <s:element minOccurs="0" maxOccurs="1" name="Temperature" type="s:integer" />

          <s:element minOccurs="0" maxOccurs="1" name="Humidity" type="s:integer" />

          <s:element minOccurs="0" maxOccurs="1" name="WindSpeed" type="s:string" />

          <s:element minOccurs="0" maxOccurs="1" name="Conditions" type="s:string" />

        s:sequence>

        <s:attribute name="Zip" type="s:string" />

      s:complexType>

    s:schema>

  wsdl:types>

Surprisingly, to get a weather report we are not required to pass parameters as Zip element became an optional one. Also, its value is no longer restricted to 5 characters length. The same striking change is seen in the response definition: all fields of the WeatherInfo element are optional now. What a big change in our service interface! Would you want to share such contract that lacks original fidelity? I wouldn’t.

Of course, what we’re observing here is a typical example of so called “impedance mismatch” between XML Schema and object-oriented worlds. Whenever mapping entities from one domain to another we have to deal with differences between document-centric and object-centric models plus variations imposed by specific type system implementation. In our case, we got this effect because BizTalk first generated .Net types (DataTypes.cs) and service endpoint code (WeatherService.asmx.cs). Then .Net framework generated WSDL from this code when we hit the service URL. Thus, original schema got distorted by .Net common type system view of the world.

Therefore, BizTalk schema publishing supports development flow as depicted below. The picture below shows parts of a service contract in blue while implementations in yellow. Notice how WSDL is no longer an abstract service description but rather description of concrete service endpoint:

However, when doing contract-first development, we want to create artifacts that belong to service contract before any implementation begins. This way, the WSDL preserves original type definitions, without exposing consumers to service implementation domain:

This is why just publishing schemas in BizTalk is not true contract-first development.

So, does BizTalk still allow designing a contract-first way? Yes, it does. Remember, we started from XML messages schema which is a part of the service contract.

Does it strictly follow contract-first development flow? No, because it creates part of the service contract (WSDL) based on premature platform specific implementation (service endpoint) which hinders original types’ definitions.

Is it possible to work around this limitation? Yes, we can disable dynamic WSDL generation and provide static WSDL that imports original unaltered schema:

    <wsdl:types>

      <xsd:schema>

        <xsd:import schemaLocation="MyTypes.xsd" namespace="http://weather.services"/>

      xsd:schema>

    wsdl:types>

Another way is to author WSDL and import it using BizTalk BPEL import project.

Are there any other practical considerations when doing contract-first development with BizTalk? Yes, stay tuned for the next article.

Posted on Tuesday, April 18, 2006 6:07 PM BizTalk , EAI | Back to top


Comments on this post: Why BizTalk Schema Publishing Is Not True Contract-First

# re: Why BizTalk Schema Publishing Is Not True Contract-First
Requesting Gravatar...
Nice post Paul.

There are a couple of other quirks that go on as well between XSD to objects and then to WSDL generation.

We also find issues from WSDL going into .NET client references as well. Depending on the shape of WSDL emitted (this applies to WSDL in general, not BTS generated WSDL).

So to name a few, having a namespace on the root element causes the WSDL to be emitted correctly, but the .NET client proxy generation fails to acurately map this.

Manual editing of the resulting client proxy class is needed.

Point to note here is that the BTS WebService Wizard can be scripted/automated through apis and the XML file found under the \temp directory in the WebService folder.

Sticking with 'Contract first development'......the truly practical way to go is to use WCF and adapter support is introduced in BTS2006 R2.

Take care - nice work.
Left by Mick Badran on Oct 02, 2006 6:02 PM

# re: Why BizTalk Schema Publishing Is Not True Contract-First
Requesting Gravatar...
Agreed. Manual work involved to follow contract-first with the current set of tools. I had to place XmlRootAttribute(Namespace="My Namespace") attributes on my data contract files to ensure proper proxy generation. Kind of breaking "Third Tenet" of SOA... but that's another story :)

Paul
Left by Paul Petrov on Oct 18, 2006 1:45 PM

# re: Why BizTalk Schema Publishing Is Not True Contract-First
Requesting Gravatar...
Thank you Paul, you have shed some serious light on a topic that's had me going round in circles for hours.
Left by Dave Bartlett on Jan 09, 2011 7:57 PM

Your comment:
 (will show your gravatar)


Copyright © Paul Petrov | Powered by: GeeksWithBlogs.net