Property Binding for WSDL

Status and Motivation

This document is another attempt to address the issue of supporting the SOAP 1.2 extensibility mechanism (features, MEPs, and protocol bindings) in WSDL 1.2. It attempts to be a minimal solution for binding abstract properties defined in features, MEPs, and protocol bindings, but also generic enough that it could easily be used for property binding of features other than SOAP.

This document is for discussion. It is not the official product of any W3C working group. It is submitted by employees of TIBCO Software, Inc., who participate in and monitor the WSD and XMLP working groups.

This draft introduces references to external binding sets, typically associated with a particular protocol (a whole set of bindings), or with a protocol/feature-specific binding document.

Table of Contents

Status

Table of Contents

Introduction

Basic Property Binding Syntax

Binding Constructed Properties

Selecting Property Bindings

Binding Scope

Open Value Model

Module Definition

Introduction: Problem Space

Glen Daniels (Macromedia) brought this problem to the attention of the WSD working group. The basic question is how best to describe (since WSDL is a description language) the extensibility mechanism introduced in SOAP 1.2. Jean-Jacques Moreau (Canon) and Amy Lewis (TIBCO) contributed to a discussion of what was called "a proposal for SOAP features/properties in WSDL." One of the challenges for this discussion was the fact that, though SOAP 1.2 defines a mechanism, there are few examples of features, MEPs, and protocol bindings, which means less material from which to gather requirements.

TIBCO (the same culprit as is responsible for this document) was producing, at about the same time, a set of proposals, using the extension mechanism, to better define publish/subscribe messaging in SOAP. These materials enlarge the set of examples, and several observations may be drawn from their construction:

From these characteristics, it becomes clear that the major task for a service description is to provide support for the binding of abstract properties to storage locations. It is also clear that each protocol binding may provide slightly different semantics (different possible locations). Working from the existing proposal set, Amy Lewis (TIBCO) attempted to define a WSDL extension for the proposed alternative email binding. The result seemed to indicate that a few new elements might usefully be added to WSDL for generic support of property binding, per-protocol. Thus this document. With generic support, the per-protocol document can become significantly smaller and better focussed.

Feedback to the original draft of this proposal tends toward the "bind it once, and reference the binding" model, rather than per-service definitions. This draft supplies syntax for protocol/feature binding documents, which are presumed to be external to the WSDL, and only referenced from inside the wsdl:binding element. The original model (which required each service to bind each property) remains available, as a means of per-service override or enhancement of the referenced external property bindings.

Protocol/Feature and Protocol/MEP Binding Syntax

A service defined in a WSDL instance MAY specify the URI of an external document which contains property bindings for a given feature or MEP to one or more protocols, or which contains property bindings for a particular protocol to one or more features or MEPs. The syntax of the reference and the syntax of the referenced document are both described here.

In implementation, supposing that extensibility mechanism gains use and credibility as a means of experimenting with and expanding SOAP and WSDL, a service may need to join multiple external references together. For instance, if an experimental feature is being tested, using an existing protocol binding, the service needs to be able to specify how to resolve any potential conflicts between the protocol binding document's property bindings, and those presented in the experimental feature. The problem grows more complex as more pieces are added.

One solution to the problem of conflicting definitions is the use of the per-service property definitions, which is described below. These definitions always absolutely override the referenced definitions (except when the external definition specifies a value of "fixed" in the use attribute of the property definition; in such cases, the service definition is an error and a fault MUST be reported).

Syntax of References

One new element is introduced as an immediate child of the wsdl:binding element. This is (perhaps confusingly?) called wsdl:protocolBinding. In its simplest form, the protocolBinding element simply points at the location of the external document which contains the binding information. More complex cases allow overrides of this information by specifying additional binding documents (protocolBinding, featureBinding, or mepBinding), and establishing how these documents are to be combined with the base document referenced. The base document may also be specified as null, which allows composition of a set of bindings from a collection of feature and mep binding documents.

  <wsdl:binding>
    <soap:binding transport="anyURI" /> <!-- change "transport" to "uri"? -->
    <wsdl:protocolBinding uri="anyURI" location="anyURI">
      <choice>
        <wsdl:protcolBinding uri="anyURI" location="anyURI" mode="append|override" />
        <wsdl:featureBinding uri="anyURI" name="NCName" location="anyURI" mode="append|override" />
        <wsdl:mepBinding uri="anyURI" name="NCName" location="anyURI" mode="append|override" />
      </choice>*
    </wsdl:protocolBinding>
  </wsdl:binding>

