Perspective 1:
I am not a fan of the way WS-Eventing is relying on WS-Addressing's EPR binding rules to correlate subscription responses (containing a parameterized "wse:SubscriptionManager" EPR holding the subscription identifier in wsa:ReferenceParameters, see table 5, line 24-26 in WS-Eventing) with subsequent renewals, unsubscribe and status inquiry operations and forces the most central information bit for the respective operation ("Which subscription do you wish to renew?") into the header of the respective message (wse:Identifier) instead of having it in the body.
So for the "GetStatus" operation, you end up with a single body element "GetStatus" that doesn't carry any content [see table 8, lines 19-21 and line 24 in WS-Eventing]. I know that XML lost everything intuitive about it a long time back, but the way this works is really counterintuitive and just doesn't look right. I would expect <GetStatus>uri:Subscription-Identifier</GetStatus>.
Perspective 2:
Now on the other hand! this is actually a sound approach if I were looking at the said SubscriptionManager EPR as a resource. What the wsa:ReferenceParameter does to the EPR is that it binds it uniquely to the respective subscription (section 1.3 of the spec mandates this).
What's confusing here (and not really a good name choice in my view) is that the wse:SubscriptionManager EPR does NOT only point to the subscription manager endpoint, but rather binds all the way through to a specific subscription. Once the binding process to that subscription is done, the requsted action is then executed on the bound resource.
Ok ... I am sorry ... too abstract? I'll rephrase.
What I am saying is that WS-Eventing is an example showing how messages aren't necessarily targeted at the thing with [WebMethod] on top of it, but they may indeed be targeted at something more specific like a database record. So the binding of the endpoint reference is not a matter of the client stopping at http://somewhere/blahblah.asmx but is only complete when the wse:Identifier header is evaluated on the service-side and inside blahblah.asmx, resolved against the subscription database and the actual message target, the respective subscription record, is found. Once the EPR is fully resolved to yield the message target (the record), <GetStatus/> indeed becomes a parameterless operation and the body does not have to carry further content.
EPR = Moniker 
Whenever you start thinking stuff is stable, it turns out that it is not the case. I am trying to implement a WS-Eventing compliant service and of course I ran into the issue that that specification sits on the August 2004 edition (and W3C submission) of WS-Addressing while WSE 2.0 sits on the March 2004 edition of WS-Addressing. To implement WS-Eventing correctly, I would now have to write a WS-Adressing implementation parallel to the one existing in WSE 2.0, because - of course - the August 2004 edition sports a new namespace and has a subtly different schema. Unfortunately, the March 2004 edition of WS-Addressing is so fundamental for WSE 2.0 that routing and security and everything would sit on the March version while my own eventing functionality and nothing else would ride on the August version at the same time and in the same message. Of course that seems just totally wrong. WSE 2.1, please!
I feel like I have been "out of business" for a really long time and like I really got nothing done in the past 3 months, even though that's objectively not true. I guess that's "conference & travel withdrawal", because I had tone and tons of bigger events in the first half of the year and 3 smaller events since TechEd Amsterdam in July. On the upside, I am pretty relaxed and have certainly reduced my stress-related health risks 
So with winter and its short days coming up, the other half of my life living a 1/3 around the planet until next spring, I can and am going to spend some serious time on a bunch of things:
On the new programming stuff front: Catch up on what has been going on in Indigo in recent months, dig deeper into "everything Whidbey", figure out the CLR aspects of SQL 2005 and familiarize myself with VS Team System.
On the existing programming stuff front: Consolidate my "e:\development\*" directory on my harddrive and pull together all my samples and utilities for Enterprise Services, ASP.NET Web Services and other enterprise-development technologies and create a production-quality library from of them for us and our customers to use. Also, because the Indigo team is doing quite a bit of COM/COM+ replumbing recently in order to have that prohgraming model ride on Indigo, I have some hope that I can now file bugs/wishes against COM+ that might have a chance of being addressed. If that happens and a particular showstopper is getting out of the way, I will reopen this project here and will, at the very least, release it as a toy.
On the architectural stuff front: Refine our SOA Workshop material, do quite a bit of additional work on the FABRIQ, evolve the Proseware architecture model, and get some pending projects done. In addition to our own SOA workshops (the next English-language workshop is held December 1-3, 2004 in Düsseldorf), there will be a series of invite-only Microsoft events on Service Orientation throughout Europe this fall/winter, and I am very happy that I will be speaking -- mostly on architecture topics -- at the Microsoft Eastern Mediterranean Developer Conference in Amman/Jordan in November and several other locations in the Middle East early next year.
And even though I hate the effort around writing books, I am seriously considering to write a book about "Services" in the next months. There's a lot of stuff here on the blog that should really be consolidated into a coherent story and there are lots and lots of considerations and motiviations for decisons I made for FABRIQ and Proseware and other services-related work that I should probably write down in one place. One goal of the book would be to write a pragmatic guide on how to design and build services using currently shipping (!) technologies that does focus on how to get stuff done and not on how to craft new, exotic SOAP headers, how to do WSDL trickery, or do other "cool" but not necessarily practical things. So don't expect a 1200 page monster.
In addition to the "how to" part, I would also like to incorporate and consolidate other architect's good (and bad) practical design and implementation experiences, and write about adoption accelerators and barriers, and some other aspects that are important to get the service idea past the CFO. That's a great pain point for many people thinking about services today. If you would be interested in contributing experiences (named or unnamed), I certainly would like to know about it.
And I also think about a German-to-English translation and a significant (English) update to my German-language Enterprise Services book.....
[And to preempt the question: No, I don't have a publisher for either project, yet.]
Five weeks already. No pain, no tricks. I simply quit.
Michael Willers really got his blog going while I was on vacation.
Today is a great day. Awesome day. Wonderful day. Significant day. Life changing day. Happily-ever-after day. Life is good.
Microsoft seems to be struggling with the Messenger service in the past two days. Right now I cannot sign in, I got booted frequently yesterday and yesterday night I could see everybody but chat with noone. What really sucks about that is that I realize how much some parts of work and life have become a dependent on Messenger working - and switching to another service or between services is not really a good answer to the problem. What's the Messenger SLA (Service-Level Agreement), anyways?
Microsoft created a new category in their MVP program
for “Solution Architects” and coming back from my vacation I was
happy to find out that they awarded me with the 2004 “Most Valuable
Professional” title in that new category. Thank you, Microsoft! (…and
thanks for the MP3 player gift, too)
 4 straight weeks are the longest time I have been offline and off work (cheating only for 3 smaller speaking engagements that were “on the way”) in the last 6 years or so. In fact, I don’t think I’ve really been offline and not working for more than 10 days straight in the last 6 years either. Together with my best-ever travel buddy and best friend Jen, I had some of the best weeks ever. We went to catch the end of the beach season on the Turkish west-coast for a week and also went to see the ancient sites of Troy, Assos and Pergamon as well as the WWI battlegrounds of Gallipolli at the Dardanells strait (all those pictures are still on – undeveloped – film).
With less than 24h turnaround at my house, we packed the car and then went on to Berlin (1st speaking engagement) for a day, and proceeded to Munich (2nd speaking engagement) on a smooth and relaxed 180 km/h evening trip. After I was done working, we celebrated the evening at Oktoberfest (including rollercoaster ride, the essential sausage treats and plenty of beer) with a bunch of people we instantly made friends with. Next day we crossed “this is all way too green” Austria into Slovenia for two great days in the wonderful Slovenian capital of Ljubljana (“Their stuff is cute!”).

From Slovenia the road took us through a tiny bit of Croatia and then back onto EU territory in Hungary where we drove along the magnificent Lake Balaton towards the next stop at Budapest for 2 days of sightseeing, wining (!), dining and then also a bit of sightseeing and wining and dining.

The following road day we went to Bratislava, the capital of Slovakia. The city center of Bratislava is an amazing place in that it is a maze in which you can always find a new little street and new places whenever you think you found them all. Yet, you can go once around the center in 20 minutes. (And someone really needs to develop their river front with bars and restaurants!).
Bratislava is also where we shot the most politically loaded picture of the tour.
Jen thinks its totally appropriate and great symbolism and I think it’s a little too much. Note how the rainbow ends right in the embassy of the United States of America.
The next day we went on a great hike for a few hours in the hills around Bratislava, which sits at the foot of the Carpathian mountain range.
Next day, next drive: onwards to Poland and Krakow.
Even though all places were awesome, Krakow turned out to be our favorite city and we stayed 3 nights. Krakow is not only full of historic sights and other great things to see, but is also an amazing place for people watching at the grand market square (the biggest in Europe) and for great food.
Part of the Krakow experience were also a necessary yet very disturbing visit at the museum and memorial in Auschwitz and, much happier, a visit to my aunt Elli who lives in nearby Katowice.
 The man who made our Krakow experience absolutely perfect was fellow Microsoft Regional Director Tadeusz Golonka who I called just an hour before we got to Krakow to say Hello and who immediately dropped all work to give us an impressive tour through Krakow’s center (better than any professional tour guide could do it) and also went to dinner with us on two nights. Thank you!
After Krakow we made a fairly quick drive westward to Wroclaw, where we first documented several instances of one of the recurring people watching themes of the tour (“serious case of white shoes”) and then later got totally trashed in a nightclub right at Wroclaw’s main market square after a fabulous dinner.
  
After a rather late check out the next morning, we went back to Germany and to Dresden, where we went to see Puccini’s opera Madame Butterfly in the world famous “Semperoper” opera house and were impressed by the energy (and money) put into the ongoing reconstruction of Dresden’s Frauenkirche and other great old buildings after the WWII destruction and Communist neglect.

Even though it would have been great to spend more time in Dresden, we had to move on to my brother’s house near Hannover the next day (for beers) and then onwards to Hamburg (my 3rd speaking engagement).
In Hamburg we did the obligatory tour through the sea port, strolled through the wild red-light district in St. Pauli at night and went shopping in the classy Jungfernstieg area.

With my talks in Hamburg done, we packed up and went back my house near Düsseldorf, completing a 3800km driving loop through Central Europe.
We had an awesome time at all the places we went to. Europe is a great place, isn’t it?
Ah, and: I am back! 
Achim found a wonderful picture that we've dropped on our nonsense blog. Schröder and finance minister Eichel. The picture takes a little while to sink in 
A little while ago a new build of Indigo found its way onto my desk. On thing that’s interesting about this particular interim milestone (don’t hope for juicy details here on the blog) is that it doesn’t support WSDL. No. Calm down. It’s not what you think. It just happens that the WSDL support wasn’t included in this particular version; it’ll be there, no worries.
Such interim binary drops that the Microsoft product groups give out to very early adopters are really only meant for the bravest of the brave with too much time on their hands. Therefore, the documentation is not entirely in synch with the feature set – and that’s a stretch. (Hey, I am not complaining.) So until someone told me “yeah, there’s no WSDL or Metadata exchange worth talking about in this build” I tried to find how contract works in this build and of course I couldn’t find it. Well, not really true. It turns out that contract works just like with ASP.NET 1.0 or ASP.NET 1.1 Web Services. At runtime, WSDL usually doesn’t play any role, at all. Unless you use some funky dynamic binding logic, WSDL is just a design-time metadata container and that’s the basis for generating CLR metadata and code. Although there is an implementation aspect to it when you generate proxies or server skeletons, the most important job of WSDL.EXE is to perform a conversion of the WSDL rendering of the message contract into a format that the ASMX infrastructure can readily understand. That format happens to be classes with methods and attribute annotations. Here is a client and a server I just typed up with Notepad:
|
Contract.asmx |
Client.cs |
|
<% @WebService class="MyService" language="C#"%>
using System.Web.Services; using System.Web.Services.Protocols;
[WebService(Namespace="http://tempuri.org")] public class MyService { [WebMethod] public string Hello( string Test ) { return "Hello "+Test; } } |
using System; using System.Web.Services; using System.Web.Services.Protocols;
[WebServiceBinding(Namespace="http://tempuri.org")] public class MyService : SoapHttpClientProtocol { [SoapDocumentMethod] public string Hello( string Test ) { return (string)Invoke("Hello", new object[]{Test})[0]; } }
public class MainApp { static void Main() { MyService m = new MyService(); m.Url = "http://localhost/contract.asmx"; Console.WriteLine("Result: "+ m.Hello("Test")); } } |
Drop the contract.asmx into x:\inetpub\wwwroot, compile the client with “csc client.cs” and run it. No WSDL ever changed hands, no “Add Web Reference”, it just works. Ok, ok, it’s the year ‘04 now and there’s really no magic there anymore. Now here’s a tiny bit of refactoring:
|
Contract.asmx |
Client.cs |
|
<% @WebService class="MyService" language="C#"%>
using System.Web.Services; using System.Web.Services.Protocols;
public interface IMyService { string Hello( string Test ); }
[WebService(Namespace="http://tempuri.org")] public class MyService : IMyService { [WebMethod] public string Hello( string Test ) { return "Hello "+Test; } } |
using System; using System.Web.Services; using System.Web.Services.Protocols;
public interface IMyService { string Hello( string Test ); }
[WebServiceBinding(Namespace="http://tempuri.org")] public class MyService : SoapHttpClientProtocol, IMyService { [SoapDocumentMethod] public string Hello( string Test ) { return (string)Invoke("Hello", new object[]{Test})[0]; } }
public class MainApp { static void Main() { MyService m = new MyService(); m.Url = "http://localhost:8080/contract.asmx"; Console.WriteLine("Result: "+ m.Hello("Test")); } } |
Extracting the interface from server and proxy makes it very, very clear that we’re dealing with the very same message contract. Mind that we only have source-code level contract equivalence between client and server here. The compiled code on either side yields distinct IMyService types and that’s supposed to be that way. In the case I am illustrating here, the language C# serves as the metadata language (and the clipboard is the mechanism) for sharing contract between client and server (or endpoints).
There are two things I find (mildly) annoying about ASP.Net Web Services 1.x and they also become quite apparent in this example: #1 the server side and the client side have a different minimum set of required attributes and #2 ASP.NET’s ASMX support doesn’t look at inherited method-level attributes. The following does not even compile:
|
Contract.asmx |
Client.cs |
|
<% @WebService class="MyService" language="C#"%>
using System.Web.Services; using System.Web.Services.Protocols;
[WebServiceBinding(Namespace="http://tempuri.org")] [WebService(Namespace="http://tempuri.org")] public interface IMyService { [SoapDocumentMethod][WebService] string Hello( string Test ); }
public class MyService : IMyService { public string Hello( string Test ) { return "Hello "+Test; } } |
using System; using System.Web.Services; using System.Web.Services.Protocols;
[WebServiceBinding(Namespace="http://tempuri.org")] [WebService(Namespace="http://tempuri.org")] public interface IMyService { [SoapDocumentMethod][WebService] string Hello( string Test ); }
public class MyService : SoapHttpClientProtocol, IMyService { public string Hello( string Test ) { return (string)Invoke("Hello", new object[]{Test})[0]; } }
public class MainApp { static void Main() { MyService m = new MyService(); m.Url = "http://localhost:8080/contract.asmx"; Console.WriteLine("Result: "+ m.Hello("Test")); } } |
And, frankly, it’s probably not bad that it doesn’t compile, because the half of the attributes on the resulting interface declaration are useless on either side.
Indigo pulls both sides together into the notion of a service contract that’s good for either side (I am using a simple variant of the “publicly known” notation here)
[ServiceContract] public interface IMyService { [ServiceMethod] string Hello( string Test ); }
If you want to see it that way, this is Indigo’s IDL (Interface Definition Language). There’s an equivalence transformation from and to WSDL, if you want to share the contract with folks who program on other platforms or who use another programming language. There are just no angle brackets here and it’s much easier to read, too.
So if you see code that I wrote and you find (even today) seemingly unnecessary interface declarations that are implemented on a single web service class within a project and nowhere else and are also not referenced from anywhere – they might not be unnecessary as they seem. It’s simply IDL!
More confusingly, you might find those declarations replicated! in source code! in another service! Yes, because services are designed to be evolved independent of each other. So while the target service is already in V4, the consumer may still be on the level of V2. Moving up to the V4 interface version is a conscious choice by the developer of the service consumer – and at that point in time he/she imports the most recent contract. Whether that’s copy/paste of a C#/VB/C++ declaration or clicking “Update” on some menu in Visual Studio that turns WSDL into proxy code is not very important; it’s just a matter of tool preference.
Using explicit interface declarations with Web Services is strictly a “contract first” model. It’s just not using WSDL, that’s all.
I wonder when "the Americans" (sorry for making a horribly generalizing statement here) will understand that creating an edit control with a mask
(###)-###-####
is a thoroughly bad idea.
We set up a new blog here - primarily for our own amusement. Expect no seriousness there.
|