Over time, services are subject to change in response to new business requirements in the enterprise. Often these changes can be internal to the service and are invisible to client applications. However in some cases the service interface changes in a way that breaks consumers that depend on a stable service contract. In such cases it is necessary to publish a new version of the service while maintaining the old version until all service clients have transitioned to the new interface. And since the development lifecycle of client applications is rarely in sync with the publication of service revisions it may be necessary to deploy parallel versions for extended periods. Therefore a service versioning strategy is a necessity for SOA solutions of even moderate size and complexity. WCF 4 introduces two new mechanisms that can facilitate service versioning.
The first is available through the WCF Routing Service. [1] This allows for a single stable service address through which requests can be routed to different service endpoints. Incoming calls are dispatched to the appropriate service version based on a set of Message Filters. This method provides fine grained content based routing and offers additional features such protocol bridging and error handling.
The Routing Service represents an implementation of the indirect broker pattern. [2] This technique simplifies addressing for the consumer. However this flexibility comes at a cost. It introduces a single access point for all calls made against a set of service versions. This can have a negative impact on performance and will hinder scalability. Additionally the router is obligated to support the highest SLA applied to any of its services.
The second approach involves using the implementation of the WS-Discovery protocol provided in WCF 4. [3] Using this infrastructure a direct broker can be created that allows clients to specify a contract version and access it directly. As will be shown this avoids many of the shortcomings of the indirect broker.
WCF Discovery supports two modes: ad hoc and managed discovery. In ad hoc mode the client sends multicast probes over the network and receives back responses directly from services which match specified criteria. In managed discovery mode services first register with a central Discovery Service. Clients then query the Discovery Service for services with given characteristics.[4]
A service can register with the central service broker and provide detailed information about itself apart from simply defining what service contract it exposes. One mechanism it can use to describe itself is service Scope. This might be used to identify to which subset the service belongs; development or production for example. Another discovery mechanism which allows for a finer-grained search is service Metadata in the form of XDocument data.
Using the metadata feature of WCF Discovery a service can be selected by client applications based on a nearly endless number of criteria. Among them could be the version of the service contract published by a given endpoint. There are a number of approaches to defining this in metadata. Below is an example that has been used in at least one production deployment. It uses what might be called namespace versioning:
[ServiceContract(Name = "ILogging", Namespace = "http://somecompany.com/2009/02/Logging")]
public interface ILogging
{
[OperationContract(IsOneWay = true)]
void LogActivity(ClientActivity clientActivity);
}
When the client probes for a given contract type it also probes for the namespace. The discovery service returns the specific version of the service which is compatible with its implementation. Additionally it returns an address and all binding information necessary for the client to dynamically build a service proxy.
The WCF Discovery Service exposes a single point of entry for client applications in the same fashion as the Routing Service or other indirect broker implementations; this can be a potential bottleneck for high throughput systems. However an increase in call frequency will not impact the Discovery Service as quickly. Queries from a client application can be cached so that subsequent calls are made directly against the target service. In the case of the Routing Service, call volume increases in direct proportion to calls made against the services it fronts.
[1] Routing Service – How To: Service Versioning
http://msdn.microsoft.com/en-us/library/ee816862(VS.100).aspx
[2] Integration Topologies
http://msdn.microsoft.com/en-us/library/ms978718.aspx#intpatt-ch05_broker
[3] Web Services Dynamic Discovery (WS-Discovery) Version 1.1
http://docs.oasis-open.org/ws-dd/discovery/1.1/pr-01/wsdd-discovery-1.1-spec-pr-01.html
[4] WCF Discovery
http://msdn.microsoft.com/en-us/library/dd456782(VS.100).aspx
See also Implementing a Service Registry for .NET Web Services by Boris Lublinsky
http://www.infoq.com/articles/net-service-registry