WCF service access for redunancy (failover) - wcf

I'm looking for the correct way to have redundancy for a WCF service. I think I'm trying to solve a "infrastructure" issue in code. I'm not up to speed on load balancers but it seems like there should be something like routers to exactly this.
// Cycle through the list of service.
foreach (var uri in InfrastructureInformation.ServiceUris)
{
try
{
using (var client = WcfClientFactory.Create<ServiceClient>(uri))
{
// Do stuff here.
}
}
catch
{
// todo: Do not catch "exception" here. We have to find a better way of doing this.
// Try the next URI.
}
}
Seems like there should be a way to have one URI that I could hit that some "balancer" would hand off to an available service. If one service goes down for maintenance then the balancer would just not give any request to that service.
Now I know about WCF routing and I thought well that's the answer. Just put up a WCF router and have it hand out the connection but what happens if it falls over? Doesn't this give you a single point of failure? I'm looking for something more industrial.

WCF in .NET 4.0 has a routing capability that can be used in a failover scenario like you describe. This WCF sample shows how the built-in RoutingService class can be used for this purpose.

You could have a look at Microsoft Network Load Balancing (aka NLB). Microsoft also mention this in the context of WCF. There is an article on this here.

Related

How to access a Service Reference from JavaScript?

(WCFDS = WCF Data Services 5,backed by Entity Framework, using oData v3, formatted as JSON, served up via IIS7 and protected by Windows authentication.)
The crux is accessing the WCFDS in an authenticated manner from an AJAX call.
To this end, I have a client as an ASP.Net Web Application with Windows authentication set in Web.config and a Service Reference pointing to the WCFDS.
I want to use client-side JavaScript to access the Service Reference. How can I do this?
I thought about creating an aspx page, hosting in the client and direct calls from JavaScript code to this page, which would then retrieve data through the Service Reference - but I'm at a loss over how to expose the full functionality of the Service Reference in this manner (there are dozens of entities).
Can anyone help with advice?
The Windows authorization settings in web.config are not directly related to WCF Data Services, so you probably won't need to set anything there. You WILL need to set your settings up properly in IIS.
There are a number of good articles out there about using Windows authorization over WCF Data Services; in a nutshell you have a wide degree of freedom in how you choose to expose authorization (ranging from filtering out individual entities from a feed to throwing 401/403s).
A couple of good articles to read through:
http://msdn.microsoft.com/en-us/data/gg192997
http://blogs.msdn.com/b/astoriateam/archive/2010/07/21/odata-and-authentication-part-7-forms-authentication.aspx (yes, I know that's forms auth but the auth part of this is entirely orthogonal to what the code looks like in your WCF Data Services)
http://blogs.msdn.com/b/astoriateam/archive/2010/07/19/odata-and-authentication-part-5-custom-httpmodules.aspx
The simplest code you could possibly write would be something along the lines of:
namespace Scratch.Web
{
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ScratchService : DataService<ScratchContext>
{
[QueryInterceptor("Products")]
public Expression<Func<Product, bool>> ProductsAuthorization()
{
if (!HttpContext.Current.Request.IsAuthenticated)
{
return (p) => false;
}
return (p) => HttpContext.Current.User.IsInRole("AllowAccessToProducts");
}
// ...rest of service code...
}
}
Note that everything on the client side is controlled by the browser, so you don't really need to do anything there (the biggest step might be to add the site to Trusted Sites so it doesn't prompt you for your credentials if you're on a domain-joined machine).

Exposing an endpoint as a sub of another endpoint?

