Features and Properties musings

In fulfillment of my action item for the group, here is another take
at the whole features and properties thing.  Please let me know if
this clears up, or fails to clear up, any confusion you might have
about the f&p patterns (that's "pattern" in the "design pattern"
sense, not the "message pattern" sense... ;)).  It's a little bit
long, but since there has been so much apparent confusion over this
topic I've tried to be as clear as possible in describing the
mechanism.  If this isn't clear enough let me know what's causing you
problems and I'll edit this document appropriately.

1. Defintions

A FEATURE is a well-specified contract, named with a URI, of some sort
of semantic between parties involved in a web service interaction.
This might be as abstract as "you agree not to sue me if the contents
of this interaction become public", or as concrete as "all integer
values of '3' in the infosets moving back and forth will be replaced
with '5's".  A feature, when it involves any sort of dataflow between
nodes, is typically described as a distributed state machine with
state represented as PROPERTIES (see below).

A SOAP MODULE is a SOAP-specific implementation of a feature, usually
using SOAP headers to convey metadata, implementation mechanics, or
both.  A SOAP BINDING is a specification for how to move SOAP messages
from node to node across a particular underlying transport mechanism.
Bindings may also implement particular features - as an example, a
binding over HTTPS might natively implement a "secure channel"
feature.  Both modules and bindings are named with URIs.

Nothing *requires* authors to build separate feature specifications
for their bindings and modules.  You could certainly build a module on
its own, and just describe the semantics of the SOAP extension.  But
if those semantics are something one might also implement via a
binding or another future extension, it's probably a good idea to do a
feature spec as well.

A PROPERTY is a well-defined piece of data, named with (surprise
surprise) a URI, which is somehow used in the execution of a feature
(or multiple features).  As an example, we might have a "conversation"
feature which associates multiple messages into a single flow.  Such a
feature might define a "conversationID" property which is used to
correlate messages together in the abstract state machine description.
The "conversationID" property might be represented on the wire in
various ways, depending on how the feature is concretely realized.  If
we were running this feature over HTTP, there might be a SOAP module
which mapped the property to a particular SOAP header containing a
UUID.  However if running over a TCP binding, the conversationID might
be implicit in the fact that the connection is persistent, and
therefore have no representation in the envelope at all - in this case
the BINDING would indicate that it implemented the feature.

Note that a property like conversationID would not really be
appropriate to mention in a WSDL, in much the same way that the
"Content-Length" header value for an HTTP interaction wouldn't be
appropriate to specify - it's an implementation detail that might
change for each concrete interaction.  Other properties, however, are
more like the "API" for a feature/module, and these will often appear
in WSDL descriptions.  For instance, a "security" feature might
specify a number of possible encryption technologies, and a property
which indicates the particular one that is in use.

2. Example

Now let's use WS-ReliableMessaging (WS-RM) [2] as another example, but
tweak it a bit as a thought experiment.  I chose this example because
it's a fairly simple specification, and it has the clear potential to
be usefully refactored as I'll describe.

First off, instead of defining the spec monolithically, putting both
the functional (this is what the spec does) and implementation (this
is the exact SOAP mechanism by which it does it) details in the same
document, let's posit that it was built as follows (in line with the
SOAP 1.2 extensibility section) instead:

[please note - all URIs in this example are contrived for easy typing
 and have no bearing on the real world.  Also, syntax may not be
 precise, my apologies]

First, we have a feature definition, with the URI
"http://features.com/reliability/".  This would describe, in english,
what reliability in this particular context means.  This spec probably
wouldn't describe things like sequence numbers for individual
messages, since that's an implementation detail, but WOULD talk about
a sequence identifier for an entire message sequence, and would define
a property for that, since that's something that the application needs
to know about (i.e. I am sending a message - is this message the first
one in a new sequence, or the next one in an existing sequence?).
That property might also be useful when

Second, a related SOAP module definition, with the URI
"http://modules.com/reliabilityModule".  This module would clearly
implement the "http://features.com/reliability/" feature, and the spec
would describe the same headers and processing rules currently
described in the SOAP-specific areas of WS-RM.

OK, so now we have a new set of specs.  How might this affect our WSDL?