Most of the above should be fairly straightforward. The location attribute is generally used as the identifier of the particular binding in use. Is that really good enough? There's some real question about whether we need to have a URI for a protocol binding that is separate from the uri that identifies the SOAP definition. Sort of one protocol for SOAP, one for WSDL. Using location attribute is not robust, clearly.

Using a QName (supply a "name" attribute on protocolBinding in definition and reference syntax) seems wrong. It seems to give features a pair of QNames as identifiers.

Okay, for the content. Normal style should be a single protocol binding reference, if the people writing the binding can do a nice job of it. When one needs to extend, then the child elements are added. Note that layered nesting isn't supported. Should it be? It seems a pain, for not much gain. Definitions are read in order: the container is first. Children are added in document order, using the mode indicated in the mode attribute. If the mode is "append", then only new property bindings will be used. No property bindings already established (by the container or an earlier child) will be changed. If the mode is "override", then the property bindings in the referenced document will replace any that have already been established.

More complexity is quite possible here, but should be avoided. Anything more complex than the two possibilities for joining together separate definition blocks should instead use the per-service overrides, below.

Syntax of Definitions

There are two patterns possible for property binding definitions. First, a protocol binding document may be created, which lists the supported features and their default storage locations, feature by feature and MEP by MEP. Second, authors or users of a feature or MEP may suggest appropriate bindings for the defined properties, protocol by protocol.

Most of the syntax of property binding per-service is reused in the external definition syntax, just wrapped in container elements.

Syntax for a single protocol, establishing bindings for (potentially) multiple features and message exchange patterns.

  <protocolBinding uri="anyURI">
    <featureBinding uri="anyURI" name="NCName" use="enum">
      <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
    </featureBinding>
    <mepBinding uri="anyURI" name="NCName" use="enum">
      <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
    </mepBinding>
  </protocolBinding>

Syntax for a single feature or message exchange pattern, establishing bindings for (potentially) multiple protocols.

  <featureBinding uri="anyURI" name="NCName">
    <protocolBinding uri="anyURI" use="enum">
      <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
    </protocolBinding>
  </featureBinding>

  <mepBinding uri="anyURI" name="NCName">
    <protocolBinding uri="anyURI" use="enum">
      <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
    </protocolBinding>
  </mepBinding>

It should be obvious from the above that the same information is provided in each case, it's just the difference between wrapping in paper and then putting it in a box, or putting it in a box and then wrapping it in paper.

Basic Property Binding Syntax

A variety of syntactic constructs are possible for binding properties. What they all have in common is that they appear as descendants of wsdl:binding. That is (and with the wsdl:module exception shown below), there is no need to place information elsewhere in the WSDL structure; property bindings are associated with wsdl:binding, not portType, nor service, nor anywhere else.

The variety of properties, and preferred locations for them, leads to the creation of either a single wsdl:property element, with content variable on the content of an attribute (a cooccurrence constraint, which is hard to model in grammar-based schema languages), or the creation of wsdl:simpleProperty, wsdl:complexProperty, and wsdl:propertyChoice. The latter variant is proposed here. The names chosen deliberately evoke their models in W3C XML Schema.

This section discusses the content model of wsdl:simpleProperty.

  <wsdl:simpleProperty name="QName"? locationType="QName" use="enum">location</wsdl:simpleProperty>

The name attribute is shown here as optional, which is misleading. The name attribute is forbidden when simpleProperty appears as the child of a complexProperty or propertyChoice element, and is required when the simpleProperty appears as the child of a binding, operation, input, output, or fault element.

The value space for the locationType is a QName. This document defines several names, in the wsdl namespace, which may be used. Extension documents may define additional location types. For instance, a MIME compliant extension might need to define the location type "partHeader" (presumably in its own namespace, or perhaps in a more general namespace: mime:partHeader).

The value space for the use attribute is: "fixed", "required", "optional", and "prohibited". A property binding with a use attribute with the value "fixed" may not be overridden. Overriding such a binding is considered to be an error in the semantic of WSDL definition. If the value of the attribute is "required", then the property must be bound. It is an error (at run time) if the property is found to be unbound in a particular message context. A property with the use attribue value "optional" may or may not be bound. If bound, the service or client is expected to handle the property appropriately; if it is not bound, the service or client may ignore it. A property marked "prohibited" is normally found as the override of a property marked, in a larger scope, "optional". [[ISSUE: should it be an error to override "required" with "prohibited"? Nice symmetry: override of "fixed" by anything is an error. Override of "required" by "prohibited" is an error. required can override required, or optional. Reverse would be true, though, required cannot override prohibited. Hmm. The interactions of allowed/permitted overrides with scope begins to get complex ... worth pursuing? Or just say that a "fixed" can never be overridden, and move on?]]. A property marked "prohibited" may not be used. This marking is normally used to indicate to a client that a service will not support certain kinds of behavior (such as composite MIME).