I have a WCF service, DummyService. It implements IDummyService and lives on two URIs, http://1.1.1.1/DummyService and http://2.2.2.2/DummyService. I would like to create a routing endpoint such that;
I can hit http://1.1.1.1/RoutingService/DummyService?wsdl and/or http://1.1.1.1/RoutingService/DummyService
This uri appears to just be the dummyservice endpoint, i can build a client proxy, etc.
Any calls get round-robined around
Is there some way to do this without having IRoutingService re-implement DummyService? I want dummyservice to essentially be a plug-in that I can add/remove at runtime.. Can I do this with WCF Routing? Any samples I can reference? I havent been able to find anything on MSDN/Google, but perhaps im asking the wrong way..
This is pretty much exactly what WCF Routing is for.
There is a sample which is part of the WCF/WF samples (info here):
http://msdn.microsoft.com/en-us/library/ee667249%28v=VS.100%29.aspx

Turn off WCF SOAP Service for Maintenance and provide friendly message

I'm hosting some SOAP services with WCF. How can I turn off these services via config for the purposes of maintenance, etc., and provide a friendly message to the service consumer with something like "The service you've requested is down for maintenance."?
You would have to have a second service, that offered the same interface, same methods etc., that would all return that friendly message instead of a real result.
That might get a bit trickier when those service methods don't just return a string but a complex data object - where do you put that "friendly" message??
In reality I think this cannot really be done - since your services typically aren't "seen" by actual people, you cannot just put up an app_offline.htm file or anything like that.
Try to have as little downtime as possible, by e.g. setting up your new version of the service on a new port and testing it there, until you're confident enough to switch over.
With WCF, it's mostly an exercise of updating / copying around the appropriate config, so your service should never really be unavailable for any extended period of time (hopefully!).
If you really must, what you could do, is just have a replacement service that will always throw a FaultContract<ServiceDownForMaintenance> - but then all the clients calling your service would have to know about this and they would have to handle this case and present an error or information message. Your service can't really provide that...
How about this: create a custom ServiceBehavior to intercept my incoming requests to the service. Then, have the custom behavior check a user-defined flag in my config file, something like <add key="IsMyServiceUp" value="true" /> and if that value returns as false then throw a ServiceException with my friendly message and HTTP code of 503 - Service Unavailable.
Does that sound reasonable? Then all I have to do is change the flag in my config file to specify where the service is up or down.
Okay, so I've created a new Custom Behavior that implements IOperationBehavior. In the Validate method, I've got
public void Validate(OperationDescription operationDescription)
{
bool isServiceUp = Boolean.Parse(ConfigurationManager.AppSettings["IsOrderServiceUp"].ToString());
if (!isServiceUp)
{
throw new ServiceException(ServiceErrorCode.Generic_Server_Exception,
ServiceErrors.Generic_Server_Exception,
SoapFaultCode.Server);
}
}
The other implemented methods ApplyClientBehavior, ApplyDispatchBehavior and AddBindingParameters are all empty.
I have decorated one of my service operations with [ServiceStatusValidation] which is the class name of my custom behavior.
When I start the service and navigate to the operation with this decoration, I do NOT get the exception I've thrown. SOAP UI shows nothing as returned in the response pane, and my consuming REST facade gives a generic 400 error with The exception message is 'The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.'.
Any ideas? Should I be doing this logic in one of the other methods that I didn't implement instead of the Validate method?

WCF Service Client Lifetime

