Keith and I have spent the last 3 weeks hammering through the low-level WSE 2.0 programming model: everywhere we find a Uri we change it to an EndpointReference. All message sending and receiving is EndpointReference centric. As someone at work remarked "It's the new URI".
If you haven't read through the WS-Addressing specification, here's a quick summary of what EndpointReferences are and how they are processed.
Every EndpointReference contains a single Address and, optionally, ReferenceProperties. When serialized into a message, the Address becomes the <wsa:To> header and every item in the ReferenceProperties becomes a header in the <soap:Header>. The Address is the core and represents a role; it may also be a physical address.
The primary WS-Addressing constructs of Destination, From, ReplyTo and FaultTo are all represented as EndpointReferences. When sending a message, the Destination is "exploded" as above. The receiver[1] is expected to take one of From, ReplyTo or FaultTo from the message and use them as the Destination for the response, subsequent one-way message or fault:
In the simplest case, WSE treats the Address component of the EndpointReference as a physical address for a service. We don't do any fancy translation of this address to determine a physical address as does the current SOAP Mail sample. Others at work may disagree, but I don't like this approach: it is used in the sample because the WSE 2.0 Tech Preview doesn't separate logical address from physical address.
At the next level, WSE 2.0 treats the Address component as the logical name for a service and then uses it's ReferralCache to map that name to a physical name[2]. This is very similar to the routing process in WSE 1.0 except that the lookup only ever returns a single physical address - it can't define a path for the message. This approach allows a service with a single name to be hosted over multiple transports and it supports the signing of the <wsa:To> header (derived from the Address) since it is now a constant in the message however many intermediaries in may travel through[3].
Finally, developers can specify the transport address directly as part of an EndpointReference construct. This is an extension to the base WS-Addressing specification but it does not affect wire-level interoperability, just the WSE programming model.
The change to EndpointReference is reflected throughout the programming model - the WS-Addressing headers are now a fixed part of the message and are not handled through the filter chain (yes, we'll still be able to talk to "legacy" HTTP Web Services that don't understand the Addressing headers provided that they follow the SOAP processing model). Building around EndpointReference has also allowed us to introduce a more powerful message dispatching process. The Tech Preview dispatches messages based on the <wsa:To> header and the <wsa:RelatesTo> header (for responses); for the 2.0 release, registration of receivers and dispatching is now fully EndpointReference based (including ReferenceProperties) and this opens new possibilities for developers in deciding how to handle incoming messages.
Moreover, the SoapSender/SoapReceiver programming model of the Tech Preview is now underpinned by a new, fundamental layer that offers another programming model (for those brave enough to use it) that is very simple and much more consistent across all transports. Plumbing a transport for a messaging product (such as MSMQ or MQSeries) that is typically unidirectional should be much easier: I'll be testing this theory out this week with Kevin's MSMQ transport, after which it will be time to check-in :-)
[1] Note that, for technical reasons, ReplyTo and FaultTo are currently ignored if you write your Web Service using the .NET Framework ASMX infrastructure instead of the WSE Messaging programming model.
[2] Benjamin may not entirely approve of this scheme, but we're some way off from solving the binding problem through either WSDL or WS-Policy.
[3] The current SOAP Mail sample has a problem in this regard as it tries to overload the <wsa:To> header as both role and transport address. It therefore needs to modify the transport address in order to unpick the soap.mail scheme and produce an http address to forward the message to: strictly speaking the <wsa:To> header should be modified to reflect this new address but doing so would break the signature.
Please tell me you have done something to make it easy to convert between the various EndpointReference types. Something like
new EndpointReference( request.Context.ReplyTo)
The 2.0 TP did not make this easy and so the places where you did allow an EndpointReference (like in the constructor of SoapClient) were actually hard to use.
With the removal of the Address filter is there still an extensibility/customization point in case we need something different than what is built into WSE 2.0+
Finally, you mention using the full EndpointReference (including ReferenceProperties) in dispatching messages. Hopefully it's not just a hard and fast equality comparison. For instance, I may very well be implementing a gateway and want to use part of the ReferenceProperties to do my own application dispatching. (For instance, the WS-Addressing paper uses as an example fabrikam:CustomerKey. I would not want to have to have one receiver per customer. I might want one receiver that then does further dispatching based on CustomerKey.)
Posted by: Dave Angers at December 3, 2003 12:33 PM