How do I measure how busy a service is and how much work is queued up for later processing?
There's no single place where you can go to see all of the work items being processed by a service or a distributed system. For example, work may be queued up in a variety of locations.
You can get a rough sense of the workload by fronting the machine with a monitoring service, such as you might see in a reactive load-balancer configuration. This gives you an approximation by inspecting the incoming requests and by examining the state of the system. The quality of the approximation depends on how much data you collect and how well your heuristic predicts reality based on that data. It turns out that some of the extremely simple heuristics for measuring work, such as the one used in round robin load-balancing, are actually hard to beat without a lot of data and sophisticated processing.
Next time: Shutting Down Service Hosts
Earlier this week the W3C HTML working group published a list of design principles for working on HTML 5. HTML isn't strictly relevant for a web services programmer but I figured that there was sufficient overlap that many people would find this work interesting. Here's the list of principles, although you'll have to follow the earlier link if you want additional descriptions.
Although not the intention, most of these principles turn out to apply equally well for the world of web services. DOM Consistency, Media Independence, and Accessibility don't map so well because most services take the separation between content and presentation to a logical extreme and essentially only deal with content. It's not that these problems don't exist in applications anymore but that the cause and solution have been punted to other parts of the system. Paving the Cowpaths comes up less frequently because usage errors tend to be scrutinized and rejected rather than tolerated, preventing alternative, illegal formulations from becoming widespread.
How do I supply additional security tokens beyond those needed to sign and encrypt the message? How do I use those tokens on the service?
The additional security tokens are configured through the binding. The client binding needs to be configured with the list of tokens that should be sent to the service. The service binding needs to be configured with the list of tokens that it should expect to receive and authenticate.
The tokens are then scoped to either a single operation or all of the operations on an endpoint. This leads to multiple buckets of tokens on the security binding element.
The tokens are authenticated at the service, and once in your service code you can enumerate them from OperationContext.Current.SupportingTokens.
Next time: Request Queues
One of the least pleasant chores of getting Orcas everywhere has been cleaning out the old versions of software. If you've just been trying out the framework in the past, then it's not too bad. I've been using Visual Studio 2008 betas everywhere in addition to the framework. All three of the machines I've upgraded so far have needed some manual intervention. Visual Studio has dozens of components that are part of the typical install. After uninstalling a beta, some of the individual component uninstallers might not have finished successfully. That can usually be fixed by removing those components explicitly. This list gives the order components should be removed if any of them are left around. I haven't needed anything more drastic yet then running the individual uninstallers.
What does adding an identity to a service endpoint do in configuration? When I tried it, nothing happened.
The questioner is asking about supplying an endpoint identity in the configuration of a service. Here's the configuration element we're talking about, with some considerable editing to keep the example simple.
<service> <endpoint address="..." binding="..." bindingConfiguration="..." contract="..."> <identity> <servicePrincipalName value="name" /> </identity> </endpoint></service>
This configuration on the service doesn't actually change any runtime behavior. Clients will connect and function properly regardless of what the setting says. Instead, this value is used when advertising the service in metadata. Clients are suggested to use the advertised service identity unless someone comes along and supplies a different identity for the client configuration.
That means you shouldn't just make up a value for the service configuration. The service runs with a particular identity and putting a value here does not change what that identity is. Either make sure the configuration matches the service or don't include this value to avoid tripping up clients that make use of metadata.
Next time: Using Supporting Tokens
The documentation for behavior, binding element, and binding extensions in configuration says that using strong names to register types is recommended. Each time I build, the assembly version gets incremented, which changes the strong name. How can I develop an extension without having to change configuration files all the time?
The simplest solution I've heard for this problem is to stop incrementing the assembly version for development and instead use the file version. Assemblies have two versions: the assembly version, which is used by the framework for strong names, and the assembly file version, which is used by the file system but not by the framework. Incrementing the file version lets you track changes without having to update configuration files for every build. You can still change the assembly version for released builds since that should happen less frequently than each compile.
Next time: Advertising Identity on the Server
The official release of the .NET Framework 3.5 took place Monday morning. As part of the download you get the new versions of WCF and WF, LINQ, and other additions to the framework as well. You'll also get the first service packs for the 2.0 and 3.0 framework versions that include all of the fixes since those releases.
Here are links to the downloadable installer as well as some other material that has been released in the last few days.
How does a DataContract type get initialized on the server? When I change the constructor for the type, nothing happens.
Older serializers relied on calling the parameter-less constructor to initialize the type when deserializing data. Data contract types have all of the data members initialized to the default values without a constructor being called. However, you can still introduce callback hooks into the serialization process by decorating methods on your data contract type with attributes. Here's a sample program that shows you exactly what goes on.
using System;using System.ServiceModel;using System.ServiceModel.Channels;using System.Runtime.Serialization;[DataContract]public class Data{ [DataMember] public int a; [OnDeserialized] void OnDeserialized(StreamingContext c) { Console.WriteLine("OnDeserialized: {0}", a); a = 1; } [OnDeserializing] void OnDeserializing(StreamingContext c) { Console.WriteLine("OnDeserializing: {0}", a); a = 2; } [OnSerialized] void OnSerialized(StreamingContext c) { Console.WriteLine("OnSerialized: {0}", a); a = 3; } [OnSerializing] void OnSerializing(StreamingContext c) { Console.WriteLine("OnSerializing: {0}", a); a = 4; }}[ServiceContract]public interface IService{ [OperationContract] void Method(Data d);}public class Service : IService{ public void Method(Data d) { Console.WriteLine("Method: {0}", d.a); }}class Program{ static void Main(string[] args) { string address = "http://localhost:8000/"; Binding binding = new BasicHttpBinding(); ServiceHost host = new ServiceHost(typeof(Service)); host.AddServiceEndpoint(typeof(IService), binding, address); host.Open(); ChannelFactory<IService> factory = new ChannelFactory<IService>(binding); factory.Open(); IService proxy = factory.CreateChannel(new EndpointAddress(address)); Data d = new Data(); d.a = 5; proxy.Method(d); factory.Close(); host.Close(); Console.ReadLine(); }}
You can try running the program to see the value of the data member at various points in time. If you're still confused, here's exactly what's going on.
Next time: Keeping up with Extension Versions
Here are a couple of quick news items that weren't long enough to get a post of their own.
Orcas: Earlier this month Somasegar announced that the final release will be out before the end of November. Within a few weeks of the release I'll try to go over all of the new WCF messaging features that are available in .NET Framework 3.5.
Oslo: The new web services initiative for the future was announced last month at the Microsoft SOA conference. Dana Gardner produced an interesting podcast earlier this week if you want to listen to some of the industry analysis that is taking place.
Two TechEds in One: The US version of TechEd is splitting into separate conferences for developers and IT professionals. Both conferences take place next year in Orlando again during June. I haven't thought about whether I want to go to one or both yet.
Message replay is an attack where a message is presented to a processor more than once in the hopes of fooling the processor into taking some action. One protection against message replay and other timing-based attacks is to have the sender timestamp messages. Security timestamps are only valid for a limited window of time, typically represented by a creation time and an expiration time. The processor may declare that messages have a limited lifetime, which can be checked by using the security timestamp.
For such a scheme to work though, the sender and receiver have to agree on what time means. Since the two sides don't share a common clock, they need to each have a clock and those clocks need to agree on the current time to a certain precision. It's impossible to make two clocks exactly agree and there's some threshold after which you have to assume that the clocks are measuring two different times. The difference between the clocks is called the skew and the threshold is called the maximum allowed clock skew.
When checking creation and expiration times, the maximum clock skew becomes a factor because it determines whether two times might be the same. Here are the interesting checks for a security timestamp.
This clock skew is a configurable setting on the SecurityBindingElement through the local client settings or local service settings. Changing that value changes the tolerance for comparing times. Since the default is several minutes, you don't normally need to worry about this unless your computer clock is quite unreliable.
Next time: Serialization and Types
After six weeks of comments and editing the primer on WS-Policy 1.5 that I mentioned earlier has been published by the working group. The primer is an explanation of how to use policy with web services along with best practice guidelines for policy authors. These are published as two separate documents on the W3C web site:
I'd recommend reading these if you are writing policy expressions by hand, writing software that deals with policy expressions, or defining your own policy assertions for other people to use.
Exciting developments in the world of network traffic capture and protocol analysis. Microsoft Network Monitor has a new companion program that lets you take network captures without having to install any software ahead of time. It even runs off of a file share or USB key. I've been using it recently to collect traces when people ask me to help figure out why their web service doesn't work.
The program is still experimental but you can get a copy by joining Microsoft Connect. If you go to the available connections page, sign in, and pick the Network Monitor 3 connection, you'll be able to get the One Click Capture beta from the Downloads section.
You'll still want a normal installation of Network Monitor to look at the capture output but you can do that on your machine without having to install the software everywhere you want to take a capture.
Next time: Controlling for Clock Skew
Obviously WSDL and XSD are two entirely different description languages, but I was looking at the outputs of the old wsdl.exe and xsd.exe programs recently to see how they differed. They turned out to generate data type classes that were pretty much the same. Starting with a description that was equivalent to the following data contract, I ran both of the programs.
[DataContract]public class Data{ [DataMember] public int a; [DataMember] public string b; [DataMember] public List<XmlElement> c;}
Going through xsd.exe gave me a data type that looked like this (I've deleted some of the surrounding code for clarity):
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.312")][System.SerializableAttribute()][System.Diagnostics.DebuggerStepThroughAttribute()][System.ComponentModel.DesignerCategoryAttribute("code")][System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://schemas.datacontract.org/2004/07/")][System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.datacontract.org/2004/07/", IsNullable = true)]public partial class Data{ private int aField; private bool aFieldSpecified; private string bField; private System.Xml.XmlElement[] cField; public int a { get { return this.aField; } set { this.aField = value; } } [System.Xml.Serialization.XmlIgnoreAttribute()] public bool aSpecified { get { return this.aFieldSpecified; } set { this.aFieldSpecified = value; } } [System.Xml.Serialization.XmlElementAttribute(IsNullable = true)] public string b { get { return this.bField; } set { this.bField = value; } } [System.Xml.Serialization.XmlArrayAttribute(IsNullable = true)] [System.Xml.Serialization.XmlArrayItemAttribute(Namespace = "http://schemas.datacontract.org/2004/07/System.Xml")] public System.Xml.XmlElement[] c { get { return this.cField; } set { this.cField = value; } }}
Going through wsdl.exe gave me a very similar data type except for two differences.
The output of the two programs for data types was interchangeable after taking into account these two differences. All of the surrounding code was completely different but I happened to just need the data types and not the proxy classes. This doesn't hold for types that use the SOAP encoding style though. In that case, wsdl.exe uses new behavior that's not present in xsd.exe.
Next time: Network Monitor
MIX 2008 is returning to Las Vegas during March 5th through 7th of next year. Although it seems ridiculously early to be talking about registration four months ahead of time, past experience has shown that the MIX events can sell out well in advance. It's probably a bad idea to wait until the week or even month before the show before signing up if you want to be guaranteed a spot. We'll have several sessions there about web service development that will be certain to please many of you.
How do I set the user principal name that the client will use when calling the service?
The user principal name can be set through either code or configuration, and it's considered a part of the endpoint address used by the client. That means that physically you'll find the user principal name and the description of the endpoint collocated.
In configuration that looks like:
<client> <endpoint address="..." binding="..." bindingConfiguration="..." contract="..." name="..."> <identity> <userPrincipalName value="name@address.com" /> </identity> </endpoint></client>
And, in code that looks like:
EndpointAddress address = new EndpointAddress( "...", UpnEndpointIdentity.CreateUpnIdentity("name@address.com"), null);
Next time: Differences Between WSDL and XSD
Rather than talking about the solution to one specific question, today's article is about asking good questions. I see a lot of requests for help that only talk about what happened in the end. The last thing that went wrong probably isn't the source of the problem. It's much more likely that the first thing that went wrong is what caused all of the trouble. It's almost impossible to guess the initial cause of an error if all you can see is what didn't work in the end. That's why it's so useful to use mechanisms like tracing that record all of the information you have about an error for later analysis.
Here are a few error messages that are almost certain not to be what actually caused the problem.
The socket connection was aborted.
Resolution: Stop doing whatever is calling abort on the socket. The socket can't send data if you abort it.
The connection was closed unexpectedly.
Is this a bug? No, it probably was totally unexpected for that connection to be closed.
The pipe has been ended.
This is another case where it's extremely likely that the error message is in fact correct.
A call to SSPI failed.
Resolution: Find out why the call failed. This is usually mentioned at or near the same time as this message. If you have to guess, then it's probably because either the client or service was configured with the wrong identity.
Next time: Setting a User Principal on the Endpoint
Two new drafts came out of the Basic Profile working group last week. For those not familiar with Basic Profile, it's a subset of some of the core web service specifications along with guidelines for using those specifications in an interoperable fashion. There are two drafts being worked on because Basic Profile 1.X represents the older track of SOAP 1.1 web services and Basic Profile 2.X represents the newer track of SOAP 1.2 web services. The two drafts that came out are for Basic Profile 1.2 and Basic Profile 2.0. All of the materials are available on the WS-I website.
Since these are drafts, comment periods are open for both of these profiles.
What are the best practices for building retry logic around network transport failures?
Let's define some terms first so that we have a common language for communication. I'll say that "retry logic" is any automatically applied compensation activity that replays the same messages to either the same or a different destination. Also, I'll say that a "network transport failure" is any delivery or communication failure while attempting to transmit an application message or an infrastructure protocol message. With that out of the way, there are two places where you could attempt to handle transport failures.
Regardless of the location, the retry logic for a network transport failure is going to look fairly similar.
Next time: A Call to SSPI Failed
How can I find out whether my service is running in ASP.NET compatibility mode?
Why do you need to detect at runtime whether you're running in compatibility mode? As I've said before, compatibility mode is something that the odd and rare service takes advantage of to get one of the few features that are not available in the standard pipeline. If you care about compatibility mode, then it's very likely that your service will simply not work without it. That's one of the reasons for decorating your service with the AspNetCompatibilityRequirements attribute. It frequently makes sense to prohibit compatibility mode and it sometimes makes sense to require compatibility mode, but it almost never makes sense to optionally allow compatibility mode. This decision should be very intentional.
If you do need to check for compatibility mode at runtime though, then you can use the AspNetCompatibilityEnabled property of ServiceHostingEnvironment.
Next time: Custom Transport Retry Logic
I have a one-way operation that processes requests and can sometimes fail. When the operation fails, the client receives a fault notification. How can I make the operation ignore the bad requests and not send back a fault notification?
This question indicates some confusion over what it means to be a one-way operation. There are actually several different concepts that you could label as one-way.
As you get further down the list, the definition of one-way becomes more encompassing. The first type of one-way prevents sending normal application data but permits sending an operation response and infrastructure messages. The second type of one-way prevents sending any type of application-level response but permits sending infrastructure messages. The third type of one-way prevents sending any kind of message.
If a fault notification is getting back to the client, then we know that the question is implying the first type of one-way operation. That's the only type that permits returning an exceptional application response. Changing the service to use one of the later types of one-way operations would prevent those fault notifications from being returned.
Next time: Detecting ASP.NET Compatibility