The Windows SDK (formerly Platform SDK) is now available in an iteration that supports our Orcas Beta 2 release of the .NET Framework as well as the latest release of Windows Server 2008. Here are the direct downloads to the pieces:
There are a few release notes that you should be particularly aware of.
.Net Framework 3.5 is not in the Windows SDK path
The .Net Framework 3.5 is not in the Windows SDK path. If the .Net Framework 3.5 is installed on a machine, its components (e.g. MSBuild) will not be found in the Windows SDK build environment by default. To workaround this issue, add the following to your path.
On an X86 machine:
C:\Windows\Microsoft.NET\Framework\v3.5
On an X64 or IA64 machine:
C:\Windows\Microsoft.NET\Framework64\v3.5
Some .NET Framework WCF samples do not build or run
The following Windows Communication Foundation (WCF) samples do not build or run correctly in the SDK build environment or Visual Studio 2008:
To workaround this issue:
TechnologySamples\Scenario\DataBinding\WPF
This issue affects only the C# version of the sample. To resolve, remove the following string from client.csproj: <UICulture>en-us</UICulture>
TechnologySamples\Scenario\RestPox
This issue affects both the C# and Visual Basic versions of the sample when running on Windows Vista. The client runs correctly almost all the way through the sample then fails near the end. To resolve the issue, remove the forward slash from the following lines of code:
TechnologySamples\Extensibility\Transport\UdpActivation
No workaround is available at this time.
IIS uses the file extension to register behaviors that take place when a particular address is requested. WCF registers one of these extensions (by default, it's *.svc) to run a build provider that takes care of executing a WCF service for a given URL. I've written about WCF build providers in the past to explain how more file extensions can be mapped to this same behavior. However, another popular request is to get the behavior for executing a service without having a file extension.
Jon Flanders provides a method for executing a service without having a file extension by using URL rewriting to trick IIS. In this case, there is a user-visible URL without an extension that maps to an internal URL with an extension. The build provider uses the internal URL making everything appear to work. I think that this is a clever approach even though URL rewriting is sometimes hard to get working because trying to trick IIS can cause it to confuse the two URLs. I haven't seen a better way of doing this yet though.
Next time: Always Begin with Accept
What does the term ESB- Enterprise Service Bus- actually mean? That question has been the topic of an ongoing debate for several years now that doesn't seem to have any sign of stopping. When I first read about ESBs in 2003, I didn't expect to still be trying to understand them more than four years later. In comparison, there have been other technologies that in the same time frame were introduced, developed, matured, and obsolete. However, it has felt like the definitions are getting closer in spirit if not words. Here is a current selection that I could find (using search to find the pages that were most referenced but possibly not most recent).
BEA defines the ESB:
At the highest level, an ESB provides common communication and integration services for composite applications and shared services in an SOA.
IBM defines the ESB:
An enterprise service bus (ESB) is a pattern of middleware that unifies and connects services, applications and resources within a business.
Oracle defines the ESB:
It provides a much-needed intermediary layer that facilitates data delivery, service access, service reuse, and service management of an enterprise SOA implementation.
Sonic defines the ESB:
An ESB is software infrastructure that simplifies the integration and flexible reuse of business components within a service-oriented architecture.
Tibco defines the ESB:
An enterprise service bus (ESB) is a standards-based communication layer in a service-oriented architecture (SOA) that enables services to be used across multiple communication protocols.
Microsoft has a site that is being put together to provide ESB guidance but dodges the question of definition (the site plays up the ESB means different things to different people angle).
At the end of the day though, the clearest definition of what companies think ESB means comes from looking at the products that they build.
One of the things that happens when a new technology framework is introduced with new patterns and best practices is that people wonder what's going to happen with the frameworks that they use today. When WCF was announced a few years ago, users of Remoting were asking this question a lot. The answer then (I have actual quotes from people) was that the introduction of WCF does not mean that Remoting is dead. A lot of scenarios that were formerly done with Remoting can now be done better with WCF, but Remoting does not go away.
I still see people asking this question, and the answer has not changed. I would not be surprised to see applications continue to come out with support for Remoting, but I would expect that those applications would represent a smaller percentage of the overall market. There are going to be some times when Remoting is actually the preferred choice. Just like we say with ASMX, if you have an existing application that works today with Remoting, then there's no reason that you have to go out and rewrite it. There should be a preference to use WCF in new applications, but there's no reason to do a conversion unless you actually need to make use of the new features.
Remoting also has benefits in some particular scenarios. The fastest standard transport for WCF today is the named pipe transport. Remoting can beat the performance of named pipes if you're communicating between two endpoints within the same process. WCF would be preferable if you want the flexibility to change the scope of the endpoints later or to use a consistent programming model at different scopes, but Remoting is useful if what you care about is performing that scenario as fast as possible.
Next time: SVC Files and Services
I've configured my web site in IIS with multiple bindings but my web service can no longer run because it refuses to start if there are multiple base addresses defined for the same URI scheme. How can I use the same configuration for both my web service and the rest of my web site?
Let's assume that you really do have a need to configure your web site with multiple bindings using the same URI scheme. Defining these multiple bindings is not an unreasonable thing to do. There are several legitimate reasons to publish your web site multiple times with the same scheme so let's look at how to fix the web service.
Obviously, if you don't actually need the multiple bindings, then removing the extra bindings is the simplest way to fix the problem. However, we're assuming that other parts of the web site require multiple bindings. Therefore, what we really need to do is find some way to remove the extra bindings just for the web service.
A direct way to remove the extra bindings without affecting the rest of the web site is to move the web service into its own web site with its own configuration. Then, we can leave the rest of the web site exactly as it is while giving the web service just the list of bindings it needs. However, that doesn't work if we need to use the same configuration for the web service as the rest of the web site. That means we need some indirect way to remove those extra bindings.
Let's assume now that we have no choice but to expose our web service to all the bindings. The part that actually blows up is the construction of the ServiceHost because the host is expecting a single base address per URI scheme. If we could intercept the list of bindings in between the time that IIS gives them to the web service and the ServiceHost is constructed, then we could save the day. There's only one piece of your code that runs during that time: execution of the ServiceHostFactory. That makes the decision easy. You'll create a custom ServiceHostFactory that filters the list of base addresses and everyone will be happy.
Next time: When to Use Remoting
After installing the most recent preview version of Orcas back in July, I noticed that Astoria was not running quite as healthily as it used to. You could say in fact that it was not running much at all. Fortunately, the Astoria team has put out a new CTP to get things working on Beta 2. While the September CTP replaces the older May CTP, it looks like there is not much of a difference in terms of features besides the compatibility fix.
What happens if I don't specify an EndpointIdentity for an EndpointAddress? I'm supposed to provide one for the domain account of my service.
Well, it might work. If you don't explicitly specify an endpoint identity, then by default we'll use host/machinename to construct the service principal name identity (machinename is actually the name of the machine). That may be the SPN that the other side is expecting as well. If it's not, then you'll see an error message that includes this line telling you what went wrong.
This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel.
The only ways to find out are to either look at the service configuration or just try and run it. If it works and you can call the service, then you're using the default. If you get the error message that I mentioned above, then you're not using the default. Nevertheless, it would help others if you included the SPN in your configuration even if you're using the default as it signals what might need to change if the client or service is relocated.
Next time: Multiple Web Site Bindings
During the last series of articles when I covered call context initializers I was primarily talking about what happens when things go right. Due to the nature of the task, the call context initializer extensibility point is very fragile. The thread context of a call includes sensitive information, such as caller identity, that must be correct for the call to work. Importantly as well, the thread context of a call must be cleaned up and restored for threads to be recycled for the next call. It would be very dangerous to leak information from one call to another because it's unpredictable who will get your thread next.
That's why there are strict rules about call context initializer execution and why the extensibility point is fragile. If any call context initializer gets executed through BeginInvoke, then the system will definitely call AfterInvoke before recycling the thread. If a failure occurs such that one invocation of BeginInvoke fails, then all of the call context initializers will be called with AfterInvoke even if they had never been run before. This means that your call context initializer has to be safe to call AfterInvoke without assuming that anything was initialized by BeginInvoke. Your call context initializer may be partially initialized if BeginInvoke failed with an exception, and AfterInvoke has to handle that case too.
Finally, successful completion of AfterInvoke is used as a sign that cleanup was successful. If AfterInvoke fails to complete successfully, then your process will be terminated to prevent any further damage. This is what makes the extensibility point fragile. You get penalized pretty harshly when a bug is encountered. I think that so far though not many people have tried to write call context initializers. I'm guessing that because the message left in the event log when your process is terminated by AfterInvoke is incorrect and I haven't seen anyone ask why.
Next time: Default SPN
Another one of those rules of thumbs that I hear often quoted but rarely demonstrated covers the performance of hosting a web service in IIS. Running a WCF service host in IIS is going to be more expensive than running that same service host in your own process. However, I've heard people quote figures of sixty, eighty, or even one hundred percent increases in throughput by self hosting. I have difficulty believing that in real practice the throughput is going to double by hosting a web service in your own process rather than in IIS. I would be less skeptical about numbers closer to twenty percent. Nevertheless, you should expect to see a difference because IIS is providing additional services for you.
In my mind, these are the most valuable services that you're trading off for that performance.
Conversely, if you find yourself trying to add these features to a self hosted web service, then you may want to think about using IIS instead because it will probably beat your implementation on performance.
Next time: AfterInvoke Must Run
Jonathan Allen of InfoQ took the time last week to bring up some points about my earlier article on not running as Administrator. I thought that there were two issues brought up that were worth going into more detail about.
The first issue is about the tooling available for HTTP security configuration. Jonathan writes,
In the XP SP 2 and Server 2003 versions of Windows, HTTP addresses and SSL Certificates can be reserved using "httpcfg.exe". As if to discourage developers from actually doing this, Vista does not have this application. Instead, one called "netsh.exe" must be used.
This blurb makes it sound as if netsh is taking a step backward from httpcfg, which is definitely not the case. It is, unlike httpcfg, a program installed with the operating system rather than a hard to find download and it is integrated with the configuration of the rest of the networking components. Both of those improvements are in my mind quite positive. What should be a point to discuss is that the ease of use once you have the tool isn't much improved (it's almost identical). You can argue that the tooling isn't going to be used that much because this is something that installers are supposed to take care of, but I've written elsewhere that I haven't seen many developers doing the small things that make the deployer's life easier. I expect that IT professionals will over time develop their own scripts and tools using the native API to take care of this chore, but I like the simplicity of having most developers satisfied by what comes in the box.
The second issue is more fundamental to the topic being discussed. Jonathan writes,
Since reassigning addresses must be accomplished as administrator, the installer must also be run as an administrator. Once again, we are back to encouraging users to run with administrator privileges.
I think that this requires me to reemphasize the point for why it is advantageous to not run services as an administrator.
I want the installer to require administrative approval because I want to control what happens to my machines. If I want to let people party on settings, then I can do that (via delegation of rights). If I want to lock things down, then I can do that too. It's my choice. Once I've configured everything the way I like, I don't want that mucked with.
I don't want the service itself to be privileged. A web service that runs normally at high privilege has a window of vulnerability that stretches out forever. The web service, by virtue of its nature, is going to be handling data across a boundary of control. The installer is something that lasts for a few seconds and that I can run when my computer is encased in lead and locked in a safe. Why spend any time thinking about what could go wrong when I can simply remove everything unnecessary to the problem at hand? It's easier to be defensive when you're defending a smaller space.
That's why I don't recommend writing a web service that asks to elevate to configure as part of its normal operation. That is a mode of design that makes both security and administration more painful later on. Take care of any issues up front and don't bother me again.
I'm setting up a custom principal for the current thread based on the received messages, but the principal gets reset before the service operation is called. How do I stop this from happening?
What's likely happening here is that the PrincipalPermissionMode is still set to its default value. Most people don't want to get involved with how the current principal is chosen. Most people don't even want to get involved with how the current principal is consumed. As long as WCF sets things up to grant a reasonable set of permissions based on the caller, most people don't want to think about authorization.
On the other hand, some people care very deeply how the current principal is chosen. For example, if you have your own role based system for authorization, then you will want to get involved in the process. That's why WCF gives you a variety of options for controlling how the principal gets established.
The ServiceAuthorizationBehavior includes a setting called PrincipalPermissionMode to control setting the current principal. By default, the PrincipalPermissionMode is set to UseWindowsGroups. Your other options are to use ASP.NET roles, provide a callback for establishing a custom principal, or disable the automatic update to CurrentPrincipal by the service. Since this case already has some code to set the current principal, the right way to make that work is to disable the automatic update by setting PrincipalPemissionMode to None.
Next time: Tradeoffs of IIS Hosting
Many services consist of more than one message processing strategy. Typically, you think of services as being represented by their application endpoints. When the service receives a message, the decision to route the message to one of those endpoints is done by applying message filters until a winning endpoint is determined. However, services also possess infrastructure endpoints to handle tasks like metadata retrieval. These endpoints are also potential routing targets so the decision from filtering has to span both collections of endpoints.
One consequence of having both infrastructure and application endpoints is that it's entirely possible for the defined filter set to be internally consistent for each of the collections but have conflicts when considering the combined set of endpoints. Whenever there is a conflict, some resolution process must take place and pick one of the endpoints to receive the message. Since you primarily think of your application endpoints, you may not consider that you've created a conflict with one of the infrastructure endpoints. Your application endpoints might not win that conflict. The most common symptom of a conflict is that you'll get an exception because the wrong endpoint is trying to process your message. For example, you'll see an address filter mismatch exception that looks like this:
The message with To '...' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.
A sometimes surprising source of this conflict is seen when you switch an operation from using the normal POST to use GET. The service help page and metadata endpoint tend to win conflicts directed to their location or any subpath of their location that use a GET request. You can disable or move these infrastructure endpoints to resolve the conflict through the ServiceDebugBehavior or ServiceMetadataBehavior, respectively, in the configuration or through code. Alternatively, you can move your application endpoint to resolve the conflict that way.
Next time: Turning Off Principal Handling
Can I configure non-HTTP web service activation from the command line?
Yes, and you don't need any special tools if you're already familiar with configuring IIS from the command line. I've already talked about how to configure a new web site or application for activation in a previous post. Modifying the configuration uses the same appcmd program that is installed as part of the IIS scripting tools. It's installed on my system as %windir%\system32\inetsrv\appcmd.exe.
All modifications to the web site are going to start with appcmd set site sitename and all modifications to the application are going to start with appcmd set app appname. The sitename and appname are the long path name for the web site or application, such as "Default Web Site" or "Default Web Site/myapp".
appcmd set site sitename
appcmd set app appname
The list of protocols for activation is associated with the application. Enabling an application to be activated using TCP would look like appcmd set app "Default Web Site/myapp" /enabledProtocols:net.tcp.
appcmd set app "Default Web Site/myapp" /enabledProtocols:net.tcp
The protocol configuration is associated with the web site. Each protocol configuration is called a binding (not related to a WCF binding) and corresponds to a protocol scheme, IP address list, port, and host header. Not all protocol schemes are going to support all of those other things. Adding a new configuration for TCP would look like appcmd set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']. That same binding would be deleted by changing the plus to a minus, appcmd set site "Default Web Site" --bindings.[protocol='net.tcp',bindingInformation='808:*'].
appcmd set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']
appcmd set site "Default Web Site" --bindings.[protocol='net.tcp',bindingInformation='808:*']
Changing the IIS configuration requires administrator approval. If you don't have permission to access the configuration file, you'll get an error that looks like this:
ERROR ( message:Configuration errorFilename: \\?\C:\Windows\system32\inetsrv\config\applicationHost.configLine Number: 0Description: Cannot read configuration file. )
Next time: Address Filters that Swallow GET
A common question about why so many classes implement ICommunicationObject requires a bit of a side trip into design history. The role of ICommunicationObject is to provide a common state machine across many different objects. That state machine has no notion of sending or receiving data; sending and receiving are aspects of another concept called channels. Instead, the state machine encompasses six notions about how an object must be used:
These notions correspond to six states called Created, Opening, Opened, Closing, Closed, and Faulted. Each of these states has a mechanism in the state machine for transition and notification.
Finally, there are the base objects that implement the state machine, collections of these objects (associated, for example, by a common channel factory or channel listener), collections of the collections, and so on. A service in many ways is just a collection of collections that splay eventually down into many operational channels that send and receive messages. When you have a collection of communication objects, it is convenient to work with them as a unit so that you have a single object running through the same state machine that reflects its contained objects. The same can be said about collections of collections. Since the state machine is embodied by ICommunicationObject, you can see why everything implements it.
Next time: Configuring TCP Activation from the Command Line
Back in May I talked about the problem of getting client IP addresses, which you don't have any good way to solve today in WCF. There were a lot of strong comments on that post that this was a feature that people really needed. As it turns out, this was a feature that we wanted to get into Orcas but couldn't get approval. I took the same questions to TechEd to see what people would say. A lot of customers there really wanted this feature as well.
The good news is that we were able to use all of that feedback to get the feature approved and into the product. When using the TCP and HTTP transports, you'll be able to get a message property off of each message that tells you the IP address and port number of the machine that sent the message. The bad news is that because this was a feature that we did very late, it wasn't done in time to appear in the beta releases. We've actually had this done for a few weeks but people continue to ask for the feature because we've had no way to tell you about it.
Rather than let that continue, we decided to let you know that this was one of the things coming in the final release that you haven't had an opportunity to see yet. Phil Henning is the developer that worked to get this done and he's really wanted to talk about it in the meantime so for those of you that are interested, I'm going to let Phil give you more details about how the message property is used. You should expect to see a post on his blog later today.
Since the last pair of performance comparisons, I've had a few people ask for similar comparisons between WCF and other products. Unfortunately I have neither the time nor the interest to setup and run all of these benchmarks. Instead, I'll point anyone that asks at the performance comparison whitepaper that was published earlier this year. It compares WCF with other technologies in a number of scenarios to get you started.
Next time: Design History of Communication Objects
I want to run this post as a reminder to people building and deploying services. I see people deploy services that require access to a restricted resource. The most common restricted resource is the ability to register a listener on part of the HTTP namespace but this advice applies to any restricted resource. Too often, I see people give their service access to the restricted resource by running the service as an administrative account. Don't do this. It is a bad idea. Greatly increasing the privileges of your service is almost never the right thing to do.
Instead, only give your service access to the restricted resource. Here are two articles that explain this process for HTTP reservations: Configuring HTTP and Configuring HTTP for Windows Vista. Don't give your service unnecessary privileges. Don't give access to the resource to unnecessary people. This may require setting up an appropriate service account identity so that you have more control over the scope of the permission.
As a developer, you should think about how people are going to deploy your services. Write down the instructions for deploying your service correctly. It's even better if your service automatically sets everything up, but if it can't then you should just tell the deployer what they should do.
Next time: WCF Performance Comparisons
Two new standards were published yesterday by W3C that cover various aspects of web service metadata. WS-Policy is one of the family of general mechanisms used to describe service requirements and capabilities. Policy attachments supplement the general mechanism to describe how policy is specifically tied to a service description language, such as WSDL. Finally, WS-Addressing Metadata explains how addressing concepts should appear in WSDL, how WSDL should appear in addresses, and how addressing is described through policy. Look for these standards to be supported in the upcoming Orcas release. You can get all of these specifications at the W3C site.
Why aren't the changes that I programmatically make to the service contract reflected in the downloaded metadata?
This is another common question around the confusion between the design time behavior and run time behavior of the system. The configuration of the system can be altered during design time. During run time it cannot. At the lower levels, design time and run time are very formally separated. There are a small number of distinguished methods, which as an effect of being called switch the object from design time mode to run time mode.
At the service level, design time and run time are separated by a murky boundary. Starting the service is a single action that switches many objects from design time to run time, and the order of the switchover can be difficult to guess. At one point, the metadata representing the various contracts is switched from design time to run time and can no longer be altered. At another point, your code may be invoked in the process of switching a separate component from design time to run time. There's clearly a dependency on the order of execution because your code needs to be run first in order for the changes to become visible. The most straightforward way of dealing with this problem is to move the code that changes the contract so that it executes before the contract switches to run time. You can be absolutely guaranteed that things will be visible if you modify them before any attempt to start the service.
Next time: Don't Run as Administrator