Exposing additional service metadata with WS-Discovery in WCF 4.0

WS-Discovery is not only a mechanism for discovering service endpoint addresses at runtime, but also a way to query for specific service information and metadata. If you look at it from another standpoint, WS-Discovery provides access to a decentralized short-lived service catalog that is available as long as the services are running. It is decentralized because every service expose their own metadata, unless you use a WS-Discovery managed proxy, which act as an intermediary and central location for service discovery. It is short-lived because it is only available when the service is running, and it is not something that clients could use at any time.

With all this, I am not saying that WS-Discovery is a good replacement for a service repository, which actually provides opposite capabilities, a centralized storage for service metadata at design time that supports full rich querying.

However, they both complement very well each, the service can configure itself from the service repository, and expose metadata and runtime information to clients through WS-Discovery.

There are two types of metadata attributes or extensions that you can configure in the “endpoint” discovery behavior,

<endpointDiscovery enabled="true">
    <scopes>
      <add scope="urn:CRM"/>
    </scopes>
    <extensions>
      <Owner>Pablo Cibraro</Owner>
      <Metadata>http://locahost:8080/?wsdl</Metadata>
    </extensions>
</endpointDiscovery>

Scopes, which represents “URI”s and can be used by clients to filter the discovery results when sending the discovery probes. For example, in the configuration above, a client could only be interested in a service that provides a “urn:CRM” scope, so this service will match that probe.

On the client side, the WCF client can specify the “scopes” as part of the “FindCriteria” argument passed to the DiscoveryClient,

var discovery = new DiscoveryClient(new UdpDiscoveryEndpoint());
 
var criteria = new FindCriteria(typeof(IHelloWorld));
criteria.Scopes.Add(new Uri("urn:CRM"));
 
var discoveryResponse = discovery.Find(criteria);

Then, you have “extensions”, which are xml elements that provide additional information about the service. In the given example, the extensions are used to provide information about the service owner (the developer), and the service metadata endpoint, but you could extend this to any service metadata or documentation.  

The service metadata endpoint (or MEX endpoint in WCF) is useful here as part of the extensions because WS-Discovery only returns the "service” endpoint address as part of the response for the probe messages.

The extensions are available on the client side as part of the discovery response message in the found endpoints.

var discovery = new DiscoveryClient(new UdpDiscoveryEndpoint());
 
var criteria = new FindCriteria(typeof(IHelloWorld));
 
var discoveryResponse = discovery.Find(criteria);
 
var address = discoveryResponse.Endpoints.First().Address;
 
Console.WriteLine(discoveryResponse.Endpoints.First().Extensions);

No Comments