Columbo
Columbo

Reputation: 193

Writing a generic WCF service client config/endpoint checker?

I have a client application that consumes a number of services. It's not always immediately obvious when a service is down or incorrectly configured. I own the service side code and hosting for most of the services, but not all of them. It's a real mixed bag of client proxies - different bindings (basichttp/wshttp/nettcp), some have been generated using svcutil.exe, while others are made programatically with ChannelFactory where the contract is in a common assembly. However, I always have access to the address, binding and contract.

I would like to have a single component in my client application that could perform a basic check of the binding/endpoint config and the service availability (to show in some diagnostic panel in the client). As a minimum I just want to know that there is an endpoint at the configured address, even better would be to find out if the endpoint is responsive and supports the binding the client is trying to use.

I tried googling and was surprised that I didn't find an example (already a bad sign perhaps) but I figured that it couldn't be that hard, all I had to do was to create a clientchannel and try to open() and close() catch any exceptions that occur and abort() if necessary.

I was wrong - in particular, with clients using BasicHttpBinding where I can specify any endpoint address and am able to open and close without any exceptions.

Here's a trimmed down version of my implementation, in reality I'm returning slightly more detailed info about the type of exception and the endpoint address but this is the basic structure.

public class GenericClientStatusChecker<TChannel> : ICanCheckServiceStatus where TChannel : class
{
    public GenericClientStatusChecker(Binding binding, EndpointAddress endpoint)
    {
        _endpoint = endpoint;
        _binding = binding;
    }

    public bool CheckServiceStatus()
    {
        bool isOk = false;
        ChannelFactory<TChannel> clientChannelFactory = null;
        IClientChannel clientChannel = null;

        try
        {
            clientChannelFactory = new ChannelFactory<TChannel>(_binding, _endpoint);
        }
        catch
        {
            return isOk;
        }

        try
        {
            clientChannel = clientChannelFactory.CreateChannel() as IClientChannel;
            clientChannel.Open();
            clientChannel.Close();
            isOk = true;
        }
        catch
        {
            if (clientChannel != null)
                clientChannel.Abort();
        }
        return isOk;            
    }
}

[Test]
public void CheckServiceAtNonexistentEndpoint_ExpectFalse()
{
    var checker = new GenericClientStatusChecker<IDateTimeService>(new BasicHttpBinding(), new Endpointaddress("http://nonexistenturl"));
    // This assert fails, because according to my implementation, everything's ok
    Assert.IsFalse(checker.CheckServiceStatus());
}

I also tried a similar technique with a dummy testclient class that implemented ClientBase with the same result. I suppose it might be possible if I knew that all my service contracts implemented a common CheckHealth() method, but because some of the services are outside my control, I can't even do that.

So, is it even possible to write such a simple general purpose generic service checker as this? And if so how? (And if not, why not?)

Thanks!

Upvotes: 2

Views: 1186

Answers (2)

ErnieL
ErnieL

Reputation: 5801

Have you looked at WCF Discovery?

WCF Discovery allows a client to search for a service based on different criteria including contract types, binding elements, namespace, scope, and keywords or version numbers. WCF Discovery enables runtime and design time discovery. Adding discovery to your application can be used to enable other scenarios such as fault tolerance and auto configuration.

For a first attempt, you could query the endpoint to see if it supports the expected contract.

The big benefit is that you can have the client “discover” which service it wants to talk to at runtime. Which removes a lot of the client side configuration errors that you are likely used to seeing.

Upvotes: 1

Mike Perrenoud
Mike Perrenoud

Reputation: 67918

You need to check out SO-AWARE. It is a web service management tool that can manage SOAP or REST WCF-based service across your organization. Further it has a Test Workbench!

Here are a couple of videos that show it off too:

To put it in perspective, this is so complex that these people make a living doing it, I don't think it's something you want to realistically build on your own.

Upvotes: 0

Related Questions