I have a WPF appliction that uses WCF services to make calls to the server.
I use this property in my code to access the service
private static IProjectWcfService ProjectService
{
get
{
_projectServiceFactory = new ProjectWcfServiceFactory();
return _projectServiceFactory.Create();
}
}
The Create on the factory looks like this
public IProjectWcfService Create()
{
_serviceClient = new ProjectWcfServiceClient();
//ToDo: Need some way of saving username and password
_serviceClient.ClientCredentials.UserName.UserName = "MyUsername";
_serviceClient.ClientCredentials.UserName.Password = "MyPassword";
return _serviceClient;
}
To access the service methods I use somethingn like the following.
ProjectService.Save(dto);
Is this a good approach for what I am trying to do? I am getting an errorthat I can't track down that I think may be realted to having too many service client connections open (is this possible?) notice I never close the service client or reuse it.
What would the best practice for WCF service client's be for WPF calling?
Thanks in advance...
You're on the right track, I'd say ;-)
Basically, creating the WCF client proxy is a two-step process:
create the channel factory
from the channel factory, create the actual channel
Step #1 is quite "expensive" in terms of time and effort needed - so it's definitely a good idea to do that once and then cache the instance of ProjectWcfServiceFactory somewhere in your code.
Step #2 is actually pretty lightweight, and since a channel between a client and a service can fall into a "faulted state" when an exception happens on the server (and then needs to be re-created from scratch), caching the actual channel per se is less desirable.
So the commonly accepted best practice would be:
create the ChannelFactory<T> (in your case: ProjectWcfServiceFactory) once and cache it for as long as possible; do that heavy lifting only once
create the actual Channel (here: IProjectWcfService) as needed, before every call. That way, you don't have to worry about checking its state and recreating it as needed
UPDATE: "what about closing the channel?" asks Burt ;-) Good point!!
The acccepted best practice for this is to wrap your service call in a try....catch....finally block. The tricky part is: upon disposing of the channel, things can do wrong, too, so you could get an exception - that's why wrapping it in a using(....) block isn't sufficient.
So basically you have:
IProjectWcfService client = ChannelFactory.CreateChannel();
try
{
client.MakeYourCall();
}
catch(CommunicationException ce)
{
// do any exception handling of your own
}
finally
{
ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
{
comObj.Abort();
}
else
{
comObj.Close();
}
}
And of course, you could definitely nicely wrap this into a method or an extension method or something in order not to have to type this out every time you make a service call.
UPDATE:
The book I always recommend to get up and running in WCF quickly is Learning WCF by Michele Leroux Bustamante. She covers all the necessary topics, and in a very understandable and approachable way. This will teach you everything - basics, intermediate topics, security, transaction control and so forth - that you need to know to write high quality, useful WCF services.
Learning WCF http://ecx.images-amazon.com/images/I/41wYa%2BNiPML._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg
The more advanced topics and more in-depth look at WCF will be covered by Programming WCF Services by Juval Lowy. He really dives into all technical details and topics and presents "the bible" for WCF programming.

wcf - transfer context into the headers

I am using wcf 4 and trying to transparently transfer context information between client and server.
I was looking at behaviors and was able to pass things around. My problem is how to flow the context received in the incoming headers to the other services that might be called by a service.
In the service behavior I intercept the the message and read the headers but don't know where to put that data to be accessible to the next service call that the current service might make.
What I am looking for is something like:
public void DoWork()
{
var someId = MyContext.SomeId;
//do something with it here and call another service
using(var proxy = GetProxy<IAnotherService>())
proxy.CallSomeOtherMethodThatShouldGetAccessTo_ MyContextualObject();
}
If I store the headers in thread local storage I might have problems due to thread agility(not sure this happens outside ASP.NET, aka custom service hosts). How would you implement the MyContext in the code above.
I chose the MyContext instead of accessing the headers directly because the initiator of the service call might not be a service in which case the MyContext is backed by HttpContext for example for storage.
In the service behavior I intercept
the the message and read the headers
but don't know where to put that data
to be accessible to the next service
call.
Typically, you don't have any state between calls. Each call is totally autonomous, each call gets a brand new instance of your service class created from scratch. That's the recommended best practice.
If you need to pass that piece of information (language, settings, whatever) to a second, third, fourth call, do so by passing it in their headers, too. Do not start to put state into the WCF server side! WCF services should always be totally autonomous and not retain any state, if at ever possible.
UPDATE: ok, after your comments: what might be of interest to you is the new RoutingService base class that will be shipped with WCF 4. It allows scenarios like you describe - getting a message from the outside and forwarding it to another service somewhere in the background. Google for "WCF4 RoutingService" - you should find a number of articles. I couldn't find antyhing in specific about headers, but I guess those would be transparently transported along.
There's also a two-part article series Building a WCF Router Part 1 (and part 2 here) in MSDN Magazine that accomplishes more or less the same in WCF 3.5 - again, not sure about headers, but maybe that could give you an idea.