If the use attribute is not specified, it defaults to "optional."

The content of the element is the actual location. For instance, if the locationType is set to "protocolHeader" for an email binding, and the property is address:original-source, the value might be set to From (it might equally reasonably be set to Sender, or even to Return-Path). The protocolHeader enumerated value permits specification of any named header field. Other locationTypes may specify an exact location using other means, such as an offset, or a conventional name (one that appears in the specification for the protocol, but not in individual packets).

The following values are suggested as part of the base enumeration for locationType:

wsdl:propertyReference
A property may be bound to the location specified by another property. When this is done, the text node contains the QName of the referenced property. The interaction of binding scope with property references may produce a loop; if a loop is created, then all properties in the loop are considered unbound. What is intended to happen is the creation of a chain, where the storage location of several properties is specified to be the same, because they share a value for a particular binding, operation, or message. For instance, to bind the failure destination feature's failure destination property to the message addressing feature's response address property, one might say <wsdl:simpleProperty name="faildest:failure-destination" locationType="wsdl:propertyReference">address:response-address</wsdl:simpleProperty>. In order for this property to be considered bound, however, a binding that resolves to a real location for the response address property MUST be in scope. Note that it is an error for a service description to leave a required property unbound.
wsdl:protocol
When a property is bound to a protocol, it is effectively being bound to some protocol information that is perhaps not usually visible at the application level. Examples are binding of IP source and destination addresses, TCP/UDP ports, or elements of the SMTP envelope. This binding style is probably best avoided, when it can be (however, see below in Binding Constructed Properties for an example of creating a pseudo-URI from an open TCP connection, which is a useful means of making explicit the implicit addressing semantics of an HTTP connection).
wsdl:protocolHeader
When a property is bound to a protocol header, the text node contains the name of the header. This works for most IETF (TCP/IP application) protocols that use the common text header format. It does not work for application protocols that define binary encodings, such as the various protocols defined using ASN.1 or XDR, which need an alternative mechanism (not explored here).
wsdl:module
When a property is bound to a module, the text node contains an XPath fragment identifying the module by its QName, followed by the identifier of the property's storage location within the SOAP header. That is, supposing that the message-address feature were implemented as a module for a particular binding, then the property binding might look like: <wsdl:simpleProperty name="address:original-source" locationType="wsdl:module" >tns:message-address/address:original-source</wsdl:simpleProperty>.

[[Note: only wsdl:module and wsdl:propertyReference are "properly" in the namespace of WSDL. protocol and protocolHeader, though, are really, really, really common.]]

This element may appear as the child of wsdl:binding, wsdl:binding/wsdl:operation, wsdl:binding/wsdl:operation/wsdl:input, wsdl:binding/wsdl:operation/wsdl:output, or wsdl:binding/wsdl:operation/wsdl:fault. See Binding Scope, below, for a discussion of how storage location is defined.

Binding Constructed Properties

In some cases, the value of a property does not map well to a single storage location. For those cases, a complexProperty type is provided. It allows the service to specify that the value of a property is to be constructed by manipulating the values of known storage locations in some fashion.

  <wsdl:complexProperty name="QName"? use="enum"?>
    <wsdl:algorithm name="QName">parameters</wsdl:algorithm>
    <choice>
      <wsdl:simpleProperty />
      <wsdl:complexProperty />
      <wsdl:propertyChoice />
    </choice>+
  </wsdl:complexProperty>

The following example is a binding for the original-source property of the message addressing feature, for a synchronous binding such as HTTP. This example also illustrates the wsdl:simpleProperty binding to a locationType of wsdl:protocol.

  <wsdl:complexProperty name="address:original-source" use="required">
    <wsdl:algorithm name="ns:printf-pattern">socket:%1:%2</wsdl:algorithm>
    <wsdl:simpleProperty locationType="wsdl:protocol">IP:Source Address</wsdl:simpleProperty>
    <wsdl:simpleProperty locationType="wsdl:protocol">TCP:Source Port</wsdl:simpleProperty>
  </wsdl:complexProperty>

This particular algorithm is simple substitution of the bits into the pattern, printf style, which should be fairly straightforward. Another algorithm type might be simple concatenation (used for the email binding), in which the consituent locations are specified, concatenated together with the character(s) specified in the text node of the algorithm. Other algorithms are possible. One or two, at least, probably ought to be defined here (this is less a definition, and more of an example).