Well, now a given PortType can talk ABSTRACTLY about the fact that it
requires a certain level of reliability:

<wsdl:interface>
  <wsdl:feature uri="http://features.com/reliability/"
                required="true"/>
  <wsdl:property uri=".../wsrm/DeliveryAssurance">
    ExactlyOnce
  </wsdl:property>
</wsdl:interface>

In other words, the reliability feature is required, and a value for
the DeliveryAssurance property has been specified.  We could have just
specified the property value and not the feature, but marking the
feature required forces the processor to ensure that there is some
concrete implementation of said feature.

The SOAP-over-http binding for this service can make clear that the
reliability module is available, and tweak additional parameters if
desired:

<soap:binding url="http://soap-over-http">
  <soap:module uri="http://modules.com/reliabilityModule"/>
  ...
  <wsdl:property uri="AcknowledgementTimeout">50000</wsdl:property>
  ...
</soap:binding>

So if you're building a client which uses this binding, we know that
even though the SOAP http binding doesn't natively support the
reliability feature, we have a module which does, so we're good with
respect to our requirement specified earlier.  And we set a property
which is specific to the module implementation of the feature; by
virtue of understanding the module URI, we agree to abide by its
specification, and that includes knowing what to do with property
values like this.  In real code, this value might end up being
passed to some API, or written into some generated code in an
appropriate place.

OK, cool.  Now, let's add a binding over Java Message Service (JMS).

<soap:binding uri="http://mybindings.com/JMSBinding">
  ...
</soap:binding>

We presume that the binding spec for this ficticious JMS binding has
been written to indicate that it natively provides support for the
reliability feature.

That's all we need to know that the feature requirement is satisfied,
because we know how the JMS binding works (otherwise we wouldn't be
able to understand that binding at all and processing it would be an
error).  If the JMS binding exposed other properties which were
settable at description-time, we could have set values/constraints on
those as well.

3. Summary

Various kinds of semantic contracts, spanning the spectrum from
abstract to concrete, can be described as FEATURES.  If a feature has
a concrete realization via wire-level mechanics, said realization will
be acheived either via a SOAP MODULE or a BINDING - in both cases, the
specification for the component (module/binding) will indicate that it
satisfies the feature.  Features use PROPERTIES as well-defined (and
shareable) names for relevant bits of data used to control or
implement the specified semantics, and properties may appear in
various forms on the wire.

4. Open Issues

* Do we need the ability to mark properties as required?  If a feature
  is marked as required, then the contract for that feature implies
  that the software knows what to do with any property values
  specified therein... so I'm leaning towards no.

* The ever-exciting QNames vs. URIs tension.  The SOAP spec currently
  specifies properties as named with URIs.  The WS-Policy spec (and
  common sense when writing XML) also allows QNames.  All the usual
  context applies here - RDF assertions vs. easy XML serializations,
  etc.  This issue will likely follow the general trend, however that
  shakes out.

* Policy allows for "combinators" such as "choose one" or "all", which
  are a nice way of expressing higher-level semantics combining
  mulitple policies (or features/properties).  Do we want something
  like that?  (see next issue)

* Properties and features are a great deal like WS-Policy, though
  there are differences.  Merging the two ideas would seem to be a
  good thing.  Some specs already use Policy assertions to control the
  behavior of SOAP extensions - this is identical to using properties
  to control the behavior of SOAP modules, except without the added
  abstraction layer of a feature specification which can be
  implemented in multiple ways.  It would seem that the ideal thing
  would be to settle on a single terminology, and use the union of the
  available functionality in both design patterns.  Unfortunately,
  features and properties are already fixed in the SOAP 1.2
  specification and the MTOM extensions, and WS-Policy is already
  being used in several extant specs, so the terminolgy merge might be
  hard.  Barring that, it seems like some solution using Policy-style
  syntax for talking about features and properties might be forged.
  The important bit, of course, is to get the extension spec authoring
  community to consider their abstractions carefully when designing
  their specs.

Thanks,
--Glen

[1] http://www-106.ibm.com/developerworks/library/ws-polfram/
[2] http://www-106.ibm.com/developerworks/webservices/library/ws-rm/

Received on Thursday, 23 October 2003 17:07:54 UTC