As the template makes clear (hopefully), a complexProperty may contain simpleProperty elements (as in the example), and complexProperty or propertyChoice elements. A nested complexProperty would occur primarily in cases in which different parts of the property value are constructed using different algorithms.

This element may appear as the child of wsdl:binding, wsdl:binding/wsdl:operation, wsdl:binding/wsdl:operation/wsdl:input, wsdl:binding/wsdl:operation/wsdl:output, or wsdl:binding/wsdl:operation/wsdl:fault. See Binding Scope, below, for a discussion of how storage location is defined.

Selecting Property Bindings

In some cases, it is difficult to assign a single location for property storage, because the locations in use depend upon some processing requirements. propertyChoice specifies a first-non-null algorithm to select from a list of possible storage locations. For instance, a property may be bound, first, to another property (which may be bound, but not contain a value, for instance). It is specified to then fall back to a second property. And failing all that, it may then specify a protocolHeader location.

  <wsdl:propertyChoice name="QName"? use="enum">
    <choice>
      <wsdl:simpleProperty />
      <wsdl:complexProperty />
    </choice>+
  </wsdl:propertyChoice>

Note that selection may not be nested, since the argument is that it's all the same algorithm, so it's all the same list.

A good example of this might be the failure destination property. It could be bound first to the response-address property, with a fallback to original-source, and possibly a final fallback (in the email binding, perhaps) to the value of the protocol header Return-Path. Thus:

  <wsdl:propertyChoice name="faildest:failure-destination">
    <wsdl:simpleProperty locationType="wsdl:propertyReference">address:response-address</wsdl:simpleProperty>
    <wsdl:simpleProperty locationType="wsdl:propertyReference">address:original-source</wsdl:simpleProperty>
    <wsdl:simpleProperty locationType="wsdl:protocolHeader">Return-Path</wsdl:simpleProperty>
  </wsdl:propertyChoice>

This element may appear as the child of wsdl:binding, wsdl:binding/wsdl:operation, wsdl:binding/wsdl:operation/wsdl:input, wsdl:binding/wsdl:operation/wsdl:output, or wsdl:binding/wsdl:operation/wsdl:fault. See Binding Scope, below, for a discussion of how storage location is defined.

Binding Scope

This specification proposes that the elements defined for binding properties may appear at four different levels of the WSDL document:

  <wsdl:binding>
    <wsdl:protocolBinding>
    <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
    <wsdl:operation>
      <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
      <wsdl:input>
        <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
      </wsdl:input>
      <wsdl:output>
        <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
      </wsdl:output>
      <wsdl:fault>
        <!-- ( simpleProperty & complexProperty & propertyChoice )+ -->
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>

This raises the question of scope. The idea behind putting a property binding at the level of a child of the binding is that it is in scope for all operations. The protocolBinding (that is, a reference to external definitions) is defined as the containing scope for properties defined at this level. A property at the level of an operation means that it is in scope for all messages of that operation. Placing it inside a message restricts it to that message only.

When a property binding is redefined in a more restricted scope, it overrides the previous definition. It does not add to the definition, it does not fallback to the previous definition. It overrides it. This can cause interesting loops for careless service describers making use of the propertyReference location type, so it requires care, especially since leaving a required property unbound is considered to be an error.

Module Definition

One of the standard means of binding anticipated in SOAP 1.2 is to a SOAP header. In order for this to work nicely, the header needs to be defined in the WSDL. We therefore propose the addition of a wsdl:module element, with characteristics more or less similar to the existing part element.

  <wsdl:module name="NCName" uri="anyURI" type="QName"? element="QName" />

The module is defined by reference to a type or element (like part) in a schema (imported or embedded). This definition will define a header, which will be a part of the message. Each property identifies its own location through a modified XPath-y dealie thing, mentioned above.

This is not terribly satisfactory, I'm afraid.

Open Issues

Robust references
References in a WSDL to an external definition are not robust in this draft. Use of the location attribute needs replacement with something more general.
Value space of use attribute
The use attribute has four values: fixed|required|optional|prohibited. A case can be made that the only place where "fixed" should be used is in a protocol/feature/mep binding (the external bit). A similar case can be made that the only place where "prohibited" should be used is in a service definition (inside wsdl:binding, that is). Should this restriction be made?
Fixed values for properties
The suggestion has been made that some services may wish to define a fixed value (not just a fixed storage location) for certain properties. This draft doesn't offer that option. Should it be offered? If it is, should it be possible to specify "must contain" sorts of fixed values, rather than the whole of the fixed value? Or "must not contain"?

Amelia A Lewis
Last modified: Wed Oct 30 13:35:06 EST 2002