<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Clemens Vasters - Technology</title>
    <link>http://vasters.com/clemensv/</link>
    <description>Cloud Development and Alien Abductions</description>
    <language>en-us</language>
    <copyright>Clemens Vasters</copyright>
    <lastBuildDate>Fri, 19 Oct 2012 09:29:10 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7067.0</generator>
    <managingEditor>cvasters@guhhome.com</managingEditor>
    <webMaster>cvasters@guhhome.com</webMaster>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=abf20c1d-a3f3-4070-b54e-2a922156343a</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,abf20c1d-a3f3-4070-b54e-2a922156343a.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,abf20c1d-a3f3-4070-b54e-2a922156343a.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=abf20c1d-a3f3-4070-b54e-2a922156343a</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just got off the call with a customer and had a bit of a déjà vu from a meeting
at the beginning of the week, so it looks like the misconception I'll explain here
is a bit more common than I expected. 
</p>
        <p>
In both cases, the folks I talked to, had the about equivalent of the following code
in their app: 
</p>
        <p>
          <span style="FONT-FAMILY: Consolas">var qc = factory.CreateQueueClient(…);<br />
for( int i = 0; i &lt; 1000; i++ ) 
<br />
{<br />
… create message …<br />
qc.BeginSend( msg, null, null );<br />
}<br />
qc.Close(); </span>
        </p>
        <p>
In both cases, the complaint was that messages were lost and strange exceptions occurred
in the logs – which is because, well, this doesn't do what they thought it does. 
</p>
        <p>
          <em>BeginSend</em> in the Service Bus APIs or other networking APIs as much as BeginWrite
on the file system isn't really doing the work that is requested. It is putting a
job into a job queue – the job queue of the I/O thread scheduler. 
</p>
        <p>
That means that once the code reaches <em>qc.Close()</em> and you have also been mighty
lucky, a few messages may indeed have been sent, but the remaining messages will now
still sit in that job queue and scheduled for an object that the code just forced
to close. With the result that every subsequent send operation that is queued but
hasn't been scheduled yet will throw as you're trying to send on a disposed object.
Those messages will fail out and be lost inside the sender's process. 
</p>
        <p>
What's worse is that writing such code stuffs a queue that is both out of the app's
control and out of the app's sight and that all the arguments (which can be pretty
big when we talk about messages) dangle on those jobs filling up memory. Also, since
the app doesn't call <em>EndSend()</em>, the application also doesn't pick up whatever
exceptions are potentially raised by the Send operation and flies completely blind.
If there is an EndXXX method for an async operation, you _must_ call that method even
if it doesn't return any values, because it might quite well throw you back what went
wrong. 
</p>
        <p>
So how should you do it? Don't throw messages blindly into the job queue. It's ok
to queue up a few to make sure there's a job in the queue as another one completes
(which is just slightly trickier than what I want to illustrate here), but generally
you should make subsequent sends depend on previous sends completing. In .NET 4.5
with async/await that's a lot easier now: 
</p>
        <p>
          <span style="FONT-FAMILY: Consolas">var qc = factory.CreateQueueClient(…);<br />
for( int i = 0; i &lt; 1000; i++ ) 
<br />
{<br />
… create message …<br />
await task.Factory.FromAsync(qc.BeginSend, qc.EndSend, msg, null );<br />
}<br />
qc.Close(); </span>
        </p>
        <p>
Keep in mind that the primary goal of async I/O is to not waste threads and lose time
through excessive thread switching as threads hang on I/O operations. <strong><em>It's
not making the I/O magically faster per-se</em></strong>. We achieve that in the above
example as the compiler will break up that code into distinct methods where the loop
continues on an I/O thread callback once the Send operation has completed. 
</p>
        <p>
Summary: 
</p>
        <ol>
          <li>
Don't stuff the I/O scheduler queue with loads of blind calls to BeginXXX without
consideration for how the work gets done and completed and that it can actually fail 
</li>
          <li>
Always call End and think about how many operations you want to have in flight and
what happens to the objects that are attached to the in-flight jobs</li>
        </ol>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=abf20c1d-a3f3-4070-b54e-2a922156343a" />
      </body>
      <title>Service Bus: BeginSend is no magic async pixie dust</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,abf20c1d-a3f3-4070-b54e-2a922156343a.aspx</guid>
      <link>http://vasters.com/clemensv/2012/10/19/Service+Bus+BeginSend+Is+No+Magic+Async+Pixie+Dust.aspx</link>
      <pubDate>Fri, 19 Oct 2012 09:29:10 GMT</pubDate>
      <description>&lt;p&gt;
I just got off the call with a customer and had a bit of a déjà vu from a meeting
at the beginning of the week, so it looks like the misconception I'll explain here
is a bit more common than I expected. 
&lt;/p&gt;
&lt;p&gt;
In both cases, the folks I talked to, had the about equivalent of the following code
in their app: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-FAMILY: Consolas"&gt;var qc = factory.CreateQueueClient(…);&lt;br&gt;
for( int i = 0; i &amp;lt; 1000; i++ ) 
&lt;br&gt;
{&lt;br&gt;
… create message …&lt;br&gt;
qc.BeginSend( msg, null, null );&lt;br&gt;
}&lt;br&gt;
qc.Close(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
In both cases, the complaint was that messages were lost and strange exceptions occurred
in the logs – which is because, well, this doesn't do what they thought it does. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;BeginSend&lt;/em&gt; in the Service Bus APIs or other networking APIs as much as BeginWrite
on the file system isn't really doing the work that is requested. It is putting a
job into a job queue – the job queue of the I/O thread scheduler. 
&lt;/p&gt;
&lt;p&gt;
That means that once the code reaches &lt;em&gt;qc.Close()&lt;/em&gt; and you have also been mighty
lucky, a few messages may indeed have been sent, but the remaining messages will now
still sit in that job queue and scheduled for an object that the code just forced
to close. With the result that every subsequent send operation that is queued but
hasn't been scheduled yet will throw as you're trying to send on a disposed object.
Those messages will fail out and be lost inside the sender's process. 
&lt;/p&gt;
&lt;p&gt;
What's worse is that writing such code stuffs a queue that is both out of the app's
control and out of the app's sight and that all the arguments (which can be pretty
big when we talk about messages) dangle on those jobs filling up memory. Also, since
the app doesn't call &lt;em&gt;EndSend()&lt;/em&gt;, the application also doesn't pick up whatever
exceptions are potentially raised by the Send operation and flies completely blind.
If there is an EndXXX method for an async operation, you _must_ call that method even
if it doesn't return any values, because it might quite well throw you back what went
wrong. 
&lt;/p&gt;
&lt;p&gt;
So how should you do it? Don't throw messages blindly into the job queue. It's ok
to queue up a few to make sure there's a job in the queue as another one completes
(which is just slightly trickier than what I want to illustrate here), but generally
you should make subsequent sends depend on previous sends completing. In .NET 4.5
with async/await that's a lot easier now: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-FAMILY: Consolas"&gt;var qc = factory.CreateQueueClient(…);&lt;br&gt;
for( int i = 0; i &amp;lt; 1000; i++ ) 
&lt;br&gt;
{&lt;br&gt;
… create message …&lt;br&gt;
await task.Factory.FromAsync(qc.BeginSend, qc.EndSend, msg, null );&lt;br&gt;
}&lt;br&gt;
qc.Close(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Keep in mind that the primary goal of async I/O is to not waste threads and lose time
through excessive thread switching as threads hang on I/O operations. &lt;strong&gt;&lt;em&gt;It's
not making the I/O magically faster per-se&lt;/em&gt;&lt;/strong&gt;. We achieve that in the above
example as the compiler will break up that code into distinct methods where the loop
continues on an I/O thread callback once the Send operation has completed. 
&lt;/p&gt;
&lt;p&gt;
Summary: 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Don't stuff the I/O scheduler queue with loads of blind calls to BeginXXX without
consideration for how the work gets done and completed and that it can actually fail 
&lt;li&gt;
Always call End and think about how many operations you want to have in flight and
what happens to the objects that are attached to the in-flight jobs&lt;/li&gt;
&lt;/ol&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=abf20c1d-a3f3-4070-b54e-2a922156343a" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,abf20c1d-a3f3-4070-b54e-2a922156343a.aspx</comments>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=8a8c025a-365e-4f15-9f89-07a0233ba669</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=8a8c025a-365e-4f15-9f89-07a0233ba669</wfw:commentRss>
      <slash:comments>14</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
as I thumb through some people's code on Github, I see a fairly large number of "catch
all" exception handling cases. It's difficult to blame folks for that, since there's
generally (and sadly) very little discipline about exception contracts and exception
masking, i.e. wrapping exceptions to avoid bubbling through failure conditions of
underlying implementation details. 
</p>
        <p>
If you're calling a function and that sits on a mountain of dependencies and folks
don't care about masking exceptions, there are many dozens of candidate exceptions
that can bubble back up to you and there's little chance to deal with them all or
even knowing them. Java has been trying to enforce more discipline in that regards,
but people cheat there with "catch all" as well.  There's also a question what
the right way tot deal with most exceptions is. In many cases, folks implement "intercept,
shrug and log" and mask the failure by telling users that something went wrong. In
other common cases, folks implement retries. It's actually fairly rare to see deeply
customized and careful reactions to particular exceptions. Again - things are complicated
and exceptions are supposed to be exceptional (reminder: throwing exceptions as part
of the regular happy path is horrifingly bad for performance and terrible from a style
perspective), so these blanket strategies are typically an efficient way of dealing
with things. 
</p>
        <p>
That all said ...
</p>
        <p>
          <strong>
            <em>Never, never ever</em>
          </strong> do this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
Work(); } <span class="kwrd">catch</span> { }</pre>
        </blockquote>
        <p>
And  <strong><em>not even</em></strong> this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
Work(); } <span class="kwrd">catch</span>(Exception e) { Trace.TraceError(e.ToString());
}</pre>
        </blockquote>
        <p>
Those examples are universally bad. (Yes, you will probably find examples of that
type even in the archive of this blog and some of my public code. Just goes to show
that I've learned some better coding practices here at Microsoft in the past 6 1/2
years.)
</p>
        <p>
The problem with them is that they catch not only the benign stuff, but they also
catch and suppress the C# runtime equivalent of the Zombie Apocalypse. If you get
thread-abort, out-of-memory, or stack-overflow exceptions thrown back at you, you
don't want to suppress those. Once you run into these, your code has ignored all the
red flags and exhausted its resources and whatever it was that you called didn't get
its job done and likely sits there as a zombie in an undefined state. That class of
exceptions is raining down your call stack like a shower of knife blades. They can't
happen. Your code must be defensively enough written to never run into that situation
and overtax resources in that way; if it does without you knowing what the root cause
is, this is an automatic "Priority 0", "drop-everything-you're-working-on" class bug.
It certainly is if you're writing services that need to stay up 99.95%+.
</p>
        <p>
What do we do? if we see any of those exceptions, it's an automatic death penalty
for the process. Once you see an unsafe out-of-memory exception or stack overflow,
you can't trust the state of the respective part of the system and likely not the
stability of the system. Mind that there's also a "it depends" here;  I would
follow a different strategy if I was talking about software for an autonomous Mars
Rover that can't crash even if its gravely ill.  There I would likely spend a
few months on the exception design and "what could go wrong here" before even thinking
about functionality, so that's a different ballgame.  In a cloud system, booting
a cluster machine that has the memory flu is a good strategy.
</p>
        <p>
Here's a variation of the helper we use:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">public</span>
            <span class="kwrd">static</span>
            <span class="kwrd">bool</span> IsFatal(<span class="kwrd">this</span> Exception
exception) { <span class="kwrd">while</span> (exception != <span class="kwrd">null</span>)
{ <span class="kwrd">if</span> (exception <span class="kwrd">as</span> OutOfMemoryException
!= <span class="kwrd">null</span> &amp;&amp; exception <span class="kwrd">as</span> InsufficientMemoryException
== <span class="kwrd">null</span> || exception <span class="kwrd">as</span> ThreadAbortException
!= <span class="kwrd">null</span> || 
<br />
exception <span class="kwrd">as</span> AccessViolationException != <span class="kwrd">null</span> ||
exception <span class="kwrd">as</span> SEHException != <span class="kwrd">null</span> ||
exception <span class="kwrd">as</span> StackOverflowException != <span class="kwrd">null</span>)
{ <span class="kwrd">return</span><span class="kwrd">true</span>; } <span class="kwrd">else</span> { <span class="kwrd">if</span> (exception <span class="kwrd">as</span> TypeInitializationException
== <span class="kwrd">null</span> &amp;&amp; exception <span class="kwrd">as</span> TargetInvocationException
== <span class="kwrd">null</span>) { <span class="kwrd">break</span>; } exception
= exception.InnerException; } } <span class="kwrd">return</span><span class="kwrd">false</span>;
}</pre>
        </blockquote>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
If you put this into a static utility class, you can use this on any exception as
an extension. And whenever you want to do a "catch all", you do this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
DoWork();<br />
} <span class="kwrd">catch</span> (Exception e) { <span class="kwrd">if</span> (e.IsFatal())
{ <span class="kwrd">throw</span>; } Trace.TraceError(..., e); }</pre>
        </blockquote>
        <p>
If the exception is fatal, you simply throw it up as high as you can. Eventually it'll
end up on the bottom of whatever thread they happen on (where you might log and rethrow)
and will hopefully take the process with it. Threads marked as background threads
don't do that, so it's actually not a good idea to use those. These exceptions are
unhandled, process-terminating disasters with a resulting process crash-dump you want
to force in a 24/7 system so that you can weed them out one by one.
</p>
        <p>
(Update) As <a href="https://twitter.com/richardblewett/status/243792951229157378">Richard
Blewett pointed</a> out after reading this post, the StackOverflowException can't
be caught in .NET 2.0+, at all, and the ThreadAbortException automatically rethrows
even if you try to suppress it. There are two reasons for them to be on the list:
first, to shut up any code review debates about which of the .NET stock exceptions
are fatal and ought to be there; second, because code might (ab-)use these exceptions
as fail-fast exceptions and fake-throw them, or the exceptions might be blindly rethrown
when marshaled from a terminated background thread where they were caught at the bottom
of the thread. However they show up, it's always bad for them to show up.
</p>
        <p>
If you catch a falling knife, rethrow. <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a8c025a-365e-4f15-9f89-07a0233ba669" />
      </body>
      <title>Are you catching falling knives?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</guid>
      <link>http://vasters.com/clemensv/2012/09/06/Are+You+Catching+Falling+Knives.aspx</link>
      <pubDate>Thu, 06 Sep 2012 19:08:10 GMT</pubDate>
      <description>&lt;p&gt;
as I thumb through some people's code on Github, I see a fairly large number of "catch
all" exception handling cases. It's difficult to blame folks for that, since there's
generally (and sadly) very little discipline about exception contracts and exception
masking, i.e. wrapping exceptions to avoid bubbling through failure conditions of
underlying implementation details. 
&lt;/p&gt;
&lt;p&gt;
If you're calling a function and that sits on a mountain of dependencies and folks
don't care about masking exceptions, there are many dozens of candidate exceptions
that can bubble back up to you and there's little chance to deal with them all or
even knowing them. Java has been trying to enforce more discipline in that regards,
but people cheat there with "catch all" as well.&amp;nbsp; There's also a question what
the right way tot deal with most exceptions is. In many cases, folks implement "intercept,
shrug and log" and mask the failure by telling users that something went wrong. In
other common cases, folks implement retries. It's actually fairly rare to see deeply
customized and careful reactions to particular exceptions. Again - things are complicated
and exceptions are supposed to be exceptional (reminder: throwing exceptions as part
of the regular happy path is horrifingly bad for performance and terrible from a style
perspective), so these blanket strategies are typically an efficient way of dealing
with things. 
&lt;/p&gt;
&lt;p&gt;
That all said ...
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Never, never ever&lt;/em&gt;&lt;/strong&gt; do this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
Work(); } &lt;span class=kwrd&gt;catch&lt;/span&gt; { }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
And&amp;nbsp; &lt;strong&gt;&lt;em&gt;not even&lt;/em&gt;&lt;/strong&gt; this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
Work(); } &lt;span class=kwrd&gt;catch&lt;/span&gt;(Exception e) { Trace.TraceError(e.ToString());
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Those examples are universally bad. (Yes, you will probably find examples of that
type even in the archive of this blog and some of my public code. Just goes to show
that I've learned some better coding practices here at Microsoft in the past 6 1/2
years.)
&lt;/p&gt;
&lt;p&gt;
The problem with them is that they catch not only the benign stuff, but they also
catch and suppress the C# runtime equivalent of the Zombie Apocalypse. If you get
thread-abort, out-of-memory, or stack-overflow exceptions thrown back at you, you
don't want to suppress those. Once you run into these, your code has ignored all the
red flags and exhausted its resources and whatever it was that you called didn't get
its job done and likely sits there as a zombie in an undefined state. That class of
exceptions is raining down your call stack like a shower of knife blades. They can't
happen. Your code must be defensively enough written to never run into that situation
and overtax resources in that way; if it does without you knowing what the root cause
is, this is an automatic "Priority 0", "drop-everything-you're-working-on" class bug.
It certainly is if you're writing services that need to stay up 99.95%+.
&lt;/p&gt;
&lt;p&gt;
What do we do? if we see any of those exceptions, it's an automatic death penalty
for the process. Once you see an unsafe out-of-memory exception or stack overflow,
you can't trust the state of the respective part of the system and likely not the
stability of the system. Mind that there's also a "it depends" here;&amp;nbsp; I would
follow a different strategy if I was talking about software for an autonomous Mars
Rover that can't crash even if its gravely ill.&amp;nbsp; There I would likely spend a
few months on the exception design and "what could go wrong here" before even thinking
about functionality, so that's a different ballgame.&amp;nbsp; In a cloud system, booting
a cluster machine that has the memory flu is a good strategy.
&lt;/p&gt;
&lt;p&gt;
Here's a variation of the helper we use:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; IsFatal(&lt;span class=kwrd&gt;this&lt;/span&gt; Exception
exception) { &lt;span class=kwrd&gt;while&lt;/span&gt; (exception != &lt;span class=kwrd&gt;null&lt;/span&gt;)
{ &lt;span class=kwrd&gt;if&lt;/span&gt; (exception &lt;span class=kwrd&gt;as&lt;/span&gt; OutOfMemoryException
!= &lt;span class=kwrd&gt;null&lt;/span&gt; &amp;amp;&amp;amp; exception &lt;span class=kwrd&gt;as&lt;/span&gt; InsufficientMemoryException
== &lt;span class=kwrd&gt;null&lt;/span&gt; || exception &lt;span class=kwrd&gt;as&lt;/span&gt; ThreadAbortException
!= &lt;span class=kwrd&gt;null&lt;/span&gt; || 
&lt;br&gt;
exception &lt;span class=kwrd&gt;as&lt;/span&gt; AccessViolationException != &lt;span class=kwrd&gt;null&lt;/span&gt; ||
exception &lt;span class=kwrd&gt;as&lt;/span&gt; SEHException != &lt;span class=kwrd&gt;null&lt;/span&gt; ||
exception &lt;span class=kwrd&gt;as&lt;/span&gt; StackOverflowException != &lt;span class=kwrd&gt;null&lt;/span&gt;)
{ &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;true&lt;/span&gt;; } &lt;span class=kwrd&gt;else&lt;/span&gt; { &lt;span class=kwrd&gt;if&lt;/span&gt; (exception &lt;span class=kwrd&gt;as&lt;/span&gt; TypeInitializationException
== &lt;span class=kwrd&gt;null&lt;/span&gt; &amp;amp;&amp;amp; exception &lt;span class=kwrd&gt;as&lt;/span&gt; TargetInvocationException
== &lt;span class=kwrd&gt;null&lt;/span&gt;) { &lt;span class=kwrd&gt;break&lt;/span&gt;; } exception = exception.InnerException;
} } &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;false&lt;/span&gt;; }&lt;/pre&gt;
&lt;/blockquote&gt; &lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
If you put this into a static utility class, you can use this on any exception as
an extension. And whenever you want to do a "catch all", you do this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
DoWork();&lt;br&gt;
} &lt;span class=kwrd&gt;catch&lt;/span&gt; (Exception e) { &lt;span class=kwrd&gt;if&lt;/span&gt; (e.IsFatal())
{ &lt;span class=kwrd&gt;throw&lt;/span&gt;; } Trace.TraceError(..., e); }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
If the exception is fatal, you simply throw it up as high as you can. Eventually it'll
end up on the bottom of whatever thread they happen on (where you might log and rethrow)
and will hopefully take the process with it. Threads marked as background threads
don't do that, so it's actually not a good idea to use those. These exceptions are
unhandled, process-terminating disasters with a resulting process crash-dump you want
to force in a 24/7 system so that you can weed them out one by one.
&lt;/p&gt;
&lt;p&gt;
(Update) As &lt;a href="https://twitter.com/richardblewett/status/243792951229157378"&gt;Richard
Blewett pointed&lt;/a&gt; out after reading this post, the StackOverflowException can't
be caught in .NET 2.0+, at all,&amp;nbsp;and the ThreadAbortException automatically rethrows
even if you try to suppress it. There are two reasons for them to be on the list:
first, to shut up any code review debates about which of the .NET stock exceptions
are fatal and ought to be there; second, because code might (ab-)use these exceptions
as fail-fast exceptions and fake-throw them, or the exceptions might be blindly rethrown
when marshaled from a terminated background thread where they were caught at the bottom
of the thread. However they show up, it's always bad for them to show up.
&lt;/p&gt;
&lt;p&gt;
If you catch a falling knife, rethrow. &lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a8c025a-365e-4f15-9f89-07a0233ba669" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</comments>
      <category>Technology</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=99035bd6-2110-4b0d-bf9e-e337ee1342a1</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,99035bd6-2110-4b0d-bf9e-e337ee1342a1.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,99035bd6-2110-4b0d-bf9e-e337ee1342a1.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=99035bd6-2110-4b0d-bf9e-e337ee1342a1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We get a ton of inquiries along the lines of “I want to program my firewall using
IP ranges to allow outbound access only to my cloud-based apps”. If you (or the IT
department) insist on doing this with Windows Azure, there is even a downloadable
and fairly regularly updated list of the IP ranges <a href="http://www.microsoft.com/en-us/download/details.aspx?id=29840" target="_blank">on
the Microsoft Download Center</a> in a straightforward XML format.
</p>
        <p>
Now, we do know that there are a lot of customers who keep insisting on using IP address
ranges for that purpose, but that strategy is not a recipe for success. 
</p>
        <p>
The IP ranges shift and expand on a very frequent basis and cover all of the Windows
Azure services. Thus, a customer will open their firewall for traffic for the entire
multitenant range of Azure, which means that the customer’s environment can reach
their own apps and the backend services for the “Whack A Panda” game just the same.
With apps in the cloud, there is no actual security gain from these sorts of constraints;
pretty much all the advantages of automated, self-service cloud environments stem
from shared resources including shared networking and shared gateways and the ability
to do dynamic failover including cross-DC failover and the like that means that there
aren’t any reservations at the IP level that last forever.
</p>
        <p>
The best way to handle this is to do the exact inverse of what’s being tried with
these rules, and rather limit access to outside resources to a constrained set of
services based on the services’ or users’ identity as it is done on our Microsoft
corporate network. At Microsoft, you can’t get out through the NAT/Proxy unless you
have an account that has external network privileges. If you are worried about a service
or user abusing access to the Internet, don’t give them Internet. If you think you
need to have tight control, make a DMZ – in the opposite direction of how you usually
think about a DMZ. 
</p>
        <p>
Using IP-address based outbound firewall access rules constraining access to public
cloud computing resources is probably getting a box on a check-list ticked, but it
doesn’t add anything from a security perspective. It’s theater. IMHO.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=99035bd6-2110-4b0d-bf9e-e337ee1342a1" />
      </body>
      <title>"I want to program my firewall using IP ranges to allow outbound access only to my cloud apps"</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,99035bd6-2110-4b0d-bf9e-e337ee1342a1.aspx</guid>
      <link>http://vasters.com/clemensv/2012/07/31/I+Want+To+Program+My+Firewall+Using+IP+Ranges+To+Allow+Outbound+Access+Only+To+My+Cloud+Apps.aspx</link>
      <pubDate>Tue, 31 Jul 2012 17:42:27 GMT</pubDate>
      <description>&lt;p&gt;
We get a ton of inquiries along the lines of “I want to program my firewall using
IP ranges to allow outbound access only to my cloud-based apps”. If you (or the IT
department) insist on doing this with Windows Azure, there is even a downloadable
and fairly regularly updated list of the IP ranges &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=29840" target=_blank&gt;on
the Microsoft Download Center&lt;/a&gt; in a straightforward XML format.
&lt;/p&gt;
&lt;p&gt;
Now, we do know that there are a lot of customers who keep insisting on using IP address
ranges for that purpose, but that strategy is not a recipe for success. 
&lt;/p&gt;
&lt;p&gt;
The IP ranges shift and expand on a very frequent basis and cover all of the Windows
Azure services. Thus, a customer will open their firewall for traffic for the entire
multitenant range of Azure, which means that the customer’s environment can reach
their own apps and the backend services for the “Whack A Panda” game just the same.
With apps in the cloud, there is no actual security gain from these sorts of constraints;
pretty much all the advantages of automated, self-service cloud environments stem
from shared resources including shared networking and shared gateways and the ability
to do dynamic failover including cross-DC failover and the like that means that there
aren’t any reservations at the IP level that last forever.
&lt;/p&gt;
&lt;p&gt;
The best way to handle this is to do the exact inverse of what’s being tried with
these rules, and rather limit access to outside resources to a constrained set of
services based on the services’ or users’ identity as it is done on our Microsoft
corporate network. At Microsoft, you can’t get out through the NAT/Proxy unless you
have an account that has external network privileges. If you are worried about a service
or user abusing access to the Internet, don’t give them Internet. If you think you
need to have tight control, make a DMZ – in the opposite direction of how you usually
think about a DMZ. 
&lt;/p&gt;
&lt;p&gt;
Using IP-address based outbound firewall access rules constraining access to public
cloud computing resources is probably getting a box on a check-list ticked, but it
doesn’t add anything from a security perspective. It’s theater. IMHO.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=99035bd6-2110-4b0d-bf9e-e337ee1342a1" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,99035bd6-2110-4b0d-bf9e-e337ee1342a1.aspx</comments>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m toying around with very small and very constrained embedded devices right now.
When you make millions of a small thing, every byte in code footprint and any processing
cycle you can save saves real money. An XML parser is a big chunk of code. So is a
JSON parser. Every HTTP stack already has a key/value pair parser for headers. We
can use that.
</p>
        <p>
NHTTP stands for NoHyperText Transfer Protocol. Yes, I made that up. No, this is not
an April Fool’s joke. Hear me out.
</p>
        <p>
All rules of RFC2616 apply, except for <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2" target="_blank">section
7.2</a>, meaning there is must never an entity body on any request or reply. Instead
we rely entirely on <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1" target="_blank">section
7.1</a> and its extensibility rule: 
</p>
        <ul>
          <li>
            <em>The extension-header mechanism allows additional entity-header fields to be defined
without changing the protocol, but these fields cannot be assumed to be recognizable
by the recipient. Unrecognized header fields SHOULD be ignored by the recipient and <font color="#ff0000">MUST</font> be
forwarded by transparent proxies.</em>
          </li>
        </ul>
        <p>
All property payloads are expressed as key/value pairs that are directly mapped onto
HTTP headers. No value can exceed 2KB in size and you can’t have more than 32 values
per message so that we stay comfortably within common HTTP infrastructure quotas.
To avoid collisions with existing headers and to allow for easy enumeration, each
property key is prefixed with “P-“ 
</p>
        <p>
POST /foo HTTP/1.1 
<br />
Host: example.com 
<br />
Content-Length: 0 
<br />
P-Name: “Clemens”
</p>
        <p>
HTTP/1.1 200 OK 
<br />
Content-Length: 0 
<br />
P-Greeting: “Hello, Clemens”
</p>
        <p>
(The fun bit is that the Windows Azure Service Bus HTTP API for sending and receiving
messages already supports this exact model since we map custom message properties
to headers and the HTTP entity body to the body of broker messages and those can be
empty)
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb" />
      </body>
      <title>NHTTP</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb.aspx</guid>
      <link>http://vasters.com/clemensv/2012/05/04/NHTTP.aspx</link>
      <pubDate>Fri, 04 May 2012 15:15:33 GMT</pubDate>
      <description>&lt;p&gt;
I’m toying around with very small and very constrained embedded devices right now.
When you make millions of a small thing, every byte in code footprint and any processing
cycle you can save saves real money. An XML parser is a big chunk of code. So is a
JSON parser. Every HTTP stack already has a key/value pair parser for headers. We
can use that.
&lt;/p&gt;
&lt;p&gt;
NHTTP stands for NoHyperText Transfer Protocol. Yes, I made that up. No, this is not
an April Fool’s joke. Hear me out.
&lt;/p&gt;
&lt;p&gt;
All rules of RFC2616 apply, except for &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2" target=_blank&gt;section
7.2&lt;/a&gt;, meaning there is must never an entity body on any request or reply. Instead
we rely entirely on &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1" target=_blank&gt;section
7.1&lt;/a&gt; and its extensibility rule: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;The extension-header mechanism allows additional entity-header fields to be defined
without changing the protocol, but these fields cannot be assumed to be recognizable
by the recipient. Unrecognized header fields SHOULD be ignored by the recipient and &lt;font color=#ff0000&gt;MUST&lt;/font&gt; be
forwarded by transparent proxies.&lt;/em&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All property payloads are expressed as key/value pairs that are directly mapped onto
HTTP headers. No value can exceed 2KB in size and you can’t have more than 32 values
per message so that we stay comfortably within common HTTP infrastructure quotas.
To avoid collisions with existing headers and to allow for easy enumeration, each
property key is prefixed with “P-“ 
&lt;/p&gt;
&lt;p&gt;
POST /foo HTTP/1.1 
&lt;br&gt;
Host: example.com 
&lt;br&gt;
Content-Length: 0 
&lt;br&gt;
P-Name: “Clemens”
&lt;/p&gt;
&lt;p&gt;
HTTP/1.1 200 OK 
&lt;br&gt;
Content-Length: 0 
&lt;br&gt;
P-Greeting: “Hello, Clemens”
&lt;/p&gt;
&lt;p&gt;
(The fun bit is that the Windows Azure Service Bus HTTP API for sending and receiving
messages already supports this exact model since we map custom message properties
to headers and the HTTP entity body to the body of broker messages and those can be
empty)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,8a3fd52b-447c-4a1d-a226-6e01dcf9e3bb.aspx</comments>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=30d7ab71-6985-4917-bb70-665970a49738</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,30d7ab71-6985-4917-bb70-665970a49738.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,30d7ab71-6985-4917-bb70-665970a49738.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=30d7ab71-6985-4917-bb70-665970a49738</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_2.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 0px 0px 6px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: right; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px" title="image" border="0" alt="image" align="right" src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_thumb.png" width="502" height="319" />
          </a>I’ll
admit this is an odd topic for me to write about since my job pretty far away from
that part of the world, but our PM team at MS is building a set of demos for which
we need some semi-random and fun input data that doesn’t change all that rapidly.
So we thought that reading the temperature off hard drives would be a nice input.
But how to get at it? 
</p>
        <p>
The solution is to use the WMI interface for ATAPI to get at the SMART data. Binging
the subject you’ll find a ton of little snippets that have one thing in common: ‘magic’.
Somehow, you get at the ‘VendorSpecific’ structure of the SMART data using WMI and
then you believe that byte number 115 is the one that holds the temperature. Of course
that’s not what someone who’s doing protocol in their day-job would ever settle for.
So I’ve been digging around a little and found a <a href="http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf" target="_blank">description
of the structure</a> and grabbed the <a href="http://en.wikipedia.org/wiki/S.M.A.R.T." target="_blank">attribute
value list</a> from Wikipedia, shook it all up a little and out came the little program
below.
</p>
        <p>
The app grabs the vendor specific array from the ATAPI data, shreds it into a set
of structures, and dumps it out. Code here, zip file at the bottom.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="rem">// (c) Microsoft Corporation</span>
          </pre>
          <pre>
            <span class="rem">// Author: Clemens Vasters (clemensv@microsoft.com)</span>
          </pre>
          <pre class="alt">
            <span class="rem">// Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html </span>
          </pre>
          <pre>
            <span class="rem">// SMART Attributes and Background: http://en.wikipedia.org/wiki/S.M.A.R.T.</span>
          </pre>
          <pre class="alt">
            <span class="rem">// SMART Attributes Overview: http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf</span>
          </pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">namespace</span> SmartDataApp</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">using</span> System;</pre>
          <pre>
            <span class="kwrd">using</span> System.Collections.Generic;</pre>
          <pre class="alt">
            <span class="kwrd">using</span> System.Management;</pre>
          <pre>
            <span class="kwrd">using</span> System.Runtime.InteropServices;</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="kwrd">public</span>
            <span class="kwrd">enum</span> SmartAttributeType
: <span class="kwrd">byte</span></pre>
          <pre class="alt">    {</pre>
          <pre>        ReadErrorRate = 0x01,</pre>
          <pre class="alt">        ThroughputPerformance = 0x02,</pre>
          <pre>        SpinUpTime = 0x03,</pre>
          <pre class="alt">        StartStopCount = 0x04,</pre>
          <pre>        ReallocatedSectorsCount = 0x05,</pre>
          <pre class="alt">        ReadChannelMargin = 0x06,</pre>
          <pre>        SeekErrorRate = 0x07,</pre>
          <pre class="alt">        SeekTimePerformance = 0x08,</pre>
          <pre>        PowerOnHoursPOH = 0x09,</pre>
          <pre class="alt">        SpinRetryCount = 0x0A,</pre>
          <pre>        CalibrationRetryCount = 0x0B,</pre>
          <pre class="alt">        PowerCycleCount = 0x0C,</pre>
          <pre>        SoftReadErrorRate = 0x0D,</pre>
          <pre class="alt">        SATADownshiftErrorCount = 0xB7,</pre>
          <pre>        EndtoEnderror = 0xB8,</pre>
          <pre class="alt">        HeadStability = 0xB9,</pre>
          <pre>        InducedOpVibrationDetection = 0xBA,</pre>
          <pre class="alt">        ReportedUncorrectableErrors = 0xBB,</pre>
          <pre>        CommandTimeout = 0xBC,</pre>
          <pre class="alt">        HighFlyWrites = 0xBD,</pre>
          <pre>        AirflowTemperatureWDC = 0xBE,</pre>
          <pre class="alt">        TemperatureDifferencefrom100 = 0xBE,</pre>
          <pre>        GSenseErrorRate = 0xBF,</pre>
          <pre class="alt">        PoweroffRetractCount = 0xC0,</pre>
          <pre>        LoadCycleCount = 0xC1,</pre>
          <pre class="alt">        Temperature = 0xC2,</pre>
          <pre>        HardwareECCRecovered = 0xC3,</pre>
          <pre class="alt">        ReallocationEventCount = 0xC4,</pre>
          <pre>        CurrentPendingSectorCount = 0xC5,</pre>
          <pre class="alt">        UncorrectableSectorCount = 0xC6,</pre>
          <pre>        UltraDMACRCErrorCount = 0xC7,</pre>
          <pre class="alt">        MultiZoneErrorRate = 0xC8,</pre>
          <pre>        WriteErrorRateFujitsu = 0xC8,</pre>
          <pre class="alt">        OffTrackSoftReadErrorRate = 0xC9,</pre>
          <pre>        DataAddressMarkerrors = 0xCA,</pre>
          <pre class="alt">        RunOutCancel = 0xCB,</pre>
          <pre>        SoftECCCorrection = 0xCC,</pre>
          <pre class="alt">        ThermalAsperityRateTAR = 0xCD,</pre>
          <pre>        FlyingHeight = 0xCE,</pre>
          <pre class="alt">        SpinHighCurrent = 0xCF,</pre>
          <pre>        SpinBuzz = 0xD0,</pre>
          <pre class="alt">        OfflineSeekPerformance = 0xD1,</pre>
          <pre>        VibrationDuringWrite = 0xD3,</pre>
          <pre class="alt">        ShockDuringWrite = 0xD4,</pre>
          <pre>        DiskShift = 0xDC,</pre>
          <pre class="alt">        GSenseErrorRateAlt = 0xDD,</pre>
          <pre>        LoadedHours = 0xDE,</pre>
          <pre class="alt">        LoadUnloadRetryCount = 0xDF,</pre>
          <pre>        LoadFriction = 0xE0,</pre>
          <pre class="alt">        LoadUnloadCycleCount = 0xE1,</pre>
          <pre>        LoadInTime = 0xE2,</pre>
          <pre class="alt">        TorqueAmplificationCount = 0xE3,</pre>
          <pre>        PowerOffRetractCycle = 0xE4,</pre>
          <pre class="alt">        GMRHeadAmplitude = 0xE6,</pre>
          <pre>        DriveTemperature = 0xE7,</pre>
          <pre class="alt">        HeadFlyingHours = 0xF0,</pre>
          <pre>        TransferErrorRateFujitsu = 0xF0,</pre>
          <pre class="alt">        TotalLBAsWritten = 0xF1,</pre>
          <pre>        TotalLBAsRead = 0xF2,</pre>
          <pre class="alt">        ReadErrorRetryRate = 0xFA,</pre>
          <pre>        FreeFallProtection = 0xFE,</pre>
          <pre class="alt">    }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">class</span> SmartData</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">readonly</span> Dictionary&lt;SmartAttributeType,
SmartAttribute&gt; attributes;</pre>
          <pre>
            <span class="kwrd">readonly</span>
            <span class="kwrd">ushort</span> structureVersion;</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="kwrd">public</span> SmartData(<span class="kwrd">byte</span>[]
arrVendorSpecific)</pre>
          <pre class="alt">        {</pre>
          <pre>            attributes = <span class="kwrd">new</span> Dictionary&lt;SmartAttributeType,
SmartAttribute&gt;();</pre>
          <pre class="alt">
            <span class="kwrd">for</span> (<span class="kwrd">int</span> offset
= 2; offset &lt; arrVendorSpecific.Length; )</pre>
          <pre>            {</pre>
          <pre class="alt">                var a = FromBytes&lt;SmartAttribute&gt;(arrVendorSpecific, <span class="kwrd">ref</span> offset,
12);</pre>
          <pre>
            <span class="rem">// Attribute values 0x00, 0xfe, 0xff are invalid</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">if</span> (a.AttributeType !=
0x00 &amp;&amp; (<span class="kwrd">byte</span>)a.AttributeType != 0xfe &amp;&amp;
(<span class="kwrd">byte</span>)a.AttributeType != 0xff)</pre>
          <pre>                {</pre>
          <pre class="alt">                    attributes[a.AttributeType] = a;</pre>
          <pre>                }</pre>
          <pre class="alt">            }</pre>
          <pre>            structureVersion = (<span class="kwrd">ushort</span>)(arrVendorSpecific[0]
* 256 + arrVendorSpecific[1]);</pre>
          <pre class="alt">        }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">ushort</span> StructureVersion</pre>
          <pre>        {</pre>
          <pre class="alt">            get</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="kwrd">return</span>
            <span class="kwrd">this</span>.structureVersion;</pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span> SmartAttribute <span class="kwrd">this</span>[SmartAttributeType
v]</pre>
          <pre>        {</pre>
          <pre class="alt">            get</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="kwrd">return</span>
            <span class="kwrd">this</span>.attributes[v];</pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span> IEnumerable&lt;SmartAttribute&gt;
Attributes</pre>
          <pre>        {</pre>
          <pre class="alt">            get</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="kwrd">return</span>
            <span class="kwrd">this</span>.attributes.Values;</pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">static</span> T FromBytes&lt;T&gt;(<span class="kwrd">byte</span>[]
bytearray, <span class="kwrd">ref</span><span class="kwrd">int</span> offset, <span class="kwrd">int</span> count)</pre>
          <pre>        {</pre>
          <pre class="alt">            IntPtr ptr = IntPtr.Zero;</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">try</span>
          </pre>
          <pre>            {</pre>
          <pre class="alt">                ptr = Marshal.AllocHGlobal(count);</pre>
          <pre>                Marshal.Copy(bytearray, offset, ptr, count);</pre>
          <pre class="alt">                offset += count;</pre>
          <pre>
            <span class="kwrd">return</span> (T)Marshal.PtrToStructure(ptr, <span class="kwrd">typeof</span>(T));</pre>
          <pre class="alt">            }</pre>
          <pre>
            <span class="kwrd">finally</span>
          </pre>
          <pre class="alt">            {</pre>
          <pre>
            <span class="kwrd">if</span> (ptr != IntPtr.Zero)</pre>
          <pre class="alt">                {</pre>
          <pre>                    Marshal.FreeHGlobal(ptr);</pre>
          <pre class="alt">                }</pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre>    }</pre>
          <pre class="alt"> </pre>
          <pre>    [StructLayout(LayoutKind.Sequential)]</pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">struct</span> SmartAttribute</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">public</span> SmartAttributeType AttributeType;</pre>
          <pre>
            <span class="kwrd">public</span>
            <span class="kwrd">ushort</span> Flags;</pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">byte</span> Value;</pre>
          <pre>        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]</pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">byte</span>[]
VendorData;</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">bool</span> Advisory</pre>
          <pre>        {</pre>
          <pre class="alt">            get</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="kwrd">return</span> (Flags &amp; 0x1)
== 0x0; <span class="rem">// Bit 0 unset?</span></pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre>
            <span class="kwrd">public</span>
            <span class="kwrd">bool</span> FailureImminent</pre>
          <pre class="alt">        {</pre>
          <pre>            get</pre>
          <pre class="alt">            {</pre>
          <pre>
            <span class="kwrd">return</span> (Flags &amp; 0x1) == 0x1; <span class="rem">//
Bit 0 set?</span></pre>
          <pre class="alt">            }</pre>
          <pre>        }</pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">bool</span> OnlineDataCollection</pre>
          <pre>        {</pre>
          <pre class="alt">            get</pre>
          <pre>            {</pre>
          <pre class="alt">
            <span class="kwrd">return</span> (Flags &amp; 0x2)
== 0x2; <span class="rem">// Bit 0 set?</span></pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre> </pre>
          <pre class="alt">    }</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">class</span> Program</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">public</span>
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> Main()</pre>
          <pre>        {</pre>
          <pre class="alt">
            <span class="kwrd">try</span>
          </pre>
          <pre>            {</pre>
          <pre class="alt">                var searcher = <span class="kwrd">new</span> ManagementObjectSearcher(<span class="str">"root\\WMI"</span>, <span class="str">"SELECT
* FROM MSStorageDriver_ATAPISmartData"</span>);</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">foreach</span> (ManagementObject
queryObj <span class="kwrd">in</span> searcher.Get())</pre>
          <pre>                {</pre>
          <pre class="alt">                    Console.WriteLine(<span class="str">"-----------------------------------"</span>);</pre>
          <pre>                    Console.WriteLine(<span class="str">"MSStorageDriver_ATAPISmartData
instance"</span>);</pre>
          <pre class="alt">                    Console.WriteLine(<span class="str">"-----------------------------------"</span>);</pre>
          <pre> </pre>
          <pre class="alt">                    var arrVendorSpecific = (<span class="kwrd">byte</span>[])queryObj.GetPropertyValue(<span class="str">"VendorSpecific"</span>);</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="rem">// Create SMART data from 'vendor
specific' array</span>
          </pre>
          <pre>                    var d = <span class="kwrd">new</span> SmartData(arrVendorSpecific);</pre>
          <pre class="alt">
            <span class="kwrd">foreach</span> (var b <span class="kwrd">in</span> d.Attributes)</pre>
          <pre>                    {</pre>
          <pre class="alt">                        Console.Write(<span class="str">"{0} :{1}
: "</span>, b.AttributeType, b.Value);</pre>
          <pre>
            <span class="kwrd">foreach</span> (<span class="kwrd">byte</span> vendorByte <span class="kwrd">in</span> b.VendorData)</pre>
          <pre class="alt">                        {</pre>
          <pre>                            Console.Write(<span class="str">"{0:x} "</span>,
vendorByte);</pre>
          <pre class="alt">                        }</pre>
          <pre>                        Console.WriteLine();</pre>
          <pre class="alt">                    }</pre>
          <pre> </pre>
          <pre class="alt">                }</pre>
          <pre>            }</pre>
          <pre class="alt">
            <span class="kwrd">catch</span> (ManagementException
e)</pre>
          <pre>            {</pre>
          <pre class="alt">                Console.WriteLine(<span class="str">"An error occurred
while querying for WMI data: "</span> + e.Message);</pre>
          <pre>            }</pre>
          <pre class="alt">        }</pre>
          <pre>    }</pre>
          <pre class="alt">}</pre>
        </div>
        <p>
          <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        </p>
        <p>
 
</p>
        <a href="http://vasters.com/clemensv/content/binary/SmartDataProgram.zip">SmartDataProgram.zip
(2.25 KB)</a>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=30d7ab71-6985-4917-bb70-665970a49738" />
      </body>
      <title>Reading ATAPI SMART Data from Drives using .NET; Temperature Anyone?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,30d7ab71-6985-4917-bb70-665970a49738.aspx</guid>
      <link>http://vasters.com/clemensv/2011/04/11/Reading+ATAPI+SMART+Data+From+Drives+Using+NET+Temperature+Anyone.aspx</link>
      <pubDate>Mon, 11 Apr 2011 16:21:16 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 0px 0px 6px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: right; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px" title=image border=0 alt=image align=right src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_thumb.png" width=502 height=319&gt;&lt;/a&gt;I’ll
admit this is an odd topic for me to write about since my job pretty far away from
that part of the world, but our PM team at MS is building a set of demos for which
we need some semi-random and fun input data that doesn’t change all that rapidly.
So we thought that reading the temperature off hard drives would be a nice input.
But how to get at it? 
&lt;/p&gt;
&lt;p&gt;
The solution is to use the WMI interface for ATAPI to get at the SMART data. Binging
the subject you’ll find a ton of little snippets that have one thing in common: ‘magic’.
Somehow, you get at the ‘VendorSpecific’ structure of the SMART data using WMI and
then you believe that byte number 115 is the one that holds the temperature. Of course
that’s not what someone who’s doing protocol in their day-job would ever settle for.
So I’ve been digging around a little and found a &lt;a href="http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf" target=_blank&gt;description
of the structure&lt;/a&gt; and grabbed the &lt;a href="http://en.wikipedia.org/wiki/S.M.A.R.T." target=_blank&gt;attribute
value list&lt;/a&gt; from Wikipedia, shook it all up a little and out came the little program
below.
&lt;/p&gt;
&lt;p&gt;
The app grabs the vendor specific array from the ATAPI data, shreds it into a set
of structures, and dumps it out. Code here, zip file at the bottom.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt;// (c) Microsoft Corporation&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=rem&gt;// Author: Clemens Vasters (clemensv@microsoft.com)&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=rem&gt;// Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=rem&gt;// SMART Attributes and Background: http://en.wikipedia.org/wiki/S.M.A.R.T.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=rem&gt;// SMART Attributes Overview: http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;&lt;span class=kwrd&gt;namespace&lt;/span&gt; SmartDataApp&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Management;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Runtime.InteropServices;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;enum&lt;/span&gt; SmartAttributeType
: &lt;span class=kwrd&gt;byte&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        ReadErrorRate = 0x01,&lt;/pre&gt;
&lt;pre class=alt&gt;        ThroughputPerformance = 0x02,&lt;/pre&gt;
&lt;pre&gt;        SpinUpTime = 0x03,&lt;/pre&gt;
&lt;pre class=alt&gt;        StartStopCount = 0x04,&lt;/pre&gt;
&lt;pre&gt;        ReallocatedSectorsCount = 0x05,&lt;/pre&gt;
&lt;pre class=alt&gt;        ReadChannelMargin = 0x06,&lt;/pre&gt;
&lt;pre&gt;        SeekErrorRate = 0x07,&lt;/pre&gt;
&lt;pre class=alt&gt;        SeekTimePerformance = 0x08,&lt;/pre&gt;
&lt;pre&gt;        PowerOnHoursPOH = 0x09,&lt;/pre&gt;
&lt;pre class=alt&gt;        SpinRetryCount = 0x0A,&lt;/pre&gt;
&lt;pre&gt;        CalibrationRetryCount = 0x0B,&lt;/pre&gt;
&lt;pre class=alt&gt;        PowerCycleCount = 0x0C,&lt;/pre&gt;
&lt;pre&gt;        SoftReadErrorRate = 0x0D,&lt;/pre&gt;
&lt;pre class=alt&gt;        SATADownshiftErrorCount = 0xB7,&lt;/pre&gt;
&lt;pre&gt;        EndtoEnderror = 0xB8,&lt;/pre&gt;
&lt;pre class=alt&gt;        HeadStability = 0xB9,&lt;/pre&gt;
&lt;pre&gt;        InducedOpVibrationDetection = 0xBA,&lt;/pre&gt;
&lt;pre class=alt&gt;        ReportedUncorrectableErrors = 0xBB,&lt;/pre&gt;
&lt;pre&gt;        CommandTimeout = 0xBC,&lt;/pre&gt;
&lt;pre class=alt&gt;        HighFlyWrites = 0xBD,&lt;/pre&gt;
&lt;pre&gt;        AirflowTemperatureWDC = 0xBE,&lt;/pre&gt;
&lt;pre class=alt&gt;        TemperatureDifferencefrom100 = 0xBE,&lt;/pre&gt;
&lt;pre&gt;        GSenseErrorRate = 0xBF,&lt;/pre&gt;
&lt;pre class=alt&gt;        PoweroffRetractCount = 0xC0,&lt;/pre&gt;
&lt;pre&gt;        LoadCycleCount = 0xC1,&lt;/pre&gt;
&lt;pre class=alt&gt;        Temperature = 0xC2,&lt;/pre&gt;
&lt;pre&gt;        HardwareECCRecovered = 0xC3,&lt;/pre&gt;
&lt;pre class=alt&gt;        ReallocationEventCount = 0xC4,&lt;/pre&gt;
&lt;pre&gt;        CurrentPendingSectorCount = 0xC5,&lt;/pre&gt;
&lt;pre class=alt&gt;        UncorrectableSectorCount = 0xC6,&lt;/pre&gt;
&lt;pre&gt;        UltraDMACRCErrorCount = 0xC7,&lt;/pre&gt;
&lt;pre class=alt&gt;        MultiZoneErrorRate = 0xC8,&lt;/pre&gt;
&lt;pre&gt;        WriteErrorRateFujitsu = 0xC8,&lt;/pre&gt;
&lt;pre class=alt&gt;        OffTrackSoftReadErrorRate = 0xC9,&lt;/pre&gt;
&lt;pre&gt;        DataAddressMarkerrors = 0xCA,&lt;/pre&gt;
&lt;pre class=alt&gt;        RunOutCancel = 0xCB,&lt;/pre&gt;
&lt;pre&gt;        SoftECCCorrection = 0xCC,&lt;/pre&gt;
&lt;pre class=alt&gt;        ThermalAsperityRateTAR = 0xCD,&lt;/pre&gt;
&lt;pre&gt;        FlyingHeight = 0xCE,&lt;/pre&gt;
&lt;pre class=alt&gt;        SpinHighCurrent = 0xCF,&lt;/pre&gt;
&lt;pre&gt;        SpinBuzz = 0xD0,&lt;/pre&gt;
&lt;pre class=alt&gt;        OfflineSeekPerformance = 0xD1,&lt;/pre&gt;
&lt;pre&gt;        VibrationDuringWrite = 0xD3,&lt;/pre&gt;
&lt;pre class=alt&gt;        ShockDuringWrite = 0xD4,&lt;/pre&gt;
&lt;pre&gt;        DiskShift = 0xDC,&lt;/pre&gt;
&lt;pre class=alt&gt;        GSenseErrorRateAlt = 0xDD,&lt;/pre&gt;
&lt;pre&gt;        LoadedHours = 0xDE,&lt;/pre&gt;
&lt;pre class=alt&gt;        LoadUnloadRetryCount = 0xDF,&lt;/pre&gt;
&lt;pre&gt;        LoadFriction = 0xE0,&lt;/pre&gt;
&lt;pre class=alt&gt;        LoadUnloadCycleCount = 0xE1,&lt;/pre&gt;
&lt;pre&gt;        LoadInTime = 0xE2,&lt;/pre&gt;
&lt;pre class=alt&gt;        TorqueAmplificationCount = 0xE3,&lt;/pre&gt;
&lt;pre&gt;        PowerOffRetractCycle = 0xE4,&lt;/pre&gt;
&lt;pre class=alt&gt;        GMRHeadAmplitude = 0xE6,&lt;/pre&gt;
&lt;pre&gt;        DriveTemperature = 0xE7,&lt;/pre&gt;
&lt;pre class=alt&gt;        HeadFlyingHours = 0xF0,&lt;/pre&gt;
&lt;pre&gt;        TransferErrorRateFujitsu = 0xF0,&lt;/pre&gt;
&lt;pre class=alt&gt;        TotalLBAsWritten = 0xF1,&lt;/pre&gt;
&lt;pre&gt;        TotalLBAsRead = 0xF2,&lt;/pre&gt;
&lt;pre class=alt&gt;        ReadErrorRetryRate = 0xFA,&lt;/pre&gt;
&lt;pre&gt;        FreeFallProtection = 0xFE,&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;class&lt;/span&gt; SmartData&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;readonly&lt;/span&gt; Dictionary&amp;lt;SmartAttributeType,
SmartAttribute&amp;gt; attributes;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; structureVersion;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartData(&lt;span class=kwrd&gt;byte&lt;/span&gt;[]
arrVendorSpecific)&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            attributes = &lt;span class=kwrd&gt;new&lt;/span&gt; Dictionary&amp;lt;SmartAttributeType,
SmartAttribute&amp;gt;();&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;for&lt;/span&gt; (&lt;span class=kwrd&gt;int&lt;/span&gt; offset
= 2; offset &amp;lt; arrVendorSpecific.Length; )&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                var a = FromBytes&amp;lt;SmartAttribute&amp;gt;(arrVendorSpecific, &lt;span class=kwrd&gt;ref&lt;/span&gt; offset,
12);&lt;/pre&gt;
&lt;pre&gt;                &lt;span class=rem&gt;// Attribute values 0x00, 0xfe, 0xff are invalid&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;if&lt;/span&gt; (a.AttributeType != 0x00
&amp;amp;&amp;amp; (&lt;span class=kwrd&gt;byte&lt;/span&gt;)a.AttributeType != 0xfe &amp;amp;&amp;amp; (&lt;span class=kwrd&gt;byte&lt;/span&gt;)a.AttributeType
!= 0xff)&lt;/pre&gt;
&lt;pre&gt;                {&lt;/pre&gt;
&lt;pre class=alt&gt;                    attributes[a.AttributeType] = a;&lt;/pre&gt;
&lt;pre&gt;                }&lt;/pre&gt;
&lt;pre class=alt&gt;            }&lt;/pre&gt;
&lt;pre&gt;            structureVersion = (&lt;span class=kwrd&gt;ushort&lt;/span&gt;)(arrVendorSpecific[0]
* 256 + arrVendorSpecific[1]);&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; StructureVersion&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            get&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.structureVersion;&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartAttribute &lt;span class=kwrd&gt;this&lt;/span&gt;[SmartAttributeType
v]&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            get&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.attributes[v];&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; IEnumerable&amp;lt;SmartAttribute&amp;gt;
Attributes&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            get&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.attributes.Values;&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;static&lt;/span&gt; T FromBytes&amp;lt;T&amp;gt;(&lt;span class=kwrd&gt;byte&lt;/span&gt;[]
bytearray, &lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;int&lt;/span&gt; offset, &lt;span class=kwrd&gt;int&lt;/span&gt; count)&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            IntPtr ptr = IntPtr.Zero;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                ptr = Marshal.AllocHGlobal(count);&lt;/pre&gt;
&lt;pre&gt;                Marshal.Copy(bytearray, offset, ptr, count);&lt;/pre&gt;
&lt;pre class=alt&gt;                offset += count;&lt;/pre&gt;
&lt;pre&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (T)Marshal.PtrToStructure(ptr, &lt;span class=kwrd&gt;typeof&lt;/span&gt;(T));&lt;/pre&gt;
&lt;pre class=alt&gt;            }&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;finally&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            {&lt;/pre&gt;
&lt;pre&gt;                &lt;span class=kwrd&gt;if&lt;/span&gt; (ptr != IntPtr.Zero)&lt;/pre&gt;
&lt;pre class=alt&gt;                {&lt;/pre&gt;
&lt;pre&gt;                    Marshal.FreeHGlobal(ptr);&lt;/pre&gt;
&lt;pre class=alt&gt;                }&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    [StructLayout(LayoutKind.Sequential)]&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;struct&lt;/span&gt; SmartAttribute&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartAttributeType AttributeType;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; Flags;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;byte&lt;/span&gt; Value;&lt;/pre&gt;
&lt;pre&gt;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;byte&lt;/span&gt;[]
VendorData;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; Advisory&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            get&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x1) ==
0x0; &lt;span class=rem&gt;// Bit 0 unset?&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; FailureImminent&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            get&lt;/pre&gt;
&lt;pre class=alt&gt;            {&lt;/pre&gt;
&lt;pre&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x1) == 0x1; &lt;span class=rem&gt;//
Bit 0 set?&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            }&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; OnlineDataCollection&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            get&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x2) ==
0x2; &lt;span class=rem&gt;// Bit 0 set?&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;class&lt;/span&gt; Program&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; Main()&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                var searcher = &lt;span class=kwrd&gt;new&lt;/span&gt; ManagementObjectSearcher(&lt;span class=str&gt;"root\\WMI"&lt;/span&gt;, &lt;span class=str&gt;"SELECT
* FROM MSStorageDriver_ATAPISmartData"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;foreach&lt;/span&gt; (ManagementObject queryObj &lt;span class=kwrd&gt;in&lt;/span&gt; searcher.Get())&lt;/pre&gt;
&lt;pre&gt;                {&lt;/pre&gt;
&lt;pre class=alt&gt;                    Console.WriteLine(&lt;span class=str&gt;"-----------------------------------"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;                    Console.WriteLine(&lt;span class=str&gt;"MSStorageDriver_ATAPISmartData
instance"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;                    Console.WriteLine(&lt;span class=str&gt;"-----------------------------------"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;                    var arrVendorSpecific = (&lt;span class=kwrd&gt;byte&lt;/span&gt;[])queryObj.GetPropertyValue(&lt;span class=str&gt;"VendorSpecific"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;                    &lt;span class=rem&gt;// Create SMART data from 'vendor
specific' array&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;                    var d = &lt;span class=kwrd&gt;new&lt;/span&gt; SmartData(arrVendorSpecific);&lt;/pre&gt;
&lt;pre class=alt&gt;                    &lt;span class=kwrd&gt;foreach&lt;/span&gt; (var b &lt;span class=kwrd&gt;in&lt;/span&gt; d.Attributes)&lt;/pre&gt;
&lt;pre&gt;                    {&lt;/pre&gt;
&lt;pre class=alt&gt;                        Console.Write(&lt;span class=str&gt;"{0} :{1} : "&lt;/span&gt;,
b.AttributeType, b.Value);&lt;/pre&gt;
&lt;pre&gt;                        &lt;span class=kwrd&gt;foreach&lt;/span&gt; (&lt;span class=kwrd&gt;byte&lt;/span&gt; vendorByte &lt;span class=kwrd&gt;in&lt;/span&gt; b.VendorData)&lt;/pre&gt;
&lt;pre class=alt&gt;                        {&lt;/pre&gt;
&lt;pre&gt;                            Console.Write(&lt;span class=str&gt;"{0:x} "&lt;/span&gt;, vendorByte);&lt;/pre&gt;
&lt;pre class=alt&gt;                        }&lt;/pre&gt;
&lt;pre&gt;                        Console.WriteLine();&lt;/pre&gt;
&lt;pre class=alt&gt;                    }&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;                }&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;catch&lt;/span&gt; (ManagementException e)&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class=alt&gt;                Console.WriteLine(&lt;span class=str&gt;"An error occurred
while querying for WMI data: "&lt;/span&gt; + e.Message);&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/SmartDataProgram.zip"&gt;SmartDataProgram.zip
(2.25 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=30d7ab71-6985-4917-bb70-665970a49738" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,30d7ab71-6985-4917-bb70-665970a49738.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=d2926b39-5935-449b-927a-2a2421c1aaeb</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,d2926b39-5935-449b-927a-2a2421c1aaeb.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,d2926b39-5935-449b-927a-2a2421c1aaeb.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=d2926b39-5935-449b-927a-2a2421c1aaeb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <iframe title="YouTube video player" height="390" src="http://www.youtube.com/embed/EqDKRCucIL8" frameborder="0" width="640" allowfullscreen="allowfullscreen">
        </iframe>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d2926b39-5935-449b-927a-2a2421c1aaeb" />
      </body>
      <title>What I do at work &amp;ndash; Cloud and Service Bus for Normal People</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,d2926b39-5935-449b-927a-2a2421c1aaeb.aspx</guid>
      <link>http://vasters.com/clemensv/2011/03/19/What+I+Do+At+Work+Ndash+Cloud+And+Service+Bus+For+Normal+People.aspx</link>
      <pubDate>Sat, 19 Mar 2011 05:06:43 GMT</pubDate>
      <description>&lt;iframe title="YouTube video player" height="390" src="http://www.youtube.com/embed/EqDKRCucIL8" frameborder="0" width="640" allowfullscreen="allowfullscreen"&gt;
&lt;/iframe&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d2926b39-5935-449b-927a-2a2421c1aaeb" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,d2926b39-5935-449b-927a-2a2421c1aaeb.aspx</comments>
      <category>Architecture</category>
      <category>Azure</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For programmers writing distributed systems and are not using queues in them just
yet. If you are a message-oriented middleware veteran - move along ;-)
</p>
        <object width="400" height="224">
          <param name="allowfullscreen" value="true" />
          <param name="movie" value="http://www.facebook.com/v/10150174116899187" />
          <embed src="http://www.facebook.com/v/10150174116899187" type="application/x-shockwave-flash" allowfullscreen="true" width="400" height="224">
          </embed>
        </object>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3" />
      </body>
      <title>Why would anyone ever use a (Message) Queue?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3.aspx</guid>
      <link>http://vasters.com/clemensv/2011/03/19/Why+Would+Anyone+Ever+Use+A+Message+Queue.aspx</link>
      <pubDate>Sat, 19 Mar 2011 05:04:39 GMT</pubDate>
      <description>&lt;p&gt;
For programmers writing distributed systems and are not using queues in them just
yet. If you are a message-oriented middleware veteran - move along ;-)
&lt;/p&gt;
&lt;object width="400" height="224" &gt;
&lt;param name="allowfullscreen" value="true" /&gt;
&lt;param name="movie" value="http://www.facebook.com/v/10150174116899187" /&gt;&lt;embed src="http://www.facebook.com/v/10150174116899187" type="application/x-shockwave-flash" allowfullscreen="true" width="400" height="224"&gt;&lt;/embed&gt;
&lt;/object&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3.aspx</comments>
      <category>Technology</category>
      <category>Technology/MSMQ</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=f5707b54-5d11-4b5a-a1c4-cfc65faca55e</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,f5707b54-5d11-4b5a-a1c4-cfc65faca55e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,f5707b54-5d11-4b5a-a1c4-cfc65faca55e.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=f5707b54-5d11-4b5a-a1c4-cfc65faca55e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
My PDC10 session is available online (it was pre-recorded). I talk about the new ‘Labs’
release that we released into the datacenter this week and about a range of future
capabilities that we’re planning for Service Bus. Some of those future capabilities
that are a bit further out are about bringing back some popular capabilities from
back in the .NET Services incubation days (like Push and Service Orchestration), some
are entirely new.
</p>
        <p>
One important note about the new release at <a href="http://portal.appfabriclabs.com">http://portal.appfabriclabs.com</a> –
for Service Bus, this is a focused release that provides mostly only new features
and doesn’t provide the full capability scope of the production system and SDK. The
goal here is to provide insight into an ongoing development process and opportunity
for feedback as we’re continuing to evolve AppFabric. So don’t derive any implications
from this release on what we’re going to do with the capabilities already in production.
</p>
        <p>
          <a href="http://player.microsoftpdc.com/Session/1f7d009e-29cb-4a15-a1bf-91ffd115c54d">Click
here to go to the talk.</a>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=f5707b54-5d11-4b5a-a1c4-cfc65faca55e" />
      </body>
      <title>PDC10 Windows Azure AppFabric - Service Bus Futures</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,f5707b54-5d11-4b5a-a1c4-cfc65faca55e.aspx</guid>
      <link>http://vasters.com/clemensv/2010/10/29/PDC10+Windows+Azure+AppFabric+Service+Bus+Futures.aspx</link>
      <pubDate>Fri, 29 Oct 2010 18:20:38 GMT</pubDate>
      <description>&lt;p&gt;
My PDC10 session is available online (it was pre-recorded). I talk about the new ‘Labs’
release that we released into the datacenter this week and about a range of future
capabilities that we’re planning for Service Bus. Some of those future capabilities
that are a bit further out are about bringing back some popular capabilities from
back in the .NET Services incubation days (like Push and Service Orchestration), some
are entirely new.
&lt;/p&gt;
&lt;p&gt;
One important note about the new release at &lt;a href="http://portal.appfabriclabs.com"&gt;http://portal.appfabriclabs.com&lt;/a&gt; –
for Service Bus, this is a focused release that provides mostly only new features
and doesn’t provide the full capability scope of the production system and SDK. The
goal here is to provide insight into an ongoing development process and opportunity
for feedback as we’re continuing to evolve AppFabric. So don’t derive any implications
from this release on what we’re going to do with the capabilities already in production.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://player.microsoftpdc.com/Session/1f7d009e-29cb-4a15-a1bf-91ffd115c54d"&gt;Click
here to go to the talk.&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=f5707b54-5d11-4b5a-a1c4-cfc65faca55e" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,f5707b54-5d11-4b5a-a1c4-cfc65faca55e.aspx</comments>
      <category>AppFabric</category>
      <category>Azure</category>
      <category>Technology</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=83f937f7-b838-43d0-ad61-74605eceafa2</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,83f937f7-b838-43d0-ad61-74605eceafa2.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,83f937f7-b838-43d0-ad61-74605eceafa2.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=83f937f7-b838-43d0-ad61-74605eceafa2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="justify">
As our team was starting to transform our parts of the Azure Services Platform from
a CTP ‘labs’ service exploring features into a full-on commercial service, it started
to dawn on us that we had set ourselves up for writing a bunch of ‘enterprise apps’.
The shiny parts of Service Bus and Access Control that we parade around are all about
user-facing features, but if I look back at the work we had to go from a toy service
to a commercial offering, I’d guess that 80%-90% of the effort went into aspects like
infrastructure, deployment, upgradeability, billing, provisioning, throttling, quotas,
security hardening, and service optimization. The lesson there was: when you’re boarding
the train to shipping a V1, you don’t load new features on that train –  you
rather throw some off. 
</p>
        <p align="justify">
The most interesting challenge for these infrastructure apps sitting on the backend
was that we didn’t have much solid ground to stand on. Remember – these were very
early days, so we couldn’t use SQL Azure since the folks over in SQL were on a pretty
heroic schedule themselves and didn’t want to take on any external dependencies even
from close friends. We also couldn’t use any of the capabilities of our own bits because
building infrastructure for your features on your features would just be plain dumb.
And while we could use capabilities of the Windows Azure platform we were building
on, a lot of those parts still had rough edges as those folks were going through a
lot of the same that we went through. In those days, the table store would be very
moody, the queue store would sometimes swallow or duplicate messages, the Azure fabric
controller would occasionally go around and kill things. All normal –  bugs.
</p>
        <p align="justify">
So under those circumstances we had to figure out the architecture for some subsystems
where we need to do a set of coordinated action across a distributed set of resources
– a distributed transaction or saga of sorts. The architecture had a few simple goals:
when we get an activation request, we must not fumble that request under any circumstance,
we must run the job to completion for all resources and, at the same time, we need
to minimize any potential for required operator intervention, i.e. if something goes
wrong, the system better knows how to deal with it – at best it should self-heal. 
</p>
        <p align="justify">
My solution to that puzzle is a pattern I call “Scheduler-Agent-Supervisor Pattern”
or, short, “Supervisor Pattern”. We keep finding applications for this pattern in
different places, so I think it’s worth writing about it in generic terms – even without
going into the details of our system.
</p>
        <p align="justify">
The pattern foots on two seemingly odd and very related assumptions: <em>‘</em><strong><em>the
system is perfect’</em></strong>and<strong><em>‘all error conditions are transient’</em>.</strong> As
a consequence, the architecture has some character traits of a toddler. It’s generally
happily optimistic and gets very grumpy, very quickly when things go wrong – to the
point that it will simply drop everything and run away screaming. It’s very precisely
like that, in fact.
</p>
        <p>
          <a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_2.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="image" border="0" alt="image" src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb.png" width="600" height="290" />
          </a>
        </p>
        <p align="justify">
The first picture here shows all key pieces except the <em>Supervisor</em> that I’ll
introduce later. At the core we have a <em>Scheduler</em> that manages a simple state
machine made up of <em>Jobs</em> and those jobs have <em>Steps</em>. The steps may
have a notion of interdependency or may be completely parallelizable. There is a <em>Job
Store</em> that holds jobs and steps and there are <em>Agents</em> that execute operations
on some resource.  Each <em>Agent</em> is (usually) fronted by a queue and the <em>Scheduler</em> has
a queue (or service endpoint) through which it receives reply messages from the <em>Agents</em>.
</p>
        <p align="justify">
Steps are recorded in a durable storage table of some sort that has at least the following
fields: <em>Current State</em> (say: Disabled, Active), <em>Desired State</em> (say:
Disabled, Active), <em>LockedUntil</em> (Date/Time value), and <em>Actor</em> plus
any step specific information you want to store and eventually submit with the job
to the step agent.
</p>
        <h3>When Things Go Right
</h3>
        <p>
The initial flow is as follows:
</p>
        <blockquote>
          <p>
            <strong>(1)a</strong> – Submit a new job into the Scheduler (and wait) 
<br /><strong>(2)a</strong> – The Scheduler creates a new job and steps with an initial
current state (<em>‘Disabled’</em>) in the job store  
<br /><strong>(2)b</strong> – The Scheduler sets ‘desired state’ of the job and of all schedulable
steps (dependencies?) to the target state (<em>‘Active’</em>) and sets the ‘locked
until’ timeout of the step to a value in the near future, e.g. ‘Now’ + 2 minutes. 
<br /><strong>(1)b</strong> – Job submission request unblocks and returns
</p>
        </blockquote>
        <p align="justify">
If all went well, we now have a job record and, here in this example, two step records
in our store. They have a current state of <em>‘Disabled’</em> and a desired state
of <em>‘Active’</em>. If things didn’t go well, we’d have incomplete or partially
wedged records or nothing in the job store, at all. The client would also know about
it since we’ve held on to the reply until we have everything done – so the client
is encouraged to retry. If we have nothing in the store and the client doesn’t retry
– well, then the job probably wasn’t all that important, after all. But if we have
at least a job record, we can make it all right later. We’re optimists, though; let’s
assume it all went well.
</p>
        <p align="justify">
For the next steps we assume that there’s a notion of dependencies between the steps
and the second steps depends on the first. If that were not the case, the two actions
would just be happening in parallel.
</p>
        <blockquote>
          <p>
            <strong>(3)</strong> – Place a step message into the queue for the actor for the first
step; Agent 1 in this case. The message contains all the information about the step,
including the current and desired state and also the <em>LockedUntil</em> that puts
an ultimatum on the activity. The message may further contain an action indicator
or arguments that are taken from the step record. 
<br /><strong>(4)</strong> – After the agent has done the work, it places a completion record
into the reply queue of the Scheduler. 
<br /><strong>(5)</strong> – The Scheduler records the step as complete by setting the current
state from ‘Disabled’ to ‘Active’; as a result the desired and the current state are
now equal. 
<br /><strong>(6)</strong> – The Scheduler sets the next step’s desired state to the target
state (<em>‘Active’</em>) and sets the <em>LockedUntil</em> timeout of the step to
a value in the near future, e.g. ‘Now’ + 1 minute. The lock timeout value is an ultimatum
for when the operation is expected to be complete and reported back as being complete
in a worst-case success case. The actual value therefore depends on the common latency
of operations in the system. If operations usually complete in milliseconds and at
worst within a second, the lock timeout can be short – but not too short. We’ll discuss
this  value in more detail a bit later. 
<br /><strong>(7)</strong>, <strong>(8)</strong>, <strong>(9)</strong> are equivalent to <strong>(3)</strong>, <strong>(4)</strong>, <strong>(5)</strong>.
</p>
        </blockquote>
        <p align="justify">
Once the last step’s current state is equal to the current state, the job’s current
state gets set to the desired state and we’re done. So that was the “99% of the time”
happy path.
</p>
        <p>
          <a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_4.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="image" border="0" alt="image" src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_1.png" width="591" height="286" />
          </a>
        </p>
        <h3>When Things Go Wrong
</h3>
        <p align="justify">
So what happens when anything goes wrong? Remember the principle <strong>‘all errors
are transient’</strong>. What we do in the error case – anywhere – is to log the error
condition and then promptly drop everything and simply hope that time, a change in
system conditions, human or divine intervention, or – at worst – a patch will heal
matters. That’s what the second principle <strong>‘the system is perfect’<em> </em></strong>is
about; the system obviously isn’t really perfect, but if we construct it in a way
that we can either wait for it to return from a wedged state into a functional state
or where we enable someone to go in and apply a fix for a blocking bug while preserving
the system state, we can consider the system ‘perfect’ in the sense that pretty much
any conceivable job that’s already in the system can be driven to completion.
</p>
        <p align="justify">
In the second picture, we have Agent 2 blowing up as it is processing the step it
got handed in <strong>(7)</strong>. If the agent just can’t get its work done since
some external dependency isn’t available – maybe a database can’t be reached or a
server it’s talking to spews out ‘server too busy’ errors – it may be able to back
off for a moment and retry. However, it must not retry past the <em>LockedUntil</em> ultimatum
that’s in the step record. When things fail and the agent is still breathing, it may,
as a matter of courtesy, notify the scheduler of the fact and report that the step
was completed with no result, i.e. the desired state and the achieved state don’t
match. That notification may also include diagnostic information. Once the <em>LockedUntil</em> ultimatum
has passed, the Agent no longer owns the job and must drop it. It must even not report
failure state back to the Scheduler past that point. 
</p>
        <p align="justify">
If the agent keels over and dies as it is processing the step (or right before or
right after), it is obviously no longer in a position to let the scheduler know about
its fate. Thus, there won’t be any message flowing back to the scheduler and the job
is stalled. But we expect that. In fact, we’re ok with any failure anywhere in the
system. We could lose or fumble a queue message, we could get a duplicate message,
we could have the scheduler die a fiery death (or just being recycled for patching
at some unfortunate moment) – all of those conditions are fine since we’ve brought
the doctor on board with us: the <em>Supervisor.</em> 
</p>
        <p align="justify">
          <a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_6.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 10px 3px 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="image" border="0" alt="image" src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_2.png" width="558" height="297" />
          </a>
        </p>
        <h3>The Supervisor
</h3>
        <p>
The Supervisor is a schedule driven process (or thread) of which one or a few instances
may run occasionally. The frequency depends on much on the average duration of operations
and the expected overall latency for completion of jobs. 
</p>
        <p>
The Supervisor’s job is to recover steps or jobs that have failed – and we’re assuming
that failures are due to some transient condition. So if the system would expect a
transient resource failure condition that prevented a job from completing just a second
ago to be healed two seconds later, it’d depend on the kind of system and resource
whether that’d be a good strategy.  What’s described here is a pattern, not a
solution, so it depends on the concrete scenario to get the  timing right for
when to try operations again once they fail.
</p>
        <p>
This desired back-off time manifests in the <em>LockedUntil</em> value.  When
a step gets scheduled, the <em>Scheduler</em> needs to state how long it is willing
to wait for that step to complete; this includes some back-off time padding. Once
that ultimatum has passed and the step is still in an inconsistent state (desired
state doesn’t equal the current state)  the <em>Supervisor</em> can pick it up
at any time and schedule it.
</p>
        <blockquote>
          <p>
            <strong>(1)</strong> – Supervisor queries the job store for any inconsistent steps
whose <em>LockedUntil</em> value has expired. 
<br /><strong>(2) – </strong>The Supervisor schedules the step again by setting the <em>LockedUntil </em>value
to a new timeout and submitting the step into the target actor’s queue 
<br /><strong>(3)</strong> – Once the step succeeds, the step is reported as complete on
the regular path back to the <em>Scheduler</em>  where it completes normally
as in steps <strong>(8)</strong>, <strong>(9)</strong> from the happy-path scenario
above. If it fails, we simply drop it again. For failures that allow reporting an
error back to the <em>Scheduler</em> it may make sense to introduce an error counter
that round-trips with the step so that the system could detect poisonous steps that
fail ‘forever’ and have the <em>Supervisor</em> ignore those after some threshold.
</p>
        </blockquote>
        <p>
The Supervisor can pursue a range of strategies for recovery. It can just take a look
at individual steps and recover them by rescheduling them – assuming the steps are
implemented as idempotent operations. If it were a bit cleverer, it may consider error
information that a cooperative (and breathing) agent has submitted back to the Scheduler
and even go as far as to fire an alert to an operator if the error condition were
to require intervention and then take the step out of the loop by marking it and setting
the <em>LockedUntil</em> value to some longer timeout so it’s taken out of the loop
and someone can take a look. 
</p>
        <p>
At the job-scope, the Supervisor may want to perform recovery such that it first schedules
all previously executed steps to revert back to the initial state by performing compensation
work (all resources that got set to active are getting disabled again here in our
example) and then scheduling another attempt at getting to the desired state. 
</p>
        <p>
In step <strong>(2)b</strong> up above, we’ve been logging current and desired state
at the job-scope and with that we can also always find inconsistent jobs where all
steps are consistent and wouldn’t show up in the step-level recovery query. That situation
can occur if the <em>Scheduler</em> were to crash between logging one step as complete
and scheduling the next step. If we find inconsistent jobs with all-consistent steps,
we just need to reschedule the next step in the dependency sequence whose desired
state isn’t matching the desired state of the overall job.
</p>
        <p>
To be thorough, we could now take a look at all the places where things can go wrong
in the system. I expect that survey to yield that at as long we can successfully get
past step <strong>(2)b </strong>from the first diagram, the <em>Supervisor</em> is
always in a position to either detect that a job isn’t making progress and help with
recovery or can at least call for help. The system always knows what its current <strong>intent</strong> is,
i.e. which state transitions it wants to drive, and never forgets about that intent
since that intent is logged in the job store at all times and all progress against
that intent is logged as well.  The submission request <strong>(1)</strong> depends
on the outcome of <strong>(2)a/b </strong>to guard against failures while putting
a job and its steps into the system so that a client can take corrective action. In
fact, once the job record is marked as inconsistent in step <strong>(2)b</strong>,
the scheduler could already report success back to the submitting party even before
the first step is scheduled, because the <em>Supervisor</em> would pick up that inconsistency
eventually.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=83f937f7-b838-43d0-ad61-74605eceafa2" />
      </body>
      <title>Cloud Architecture: The Scheduler-Agent-Supervisor Pattern</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,83f937f7-b838-43d0-ad61-74605eceafa2.aspx</guid>
      <link>http://vasters.com/clemensv/2010/09/28/Cloud+Architecture+The+SchedulerAgentSupervisor+Pattern.aspx</link>
      <pubDate>Tue, 28 Sep 2010 01:55:18 GMT</pubDate>
      <description>&lt;p align=justify&gt;
As our team was starting to transform our parts of the Azure Services Platform from
a CTP ‘labs’ service exploring features into a full-on commercial service, it started
to dawn on us that we had set ourselves up for writing a bunch of ‘enterprise apps’.
The shiny parts of Service Bus and Access Control that we parade around are all about
user-facing features, but if I look back at the work we had to go from a toy service
to a commercial offering, I’d guess that 80%-90% of the effort went into aspects like
infrastructure, deployment, upgradeability, billing, provisioning, throttling, quotas,
security hardening, and service optimization. The lesson there was: when you’re boarding
the train to shipping a V1, you don’t load new features on that train –&amp;nbsp; you
rather throw some off. 
&lt;/p&gt;
&lt;p align=justify&gt;
The most interesting challenge for these infrastructure apps sitting on the backend
was that we didn’t have much solid ground to stand on. Remember – these were very
early days, so we couldn’t use SQL Azure since the folks over in SQL were on a pretty
heroic schedule themselves and didn’t want to take on any external dependencies even
from close friends. We also couldn’t use any of the capabilities of our own bits because
building infrastructure for your features on your features would just be plain dumb.
And while we could use capabilities of the Windows Azure platform we were building
on, a lot of those parts still had rough edges as those folks were going through a
lot of the same that we went through. In those days, the table store would be very
moody, the queue store would sometimes swallow or duplicate messages, the Azure fabric
controller would occasionally go around and kill things. All normal –&amp;nbsp; bugs.
&lt;/p&gt;
&lt;p align=justify&gt;
So under those circumstances we had to figure out the architecture for some subsystems
where we need to do a set of coordinated action across a distributed set of resources
– a distributed transaction or saga of sorts. The architecture had a few simple goals:
when we get an activation request, we must not fumble that request under any circumstance,
we must run the job to completion for all resources and, at the same time, we need
to minimize any potential for required operator intervention, i.e. if something goes
wrong, the system better knows how to deal with it – at best it should self-heal. 
&lt;/p&gt;
&lt;p align=justify&gt;
My solution to that puzzle is a pattern I call “Scheduler-Agent-Supervisor Pattern”
or, short, “Supervisor Pattern”. We keep finding applications for this pattern in
different places, so I think it’s worth writing about it in generic terms – even without
going into the details of our system.
&lt;/p&gt;
&lt;p align=justify&gt;
The pattern foots on two seemingly odd and very related assumptions: &lt;em&gt;‘&lt;/em&gt;&lt;strong&gt;&lt;em&gt;the
system is perfect’&lt;/em&gt; &lt;/strong&gt;and&lt;strong&gt; &lt;em&gt;‘all error conditions are transient’&lt;/em&gt;.&lt;/strong&gt; As
a consequence, the architecture has some character traits of a toddler. It’s generally
happily optimistic and gets very grumpy, very quickly when things go wrong – to the
point that it will simply drop everything and run away screaming. It’s very precisely
like that, in fact.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb.png" width=600 height=290&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p align=justify&gt;
The first picture here shows all key pieces except the &lt;em&gt;Supervisor&lt;/em&gt; that I’ll
introduce later. At the core we have a &lt;em&gt;Scheduler&lt;/em&gt; that manages a simple state
machine made up of &lt;em&gt;Jobs&lt;/em&gt; and those jobs have &lt;em&gt;Steps&lt;/em&gt;. The steps may
have a notion of interdependency or may be completely parallelizable. There is a &lt;em&gt;Job
Store&lt;/em&gt; that holds jobs and steps and there are &lt;em&gt;Agents&lt;/em&gt; that execute operations
on some resource.&amp;nbsp; Each &lt;em&gt;Agent&lt;/em&gt; is (usually) fronted by a queue and the &lt;em&gt;Scheduler&lt;/em&gt; has
a queue (or service endpoint) through which it receives reply messages from the &lt;em&gt;Agents&lt;/em&gt;.
&lt;/p&gt;
&lt;p align=justify&gt;
Steps are recorded in a durable storage table of some sort that has at least the following
fields: &lt;em&gt;Current State&lt;/em&gt; (say: Disabled, Active), &lt;em&gt;Desired State&lt;/em&gt; (say:
Disabled, Active), &lt;em&gt;LockedUntil&lt;/em&gt; (Date/Time value), and &lt;em&gt;Actor&lt;/em&gt; plus
any step specific information you want to store and eventually submit with the job
to the step agent.
&lt;/p&gt;
&lt;h3&gt;When Things Go Right
&lt;/h3&gt;
&lt;p&gt;
The initial flow is as follows:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;(1)a&lt;/strong&gt; – Submit a new job into the Scheduler (and wait) 
&lt;br&gt;
&lt;strong&gt;(2)a&lt;/strong&gt; – The Scheduler creates a new job and steps with an initial
current state (&lt;em&gt;‘Disabled’&lt;/em&gt;) in the job store&amp;nbsp; 
&lt;br&gt;
&lt;strong&gt;(2)b&lt;/strong&gt; – The Scheduler sets ‘desired state’ of the job and of all schedulable
steps (dependencies?) to the target state (&lt;em&gt;‘Active’&lt;/em&gt;) and sets the ‘locked
until’ timeout of the step to a value in the near future, e.g. ‘Now’ + 2 minutes. 
&lt;br&gt;
&lt;strong&gt;(1)b&lt;/strong&gt; – Job submission request unblocks and returns
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p align=justify&gt;
If all went well, we now have a job record and, here in this example, two step records
in our store. They have a current state of &lt;em&gt;‘Disabled’&lt;/em&gt; and a desired state
of &lt;em&gt;‘Active’&lt;/em&gt;. If things didn’t go well, we’d have incomplete or partially
wedged records or nothing in the job store, at all. The client would also know about
it since we’ve held on to the reply until we have everything done – so the client
is encouraged to retry. If we have nothing in the store and the client doesn’t retry
– well, then the job probably wasn’t all that important, after all. But if we have
at least a job record, we can make it all right later. We’re optimists, though; let’s
assume it all went well.
&lt;/p&gt;
&lt;p align=justify&gt;
For the next steps we assume that there’s a notion of dependencies between the steps
and the second steps depends on the first. If that were not the case, the two actions
would just be happening in parallel.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;(3)&lt;/strong&gt; – Place a step message into the queue for the actor for the first
step; Agent 1 in this case. The message contains all the information about the step,
including the current and desired state and also the &lt;em&gt;LockedUntil&lt;/em&gt; that puts
an ultimatum on the activity. The message may further contain an action indicator
or arguments that are taken from the step record. 
&lt;br&gt;
&lt;strong&gt;(4)&lt;/strong&gt; – After the agent has done the work, it places a completion record
into the reply queue of the Scheduler. 
&lt;br&gt;
&lt;strong&gt;(5)&lt;/strong&gt; – The Scheduler records the step as complete by setting the current
state from ‘Disabled’ to ‘Active’; as a result the desired and the current state are
now equal. 
&lt;br&gt;
&lt;strong&gt;(6)&lt;/strong&gt; – The Scheduler sets the next step’s desired state to the target
state (&lt;em&gt;‘Active’&lt;/em&gt;) and sets the &lt;em&gt;LockedUntil&lt;/em&gt; timeout of the step to
a value in the near future, e.g. ‘Now’ + 1 minute. The lock timeout value is an ultimatum
for when the operation is expected to be complete and reported back as being complete
in a worst-case success case. The actual value therefore depends on the common latency
of operations in the system. If operations usually complete in milliseconds and at
worst within a second, the lock timeout can be short – but not too short. We’ll discuss
this&amp;nbsp; value in more detail a bit later. 
&lt;br&gt;
&lt;strong&gt;(7)&lt;/strong&gt;, &lt;strong&gt;(8)&lt;/strong&gt;, &lt;strong&gt;(9)&lt;/strong&gt; are equivalent to &lt;strong&gt;(3)&lt;/strong&gt;, &lt;strong&gt;(4)&lt;/strong&gt;, &lt;strong&gt;(5)&lt;/strong&gt;.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p align=justify&gt;
Once the last step’s current state is equal to the current state, the job’s current
state gets set to the desired state and we’re done. So that was the “99% of the time”
happy path.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_4.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_1.png" width=591 height=286&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;When Things Go Wrong
&lt;/h3&gt;
&lt;p align=justify&gt;
So what happens when anything goes wrong? Remember the principle &lt;strong&gt;‘all errors
are transient’&lt;/strong&gt;. What we do in the error case – anywhere – is to log the error
condition and then promptly drop everything and simply hope that time, a change in
system conditions, human or divine intervention, or – at worst – a patch will heal
matters. That’s what the second principle &lt;strong&gt;‘the system is perfect’&lt;em&gt;&amp;nbsp;&lt;/em&gt;&lt;/strong&gt;is
about; the system obviously isn’t really perfect, but if we construct it in a way
that we can either wait for it to return from a wedged state into a functional state
or where we enable someone to go in and apply a fix for a blocking bug while preserving
the system state, we can consider the system ‘perfect’ in the sense that pretty much
any conceivable job that’s already in the system can be driven to completion.
&lt;/p&gt;
&lt;p align=justify&gt;
In the second picture, we have Agent 2 blowing up as it is processing the step it
got handed in &lt;strong&gt;(7)&lt;/strong&gt;. If the agent just can’t get its work done since
some external dependency isn’t available – maybe a database can’t be reached or a
server it’s talking to spews out ‘server too busy’ errors – it may be able to back
off for a moment and retry. However, it must not retry past the &lt;em&gt;LockedUntil&lt;/em&gt; ultimatum
that’s in the step record. When things fail and the agent is still breathing, it may,
as a matter of courtesy, notify the scheduler of the fact and report that the step
was completed with no result, i.e. the desired state and the achieved state don’t
match. That notification may also include diagnostic information. Once the &lt;em&gt;LockedUntil&lt;/em&gt; ultimatum
has passed, the Agent no longer owns the job and must drop it. It must even not report
failure state back to the Scheduler past that point. 
&lt;/p&gt;
&lt;p align=justify&gt;
If the agent keels over and dies as it is processing the step (or right before or
right after), it is obviously no longer in a position to let the scheduler know about
its fate. Thus, there won’t be any message flowing back to the scheduler and the job
is stalled. But we expect that. In fact, we’re ok with any failure anywhere in the
system. We could lose or fumble a queue message, we could get a duplicate message,
we could have the scheduler die a fiery death (or just being recycled for patching
at some unfortunate moment) – all of those conditions are fine since we’ve brought
the doctor on board with us: the &lt;em&gt;Supervisor.&lt;/em&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p align=justify&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_6.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 10px 3px 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_2.png" width=558 height=297&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;The Supervisor
&lt;/h3&gt;
&lt;p&gt;
The Supervisor is a schedule driven process (or thread) of which one or a few instances
may run occasionally. The frequency depends on much on the average duration of operations
and the expected overall latency for completion of jobs. 
&lt;/p&gt;
&lt;p&gt;
The Supervisor’s job is to recover steps or jobs that have failed – and we’re assuming
that failures are due to some transient condition. So if the system would expect a
transient resource failure condition that prevented a job from completing just a second
ago to be healed two seconds later, it’d depend on the kind of system and resource
whether that’d be a good strategy.&amp;nbsp; What’s described here is a pattern, not a
solution, so it depends on the concrete scenario to get the&amp;nbsp; timing right for
when to try operations again once they fail.
&lt;/p&gt;
&lt;p&gt;
This desired back-off time manifests in the &lt;em&gt;LockedUntil&lt;/em&gt; value.&amp;nbsp; When
a step gets scheduled, the &lt;em&gt;Scheduler&lt;/em&gt; needs to state how long it is willing
to wait for that step to complete; this includes some back-off time padding. Once
that ultimatum has passed and the step is still in an inconsistent state (desired
state doesn’t equal the current state)&amp;nbsp; the &lt;em&gt;Supervisor&lt;/em&gt; can pick it up
at any time and schedule it.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;(1)&lt;/strong&gt; – Supervisor queries the job store for any inconsistent steps
whose &lt;em&gt;LockedUntil&lt;/em&gt; value has expired. 
&lt;br&gt;
&lt;strong&gt;(2) – &lt;/strong&gt;The Supervisor schedules the step again by setting the &lt;em&gt;LockedUntil &lt;/em&gt;value
to a new timeout and submitting the step into the target actor’s queue 
&lt;br&gt;
&lt;strong&gt;(3)&lt;/strong&gt; – Once the step succeeds, the step is reported as complete on
the regular path back to the &lt;em&gt;Scheduler&lt;/em&gt;&amp;nbsp; where it completes normally
as in steps &lt;strong&gt;(8)&lt;/strong&gt;, &lt;strong&gt;(9)&lt;/strong&gt; from the happy-path scenario
above. If it fails, we simply drop it again. For failures that allow reporting an
error back to the &lt;em&gt;Scheduler&lt;/em&gt; it may make sense to introduce an error counter
that round-trips with the step so that the system could detect poisonous steps that
fail ‘forever’ and have the &lt;em&gt;Supervisor&lt;/em&gt; ignore those after some threshold.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The Supervisor can pursue a range of strategies for recovery. It can just take a look
at individual steps and recover them by rescheduling them – assuming the steps are
implemented as idempotent operations. If it were a bit cleverer, it may consider error
information that a cooperative (and breathing) agent has submitted back to the Scheduler
and even go as far as to fire an alert to an operator if the error condition were
to require intervention and then take the step out of the loop by marking it and setting
the &lt;em&gt;LockedUntil&lt;/em&gt; value to some longer timeout so it’s taken out of the loop
and someone can take a look. 
&lt;/p&gt;
&lt;p&gt;
At the job-scope, the Supervisor may want to perform recovery such that it first schedules
all previously executed steps to revert back to the initial state by performing compensation
work (all resources that got set to active are getting disabled again here in our
example) and then scheduling another attempt at getting to the desired state. 
&lt;/p&gt;
&lt;p&gt;
In step &lt;strong&gt;(2)b&lt;/strong&gt; up above, we’ve been logging current and desired state
at the job-scope and with that we can also always find inconsistent jobs where all
steps are consistent and wouldn’t show up in the step-level recovery query. That situation
can occur if the &lt;em&gt;Scheduler&lt;/em&gt; were to crash between logging one step as complete
and scheduling the next step. If we find inconsistent jobs with all-consistent steps,
we just need to reschedule the next step in the dependency sequence whose desired
state isn’t matching the desired state of the overall job.
&lt;/p&gt;
&lt;p&gt;
To be thorough, we could now take a look at all the places where things can go wrong
in the system. I expect that survey to yield that at as long we can successfully get
past step &lt;strong&gt;(2)b &lt;/strong&gt;from the first diagram, the &lt;em&gt;Supervisor&lt;/em&gt; is
always in a position to either detect that a job isn’t making progress and help with
recovery or can at least call for help. The system always knows what its current &lt;strong&gt;intent&lt;/strong&gt; is,
i.e. which state transitions it wants to drive, and never forgets about that intent
since that intent is logged in the job store at all times and all progress against
that intent is logged as well.&amp;nbsp; The submission request &lt;strong&gt;(1)&lt;/strong&gt; depends
on the outcome of &lt;strong&gt;(2)a/b &lt;/strong&gt;to guard against failures while putting
a job and its steps into the system so that a client can take corrective action. In
fact, once the job record is marked as inconsistent in step &lt;strong&gt;(2)b&lt;/strong&gt;,
the scheduler could already report success back to the submitting party even before
the first step is scheduled, because the &lt;em&gt;Supervisor&lt;/em&gt; would pick up that inconsistency
eventually.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=83f937f7-b838-43d0-ad61-74605eceafa2" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,83f937f7-b838-43d0-ad61-74605eceafa2.aspx</comments>
      <category>Architecture</category>
      <category>Architecture/SOA</category>
      <category>Azure</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=a14d84f7-0d07-49da-a5d8-35088052c3e5</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,a14d84f7-0d07-49da-a5d8-35088052c3e5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,a14d84f7-0d07-49da-a5d8-35088052c3e5.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=a14d84f7-0d07-49da-a5d8-35088052c3e5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In case you need a refresher or update about the things me and our team work on at
Microsoft, <a href="http://www.msteched.com/2010/Australia/COS230">go here</a> for
a very recent and very good presentation by my PM colleague <a href="http://twitter.com/mmyslin">Maggie
Myslinska</a> from TechEd Australia 2010 about Windows Azure AppFabric with Service
Bus demos and a demo of the new Access Control V2 CTP
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=a14d84f7-0d07-49da-a5d8-35088052c3e5" />
      </body>
      <title>Windows Azure AppFabric Overview session from TechEd Australia 2010 </title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,a14d84f7-0d07-49da-a5d8-35088052c3e5.aspx</guid>
      <link>http://vasters.com/clemensv/2010/09/09/Windows+Azure+AppFabric+Overview+Session+From+TechEd+Australia+2010.aspx</link>
      <pubDate>Thu, 09 Sep 2010 01:08:52 GMT</pubDate>
      <description>&lt;p&gt;
In case you need a refresher or update about the things me and our team work on at
Microsoft, &lt;a href="http://www.msteched.com/2010/Australia/COS230"&gt;go here&lt;/a&gt; for
a very recent and very good presentation by my PM colleague &lt;a href="http://twitter.com/mmyslin"&gt;Maggie
Myslinska&lt;/a&gt; from TechEd Australia 2010 about Windows Azure AppFabric with Service
Bus demos and a demo of the new Access Control V2 CTP
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=a14d84f7-0d07-49da-a5d8-35088052c3e5" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,a14d84f7-0d07-49da-a5d8-35088052c3e5.aspx</comments>
      <category>AppFabric</category>
      <category>Architecture/SOA</category>
      <category>Azure</category>
      <category>Technology</category>
      <category>Technology/ISB</category>
      <category>Technology/WCF</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=daa81750-f570-46e1-a38a-05d008e57585</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,daa81750-f570-46e1-a38a-05d008e57585.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,daa81750-f570-46e1-a38a-05d008e57585.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=daa81750-f570-46e1-a38a-05d008e57585</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Room 398, Tuesday June 8 
<br />
3:15pm-4:30pm 
<br /><br />
Session Type: Breakout Session 
<br />
Track: Application Server &amp; Infrastructure 
<br />
Speaker(s): Maggie Myslinska 
<br />
Level: 200 – Intermediate 
<br /><br /><em>Come learn how to use Windows Azure AppFabric (with Service Bus and Access Control)
as building block services for Web-based and hosted applications, and how developers
can leverage services to create applications in the cloud and connect them with on-premises
systems.</em></p>
        <p>
If you are planning on seeing <a href="http://vasters.com/clemensv/PermaLink,guid,3ce38507-44b7-4a2a-bacb-aeb7aaacdf56.aspx">Juval’s
and my talk ASI304 at TechEd</a> and/or if you need to know more about how <a href="http://www.microsoft.com/windowsazure/appfabric/">Windows
Azure AppFabric</a> enables federated cloud/on-premise applications and a range of
other scenarios, you should definitely put <a href="http://northamerica.msteched.com/ScheduleBuilder?keyword=asi204">Maggie’s
talk onto your TechEd schedule</a> as well.  
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=daa81750-f570-46e1-a38a-05d008e57585" />
      </body>
      <title>TechEd: ASI204 Windows Azure Platform AppFabric Overview</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,daa81750-f570-46e1-a38a-05d008e57585.aspx</guid>
      <link>http://vasters.com/clemensv/2010/06/01/TechEd+ASI204+Windows+Azure+Platform+AppFabric+Overview.aspx</link>
      <pubDate>Tue, 01 Jun 2010 21:15:06 GMT</pubDate>
      <description>&lt;p&gt;
Room 398, Tuesday June 8 
&lt;br&gt;
3:15pm-4:30pm 
&lt;br&gt;
&lt;br&gt;
Session Type: Breakout Session 
&lt;br&gt;
Track: Application Server &amp;amp; Infrastructure 
&lt;br&gt;
Speaker(s): Maggie Myslinska 
&lt;br&gt;
Level: 200 – Intermediate 
&lt;br&gt;
&lt;br&gt;
&lt;em&gt;Come learn how to use Windows Azure AppFabric (with Service Bus and Access Control)
as building block services for Web-based and hosted applications, and how developers
can leverage services to create applications in the cloud and connect them with on-premises
systems.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
If you are planning on seeing &lt;a href="http://vasters.com/clemensv/PermaLink,guid,3ce38507-44b7-4a2a-bacb-aeb7aaacdf56.aspx"&gt;Juval’s
and my talk ASI304 at TechEd&lt;/a&gt; and/or if you need to know more about how &lt;a href="http://www.microsoft.com/windowsazure/appfabric/"&gt;Windows
Azure AppFabric&lt;/a&gt; enables federated cloud/on-premise applications and a range of
other scenarios, you should definitely put &lt;a href="http://northamerica.msteched.com/ScheduleBuilder?keyword=asi204"&gt;Maggie’s
talk onto your TechEd schedule&lt;/a&gt; as well.&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=daa81750-f570-46e1-a38a-05d008e57585" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,daa81750-f570-46e1-a38a-05d008e57585.aspx</comments>
      <category>AppFabric</category>
      <category>Talks</category>
      <category>Talks/TechEd US</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=29ec4fe1-65d8-467e-8360-ce50a2ccd1ff</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,29ec4fe1-65d8-467e-8360-ce50a2ccd1ff.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,29ec4fe1-65d8-467e-8360-ce50a2ccd1ff.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=29ec4fe1-65d8-467e-8360-ce50a2ccd1ff</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I put the slides for my talks at NT Konferenca 2010 <a href="http://cid-123ccd2a7ab10107.skydrive.live.com/browse.aspx/NT%20Konferenca%202010">on
SkyDrive</a>. The major difference from my <a href="http://vasters.com/clemensv/PermaLink,guid,cb6599da-5785-4186-8ca1-68a0f32f4495.aspx">APAC
slides</a> is that I had to put compute and storage <a href="http://cid-123ccd2a7ab10107.skydrive.live.com/self.aspx/NT%20Konferenca%202010/NTK2010-Azure-CapabilitiesAndTips.pptx">into
one deck</a> due to the conference schedule, but instead of purely consolidating and
cutting down the slide count,  I also incorporated some common patterns coming
out from debates in Asia and added slides on predictable and dynamic scaling as well
as on multitenancy. Sadly, I need to rush through all that in 45 minutes
today. 
</p>
        <p>
          <iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 98px; PADDING-RIGHT: 0px; HEIGHT: 115px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-123ccd2a7ab10107.skydrive.live.com/embedicon.aspx/NT%20Konferenca%202010" frameborder="0" marginwidth="0" scrolling="no">
          </iframe>
        </p>
        <p>
 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=29ec4fe1-65d8-467e-8360-ce50a2ccd1ff" />
      </body>
      <title>NT Konferenca 2010 - Windows Azure Slidedecks</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,29ec4fe1-65d8-467e-8360-ce50a2ccd1ff.aspx</guid>
      <link>http://vasters.com/clemensv/2010/05/25/NT+Konferenca+2010+Windows+Azure+Slidedecks.aspx</link>
      <pubDate>Tue, 25 May 2010 07:08:59 GMT</pubDate>
      <description>&lt;p&gt;
I put the slides for my talks at NT Konferenca 2010 &lt;a href="http://cid-123ccd2a7ab10107.skydrive.live.com/browse.aspx/NT%20Konferenca%202010"&gt;on
SkyDrive&lt;/a&gt;.&amp;nbsp;The major difference from my&amp;nbsp;&lt;a href="http://vasters.com/clemensv/PermaLink,guid,cb6599da-5785-4186-8ca1-68a0f32f4495.aspx"&gt;APAC
slides&lt;/a&gt;&amp;nbsp;is that I had to put compute and storage&amp;nbsp;&lt;a href="http://cid-123ccd2a7ab10107.skydrive.live.com/self.aspx/NT%20Konferenca%202010/NTK2010-Azure-CapabilitiesAndTips.pptx"&gt;into
one deck&lt;/a&gt; due to the conference schedule, but instead of purely consolidating and
cutting down the slide count,&amp;nbsp; I also incorporated some common patterns coming
out from debates in Asia and added slides on predictable and dynamic scaling as well
as on&amp;nbsp;multitenancy. Sadly, I need to rush&amp;nbsp;through all that in&amp;nbsp;45 minutes
today. 
&lt;/p&gt;
&lt;p&gt;
&lt;iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 98px; PADDING-RIGHT: 0px; HEIGHT: 115px; PADDING-TOP: 0px" title=Preview marginheight=0 src="http://cid-123ccd2a7ab10107.skydrive.live.com/embedicon.aspx/NT%20Konferenca%202010" frameborder=0 marginwidth=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=29ec4fe1-65d8-467e-8360-ce50a2ccd1ff" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,29ec4fe1-65d8-467e-8360-ce50a2ccd1ff.aspx</comments>
      <category>AppFabric</category>
      <category>Architecture</category>
      <category>Azure</category>
      <category>Talks</category>
      <category>Technology</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=26dc5df1-8b8c-4f71-8765-8904e584505b</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,26dc5df1-8b8c-4f71-8765-8904e584505b.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,26dc5df1-8b8c-4f71-8765-8904e584505b.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=26dc5df1-8b8c-4f71-8765-8904e584505b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Anyone using the .NET Service Bus should take a good look at the <a href="http://blogs.aws.net/atc/post/SocketShifter-Warping-the-Internet-Space-Time-Continuum-with-the-Azure-NET-Service-Bus.aspx">SocketShifter
project</a> started by Rob Blackwell and Richard Prodger from AWS in the UK. AWS stands
for <a href="http://www.aws.net">Active Web Solutions</a>, not for the "other" AWS.
The full project is up on <a href="http://socketshifter.codeplex.com/">Codeplex</a>.
</p>
        <p>
What makes SocketShifter significant is that it takes the network abstraction of SOAP,
WS-Addressing, and the Service Bus full circle and layers the very bottom of that
stack - plain TCP connections - as a virtualization on top of the the stack. In other
words: SocketShifter allows you to create full-fidelity, bi-directional socket connections
through the .NET Service Bus.
</p>
        <p>
We've created something very similar to SocketShifter last year (we're using
it for a few internal purposes), but haven't made it public so far. I'm glad that
the AWS folks built this, so that you get to play with it.   
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=26dc5df1-8b8c-4f71-8765-8904e584505b" />
      </body>
      <title>SocketShifter - Network virtualization over the .NET Service Bus</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,26dc5df1-8b8c-4f71-8765-8904e584505b.aspx</guid>
      <link>http://vasters.com/clemensv/2009/07/06/SocketShifter+Network+Virtualization+Over+The+NET+Service+Bus.aspx</link>
      <pubDate>Mon, 06 Jul 2009 16:06:48 GMT</pubDate>
      <description>&lt;p&gt;
Anyone using the .NET Service Bus should take a good look at the &lt;a href="http://blogs.aws.net/atc/post/SocketShifter-Warping-the-Internet-Space-Time-Continuum-with-the-Azure-NET-Service-Bus.aspx"&gt;SocketShifter
project&lt;/a&gt; started by Rob Blackwell and Richard Prodger from AWS in the UK. AWS stands
for &lt;a href="http://www.aws.net"&gt;Active Web Solutions&lt;/a&gt;, not for the "other" AWS.
The full project is up on &lt;a href="http://socketshifter.codeplex.com/"&gt;Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
What makes SocketShifter significant is that it takes the network abstraction of SOAP,
WS-Addressing, and the Service Bus full circle and layers the very bottom of that
stack - plain TCP connections - as a virtualization on top of the the stack. In other
words: SocketShifter allows you to create full-fidelity, bi-directional socket connections
through the .NET Service Bus.
&lt;/p&gt;
&lt;p&gt;
We've created something very similar to SocketShifter last year&amp;nbsp;(we're using
it for a few internal purposes), but haven't made it public so far. I'm glad that
the AWS folks&amp;nbsp;built this, so that you get to play with it.&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=26dc5df1-8b8c-4f71-8765-8904e584505b" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,26dc5df1-8b8c-4f71-8765-8904e584505b.aspx</comments>
      <category>.NET Services</category>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=634b72d9-e200-45de-82db-2ae4c8ef947e</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,634b72d9-e200-45de-82db-2ae4c8ef947e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,634b72d9-e200-45de-82db-2ae4c8ef947e.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=634b72d9-e200-45de-82db-2ae4c8ef947e</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>… <a href="http://de.wikipedia.org/wiki/Auf_der_Mauer,_auf_der_Lauer">seht Euch
mal die Wa an, wie die Wa ta kann. Auf der Mauer auf der Lauer sitzt ‘ne kleine Wa!</a>.</em>
        </p>
        <p>
It’s a German children’s song. The song starts out with “… sitzt ‘ne kleine Wanze”
(bedbug) and with each verse you leave off a letter: Wanz, Wan, Wa, W, – silence. 
</p>
        <p>
I’ll do the same here, but not with a bedbug:
</p>
        <p>
Let’s sing:
</p>
        <p>
          <font face="Courier New">&lt;soap:Envelope xmlns:soap=”” xmlns:wsaddr=”” xmlns:wsrm=””
xmlns:wsu=”” xmlns:app=””&gt;<br />
   &lt;soap:Header&gt;<br />
         &lt;addr:Action&gt;http://tempuri.org/1.0/Status.set&lt;/addr:Action&gt;<br />
         &lt;wsrm:Sequence&gt;<br />
              &lt;wsrm:Identifier&gt;urn:session-id&lt;/wsrm:Identifier&gt;<br />
              &lt;wsrm:MessageNumber&gt;5&lt;/wsrm:MessageNumber&gt;<br />
          &lt;/wsrm:Sequence&gt;<br />
          &lt;wsse:Security xmlns:wsse=”…”&gt;<br />
              
&lt;wsse:BinarySecurityToken ValueType="</font>
          <font face="Courier New">http://tempuri.org#CustomToken</font>
          <font face="Courier New">" 
<br />
                                        
EncodingType="...#Base64Binary" wsu:Id=" MyID "&gt;<br />
                         
FHUIORv...<br />
               
&lt;/wsse:BinarySecurityToken&gt;<br />
              
&lt;ds:Signature&gt;<br />
                 
&lt;ds:SignedInfo&gt; 
<br />
                     
&lt;ds:CanonicalizationMethod Algorithm="</font>
          <font face="Courier New">http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;</font>
          <br />
          <font face="Courier New">                     
&lt;ds:SignatureMethod Algorithm="</font>
          <font face="Courier New">http://www.w3.org/2000/09/xmldsig#md5"/</font>
          <font face="Courier New">&gt;  
<br />
                     
&lt;ds:Reference URI="#MsgBody"&gt;<br />
                           
&lt;ds:DigestMethod  Algorithm="</font>
          <font face="Courier New">http://www.w3.org/2000/09/xmldsig#md5"/&gt;</font>
          <font face="Courier New"> <br />
                           
&lt;ds:DigestValue&gt;LyLsF0Pi4wPU...&lt;/ds:DigestValue&gt;<br />
                     
&lt;/ds:Reference&gt;<br />
                
&lt;/ds:SignedInfo&gt;   
<br />
                
&lt;ds:SignatureValue&gt;DJbchm5gK...&lt;/ds:SignatureValue&gt; 
<br />
                
&lt;ds:KeyInfo&gt;  
<br />
                 
&lt;wsse:SecurityTokenReference&gt;  
<br />
                   
&lt;wsse:Reference URI="#MyID"/&gt; 
<br />
                  
&lt;/wsse:SecurityTokenReference&gt; 
<br />
              
&lt;/ds:KeyInfo&gt; 
<br />
             &lt;/ds:Signature&gt;<br />
         &lt;/wsse:Security&gt;<br />
         &lt;app:ResponseFormat&gt;Xml&lt;/app:ResponseFormat&gt;<br />
         &lt;app:Key wsu:Id=”AppKey”&gt;27729912882….&lt;/app:Key&gt; 
<br />
    &lt;soap:Header&gt;<br />
    &lt;soap:Body wsu:Id=”MyId”&gt;<br />
          &lt;app:status&gt;Hello, I’m
good&lt;/app:status&gt;<br />
     &lt;/soap:Body&gt;<br />
&lt;/soap:Envelope&gt; </font>
        </p>
        <p>
Not a very pretty song, I’ll admit. Let’s drop a some stuff. Let’s assume that we
don’t need to tell the other party that we’re looking to give it an MD5 signature,
but let’s say that’s implied and so were the canonicalization algorithm. Let’s also
assume that the other side already knows the security token and the key. Since we
only have a single signature digest here and yield a single signature we can just
collapse to the signature value. Heck, you may not even know about what that all means.
Verse 2:
</p>
        <p>
          <font face="Courier New">&lt;soap:Envelope xmlns:soap=”” xmlns:wsaddr=”” xmlns:wsrm=””
xmlns:wsu=”” xmlns:app=””&gt;<br />
   &lt;soap:Header&gt;<br />
         &lt;addr:Action&gt;http://tempuri.org/1.0/Status.set&lt;/addr:Action&gt;<br />
         &lt;wsrm:Sequence&gt;<br />
              &lt;wsrm:Identifier&gt;urn:session-id&lt;/wsrm:Identifier&gt;<br />
              &lt;wsrm:MessageNumber&gt;5&lt;/wsrm:MessageNumber&gt;<br />
          &lt;/wsrm:Sequence&gt;<br />
          &lt;wsse:Security xmlns:wsse=”…”&gt;<br />
              
&lt;ds:Signature&gt;<br />
                 
&lt;ds:SignatureValue&gt;DJbchm5gK...&lt;/ds:SignatureValue&gt; 
<br />
             &lt;/ds:Signature&gt;<br />
         &lt;/wsse:Security&gt;<br />
         &lt;app:ResponseFormat&gt;Xml&lt;/app:ResponseFormat&gt;<br />
         &lt;app:Key wsu:Id=”AppKey”&gt;27729912882….&lt;/app:Key&gt; 
<br />
    &lt;soap:Header&gt;<br />
    &lt;soap:Body wsu:Id=”MyId”&gt;<br />
          &lt;app:status&gt;Hello, I’m
good&lt;/app:status&gt;<br />
     &lt;/soap:Body&gt;<br />
&lt;/soap:Envelope&gt; </font>
        </p>
        <p>
Better. Now let’s strip all these extra XML namespace decorations since there aren’t
any name collisions as far as I can see. We’ll also collapse the rest of the security
elements into one element since there’s no need for three levels of nesting with a
single signature. Verse 3:
</p>
        <p>
          <font face="Courier New">&lt;Envelope&gt;<br />
   &lt;Header&gt;<br />
         &lt;Action&gt;http://tempuri.org/1.0/Status.set&lt;/Action&gt;<br />
         &lt;Sequence&gt;<br />
              &lt;Identifier&gt;urn:session-id&lt;/Identifier&gt;<br />
              &lt;MessageNumber&gt;5&lt;/MessageNumber&gt;<br />
          &lt;/Sequence&gt;<br />
          &lt;SignatureValue&gt;DJbchm5gK...&lt;/SignatureValue&gt;<br />
          &lt;ResponseFormat&gt;Xml&lt;/ResponseFormat&gt;<br />
          &lt;Key&gt;27729912882….&lt;/Key&gt; 
<br />
    &lt;Header&gt;<br />
    &lt;Body&gt;<br />
       &lt;status&gt;Hello, I’m good&lt;/status&gt;<br />
     &lt;/Body&gt;<br />
&lt;/Envelope&gt; </font>
        </p>
        <p>
Much better. The whole angle-bracket stuff and the nesting seems semi-gratuitous and
repetitive here, too. Let’s make that a bit simpler. Verse 4:
</p>
        <p>
          <font face="Courier New">         Action=http://tempuri.org/1.0/Status.set<br />
         Sequence-Identifier=urn:session-id<br />
         Sequence-MessageNumber=5<br />
         SignatureValue=DJbchm5gK...<br />
         ResponseFormat=Xml<br />
         Key=27729912882…. 
<br />
         status=Hello, I’m good</font>
        </p>
        <p>
Much, much better. Now let’s get rid of that weird URI up there and split up the action
and the version info, make some of these keys are little more terse and turn that
into a format that’s easily transmittable over HTTP. By what we have here application/www-form-urlencoded
would probably be best. Verse 5:
</p>
        <p>
          <font face="Courier New">         method=Status.set<br />
         &amp;v=1.0<br />
         &amp;session_key=929872172..<br />
         &amp;call_id=5<br />
         &amp;sig=DJbchm5gK...<br />
         &amp;format=Xml<br />
         &amp;api_key=27729912882…. 
<br />
         &amp;status=Hello,%20I’m%20good</font>
        </p>
        <p>
Oops. <a href="http://wiki.developers.facebook.com/index.php/Status.set">Facebook</a>’s
Status.set API. How did that happen? I thought that was REST?
</p>
        <p>
Now play the song backwards. The “new thing” is largely analogous to where we started
before the WS* Web Services stack and its CORBA/DCE/DCOM predecessors came around
and there are, believe it or not, good reasons for having of that additional “overhead”.
A common way to frame message content and the related control data, a common way to
express complex data structures and distinguish between data domains, a common way
to deal with addressing in multi-hop or store-and-forward messaging scenarios, an
agreed notion of sessions and message sequencing, a solid mechanism for protecting
the integrity of messages and parts of messages. This isn’t all just stupid.
</p>
        <p>
It’s well worth discussing whether messages need to be expressed as XML 1.0 text on
the wire at all times. I don’t think they need to and there are alternatives that
aren’t as heavy. JSON is fine and encodings like the .NET Binary Encoding or Fast
Infoset are viable alternatives as well. It’s also well worth discussing whether WS-Security
and the myriad of related standards that were clearly built by security geniuses for
security geniuses really need to be that complicated or whether we could all live
with a handful of simple profiles and just cut out 80% of the options and knobs and
parameters in that land. 
</p>
        <p>
I find it very sad that the discussion isn’t happening. Instead, people use the “REST”
moniker as the escape hatch to conveniently ignore any existing open standard for
tunnel-through-HTTP messaging and completely avoid the discussion. 
</p>
        <p>
It’s not only sad, it’s actually a bit frustrating. As one of the people responsible
for the protocol surface of the .NET Service Bus, I am absolutely not at liberty to
ignore what exists in the standards space. And this isn’t a mandate handed down to
me, but something I do because I believe it’s the right thing to live with the constraints
of the standards frameworks that exist. 
</p>
        <p>
When we’re sitting down and talk about a REST API, were designing a set of resources
– which may result in splitting a thing like a queue into two resources, head and
tail - and then we put RFC2616 on the table and try to be very precise in picking
the appropriate predefined HTTP method for a given semantic and how the HTTP 2xx,
3xx, 4xx, 5xx status codes map to success and error conditions. We’re also trying
to avoid inventing new ways to express things for which standards exists. There’s
a standard for how to express and manage lists with ATOM and APP and hence we use
that as a foundation. We use the designed extension points to add data to those lists
whenever necessary.
</p>
        <p>
When we’re designing a <strike>RPC</strike> SOAP API, we’re intentionally trying to
avoid inventing new protocol surface and will try to leverage as much from the existing
and standardized stack as we possibly can – at a minimum we’ll stick with established
patterns such as the Create/GetInfo/Renew/Delete patterns for endpoint factories with
renewal (which is used in several standards). I’ll add that we are – ironically -
a bit backlogged on the protocol documentation for our SOAP endpoints and have more
info on the REST endpoint in the latest SDK, but we’ll make that up in the near future.
</p>
        <p>
So - can I build “REST” (mind the quotes) protocols that are as reduced as Facebook,
Twitter, Flickr, etc? Absolutely. There wouldn’t be much new work. It’s just a matter
of how we put messages on and pluck message off the wire. It’s really mostly a matter
of formatting and we have a lot of the necessary building blocks in the shipping WCF
bits today. I would just omit a bunch of decoration as things go out and make a bunch
of assumptions on things that come in.
</p>
        <p>
I just have a sense that I’d be hung upside down from a tree by the press and the
blogging, twittering, facebooking community if I, as someone at Microsoft, wouldn’t
follow the existing open and agreed standards or at least use protocols that we’ve
published under the <a href="http://www.microsoft.com/interop/osp/default.mspx">OSP</a> and
instead just started to do my own interpretative dance - even if that looked strikingly
similar to what the folks down in the Valley are doing. At the very least, someone
would call it a rip-off.
</p>
        <p>
What do you think? What should I/we do? 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=634b72d9-e200-45de-82db-2ae4c8ef947e" />
      </body>
      <title>[Intermission] Auf der Mauer, auf der Lauer sitzt 'ne kleine Wa! - or: When REST isn't REST - or: Why and How I Care About Standards-Compliance</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,634b72d9-e200-45de-82db-2ae4c8ef947e.aspx</guid>
      <link>http://vasters.com/clemensv/2009/04/01/Intermission+Auf+Der+Mauer+Auf+Der+Lauer+Sitzt+Ne+Kleine+Wa+Or+When+REST+Isnt+REST+Or+Why+And+How+I+Care+About+StandardsCompliance.aspx</link>
      <pubDate>Wed, 01 Apr 2009 17:40:41 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;… &lt;a href="http://de.wikipedia.org/wiki/Auf_der_Mauer,_auf_der_Lauer"&gt;seht Euch
mal die Wa an, wie die Wa ta kann. Auf der Mauer auf der Lauer sitzt ‘ne kleine Wa!&lt;/a&gt;.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
It’s a German children’s song. The song starts out with “… sitzt ‘ne kleine Wanze”
(bedbug) and with each verse you leave off a letter: Wanz, Wan, Wa, W, – silence. 
&lt;/p&gt;
&lt;p&gt;
I’ll do the same here, but not with a bedbug:
&lt;/p&gt;
&lt;p&gt;
Let’s sing:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;lt;soap:Envelope xmlns:soap=”” xmlns:wsaddr=”” xmlns:wsrm=””
xmlns:wsu=”” xmlns:app=””&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;soap:Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;addr:Action&amp;gt;http://tempuri.org/1.0/Status.set&amp;lt;/addr:Action&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:Identifier&amp;gt;urn:session-id&amp;lt;/wsrm:Identifier&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:MessageNumber&amp;gt;5&amp;lt;/wsrm:MessageNumber&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsrm:Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsse:Security xmlns:wsse=”…”&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;wsse:BinarySecurityToken ValueType="&lt;/font&gt;&lt;font face="Courier New"&gt;http://tempuri.org#CustomToken&lt;/font&gt;&lt;font face="Courier New"&gt;" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
EncodingType="...#Base64Binary" wsu:Id=" MyID "&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
FHUIORv...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/wsse:BinarySecurityToken&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:Signature&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:SignedInfo&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:CanonicalizationMethod Algorithm="&lt;/font&gt;&lt;font face="Courier New"&gt;http://www.w3.org/2001/10/xml-exc-c14n#"/&amp;gt;&lt;/font&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:SignatureMethod Algorithm="&lt;/font&gt;&lt;font face="Courier New"&gt;http://www.w3.org/2000/09/xmldsig#md5"/&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:Reference URI="#MsgBody"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:DigestMethod&amp;nbsp; Algorithm="&lt;/font&gt;&lt;font face="Courier New"&gt;http://www.w3.org/2000/09/xmldsig#md5"/&amp;gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:DigestValue&amp;gt;LyLsF0Pi4wPU...&amp;lt;/ds:DigestValue&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/ds:Reference&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/ds:SignedInfo&amp;gt;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:SignatureValue&amp;gt;DJbchm5gK...&amp;lt;/ds:SignatureValue&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:KeyInfo&amp;gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;wsse:SecurityTokenReference&amp;gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;wsse:Reference URI="#MyID"/&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/wsse:SecurityTokenReference&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/ds:KeyInfo&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ds:Signature&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsse:Security&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:ResponseFormat&amp;gt;Xml&amp;lt;/app:ResponseFormat&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:Key wsu:Id=”AppKey”&amp;gt;27729912882….&amp;lt;/app:Key&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;soap:Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;soap:Body wsu:Id=”MyId”&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:status&amp;gt;Hello, I’m
good&amp;lt;/app:status&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/soap:Body&amp;gt;&lt;br&gt;
&amp;lt;/soap:Envelope&amp;gt; &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Not a very pretty song, I’ll admit. Let’s drop a some stuff. Let’s assume that we
don’t need to tell the other party that we’re looking to give it an MD5 signature,
but let’s say that’s implied and so were the canonicalization algorithm. Let’s also
assume that the other side already knows the security token and the key. Since we
only have a single signature digest here and yield a single signature we can just
collapse to the signature value. Heck, you may not even know about what that all means.
Verse 2:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;lt;soap:Envelope xmlns:soap=”” xmlns:wsaddr=”” xmlns:wsrm=””
xmlns:wsu=”” xmlns:app=””&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;soap:Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;addr:Action&amp;gt;http://tempuri.org/1.0/Status.set&amp;lt;/addr:Action&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:Identifier&amp;gt;urn:session-id&amp;lt;/wsrm:Identifier&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsrm:MessageNumber&amp;gt;5&amp;lt;/wsrm:MessageNumber&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsrm:Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;wsse:Security xmlns:wsse=”…”&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:Signature&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;ds:SignatureValue&amp;gt;DJbchm5gK...&amp;lt;/ds:SignatureValue&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ds:Signature&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/wsse:Security&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:ResponseFormat&amp;gt;Xml&amp;lt;/app:ResponseFormat&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:Key wsu:Id=”AppKey”&amp;gt;27729912882….&amp;lt;/app:Key&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;soap:Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;soap:Body wsu:Id=”MyId”&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;app:status&amp;gt;Hello, I’m
good&amp;lt;/app:status&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/soap:Body&amp;gt;&lt;br&gt;
&amp;lt;/soap:Envelope&amp;gt; &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Better. Now let’s strip all these extra XML namespace decorations since there aren’t
any name collisions as far as I can see. We’ll also collapse the rest of the security
elements into one element since there’s no need for three levels of nesting with a
single signature. Verse 3:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;lt;Envelope&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Action&amp;gt;http://tempuri.org/1.0/Status.set&amp;lt;/Action&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Identifier&amp;gt;urn:session-id&amp;lt;/Identifier&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;MessageNumber&amp;gt;5&amp;lt;/MessageNumber&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Sequence&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SignatureValue&amp;gt;DJbchm5gK...&amp;lt;/SignatureValue&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResponseFormat&amp;gt;Xml&amp;lt;/ResponseFormat&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Key&amp;gt;27729912882….&amp;lt;/Key&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Header&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Body&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;status&amp;gt;Hello, I’m good&amp;lt;/status&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Body&amp;gt;&lt;br&gt;
&amp;lt;/Envelope&amp;gt; &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Much better. The whole angle-bracket stuff and the nesting seems semi-gratuitous and
repetitive here, too. Let’s make that a bit simpler. Verse 4:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action=http://tempuri.org/1.0/Status.set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sequence-Identifier=urn:session-id&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sequence-MessageNumber=5&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SignatureValue=DJbchm5gK...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ResponseFormat=Xml&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Key=27729912882…. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; status=Hello, I’m good&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Much, much better. Now let’s get rid of that weird URI up there and split up the action
and the version info, make some of these keys are little more terse and turn that
into a format that’s easily transmittable over HTTP. By what we have here application/www-form-urlencoded
would probably be best. Verse 5:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method=Status.set&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;v=1.0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;session_key=929872172..&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;call_id=5&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;sig=DJbchm5gK...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;format=Xml&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;api_key=27729912882…. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;status=Hello,%20I’m%20good&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Oops. &lt;a href="http://wiki.developers.facebook.com/index.php/Status.set"&gt;Facebook&lt;/a&gt;’s
Status.set API. How did that happen? I thought that was REST?
&lt;/p&gt;
&lt;p&gt;
Now play the song backwards. The “new thing” is largely analogous to where we started
before the WS* Web Services stack and its CORBA/DCE/DCOM predecessors came around
and there are, believe it or not, good reasons for having of that additional “overhead”.
A common way to frame message content and the related control data, a common way to
express complex data structures and distinguish between data domains, a common way
to deal with addressing in multi-hop or store-and-forward messaging scenarios, an
agreed notion of sessions and message sequencing, a solid mechanism for protecting
the integrity of messages and parts of messages. This isn’t all just stupid.
&lt;/p&gt;
&lt;p&gt;
It’s well worth discussing whether messages need to be expressed as XML 1.0 text on
the wire at all times. I don’t think they need to and there are alternatives that
aren’t as heavy. JSON is fine and encodings like the .NET Binary Encoding or Fast
Infoset are viable alternatives as well. It’s also well worth discussing whether WS-Security
and the myriad of related standards that were clearly built by security geniuses for
security geniuses really need to be that complicated or whether we could all live
with a handful of simple profiles and just cut out 80% of the options and knobs and
parameters in that land. 
&lt;/p&gt;
&lt;p&gt;
I find it very sad that the discussion isn’t happening. Instead, people use the “REST”
moniker as the escape hatch to conveniently ignore any existing open standard for
tunnel-through-HTTP messaging and completely avoid the discussion. 
&lt;/p&gt;
&lt;p&gt;
It’s not only sad, it’s actually a bit frustrating. As one of the people responsible
for the protocol surface of the .NET Service Bus, I am absolutely not at liberty to
ignore what exists in the standards space. And this isn’t a mandate handed down to
me, but something I do because I believe it’s the right thing to live with the constraints
of the standards frameworks that exist. 
&lt;/p&gt;
&lt;p&gt;
When we’re sitting down and talk about a REST API, were designing a set of resources
– which may result in splitting a thing like a queue into two resources, head and
tail - and then we put RFC2616 on the table and try to be very precise in picking
the appropriate predefined HTTP method for a given semantic and how the HTTP 2xx,
3xx, 4xx, 5xx status codes map to success and error conditions. We’re also trying
to avoid inventing new ways to express things for which standards exists. There’s
a standard for how to express and manage lists with ATOM and APP and hence we use
that as a foundation. We use the designed extension points to add data to those lists
whenever necessary.
&lt;/p&gt;
&lt;p&gt;
When we’re designing a &lt;strike&gt;RPC&lt;/strike&gt; SOAP API, we’re intentionally trying to
avoid inventing new protocol surface and will try to leverage as much from the existing
and standardized stack as we possibly can – at a minimum we’ll stick with established
patterns such as the Create/GetInfo/Renew/Delete patterns for endpoint factories with
renewal (which is used in several standards). I’ll add that we are – ironically -
a bit backlogged on the protocol documentation for our SOAP endpoints and have more
info on the REST endpoint in the latest SDK, but we’ll make that up in the near future.
&lt;/p&gt;
&lt;p&gt;
So - can I build “REST” (mind the quotes) protocols that are as reduced as Facebook,
Twitter, Flickr, etc? Absolutely. There wouldn’t be much new work. It’s just a matter
of how we put messages on and pluck message off the wire. It’s really mostly a matter
of formatting and we have a lot of the necessary building blocks in the shipping WCF
bits today. I would just omit a bunch of decoration as things go out and make a bunch
of assumptions on things that come in.
&lt;/p&gt;
&lt;p&gt;
I just have a sense that I’d be hung upside down from a tree by the press and the
blogging, twittering, facebooking community if I, as someone at Microsoft, wouldn’t
follow the existing open and agreed standards or at least use protocols that we’ve
published under the &lt;a href="http://www.microsoft.com/interop/osp/default.mspx"&gt;OSP&lt;/a&gt; and
instead just started to do my own interpretative dance - even if that looked strikingly
similar to what the folks down in the Valley are doing. At the very least, someone
would call it a rip-off.
&lt;/p&gt;
&lt;p&gt;
What do you think? What should I/we do? 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=634b72d9-e200-45de-82db-2ae4c8ef947e" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,634b72d9-e200-45de-82db-2ae4c8ef947e.aspx</comments>
      <category>.NET Services</category>
      <category>Architecture</category>
      <category>Azure</category>
      <category>Technology</category>
      <category>Technology/ISB</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=82d7c041-691b-4d37-b552-6de980c3c2b1</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,82d7c041-691b-4d37-b552-6de980c3c2b1.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,82d7c041-691b-4d37-b552-6de980c3c2b1.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=82d7c041-691b-4d37-b552-6de980c3c2b1</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've got a discussion forum up on MSDN where you can ask questions about Microsoft
.NET Services (Service Bus, Workflow, Access Control): <a href="http://social.msdn.microsoft.com/Forums/en-US/netservices/threads/">http://social.msdn.microsoft.com/Forums/en-US/netservices/threads/</a></p>
        <p>
 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=82d7c041-691b-4d37-b552-6de980c3c2b1" />
      </body>
      <title>Questions about .NET Services? Hit the forums.</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,82d7c041-691b-4d37-b552-6de980c3c2b1.aspx</guid>
      <link>http://vasters.com/clemensv/2008/10/28/Questions+About+NET+Services+Hit+The+Forums.aspx</link>
      <pubDate>Tue, 28 Oct 2008 20:20:15 GMT</pubDate>
      <description>&lt;p&gt;
We've got a discussion forum up on MSDN where you can ask questions about Microsoft
.NET Services (Service Bus, Workflow, Access Control): &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/netservices/threads/"&gt;http://social.msdn.microsoft.com/Forums/en-US/netservices/threads/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=82d7c041-691b-4d37-b552-6de980c3c2b1" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,82d7c041-691b-4d37-b552-6de980c3c2b1.aspx</comments>
      <category>Talks</category>
      <category>Technology</category>
      <category>Technology/ISB</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=798bbf5b-f9f9-45b9-87ba-f6a30c359af9</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,798bbf5b-f9f9-45b9-87ba-f6a30c359af9.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,798bbf5b-f9f9-45b9-87ba-f6a30c359af9.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=798bbf5b-f9f9-45b9-87ba-f6a30c359af9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="justify">
A flock of pigs has been doing aerobatics high up over Microsoft Campus in Redmond
in the past three weeks. Neither City of Redmond nor Microsoft spokespeople returned
calls requesting comments in time for this article. An Microsoft worker who requested
anonymity and has seen the pigs flying overhead commented that "they are as good as
the Blue Angels at Seafair, just funnier" and "they seem to circle over building 42
a lot, but I wouldn't know why". 
</p>
        <p>
In related news ... 
</p>
        <p align="justify">
We wrapped up the BizTalk Services "R11" CTP this last Thursday and put the latest
SDK release up on <a href="http://labs.biztalk.net/">http://labs.biztalk.net/</a>.
As you may or may not know, "BizTalk Services" is the codename for Microsoft's cloud-based
Identity and Connectivity services - with a significant set of further services in
the pipeline. The R11 release is a major milestone for the data center side of BizTalk
Services, but we've also added several new client-facing features, especially on the
Identity services. You can now authenticate using a certificate in addition to username
and CardSpace authentication, we have enabled support for 3rd party managed CardSpace
cards, and there is extended support for claims based authorization. 
</p>
        <p>
Now the surprising bit:
</p>
        <p align="justify">
Only about an hour before we locked down the SDK on Thursday, we checked a sample
into the samples tree that has a rather unusual set of prerequisites for something
coming out of Microsoft: 
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p align="justify">
Runtime: <a href="http://java.sun.com/javaee/">Java EE 5</a> on <a href="https://glassfish.dev.java.net/">Sun
Glassfish v2</a> + <a href="https://metro.dev.java.net/">Sun WSIT/Metro</a> (JAX-WS
extensions), Tool: <a href="http://netbeans.org">Netbeans 6.0 IDE</a>. 
</p>
        </blockquote>
        <p align="justify">
The sample shows how to use the BizTalk Services Identity Security Token Service (STS)
to secure the communication between a Java client and a Java service providing federated
authentication and claims-based authorization.
</p>
        <p align="justify">
The sample, which you can find in <em>./Samples/OtherPlatforms/StandaloneAccessControl/JavaEE5</em> once
you installed the SDK, is a pure Java sample not requiring any of our bits on either
the service or client side. The interaction with our services is purely happening
on the wire. 
</p>
        <p align="justify">
If you are a "Javahead", it might seem odd that we're shipping this sample inside
a Windows-only MSI installer and I will agree that that's odd. It's simply a function
of timing and the point in time when we knew that we could get it done (some more
on that below). For the next BizTalk Services SDK release I expect there to be an
additional .jar file for the Java samples.
</p>
        <p align="justify">
It's important to note that this isn't just a thing we did as a one-time thing and
because we could. We have done a significant amount of work on the backend protocol
implementations to start opening up a very broad set of scenarios on the BizTalk Services
Connectivity services for platforms other than .NET. We already have a set of additional
Java EE samples lined up for when we enable that functionality on the backend. However,
since getting security and identity working is a prerequisite for making all other
services work, that's where we started. There'll be more and there'll be more platform
and language choice than Java down the road. 
</p>
        <p align="justify">
Just to be perfectly clear: Around here we strongly believe that .NET and the Windows
Communication Foundation in particular is the most advanced platform to build services,
irrespective of whether they are of the WS-* or REST variety. If you care about my
personal opinion, I'll say that several months of research into the capabilities of
other platforms has only reaffirmed that belief for me and I don't even need to put
a Microsoft hat on to say that. 
</p>
        <p align="justify">
But we recognize and respect that there are a great variety of individual reasons
why people might not be using .NET and WCF. The obvious one is "platform". If you
run on Linux or Unix and/or if your deployment target is a Java Application Server,
then your platform is very likely not .NET. It's something else. If that's your
world, we still think that our services are something that's useful for your applications
and we want to show you why. And it is absolutely not enough for us to say "here is
the wire protocol documentation; go party!". Only Code is Truth.
</p>
        <p align="justify">
I'm also writing "Only Code is Truth" also because we've found - perhaps not too surprisingly
- that there is a significant difference between reading and implementing the WS-*
specs and having things actually work. And here I get to the point where a round of
public "Thank You" is due:
</p>
        <p align="justify">
The Metro team over at Sun Microsystems has made a very significant contribution to
making this all work. Before we started making changes to accommodate Java, there
would have been very little hope for anyone to get this seemingly simple
scenario to work. We had to make quite a few changes even though our service did follow
the specs. 
</p>
        <p align="justify">
While we were adjusting our backend STS accordingly, the Sun Metro team worked on
a set of issues that we identified on their end (with fantastic turnaround times)
and worked those into their public nightly builds. The Sun team also 'promoted' a
nightly build of Metro 1.2 to a semi-permanent <a href="https://metro.dev.java.net/servlets/ProjectDocumentList?folderID=8958&amp;expandFolder=8958&amp;folderID=7636">download
location</a> (the first 1.2 build that got that treatment), because it is the build
tested to successfully interop with our SDK release, even though that build is known
to have some regressions for some of their other test scenarios. As they work towards
wrapping up their 1.2 release and fix those other bugs, we’ll continue to test and
talk to help that the interop scenarios keep working. 
</p>
        <p align="justify">
As a result of this collaboration, Metro 1.2 is going to be a better and more interoperable
release for the Sun's customers and the greater Java community and BizTalk Services
as well as our future identity products will be better and more interoperable, too.
Win-Win. Thank you, Sun.
</p>
        <p align="justify">
As a goodie, I put some code into the Java sample that might be useful even if you
don't even care about our services. Since configuring the Java certificate stores
for standalone applications can be really painful, I added some simple code that's
using a week-old feature of the latest Metro 1.2 bits that allows configuring the
Truststores/Keystores dynamically and pull the stores from the client's .jar at runtime.
The code also has an authorization utility class that shows how to get and evaluate
claims on the service side by pulling the SAML token out of the context and pulling
the correct attributes from the token.
</p>
        <p>
Have fun.
</p>
        <p>
[By the way, this is not an April Fool's joke, in case you were wondering]<br /></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=798bbf5b-f9f9-45b9-87ba-f6a30c359af9" />
      </body>
      <title>BizTalk Services "R11" CTP Comes with a Surprise</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,798bbf5b-f9f9-45b9-87ba-f6a30c359af9.aspx</guid>
      <link>http://vasters.com/clemensv/2008/03/31/BizTalk+Services+R11+CTP+Comes+With+A+Surprise.aspx</link>
      <pubDate>Mon, 31 Mar 2008 17:56:40 GMT</pubDate>
      <description>&lt;p align=justify&gt;
A flock of pigs has been doing aerobatics high up over Microsoft Campus in Redmond
in the past three weeks. Neither City of Redmond nor Microsoft spokespeople returned
calls requesting comments in time for this article. An Microsoft worker who requested
anonymity and has seen the pigs flying overhead commented that "they are as good as
the Blue Angels at Seafair, just funnier" and "they seem to circle over building 42
a lot, but I wouldn't know why". 
&lt;/p&gt;
&lt;p&gt;
In related news ... 
&lt;/p&gt;
&lt;p align=justify&gt;
We wrapped up the BizTalk Services "R11" CTP this last Thursday and put the latest
SDK release up on &lt;a href="http://labs.biztalk.net/"&gt;http://labs.biztalk.net/&lt;/a&gt;.
As you may or may not know, "BizTalk Services" is the codename for Microsoft's cloud-based
Identity and Connectivity services - with a significant set of further services in
the pipeline. The R11 release is a major milestone for the data center side of BizTalk
Services, but we've also added several new client-facing features, especially on the
Identity services. You can now authenticate using a certificate in addition to username
and CardSpace authentication, we have enabled support for 3rd party managed CardSpace
cards, and there is extended support for claims based authorization. 
&lt;/p&gt;
&lt;p&gt;
Now the surprising bit:
&lt;/p&gt;
&lt;p align=justify&gt;
Only about an hour before we locked down the SDK on Thursday, we checked a sample
into the samples tree that has a rather unusual set of prerequisites for something
coming out of Microsoft: 
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p align=justify&gt;
Runtime: &lt;a href="http://java.sun.com/javaee/"&gt;Java EE 5&lt;/a&gt; on &lt;a href="https://glassfish.dev.java.net/"&gt;Sun
Glassfish v2&lt;/a&gt; + &lt;a href="https://metro.dev.java.net/"&gt;Sun WSIT/Metro&lt;/a&gt; (JAX-WS
extensions), Tool: &lt;a href="http://netbeans.org"&gt;Netbeans 6.0 IDE&lt;/a&gt;. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p align=justify&gt;
The sample shows how to use the BizTalk Services Identity Security Token Service (STS)
to secure the communication between a Java client and a Java service providing federated
authentication and claims-based authorization.
&lt;/p&gt;
&lt;p align=justify&gt;
The sample, which you can find in &lt;em&gt;./Samples/OtherPlatforms/StandaloneAccessControl/JavaEE5&lt;/em&gt; once
you installed the SDK, is a pure Java sample not requiring any of our bits on either
the service or client side. The interaction with our services is purely happening
on the wire. 
&lt;/p&gt;
&lt;p align=justify&gt;
If you are a "Javahead", it might seem odd that we're shipping this sample inside
a Windows-only MSI installer and I will agree that that's odd. It's simply a function
of timing and the point in time when we knew that we could get it done (some more
on that below). For the next BizTalk Services SDK release I expect there to be an
additional .jar file for the Java samples.
&lt;/p&gt;
&lt;p align=justify&gt;
It's important to note that this isn't just a thing we did as a one-time thing and
because we could. We have done a significant amount of work on the backend protocol
implementations to start opening up a very broad set of scenarios on the BizTalk Services
Connectivity services for platforms other than .NET. We already have a set of additional
Java EE samples lined up for when we enable that functionality on the backend. However,
since getting security and identity working is a prerequisite for making all other
services work, that's where we started. There'll be more and there'll be more platform
and language choice than Java down the road. 
&lt;/p&gt;
&lt;p align=justify&gt;
Just to be perfectly clear: Around here we strongly believe that .NET and the Windows
Communication Foundation in particular is the most advanced platform to build services,
irrespective of whether they are of the WS-* or REST variety. If you care about my
personal opinion, I'll say that several months of research into the capabilities of
other platforms has only reaffirmed that belief for me and I don't even need to put
a Microsoft hat on to say that. 
&lt;/p&gt;
&lt;p align=justify&gt;
But we recognize and respect that there are a great variety of individual reasons
why people might not be using .NET and WCF. The obvious one is "platform". If you
run on Linux or Unix and/or if your deployment target is a Java Application Server,
then your platform is very likely not .NET. It's something else.&amp;nbsp;If that's your
world, we still think that our services are something that's useful for your applications
and we want to show you why. And it is absolutely not enough for us to say "here is
the wire protocol documentation; go party!". Only Code is Truth.
&lt;/p&gt;
&lt;p align=justify&gt;
I'm also writing "Only Code is Truth" also because we've found - perhaps not too surprisingly
- that there is a significant difference between reading and implementing the WS-*
specs and having things actually work. And here I get to the point where a round of
public "Thank You" is due:
&lt;/p&gt;
&lt;p align=justify&gt;
The Metro team over at Sun Microsystems has made a very significant contribution to
making this all work. Before we started making changes to accommodate Java, there
would have been&amp;nbsp;very little&amp;nbsp;hope for anyone to get this seemingly simple
scenario to work. We had to make quite a few changes even though our service did follow
the specs. 
&lt;/p&gt;
&lt;p align=justify&gt;
While we were adjusting our backend STS accordingly, the Sun Metro team worked on
a set of issues that we identified on their end (with fantastic turnaround times)
and worked those into their public nightly builds. The Sun team also 'promoted' a
nightly build of Metro 1.2 to a semi-permanent &lt;a href="https://metro.dev.java.net/servlets/ProjectDocumentList?folderID=8958&amp;amp;expandFolder=8958&amp;amp;folderID=7636"&gt;download
location&lt;/a&gt; (the first 1.2 build that got that treatment), because it is the build
tested to successfully interop with our SDK release, even though that build is known
to have some regressions for some of their other test scenarios. As they work towards
wrapping up their 1.2 release and fix those other bugs, we’ll continue to test and
talk to help that the interop scenarios keep working. 
&lt;/p&gt;
&lt;p align=justify&gt;
As a result of this collaboration, Metro 1.2 is going to be a better and more interoperable
release for the Sun's customers and the greater Java community and BizTalk Services
as well as our future identity products will be better and more interoperable, too.
Win-Win. Thank you, Sun.
&lt;/p&gt;
&lt;p align=justify&gt;
As a goodie, I put some code into the Java sample that might be useful even if you
don't even care about our services. Since configuring the Java certificate stores
for standalone applications can be really painful, I added some simple code that's
using a week-old feature of the latest Metro 1.2 bits that allows configuring the
Truststores/Keystores dynamically and pull the stores from the client's .jar at runtime.
The code also has an authorization utility class that shows how to get and evaluate
claims on the service side by pulling the SAML token out of the context and pulling
the correct attributes from the token.
&lt;/p&gt;
&lt;p&gt;
Have fun.
&lt;/p&gt;
&lt;p&gt;
[By the way, this is not an April Fool's joke, in case you were wondering]&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=798bbf5b-f9f9-45b9-87ba-f6a30c359af9" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,798bbf5b-f9f9-45b9-87ba-f6a30c359af9.aspx</comments>
      <category>Architecture</category>
      <category>IT Strategy</category>
      <category>Technology</category>
      <category>Technology/CardSpace</category>
      <category>Technology/ISB</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://winliveid.spaces.live.com/blog/cns!AEE1BB0D86E23AAC!931.entry">Check
this out</a>.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e" />
      </body>
      <title>LiveID + CardSpace</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e.aspx</guid>
      <link>http://vasters.com/clemensv/2007/08/28/LiveID+CardSpace.aspx</link>
      <pubDate>Tue, 28 Aug 2007 00:58:21 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://winliveid.spaces.live.com/blog/cns!AEE1BB0D86E23AAC!931.entry"&gt;Check
this out&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,48f3d81b-61f9-4bd5-99d5-8624bfcd0b5e.aspx</comments>
      <category>Technology</category>
      <category>Technology/CardSpace</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=64a8caa0-f9c1-4515-82d3-359a95c56954</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,64a8caa0-f9c1-4515-82d3-359a95c56954.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,64a8caa0-f9c1-4515-82d3-359a95c56954.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=64a8caa0-f9c1-4515-82d3-359a95c56954</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img style="FLOAT: left" src="http://vasters.com/clemensv/content/binary/image00112345678910111213.jpg" border="0" />Having
an <a href="http://vasters.com/clemensv/PermaLink,guid,842e5373-60c1-4390-b820-00dba8b0cb4c.aspx">Internet
Service Bus</a> up in the cloud is not very entertaining unless there are services
in the bus. Therefore, I built one (and already showed some of the <a href="http://vasters.com/clemensv/PermaLink,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx">code
basics</a>) that’s hopefully fun to play with and will soon share the first version
with you after some scrubbing and pending a few updates to the ISB that will optimize
the authentication process. It’s a 0.1 version and an experiment. The code download
should be ready in the next two weeks, including those adjustments. But you can actually
play with parts of it today without compiling or installing anything. The info is
at the bottom of this post.
</p>
        <p>
To make matters really interesting, this sample not only shows how to plug a service
into the cloud and call it from some Console app, but is a combo of two rather unusual
hosts for WCF services: A Windows Live Messenger Add-In that acts as the server, and
a Windows Vista Sidebar gadget that acts as the client. 
</p>
        <p>
Since the Silicon Valley scene is currently all over <a href="http://www.twitter.com/">Twitter</a> and
clones of Twitter are apparently popping up <a href="http://www.techcrunch.com/2007/05/14/web-2-in-germany-copy-paste-innovation-or-more/">somewhere
every day</a>, I thought I could easily provide fodder to the proponents of the alleged
Microsoft tradition of purely relying on copying other’s ideas and clone them as well
;-)  Well, no, maybe not. This is a bit different. 
</p>
        <p>
          <img style="FLOAT: right" src="http://vasters.com/clemensv/content/binary/image0021234567891011121314.jpg" border="0" />TweetieBot
is an example of a simple personal service. If you choose to host it, you own it,
you run it, you control it. The data is held nowhere but on your personal machine
and it’s using the BizTalk Services ISB to stick its head up into the cloud and at
a stable endpoint so that its easily reachable for a circle of friends, bridging the
common obstacles of dynamic IPs, firewalls and NAT. No need to use UPnP or open up
ports on your router. If you choose to do so, you can encrypt traffic so that there’s
no chance that anyone looking at our ISB nor anyone else can see the what’s actually
going across the wire. 
</p>
        <p>
Right now, lots of the Web 2.0 world lives on the assumption that everything needs
to live at central places and that community forms around ad-driven hubs. The mainframe
folks had a similar stance in the 70s and 80s and then Personal Computers came along.
The pendulum is always swinging and I have little doubt that it will swing back to
“personal” once more and that the federation of personal services will seriously challenge
the hub model once more.
</p>
        <p>
So what does the sample do? As indicated, TweetieBot is a bot that plugs into a Windows
Live Messenger using a simple Add-In. <a href="http://community.bartdesmet.net/blogs/bart/archive/2006/09/17/4431.aspx">Bart
De Smet</a> has a brilliant summary for how to build such Add-Ins. When the Add-In
is active and someone chats the bot, it answers politely and remembers the chat line,
time and sender. The bird has a leaky long term memory, though. It forgets everything
past the last 40 lines.
</p>
        <p>
Where it gets interesting is that the Add-In can stick three endpoints into the BizTalk
Services ISB:
</p>
        <ul>
          <li>
A Request/Response Web Service that allows retrieving the list of the last 40 (or
less) “tweets” and also allows client to submit tweets programmatically. 
</li>
          <li>
An RSS service that allows (right now) anyone to peek in to the chat log of the last
40 tweets. 
</li>
          <li>
An Event service that allows subscribers to get real-time notifications whenever a
new tweet is recorded.</li>
        </ul>
        <p>
The accompanying Sidebar Gadget, which is implemented <a href="http://blogs.msdn.com/karstenj/archive/2006/10/09/activex-wpf-gadget.aspx">using
WPF</a>, is a client for two of these services. 
</p>
        <p>
          <img style="FLOAT: left" src="http://vasters.com/clemensv/content/binary/image00312345678910.jpg" border="0" /> <img style="FLOAT: right" src="http://vasters.com/clemensv/content/binary/image00412345.jpg" border="0" />When
you drop the Gadget on the Sidebar, it will prompt for the IM address of the TweetieBot
service you’d like to subscribe to. Once you’ve authenticated at the relay using your
registered Information Card, the gadget will pull and show the current list of Tweets
and subscribe to the Events service for real-time updates. And whenever someone chats
the bot, the Sidebar gadget will immediately show the new entry. So even though the
Gadget lives on some client machine that’s hidden between several layers of firewalls
and behind NAT, it can actually get push-style event notifications through the cloud! 
</p>
        <p>
“How do I send events to clients?” must be one of the most frequent questions that
I’ve been asked about Web Services in the past several years. Well, this is your answer
right here.
</p>
        <p>
While I’m still toying around with the code and the guys on the 1st floor in my building
are doing some tweaks on the ISB infrastructure to make multi-endpoint authentication
simpler, you can already play with the bot and help me a bit: 
</p>
        <p>
Using Windows Live Messenger you can chat (<a href="msnim:chat?contact=TweetieBot@hotmail.com">click
here</a>) <a href="mailto:tweetiebot@hotmail.com">tweetiebot@hotmail.com</a><b>now</b>.
Drop a few lines. If the bot is online (which means that I’m not tinkering with it)
it will reply. Then look at this <a href="http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss/">RSS
feed</a> [1] and you can see what you and everyone else have been telling the bot
recently. Enjoy.
</p>
        <p>
[1] <a href="http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss">http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss</a></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=64a8caa0-f9c1-4515-82d3-359a95c56954" />
      </body>
      <title>TweetieBot - A BizTalk Services Experiment</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,64a8caa0-f9c1-4515-82d3-359a95c56954.aspx</guid>
      <link>http://vasters.com/clemensv/2007/05/16/TweetieBot+A+BizTalk+Services+Experiment.aspx</link>
      <pubDate>Wed, 16 May 2007 19:33:48 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img style="FLOAT: left" src="http://vasters.com/clemensv/content/binary/image00112345678910111213.jpg" border=0&gt;Having
an &lt;a href="http://vasters.com/clemensv/PermaLink,guid,842e5373-60c1-4390-b820-00dba8b0cb4c.aspx"&gt;Internet
Service Bus&lt;/a&gt; up in the cloud is not very entertaining unless there are services
in the bus. Therefore, I built one (and already showed some of the &lt;a href="http://vasters.com/clemensv/PermaLink,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx"&gt;code
basics&lt;/a&gt;) that’s hopefully fun to play with and will soon share the first version
with you after some scrubbing and pending a few updates to the ISB that will optimize
the authentication process. It’s a 0.1 version and an experiment. The code download
should be ready in the next two weeks, including those adjustments. But you can actually
play with parts of it today without compiling or installing anything. The info is
at the bottom of this post.
&lt;/p&gt;
&lt;p&gt;
To make matters really interesting, this sample not only shows how to plug a service
into the cloud and call it from some Console app, but is a combo of two rather unusual
hosts for WCF services: A Windows Live Messenger Add-In that acts as the server, and
a Windows Vista Sidebar gadget that acts as the client. 
&lt;/p&gt;
&lt;p&gt;
Since the Silicon Valley scene is currently all over &lt;a href="http://www.twitter.com/"&gt;Twitter&lt;/a&gt; and
clones of Twitter are apparently popping up &lt;a href="http://www.techcrunch.com/2007/05/14/web-2-in-germany-copy-paste-innovation-or-more/"&gt;somewhere
every day&lt;/a&gt;, I thought I could easily provide fodder to the proponents of the alleged
Microsoft tradition of purely relying on copying other’s ideas and clone them as well
;-)&amp;nbsp; Well, no, maybe not. This is a bit different. 
&lt;/p&gt;
&lt;p&gt;
&lt;img style="FLOAT: right" src="http://vasters.com/clemensv/content/binary/image0021234567891011121314.jpg" border=0&gt;TweetieBot
is an example of a simple personal service. If you choose to host it, you own it,
you run it, you control it. The data is held nowhere but on your personal machine
and it’s using the BizTalk Services ISB to stick its head up into the cloud and at
a stable endpoint so that its easily reachable for a circle of friends, bridging the
common obstacles of dynamic IPs, firewalls and NAT. No need to use UPnP or open up
ports on your router. If you choose to do so, you can encrypt traffic so that there’s
no chance that anyone looking at our ISB nor anyone else can see the what’s actually
going across the wire. 
&lt;/p&gt;
&lt;p&gt;
Right now, lots of the Web 2.0 world lives on the assumption that everything needs
to live at central places and that community forms around ad-driven hubs. The mainframe
folks had a similar stance in the 70s and 80s and then Personal Computers came along.
The pendulum is always swinging and I have little doubt that it will swing back to
“personal” once more and that the federation of personal services will seriously challenge
the hub model once more.
&lt;/p&gt;
&lt;p&gt;
So what does the sample do? As indicated, TweetieBot is a bot that plugs into a Windows
Live Messenger using a simple Add-In. &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2006/09/17/4431.aspx"&gt;Bart
De Smet&lt;/a&gt; has a brilliant summary for how to build such Add-Ins. When the Add-In
is active and someone chats the bot, it answers politely and remembers the chat line,
time and sender. The bird has a leaky long term memory, though. It forgets everything
past the last 40 lines.
&lt;/p&gt;
&lt;p&gt;
Where it gets interesting is that the Add-In can stick three endpoints into the BizTalk
Services ISB:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A Request/Response Web Service that allows retrieving the list of the last 40 (or
less) “tweets” and also allows client to submit tweets programmatically. 
&lt;li&gt;
An RSS service that allows (right now) anyone to peek in to the chat log of the last
40 tweets. 
&lt;li&gt;
An Event service that allows subscribers to get real-time notifications whenever a
new tweet is recorded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The accompanying Sidebar Gadget, which is implemented &lt;a href="http://blogs.msdn.com/karstenj/archive/2006/10/09/activex-wpf-gadget.aspx"&gt;using
WPF&lt;/a&gt;, is a client for two of these services. 
&lt;/p&gt;
&lt;p&gt;
&lt;img style="FLOAT: left" src="http://vasters.com/clemensv/content/binary/image00312345678910.jpg" border=0&gt;&amp;nbsp;&lt;img style="FLOAT: right" src="http://vasters.com/clemensv/content/binary/image00412345.jpg" border=0&gt;When
you drop the Gadget on the Sidebar, it will prompt for the IM address of the TweetieBot
service you’d like to subscribe to. Once you’ve authenticated at the relay using your
registered Information Card, the gadget will pull and show the current list of Tweets
and subscribe to the Events service for real-time updates. And whenever someone chats
the bot, the Sidebar gadget will immediately show the new entry. So even though the
Gadget lives on some client machine that’s hidden between several layers of firewalls
and behind NAT, it can actually get push-style event notifications through the cloud! 
&lt;/p&gt;
&lt;p&gt;
“How do I send events to clients?” must be one of the most frequent questions that
I’ve been asked about Web Services in the past several years. Well, this is your answer
right here.
&lt;/p&gt;
&lt;p&gt;
While I’m still toying around with the code and the guys on the 1st floor in my building
are doing some tweaks on the ISB infrastructure to make multi-endpoint authentication
simpler, you can already play with the bot and help me a bit: 
&lt;/p&gt;
&lt;p&gt;
Using Windows Live Messenger you can chat (&lt;a href="msnim:chat?contact=TweetieBot@hotmail.com"&gt;click
here&lt;/a&gt;) &lt;a href="mailto:tweetiebot@hotmail.com"&gt;tweetiebot@hotmail.com&lt;/a&gt; &lt;b&gt;now&lt;/b&gt;.
Drop a few lines. If the bot is online (which means that I’m not tinkering with it)
it will reply. Then look at this &lt;a href="http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss/"&gt;RSS
feed&lt;/a&gt; [1] and you can see what you and everyone else have been telling the bot
recently. Enjoy.
&lt;/p&gt;
&lt;p&gt;
[1] &lt;a href="http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss"&gt;http://connect.biztalk.net/services/tweetiebot/tweetiebot%40hotmail.com/rss&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=64a8caa0-f9c1-4515-82d3-359a95c56954" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,64a8caa0-f9c1-4515-82d3-359a95c56954.aspx</comments>
      <category>Technology</category>
      <category>Technology/BizTalk</category>
      <category>Technology/ISB</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=603e2393-c8de-40dd-b2e9-88f504b44149</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=603e2393-c8de-40dd-b2e9-88f504b44149</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I wrote a slightly Twitter-inspired, fun app over the weekend that's using the BizTalk
Services Connectivity service and relay. In the spirit of Software+Services I'm going
to give you half of it [for now] ;-)   You must have the <a href="http://labs.biztalk.net/downloads.aspx">BizTalk
Services SDK</a> installed to run the sample.
</p>
        <p>
The server app, which I'm keeping to myself for the next few days as part of
the experiment, is an extension (add-in) to Windows Live Messenger. The
Messenger add-in monitors all chats with <a href="mailto:tweetiebot@hotmail.com">tweetiebot@hotmail.com</a> and
keeps circular buffer with the last 40 incoming messages. Using the client (which
is in the attached archive), you can get a list of "Tweets" and add a new one (same
as chatting)
</p>
        <p>
[<font color="#2b91af">ServiceContract</font>(Name = <font color="#a31515">"TweetieBot"</font>,
Namespace = <font color="#a31515"><a href="http://samples.vasters.com/2007/05/tweetiebot">http://samples.vasters.com/2007/05/tweetiebot</a></font>)]<br /><font color="#0000ff">public</font><font color="#0000ff">interface</font><font color="#2b91af">ITweetieBot<br /></font>{<br />
  [<font color="#2b91af">OperationContract</font>]<br /><font color="#2b91af">  IList</font>&lt;<font color="#2b91af">Tweet</font>&gt;
GetTweets(<font color="#2b91af">DateTime</font>? since);<br />
  [<font color="#2b91af">OperationContract</font>]<br /><font color="#0000ff">  void</font> Tweet(<font color="#0000ff">string</font> nickname, <font color="#0000ff">string</font> text);<br />
}
</p>
        <p>
or you can subscribe to new tweets and get them as they arrive
</p>
        <p>
[<font color="#2b91af">ServiceContract</font>(Name = <font color="#a31515">"TweetieEvents"</font>,
Namespace = <font color="#a31515"><a href="http://samples.vasters.com/2007/05/tweetiebot">http://samples.vasters.com/2007/05/tweetiebot</a></font>)]<br /><font color="#0000ff">public</font><font color="#0000ff">interface</font><font color="#2b91af">ITweetieEvents<br /></font>{<br />
  [<font color="#2b91af">OperationContract</font>(IsOneWay=<font color="#0000ff">true</font>)]<br /><font color="#0000ff">  void</font> OnTweet(<font color="#2b91af">Tweet</font> tweet);<br />
}
</p>
        <p>
The client application hooks up to the client (that lives right on my desktop machine)
through the BizTalk Services ISB and the server fires events back through the
ISB relay into the client as new tweets arrive. So when you run the attached client
app, you'll find that it starts with a dump of the current log of the bot and then
keeps spitting out events as they arrive. 
</p>
        <p>
The client is actually pretty simple. The <em>EventsClient</em> is the subscriber
for the pub/sub service (ConnectionMode.RelayMulticast) that writes out the received
events to the console. The rest all happens in <em>Main</em> (parsing an validating
the command line argument) and in <em>Run</em>.
</p>
        <p>
          <span style="FONT-SIZE: 12pt; COLOR: blue; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes">
            <font size="2">   
class</font>
          </span>
          <span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes">
            <font color="#000000" size="2">
            </font>
            <span style="COLOR: #2b91af">
              <font size="2">Program<br /></font>
            </span>
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">    </span>{<br /><span style="mso-spacerun: yes">        </span></font>
              <span style="COLOR: blue">class</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">EventsClient</span>
              <font color="#000000"> : </font>
            </font>
            <span style="COLOR: #2b91af">
              <font size="2">ITweetieEvents<br /></font>
            </span>
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">        </span>{<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: blue">public</span>
              <font color="#000000">
              </font>
              <span style="COLOR: blue">void</span>
              <font color="#000000"> OnTweet(</font>
              <span style="COLOR: #2b91af">Tweet</span>
            </font>
            <font size="2">
              <font color="#000000"> tweet)<br /><span style="mso-spacerun: yes">            </span>{<br /><span style="mso-spacerun: yes">                </span></font>
              <span style="COLOR: #2b91af">Console</span>
              <font color="#000000">.WriteLine(</font>
              <span style="COLOR: #a31515">"[{0}]
{1}:{2}"</span>
            </font>
            <font size="2">
              <font color="#000000">, tweet.Time, tweet.User,
tweet.Text);<br /><span style="mso-spacerun: yes">            </span>}<br /><span style="mso-spacerun: yes">        </span>}<br /><br /><span style="mso-spacerun: yes">        </span></font>
              <span style="COLOR: blue">static</span>
              <font color="#000000">
              </font>
              <span style="COLOR: blue">void</span>
              <font color="#000000"> Main(</font>
              <span style="COLOR: blue">string</span>
            </font>
            <font size="2">
              <font color="#000000">[]
args)<br /><span style="mso-spacerun: yes">        </span>{<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: blue">string</span>
              <font color="#000000"> usageMessage
= </font>
              <span style="COLOR: #a31515">"Usage: IMBotClient &lt;messenger-email-address&gt;"</span>
            </font>
            <font size="2">
              <font color="#000000">;<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: blue">if</span>
            </font>
            <font size="2">
              <font color="#000000"> (args.Length
== 0)<br /><span style="mso-spacerun: yes">            </span>{<br /><span style="mso-spacerun: yes">                </span></font>
              <span style="COLOR: #2b91af">Console</span>
            </font>
            <font color="#000000">
              <font size="2">.WriteLine(usageMessage);<br /><span style="mso-spacerun: yes">            </span>}<br /><span style="mso-spacerun: yes">            </span></font>
            </font>
            <span style="COLOR: blue">
              <font size="2">else<br /></font>
            </span>
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">            </span>{<br /><span style="mso-spacerun: yes">                </span></font>
              <span style="COLOR: blue">if</span>
              <font color="#000000"> (!</font>
              <span style="COLOR: #2b91af">Regex</span>
              <font color="#000000">.IsMatch(args[0], </font>
              <span style="COLOR: #a31515">@"^([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$"</span>
            </font>
            <font size="2">
              <font color="#000000">))<br /><span style="mso-spacerun: yes">                </span>{<br /><span style="mso-spacerun: yes">                    </span></font>
              <span style="COLOR: #2b91af">Console</span>
            </font>
            <font size="2">
              <font color="#000000">.WriteLine(usageMessage);<br /><span style="mso-spacerun: yes">                    </span></font>
              <span style="COLOR: #2b91af">Console</span>
              <font color="#000000">.WriteLine(</font>
              <span style="COLOR: #a31515">"'{0}'
is not a valid email address"</span>
            </font>
            <font color="#000000">
              <font size="2">);<br /><span style="mso-spacerun: yes">                </span>}<br /><span style="mso-spacerun: yes">                </span></font>
            </font>
            <span style="COLOR: blue">
              <font size="2">else<br /></font>
            </span>
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">                </span>{<br /><span style="mso-spacerun: yes">                    </span>Run(args[0]);<br /><span style="mso-spacerun: yes">                </span>}<br /><span style="mso-spacerun: yes">            </span>}<br /><span style="mso-spacerun: yes">        </span>}<br /><br /><span style="mso-spacerun: yes">        </span></font>
              <span style="COLOR: blue">private</span>
              <font color="#000000">
              </font>
              <span style="COLOR: blue">static</span>
              <font color="#000000">
              </font>
              <span style="COLOR: blue">void</span>
              <font color="#000000"> Run(</font>
              <span style="COLOR: blue">string</span>
            </font>
            <font size="2">
              <font color="#000000"> emailAddress)<br /><span style="mso-spacerun: yes">        </span>{<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">EndpointAddress</span>
              <font color="#000000"> serviceAddress
= 
<br />
                </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">EndpointAddress</span>
              <font color="#000000">(</font>
              <span style="COLOR: #2b91af">String</span>
              <font color="#000000">.Format(</font>
              <span style="COLOR: #2b91af">String</span>
              <font color="#000000">.Format(</font>
              <span style="COLOR: #a31515">"sb://{0}/services/tweetiebot/{1}/service"</span>
              <font color="#000000">, <br />
                                    </font>
              <span style="COLOR: #2b91af">RelayBinding</span>
              <font color="#000000">.DefaultRelayHostName, </font>
              <span style="COLOR: #2b91af">Uri</span>
            </font>
            <font size="2">
              <font color="#000000">.EscapeDataString(emailAddress))));<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">EndpointAddress</span>
              <font color="#000000"> eventsAddress
= 
<br />
                </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">EndpointAddress</span>
              <font color="#000000">(</font>
              <span style="COLOR: #2b91af">String</span>
              <font color="#000000">.Format(</font>
              <span style="COLOR: #2b91af">String</span>
              <font color="#000000">.Format(</font>
              <span style="COLOR: #a31515">"sb://{0}/services/tweetiebot/{1}/events"</span>
              <font color="#000000">, 
<br />
                                    </font>
              <span style="COLOR: #2b91af">RelayBinding</span>
              <font color="#000000">.DefaultRelayHostName, </font>
              <span style="COLOR: #2b91af">Uri</span>
            </font>
            <font size="2">
              <font color="#000000">.EscapeDataString(emailAddress))));<br /><br /><span style="mso-spacerun: yes"><font face="Verdana" color="#003300">The URI scheme
for services that hook into the ISB is "sb:" and the default address of the relay
is encoded in the SDK assemblies. We set up two endpoints here. One for the client
channel to fetch the initial list and one for the event subscriber. </font></span></font>
            </font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes">
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">            </span>
              </font>
              <span style="COLOR: #2b91af">RelayBinding</span>
              <font color="#000000"> relayBinding
= </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">RelayBinding</span>
            </font>
            <font size="2">
              <font color="#000000">();<br /><span style="mso-spacerun: yes">     </span></font>
            </font>
            <font size="2">
              <font color="#000000">
                <br />
                <span style="mso-spacerun: yes">      </span>
                <span style="mso-spacerun: yes">      </span>
              </font>
              <span style="COLOR: #2b91af">ServiceHost</span>
              <font color="#000000"> eventsHost
= </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">ServiceHost</span>
              <font color="#000000">(</font>
              <span style="COLOR: blue">typeof</span>
              <font color="#000000">(</font>
              <span style="COLOR: #2b91af">EventsClient</span>
            </font>
            <font size="2">
              <font color="#000000">));<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">RelayBinding</span>
              <font color="#000000"> eventBinding
= </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">RelayBinding</span>
              <font color="#000000">(</font>
              <span style="COLOR: #2b91af">RelayConnectionMode</span>
            </font>
            <font size="2">
              <font color="#000000">.RelayedMulticast);<br /><span style="mso-spacerun: yes">            </span>eventsHost.AddServiceEndpoint(</font>
              <span style="COLOR: blue">typeof</span>
              <font color="#000000">(</font>
              <span style="COLOR: #2b91af">ITweetieEvents</span>
            </font>
            <font size="2">
              <font color="#000000">),
eventBinding, eventsAddress.ToString());<br /><span style="mso-spacerun: yes">            </span>eventsHost.Open();<br /><br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">ChannelFactory</span>
              <font color="#000000">&lt;</font>
              <span style="COLOR: #2b91af">TweetieBotChannel</span>
              <font color="#000000">&gt;
channelFactory = </font>
              <span style="COLOR: blue">new</span>
              <font color="#000000">
              </font>
              <span style="COLOR: #2b91af">ChannelFactory</span>
              <font color="#000000">&lt;</font>
              <span style="COLOR: #2b91af">TweetieBotChannel</span>
            </font>
            <font size="2">
              <font color="#000000">&gt;(relayBinding,
serviceAddress);<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">TweetieBotChannel</span>
            </font>
            <font size="2">
              <font color="#000000"> channel
= channelFactory.CreateChannel();<br /><span style="mso-spacerun: yes">            </span>channel.Open();<br /><br /><span style="mso-spacerun: yes"><span style="mso-spacerun: yes"><font face="Verdana" color="#003300">The
two *.Open() calls will each prompt for a CardSpace authentication, so you will have
to be <a href="https://identity.biztalk.net/MemberRegister.aspx">registered</a> to
run the sample. Once you have opened the channels (and my service is
running), you'll be able to pull the list of current tweets. Meanwhile, whenever
a new event pops up, the <em>EventsClient</em> above will write out a new line.</font></span></span></font>
            </font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes">
            <font size="2">
              <font color="#000000">
                <span style="mso-spacerun: yes">            </span>
              </font>
              <span style="COLOR: #2b91af">IList</span>
              <font color="#000000">&lt;</font>
              <span style="COLOR: #2b91af">Tweet</span>
            </font>
            <font size="2">
              <font color="#000000">&gt;
tweets = channel.GetTweets(lastTime);<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: blue">foreach</span>
              <font color="#000000"> (</font>
              <span style="COLOR: #2b91af">Tweet</span>
              <font color="#000000"> tweet </font>
              <span style="COLOR: blue">in</span>
            </font>
            <font size="2">
              <font color="#000000"> tweets)<br /><span style="mso-spacerun: yes">            </span>{<br /><span style="mso-spacerun: yes">                </span></font>
              <span style="COLOR: #2b91af">Console</span>
              <font color="#000000">.WriteLine(</font>
              <span style="COLOR: #a31515">"[{0}]
{1}:{2}"</span>
            </font>
            <font size="2">
              <font color="#000000">, tweet.Time, tweet.User,
tweet.Text);<br /><span style="mso-spacerun: yes">            </span>}<br /><br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">Console</span>
              <font color="#000000">.WriteLine(</font>
              <span style="COLOR: #a31515">"Press
ENTER to quit at any time"</span>
            </font>
            <font size="2">
              <font color="#000000">);<br /><span style="mso-spacerun: yes">            </span></font>
              <span style="COLOR: #2b91af">Console</span>
            </font>
            <font color="#000000" size="2">.ReadLine();<br /><br /><span style="mso-spacerun: yes">            </span>eventsHost.Close();<br /><span style="mso-spacerun: yes">            </span>channel.Close();<br /><span style="mso-spacerun: yes">            </span>channelFactory.Close();<br /><span style="mso-spacerun: yes">      </span><span style="mso-spacerun: yes">  </span>}<span style="mso-spacerun: yes">        </span></font>
          </span>
        </p>
        <span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes">
          <font color="#000000" size="2">
            <span style="mso-spacerun: yes">
            </span>
            <p>
              <br />
              <span style="mso-spacerun: yes">
                <span style="mso-spacerun: yes">
                  <span style="mso-spacerun: yes">
                    <font face="Verdana" color="#003300">So
when you run the app, you can chat (anyone can, you don't need to be a buddy) <a href="mailto:tweetiebot@hotmail.com">tweetiebot@hotmail.com</a> through
Live Messenger and you'll see your chat lines (and potentially others') popping out
as events from the service bus. </font>
                  </span>
                </span>
              </span>
            </p>
            <p>
              <span style="mso-spacerun: yes">
                <span style="mso-spacerun: yes">
                  <span style="mso-spacerun: yes">
                    <font face="Verdana" color="#003300">To
run the sample with my bot, you need to call the client with "IMBotClient tweetiebot@hotmail.com"
and select your BizTalk Services Information Card twice as you are prompted.</font>
                  </span>
                </span>
              </span>
            </p>
            <p>
              <span style="mso-spacerun: yes">
                <span style="mso-spacerun: yes">
                  <span style="mso-spacerun: yes">
                    <font face="Verdana" color="#003300">
                      <strong>Privacy
notice</strong>: I'm anonymizing the name of the contact only insofar as I'm clipping
anything including and following the "at" sign of the user that chats the
bot. So whatever you say is published as "<em>emailname</em>: text line"</font>
                  </span>
                </span>
              </span>
            </p>
          </font>
        </span>
        <a href="http://friends.newtelligence.net/clemensv/content/binary/IMBotClient.zip">IMBotClient.zip
(3.61 KB)</a>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=603e2393-c8de-40dd-b2e9-88f504b44149" />
      </body>
      <title>Some fun with the BizTalk Services ISB</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx</guid>
      <link>http://vasters.com/clemensv/2007/05/07/Some+Fun+With+The+BizTalk+Services+ISB.aspx</link>
      <pubDate>Mon, 07 May 2007 21:00:21 GMT</pubDate>
      <description>&lt;p&gt;
I wrote a slightly Twitter-inspired, fun app over the weekend that's using the BizTalk
Services Connectivity service and relay. In the spirit of Software+Services I'm going
to give you half of it [for now] ;-)&amp;nbsp;&amp;nbsp; You must have the &lt;a href="http://labs.biztalk.net/downloads.aspx"&gt;BizTalk
Services SDK&lt;/a&gt; installed to run the sample.
&lt;/p&gt;
&lt;p&gt;
The server app, which I'm keeping&amp;nbsp;to myself for the next few days as part of
the experiment,&amp;nbsp;is an extension (add-in) to Windows Live Messenger.&amp;nbsp;The
Messenger add-in monitors all chats&amp;nbsp;with&amp;nbsp;&lt;a href="mailto:tweetiebot@hotmail.com"&gt;tweetiebot@hotmail.com&lt;/a&gt;&amp;nbsp;and
keeps circular buffer with the last 40 incoming messages. Using the client (which
is in the attached archive), you can get a list of "Tweets" and add a new one (same
as chatting)
&lt;/p&gt;
&lt;p&gt;
[&lt;font color=#2b91af&gt;ServiceContract&lt;/font&gt;(Name = &lt;font color=#a31515&gt;"TweetieBot"&lt;/font&gt;,
Namespace = &lt;font color=#a31515&gt;&lt;a href="http://samples.vasters.com/2007/05/tweetiebot"&gt;http://samples.vasters.com/2007/05/tweetiebot&lt;/a&gt;&lt;/font&gt;)]&lt;br&gt;
&lt;font color=#0000ff&gt;public&lt;/font&gt; &lt;font color=#0000ff&gt;interface&lt;/font&gt; &lt;font color=#2b91af&gt;ITweetieBot&lt;br&gt;
&lt;/font&gt;{&lt;br&gt;
&amp;nbsp; [&lt;font color=#2b91af&gt;OperationContract&lt;/font&gt;]&lt;br&gt;
&lt;font color=#2b91af&gt;&amp;nbsp; IList&lt;/font&gt;&amp;lt;&lt;font color=#2b91af&gt;Tweet&lt;/font&gt;&amp;gt; GetTweets(&lt;font color=#2b91af&gt;DateTime&lt;/font&gt;?
since);&lt;br&gt;
&amp;nbsp; [&lt;font color=#2b91af&gt;OperationContract&lt;/font&gt;]&lt;br&gt;
&lt;font color=#0000ff&gt;&amp;nbsp; void&lt;/font&gt; Tweet(&lt;font color=#0000ff&gt;string&lt;/font&gt; nickname, &lt;font color=#0000ff&gt;string&lt;/font&gt; text);&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
or you can subscribe to new tweets and get them as they arrive
&lt;/p&gt;
&lt;p&gt;
[&lt;font color=#2b91af&gt;ServiceContract&lt;/font&gt;(Name = &lt;font color=#a31515&gt;"TweetieEvents"&lt;/font&gt;,
Namespace = &lt;font color=#a31515&gt;&lt;a href="http://samples.vasters.com/2007/05/tweetiebot"&gt;http://samples.vasters.com/2007/05/tweetiebot&lt;/a&gt;&lt;/font&gt;)]&lt;br&gt;
&lt;font color=#0000ff&gt;public&lt;/font&gt; &lt;font color=#0000ff&gt;interface&lt;/font&gt; &lt;font color=#2b91af&gt;ITweetieEvents&lt;br&gt;
&lt;/font&gt;{&lt;br&gt;
&amp;nbsp; [&lt;font color=#2b91af&gt;OperationContract&lt;/font&gt;(IsOneWay=&lt;font color=#0000ff&gt;true&lt;/font&gt;)]&lt;br&gt;
&lt;font color=#0000ff&gt;&amp;nbsp; void&lt;/font&gt; OnTweet(&lt;font color=#2b91af&gt;Tweet&lt;/font&gt; tweet);&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
The client application hooks up to the client (that lives right on my desktop machine)
through the BizTalk Services ISB and the&amp;nbsp;server fires events back through the
ISB relay into the client as new tweets arrive. So when you run the attached client
app, you'll find that it starts with a dump of the current log of the bot and then
keeps spitting out events as they arrive. 
&lt;/p&gt;
&lt;p&gt;
The client is actually pretty simple. The &lt;em&gt;EventsClient&lt;/em&gt; is the subscriber
for the pub/sub service (ConnectionMode.RelayMulticast) that writes out the received
events to the console.&amp;nbsp;The rest all happens in &lt;em&gt;Main&lt;/em&gt; (parsing an validating
the command line argument) and in &lt;em&gt;Run&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 12pt; COLOR: blue; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes"&gt;&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
class&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes"&gt;&lt;font color=#000000 size=2&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;&lt;font size=2&gt;Program&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;class&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EventsClient&lt;/span&gt;&lt;font color=#000000&gt; : &lt;/font&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;&lt;font size=2&gt;ITweetieEvents&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; OnTweet(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Tweet&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; tweet)&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;font color=#000000&gt;.WriteLine(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"[{0}]
{1}:{2}"&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;, tweet.Time, tweet.User, tweet.Text);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;static&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; Main(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;[]
args)&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; usageMessage
= &lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"Usage: IMBotClient &amp;lt;messenger-email-address&amp;gt;"&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;;&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; (args.Length
== 0)&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;/font&gt;&lt;font color=#000000&gt;&lt;font size=2&gt;.WriteLine(usageMessage);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;&lt;font size=2&gt;else&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;&lt;font color=#000000&gt; (!&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Regex&lt;/span&gt;&lt;font color=#000000&gt;.IsMatch(args[0], &lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;@"^([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$"&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;))&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;.WriteLine(usageMessage);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;font color=#000000&gt;.WriteLine(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"'{0}'
is not a valid email address"&lt;/span&gt;&lt;/font&gt;&lt;font color=#000000&gt;&lt;font size=2&gt;);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;&lt;font size=2&gt;else&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Run(args[0]);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;static&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; Run(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; emailAddress)&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EndpointAddress&lt;/span&gt;&lt;font color=#000000&gt; serviceAddress
= 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EndpointAddress&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;&lt;font color=#000000&gt;.Format(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;&lt;font color=#000000&gt;.Format(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"sb://{0}/services/tweetiebot/{1}/service"&lt;/span&gt;&lt;font color=#000000&gt;,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;font color=#000000&gt;.DefaultRelayHostName, &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Uri&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;.EscapeDataString(emailAddress))));&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EndpointAddress&lt;/span&gt;&lt;font color=#000000&gt; eventsAddress
= 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EndpointAddress&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;&lt;font color=#000000&gt;.Format(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;&lt;font color=#000000&gt;.Format(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"sb://{0}/services/tweetiebot/{1}/events"&lt;/span&gt;&lt;font color=#000000&gt;, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;font color=#000000&gt;.DefaultRelayHostName, &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Uri&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;.EscapeDataString(emailAddress))));&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&lt;font face=Verdana color=#003300&gt;The URI scheme for
services that hook into the ISB is "sb:" and the default address of the relay is encoded
in the SDK assemblies. We set up two endpoints here. One for the client channel to
fetch the initial list and one for the event subscriber.&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes"&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;font color=#000000&gt; relayBinding
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;();&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;ServiceHost&lt;/span&gt;&lt;font color=#000000&gt; eventsHost
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;ServiceHost&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;EventsClient&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;));&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;font color=#000000&gt; eventBinding
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayBinding&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;RelayConnectionMode&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;.RelayedMulticast);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;eventsHost.AddServiceEndpoint(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;ITweetieEvents&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;),
eventBinding, eventsAddress.ToString());&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;eventsHost.Open();&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;ChannelFactory&lt;/span&gt;&lt;font color=#000000&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;TweetieBotChannel&lt;/span&gt;&lt;font color=#000000&gt;&amp;gt;
channelFactory = &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;ChannelFactory&lt;/span&gt;&lt;font color=#000000&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;TweetieBotChannel&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&amp;gt;(relayBinding,
serviceAddress);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;TweetieBotChannel&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; channel
= channelFactory.CreateChannel();&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;channel.Open();&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face=Verdana color=#003300&gt;The
two *.Open() calls will each prompt for a CardSpace authentication, so you will have
to be &lt;a href="https://identity.biztalk.net/MemberRegister.aspx"&gt;registered&lt;/a&gt; to
run the sample.&amp;nbsp;Once&amp;nbsp;you have&amp;nbsp;opened the channels (and my service is
running), you'll be able to pull the list of current tweets.&amp;nbsp;Meanwhile, whenever
a new event pops up, the &lt;em&gt;EventsClient&lt;/em&gt; above will write out a new line.&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes"&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;IList&lt;/span&gt;&lt;font color=#000000&gt;&amp;lt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Tweet&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;&amp;gt;
tweets = channel.GetTweets(lastTime);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt;&lt;font color=#000000&gt; (&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Tweet&lt;/span&gt;&lt;font color=#000000&gt; tweet &lt;/font&gt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; tweets)&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;font color=#000000&gt;.WriteLine(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"[{0}]
{1}:{2}"&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;, tweet.Time, tweet.User, tweet.Text);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;font color=#000000&gt;.WriteLine(&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"Press
ENTER to quit at any time"&lt;/span&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;);&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;.ReadLine();&lt;br&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;eventsHost.Close();&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;channel.Close();&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;channelFactory.Close();&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: Courier New; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-no-proof: yes"&gt;&lt;font color=#000000 size=2&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;/span&gt; 
&lt;p&gt;
&lt;br&gt;
&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face=Verdana color=#003300&gt;So
when you run the app, you can chat (anyone can, you don't need to be a buddy) &lt;a href="mailto:tweetiebot@hotmail.com"&gt;tweetiebot@hotmail.com&lt;/a&gt; through
Live Messenger and you'll see your chat lines (and potentially others') popping out
as events from the service bus. &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face=Verdana color=#003300&gt;To
run the sample with my bot, you need to call the client with "IMBotClient tweetiebot@hotmail.com"
and select your BizTalk Services Information Card twice as you are prompted.&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font face=Verdana color=#003300&gt;&lt;strong&gt;Privacy
notice&lt;/strong&gt;: I'm anonymizing the name of the contact only insofar as I'm clipping
anything&amp;nbsp;including and following&amp;nbsp;the "at" sign of the user that chats the
bot. So whatever you say is published as "&lt;em&gt;emailname&lt;/em&gt;: text line"&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/font&gt;&lt;/span&gt;&gt;
&lt;a href="http://friends.newtelligence.net/clemensv/content/binary/IMBotClient.zip"&gt;IMBotClient.zip
(3.61 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=603e2393-c8de-40dd-b2e9-88f504b44149" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,603e2393-c8de-40dd-b2e9-88f504b44149.aspx</comments>
      <category>Technology</category>
      <category>Technology/BizTalk</category>
      <category>Technology/CardSpace</category>
      <category>Technology/ISB</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=22aef11a-20e4-4583-ae05-8ad0c15c7526</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,22aef11a-20e4-4583-ae05-8ad0c15c7526.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,22aef11a-20e4-4583-ae05-8ad0c15c7526.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=22aef11a-20e4-4583-ae05-8ad0c15c7526</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For those of you who couldn't make it to MIX, here are the (Silverlight-) videos of
the talks from the Connected Systems Division deep-linked to <a href="http://sessions.visitmix.com">sessions.visitmix.com</a></p>
        <ul>
          <li>
            <a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=DEV03 - Navigating the Programmable Web&amp;speakers=Don Box, Steve Maine&amp;source=videos/DEV03.wmv" target="_blank">Don
Box, Steve Maine: <strong>Navigating the Programmable Web</strong></a>
          </li>
          <li>
            <a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=XBD07 - Enable Windows CardSpace and Information Cards in Your Web Site&amp;speakers=Garrett Serack, Mike Jones, Pat Felsted&amp;source=videos/XBD07.wmv" target="_blank">Garrett
Serack, Mike Jones, Pat Felsted: <strong>Enable Windows CardSpace and Information
Cards on Your Web Site</strong></a>
          </li>
          <li>
            <a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=PAN03 - PANEL DISCUSSION: Digital Identity and the Psychology of Security&amp;speakers=Kaliya Hamlin, Kim Cameron, Laurie Rae, Marc Canter, Scott Kveton&amp;source=videos/PAN03.wmv" target="_blank">Kim
Cameron and Panel: <strong>Digital Identity and the Psychology of Security</strong></a>
          </li>
        </ul>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=22aef11a-20e4-4583-ae05-8ad0c15c7526" />
      </body>
      <title>Connected Systems @MIX: The Videos</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,22aef11a-20e4-4583-ae05-8ad0c15c7526.aspx</guid>
      <link>http://vasters.com/clemensv/2007/05/05/Connected+Systems+MIX+The+Videos.aspx</link>
      <pubDate>Sat, 05 May 2007 04:07:23 GMT</pubDate>
      <description>&lt;p&gt;
For those of you who couldn't make it to MIX, here are the (Silverlight-) videos of
the talks from the Connected Systems Division deep-linked to &lt;a href="http://sessions.visitmix.com"&gt;sessions.visitmix.com&lt;/a&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=DEV03 - Navigating the Programmable Web&amp;amp;speakers=Don Box, Steve Maine&amp;amp;source=videos/DEV03.wmv" target=_blank&gt;Don
Box, Steve Maine: &lt;strong&gt;Navigating the Programmable Web&lt;/strong&gt;&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=XBD07 - Enable Windows CardSpace and Information Cards in Your Web Site&amp;amp;speakers=Garrett Serack, Mike Jones, Pat Felsted&amp;amp;source=videos/XBD07.wmv" target=_blank&gt;Garrett
Serack, Mike Jones, Pat Felsted: &lt;strong&gt;Enable Windows CardSpace and Information
Cards on Your Web Site&lt;/strong&gt;&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://int1.fp.sandpiper.net/soma/applications/silverlight/v1/Default.html?title=PAN03 - PANEL DISCUSSION: Digital Identity and the Psychology of Security&amp;amp;speakers=Kaliya Hamlin, Kim Cameron, Laurie Rae, Marc Canter, Scott Kveton&amp;amp;source=videos/PAN03.wmv" target=_blank&gt;Kim
Cameron and Panel: &lt;strong&gt;Digital Identity and the Psychology of Security&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=22aef11a-20e4-4583-ae05-8ad0c15c7526" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,22aef11a-20e4-4583-ae05-8ad0c15c7526.aspx</comments>
      <category>Talks</category>
      <category>Technology</category>
      <category>Technology/CardSpace</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=aa502cba-e47c-4cfe-a036-875175ad295a</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,aa502cba-e47c-4cfe-a036-875175ad295a.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,aa502cba-e47c-4cfe-a036-875175ad295a.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=aa502cba-e47c-4cfe-a036-875175ad295a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We love WS-* as much as we do love Web-Style services. I say "Web-style",
full knowing that the buzzterm is REST. Since REST is an architectural style and not
an implementation technology, it makes sense to make a distinction and, also, claiming
complete RESTfulness for a system is actually a pretty high bar to aspire to. So in
order to avoid monikers like POX or Lo-REST/Hi-REST, I just call it what it
what this is all about to mere mortals whose don't have an advanced degree in HTTP
Philosophy: Services that work like the Web - or Web-Style. That's not to say
that a Web-Style service cannot be fully RESTful. It surely can be. But if all you
want to do is GET to serve up data into mashups and manipulate your backend resources
in some other way, that's up to you. Anyways....
</p>
        <p>
Tomorrow at 10:00am (Session DEV03, Room Delfino 4101A), our resident Lo-REST/Hi-REST/POX/Web-Style Program
Manager <strong>Steve Maine</strong> and our Architect <strong>Don Box</strong> will
explain to you how to use the new Web-Style "Programmable Web" features that we're
adding to the .NET Framework 3.5 to implement the server magic and the service-client
magic to power all the user experience goodness you've seen here at MIX.
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <div style="FONT-WEIGHT: bold">
            <em>Navigating the Programmable Web</em>
          </div>
          <div>
            <em>
            </em>
          </div>
          <div>
            <em>
              <span class="catalogSpeakerLabel">Speaker(s):</span>
              <span>Don Box - Microsoft</span>, <span>Steve
Maine</span></em>
          </div>
          <div>
            <em>
              <span class="catalogCategoryLabel">Audience(s):</span> Developer</em>
          </div>
          <div>
            <em>RSS. ATOM. JSON. POX. REST. WS-*. What are all these terms, and how do they
impact the daily life of a developer trying to navigate today’s programmable Web?
Join us as we explore how to consume and create Web services using a variety of different
formats and protocols. Using popular services (Flickr, GData, and Amazon S3) as case
studies, we look at what it takes to program against these services using the Microsoft
platform today and how that will change in the future.</em>
          </div>
        </blockquote>
        <div dir="ltr">If you are in Vegas for MIX, come see the session. I just saw the demo,
it'll be good.
</div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=aa502cba-e47c-4cfe-a036-875175ad295a" />
      </body>
      <title>Live at MIX: WCF and the Web (and Steve Maine, and Don Box)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,aa502cba-e47c-4cfe-a036-875175ad295a.aspx</guid>
      <link>http://vasters.com/clemensv/2007/05/02/Live+At+MIX+WCF+And+The+Web+And+Steve+Maine+And+Don+Box.aspx</link>
      <pubDate>Wed, 02 May 2007 00:51:05 GMT</pubDate>
      <description>&lt;p&gt;
We love WS-*&amp;nbsp;as much as we do love&amp;nbsp;Web-Style services. I say "Web-style",
full knowing that the buzzterm is REST. Since REST is an architectural style and not
an implementation technology, it makes sense to make a distinction and, also, claiming
complete RESTfulness for a system is actually a pretty high bar to aspire to. So in
order to avoid&amp;nbsp;monikers like POX or Lo-REST/Hi-REST, I just call it what&amp;nbsp;it
what this is all about to mere mortals whose don't have an advanced degree in HTTP
Philosophy: Services that work like the Web - or Web-Style.&amp;nbsp;That's not to say
that a Web-Style service cannot be fully RESTful. It surely can be. But if all you
want to do is GET to serve up data into mashups and manipulate your backend resources
in some other way, that's up to you. Anyways....
&lt;/p&gt;
&lt;p&gt;
Tomorrow at 10:00am (Session DEV03, Room Delfino 4101A), our&amp;nbsp;resident Lo-REST/Hi-REST/POX/Web-Style&amp;nbsp;Program
Manager&amp;nbsp;&lt;strong&gt;Steve Maine&lt;/strong&gt; and our Architect &lt;strong&gt;Don Box&lt;/strong&gt; will
explain to you how to use the new Web-Style "Programmable Web" features that we're
adding to the .NET Framework 3.5 to implement&amp;nbsp;the server magic and the service-client
magic to power all the&amp;nbsp;user experience&amp;nbsp;goodness you've seen here at MIX.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;div style="FONT-WEIGHT: bold"&gt;&lt;em&gt;Navigating the Programmable Web&lt;/em&gt;
&lt;/div&gt;
&lt;div&gt;&lt;em&gt;&lt;/em&gt;
&lt;/div&gt;
&lt;div&gt;&lt;em&gt;&lt;span class=catalogSpeakerLabel&gt;Speaker(s):&lt;/span&gt; &lt;span&gt;Don Box - Microsoft&lt;/span&gt;, &lt;span&gt;Steve
Maine&lt;/span&gt;&lt;/em&gt;
&lt;/div&gt;
&lt;div&gt;&lt;em&gt;&lt;span class=catalogCategoryLabel&gt;Audience(s):&lt;/span&gt; Developer&lt;/em&gt;
&lt;/div&gt;
&lt;div&gt;&lt;em&gt;RSS. ATOM. JSON. POX. REST. WS-*. What are all these terms, and how do they
impact the daily life of a developer trying to navigate today’s programmable Web?
Join us as we explore how to consume and create Web services using a variety of different
formats and protocols. Using popular services (Flickr, GData, and Amazon S3) as case
studies, we look at what it takes to program against these services using the Microsoft
platform today and how that will change in the future.&lt;/em&gt;
&lt;/div&gt;
&lt;/blockquote&gt; 
&lt;div dir=ltr&gt;If you are in Vegas for MIX, come see the session. I just saw the demo,
it'll be good.
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=aa502cba-e47c-4cfe-a036-875175ad295a" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,aa502cba-e47c-4cfe-a036-875175ad295a.aspx</comments>
      <category>Talks</category>
      <category>Technology</category>
      <category>Technology/WCF</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=d53f0e81-eebb-4327-a92f-2f2ab5fcc602</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,d53f0e81-eebb-4327-a92f-2f2ab5fcc602.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,d53f0e81-eebb-4327-a92f-2f2ab5fcc602.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=d53f0e81-eebb-4327-a92f-2f2ab5fcc602</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Steve has a <a href="http://www.stephenforte.net/owdasblog/PermaLink.aspx?guid=a8de9324-c373-4cab-8e10-4e23251a3fb4">great
analysis </a>of what BizTalk Services means for Corzen and how he views it in the
broader industry context. 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d53f0e81-eebb-4327-a92f-2f2ab5fcc602" />
      </body>
      <title>Stephen Forte on what BizTalk Services means for his shop</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,d53f0e81-eebb-4327-a92f-2f2ab5fcc602.aspx</guid>
      <link>http://vasters.com/clemensv/2007/04/26/Stephen+Forte+On+What+BizTalk+Services+Means+For+His+Shop.aspx</link>
      <pubDate>Thu, 26 Apr 2007 22:09:51 GMT</pubDate>
      <description>&lt;p&gt;
Steve has a &lt;a href="http://www.stephenforte.net/owdasblog/PermaLink.aspx?guid=a8de9324-c373-4cab-8e10-4e23251a3fb4"&gt;great
analysis &lt;/a&gt;of what BizTalk Services means for Corzen and how he views it in the
broader industry context. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d53f0e81-eebb-4327-a92f-2f2ab5fcc602" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,d53f0e81-eebb-4327-a92f-2f2ab5fcc602.aspx</comments>
      <category>Architecture</category>
      <category>Architecture/SOA</category>
      <category>IT Strategy</category>
      <category>Technology</category>
      <category>Technology/BizTalk</category>
      <category>Technology/WCF</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=9a674bcb-17fd-4f08-a888-d6fd93d0cbed</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,9a674bcb-17fd-4f08-a888-d6fd93d0cbed.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,9a674bcb-17fd-4f08-a888-d6fd93d0cbed.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=9a674bcb-17fd-4f08-a888-d6fd93d0cbed</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's been <a href="http://developers.slashdot.org/article.pl?sid=06/12/20/0155238">slashdotted</a> and
also otherwise widely discussed that Google has deprecated their SOAP
API. A deadly blow for SOAP as people are speculating? Guess not.
</p>
        <p>
What I find striking are the differences in the licenses between the AJAX API and
the SOAP API. That's where the beef is. While the results obtained through the SOAP
API can be used (for non-commercial purposes) practically in any way except
that "you may not use the search results provided by the Google SOAP Search API service
with an existing product or service that competes with products or services offered
by Google.", the AJAX API is constrained to use with web sites with the terms of use
stating that "The API is limited to allowing You to host and display Google Search
Results on your site, and does not provide You with the ability to access other underlying
Google Services or data."
</p>
        <p>
The AJAX API is a Web service that works for Google because its terms of use are very
prescriptive for how to build a service that ensures Google's advertising machine
gets exposure and clicks. That's certainly a reasonable business decision, but has
nothing to do with SOAP vs. REST or anything else technical. There's just no money
in application-to-application messaging for Google (unless they'd actually set up
an infrastructure to charge for software as a service and provide support and proper
SLAs for it that is saying more than "we don't make any guarantees whatsoever") while
there's a lot of money for them in being able to get lots and lots of people
to give them a free spot on their own site onto which they can place their advertising.
That's what their business is about, not software.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=9a674bcb-17fd-4f08-a888-d6fd93d0cbed" />
      </body>
      <title>"Google kills SOAP!"</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,9a674bcb-17fd-4f08-a888-d6fd93d0cbed.aspx</guid>
      <link>http://vasters.com/clemensv/2006/12/20/Google+Kills+SOAP.aspx</link>
      <pubDate>Wed, 20 Dec 2006 23:07:04 GMT</pubDate>
      <description>&lt;p&gt;
It's been &lt;a href="http://developers.slashdot.org/article.pl?sid=06/12/20/0155238"&gt;slashdotted&lt;/a&gt; and
also otherwise widely discussed&amp;nbsp;that Google&amp;nbsp;has deprecated&amp;nbsp;their SOAP
API. A deadly blow for SOAP as people are speculating? Guess not.
&lt;/p&gt;
&lt;p&gt;
What I find striking are the differences in the licenses between the AJAX API and
the SOAP API. That's where the beef is. While the results obtained through the SOAP
API can be used (for non-commercial purposes)&amp;nbsp;practically in any way&amp;nbsp;except
that "you may not use the search results provided by the Google SOAP Search API service
with an existing product or service that competes with products or services offered
by Google.", the AJAX API is constrained to use with web sites with the terms of use
stating that "The API is limited to allowing You to host and display Google Search
Results on your site, and does not provide You with the ability to access other underlying
Google Services or data."
&lt;/p&gt;
&lt;p&gt;
The AJAX API is a Web service that works for Google because its terms of use are&amp;nbsp;very
prescriptive for how to build a service that ensures Google's advertising&amp;nbsp;machine
gets exposure and clicks. That's certainly a reasonable business decision, but has
nothing to do with SOAP vs. REST or anything else technical. There's just no money
in application-to-application messaging for Google (unless they'd actually set up
an infrastructure to charge for software as a service and provide support and proper
SLAs for it that is saying more than&amp;nbsp;"we don't make any guarantees whatsoever")&amp;nbsp;while
there's a lot of money for them in being able to&amp;nbsp;get lots and lots of people
to give them a free spot on their own site onto which they can place their advertising.
That's what their business is about, not software.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=9a674bcb-17fd-4f08-a888-d6fd93d0cbed" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,9a674bcb-17fd-4f08-a888-d6fd93d0cbed.aspx</comments>
      <category>IT Strategy</category>
      <category>Technology</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=57b03894-e197-4512-b9ea-648105890103</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,57b03894-e197-4512-b9ea-648105890103.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,57b03894-e197-4512-b9ea-648105890103.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=57b03894-e197-4512-b9ea-648105890103</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was sad when "Indigo" and "Avalon" went away. It'd be great if we'd have
a pool of cool legal-approved code-names for which we own the trademark rights and
which we could stick to. Think Delphi or Safari. "Indigo" was cool insofar as
it was very handy to refer to the technology set, but was removed far enough
from the specifics that it doesn't create a sharply defined, product-like island
within the larger managed-code landscape or has legacy connotations like "ADO.NET".
 Also, my talks these days could be 10 minutes shorter if I could refer to Indigo
instead of "Windows Communications Foundation". Likewise, my job title wouldn't have
to have a line wrap on the business card of I ever spelled it out in full.
</p>
        <p>
However, when I learned about the WinFX name going away (several weeks before the
public announcement) and the new "Vista Wave" technologies (WPF/WF/WCF/WCS) being rolled
up under the <a href="http://msdn.microsoft.com/winfx/">.NET Framework</a> brand,
I was quite happy. Ever since it became clear in 2004 that the grand plan to put
a complete, covers-all-and-everything managed API on top (and on quite a
bit of the bottom) of everything Windows would have to wait until siginificantly after
Vista and that therefore the Win16&gt;Win32&gt;WinFX continuity would not
tell the true story, that name made only limited sense to stick to. The .NET Framework
is the #1 choice for business applications and a well established brand. People refer
to themselves as being "dotnet" developers. But even though the .NET Framework covers
a lot of ground and "Indigo", "Avalon", "InfoCard", and "Workflow" are overwhelmingly
(or exclusively) managed-code based, there are still quite a few things in Windows
Vista that still require using P/Invoke or COM/Interop from managed code or unmanaged
code outright. That's not a problem. Something has to manage the managed code
and there's no urgent need to rewrite entire subsystems to managed code if you
only want to add or revise features. 
</p>
        <p>
So now all the new stuff is now part of the .NET Framework. That is a good, good,
good change. This says what it all is. 
</p>
        <p>
Admittedly confusing is the "3.0" bit. What we'll ship is a Framework 3.0 that rides
on top of the 2.0 CLR and includes the 2.0 versions of the Base-Class Library, Windows
Forms, and ASP.NET. It doesn't include the formerly-announced-as-to-be-part-of-3.0
technologies like VB9 (there you have the version number consistency flying out
the window outright), C# 3.0, and LINQ. Personally, I think that it might be
a tiny bit less confusing if the Framework had a version-number neutral name such
as ".NET Framework 2006" which would allow doing what we do now with less potential
for confusion, but only a tiny bit. Certainly not enough to stage a war
over "2006" vs. "3.0".
</p>
        <p>
It's a matter of project management reality and also one of platform predictability
that the ASP.NET, or Windows Forms teams do not and should not ship a full
major-version revision of their bits every year. They shipped Whidbey (2.0) in late
2005 and hence it's healthy for them to have boarded the scheduled-to-arrive-in-2007
boat heading to Orcas. We (the "WinFX" teams) subscribed to the Vista ship docking later
this year and we bring great innovation which will be preinstalled on every copy of
it. LINQ as well as VB9 and C# incorporating it on a language-level are
very obviously Visual Studio bound and hence they are on the Orcas ferry as well.
The .NET Framework is a steadily growing development platform that spans technologies
from the Developer Division, Connected Systems, Windows Server, Windows Client, SQL
Server, and other groups, and my gut feeling is that it will become the norm that
it will be extended off-cycle from the Developer Division's Visual Studio and
CLR releases. Whenever a big ship docks in the port, may it be Office, SQL, BizTalk,
Windows Server, or Windows Client, and as more and more of the still-unmanaged Win32/Win64
surface area gets wrapped, augmented or replaced by managed-code APIs over time and
entirely new things are added, there might be bits that fit into and update the
Framework.  
</p>
        <p>
So one sane way to think about the .NET Framework version number is that it merely
labels the overall package and not the individual assemblies and components included
within it. Up to 2.0 everything was pretty synchronized, but given the ever-increasing
scale of the thing, it's good to think of that being a lucky (even if intended) coindicence
of scheduling. This surely <a href="http://en.wikipedia.org/wiki/Microsoft_BackOffice">isn't
the first time</a> that packages were versioned independently of their components.
There was and is no reason for the ASP.NET team to gratuitously recompile their existing
bits with a new version number just to have the GAC look pretty and to create the
illusion that everything is new - and to break Visual Studio compatibility in the
process.
</p>
        <p>
Of course, once we cover 100% of the Win32 surface area, we can rename it all into
WinFX again ;-)  (just kidding)
</p>
        <p>
[All the usual "personal opinion" disclaimers apply to this post]
</p>
        <p>
          <font size="1">
            <em>Update:</em> Removed reference to "Win64".</font>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=57b03894-e197-4512-b9ea-648105890103" />
      </body>
      <title>Code-Name WinFX vs .NET Framework 3.0</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,57b03894-e197-4512-b9ea-648105890103.aspx</guid>
      <link>http://vasters.com/clemensv/2006/06/18/CodeName+WinFX+Vs+NET+Framework+30.aspx</link>
      <pubDate>Sun, 18 Jun 2006 12:39:48 GMT</pubDate>
      <description>&lt;p&gt;
I was sad when "Indigo" and "Avalon" went away. It'd be great&amp;nbsp;if we'd&amp;nbsp;have
a pool of cool legal-approved code-names for which we own the trademark rights and
which we could stick to.&amp;nbsp;Think Delphi or Safari. "Indigo" was cool insofar as
it was very handy to refer to the technology set, but&amp;nbsp;was removed&amp;nbsp;far&amp;nbsp;enough
from the specifics that it doesn't&amp;nbsp;create a sharply defined, product-like island
within the larger managed-code landscape or has legacy connotations&amp;nbsp;like "ADO.NET".
&amp;nbsp;Also, my talks these days could be 10 minutes shorter if I could refer to Indigo
instead of "Windows Communications Foundation". Likewise, my job title wouldn't have
to&amp;nbsp;have a line wrap on the business card of I ever spelled it out in full.
&lt;/p&gt;
&lt;p&gt;
However, when I learned about the WinFX name going away (several weeks before the
public announcement) and the new "Vista Wave" technologies (WPF/WF/WCF/WCS) being&amp;nbsp;rolled
up&amp;nbsp;under the&amp;nbsp;&lt;a href="http://msdn.microsoft.com/winfx/"&gt;.NET Framework&lt;/a&gt;&amp;nbsp;brand,
I was&amp;nbsp;quite happy. Ever since it became clear in 2004 that the grand plan to&amp;nbsp;put
a complete,&amp;nbsp;covers-all-and-everything&amp;nbsp;managed API on top (and on quite a
bit of the bottom) of everything Windows would have to wait until siginificantly after
Vista and that&amp;nbsp;therefore&amp;nbsp;the Win16&amp;gt;Win32&amp;gt;WinFX continuity would not
tell the true story, that name made only limited sense to stick to. The .NET Framework
is the #1 choice for business applications and a well established brand. People refer
to themselves as being "dotnet" developers. But even though the .NET Framework covers
a lot of ground and "Indigo", "Avalon", "InfoCard", and "Workflow" are&amp;nbsp;overwhelmingly
(or exclusively) managed-code based, there are still quite a few things in Windows
Vista that still require using P/Invoke or COM/Interop from managed code or unmanaged
code outright. That's not a problem.&amp;nbsp;Something has to manage the managed code
and there's no urgent need to rewrite entire subsystems to managed code if&amp;nbsp;you
only want to add or revise features.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So now all the new stuff is now part of the .NET Framework. That is a good, good,
good&amp;nbsp;change. This says what it all is. 
&lt;/p&gt;
&lt;p&gt;
Admittedly confusing is the "3.0" bit. What we'll ship is a Framework 3.0 that rides
on top of the 2.0 CLR and includes the 2.0 versions of the Base-Class Library, Windows
Forms,&amp;nbsp;and ASP.NET. It doesn't include the formerly-announced-as-to-be-part-of-3.0
technologies like VB9 (there&amp;nbsp;you have the version number consistency flying out
the window outright), C# 3.0, and&amp;nbsp;LINQ. Personally, I think&amp;nbsp;that it might&amp;nbsp;be
a tiny bit less confusing if the Framework had a version-number neutral name such
as ".NET Framework 2006" which would allow&amp;nbsp;doing what we do now with less potential
for confusion, but only a tiny bit.&amp;nbsp;Certainly not enough to&amp;nbsp;stage a war
over "2006" vs. "3.0".
&lt;/p&gt;
&lt;p&gt;
It's a matter of project management&amp;nbsp;reality and also one of platform predictability
that the ASP.NET, or Windows Forms&amp;nbsp;teams&amp;nbsp;do not and should not ship a full
major-version revision of their bits every year. They shipped Whidbey (2.0) in late
2005 and hence&amp;nbsp;it's healthy for them&amp;nbsp;to&amp;nbsp;have boarded the scheduled-to-arrive-in-2007
boat heading to Orcas. We (the "WinFX" teams) subscribed to the Vista ship&amp;nbsp;docking&amp;nbsp;later
this year and we bring great innovation which will be preinstalled on every copy of
it. LINQ&amp;nbsp;as well as&amp;nbsp;VB9 and C# incorporating it on a language-level are
very obviously Visual Studio bound and hence they are on the Orcas ferry as well.
The .NET Framework is a steadily growing development platform that spans technologies
from the Developer Division, Connected Systems, Windows Server, Windows Client, SQL
Server, and other groups, and my gut feeling is that it will become the norm that
it will be extended off-cycle from the Developer Division's&amp;nbsp;Visual Studio and
CLR releases. Whenever a big ship docks in the port, may it be Office, SQL, BizTalk,
Windows Server, or Windows Client, and as more and more of the still-unmanaged Win32/Win64
surface area gets wrapped, augmented or replaced by managed-code APIs over time and
entirely new things are added, there might be bits that&amp;nbsp;fit into and update the
Framework. &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So one sane way to think about the .NET Framework version number is that&amp;nbsp;it merely
labels the overall package and not the individual assemblies and components included
within it. Up to 2.0&amp;nbsp;everything was pretty synchronized, but&amp;nbsp;given the ever-increasing
scale of the thing, it's good to think of that being a lucky (even if intended) coindicence
of scheduling. This surely &lt;a href="http://en.wikipedia.org/wiki/Microsoft_BackOffice"&gt;isn't
the first time&lt;/a&gt; that&amp;nbsp;packages were versioned independently of their components.
There was and is no reason for the ASP.NET team to gratuitously recompile their existing
bits with a new version number just to have the GAC look pretty and to create the
illusion that everything is new - and to break Visual Studio compatibility in the
process.
&lt;/p&gt;
&lt;p&gt;
Of course, once we cover 100% of the Win32 surface area, we can rename it all into
WinFX again ;-)&amp;nbsp; (just kidding)
&lt;/p&gt;
&lt;p&gt;
[All the usual&amp;nbsp;"personal opinion" disclaimers apply to this post]
&lt;/p&gt;
&lt;p&gt;
&lt;font size=1&gt;&lt;em&gt;Update:&lt;/em&gt; Removed reference to "Win64".&lt;/font&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=57b03894-e197-4512-b9ea-648105890103" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,57b03894-e197-4512-b9ea-648105890103.aspx</comments>
      <category>IT Strategy</category>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
      <category>Technology/Avalon</category>
      <category>Technology/CLR</category>
      <category>Technology/Indigo</category>
      <category>Technology/Longhorn</category>
      <category>Technology/WCF</category>
      <category>Technology/Windows</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=62b10909-f329-4cc6-8a7e-a9123559a7b9</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,62b10909-f329-4cc6-8a7e-a9123559a7b9.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,62b10909-f329-4cc6-8a7e-a9123559a7b9.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=62b10909-f329-4cc6-8a7e-a9123559a7b9</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just so that you know: In addition to the regular breakout sessions, we have a number
of interactive <a href="http://wcf.netfx3.com/content/TechEd2006ChalkTalkSchedule.aspx">chalk
talks</a> scheduled here at the Connected Systems Technical Learning Center in the
Expo Hall. Come by.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=62b10909-f329-4cc6-8a7e-a9123559a7b9" />
      </body>
      <title>TechEd: WCF and Workflow Chalk Talks</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,62b10909-f329-4cc6-8a7e-a9123559a7b9.aspx</guid>
      <link>http://vasters.com/clemensv/2006/06/12/TechEd+WCF+And+Workflow+Chalk+Talks.aspx</link>
      <pubDate>Mon, 12 Jun 2006 14:38:15 GMT</pubDate>
      <description>&lt;p&gt;
Just so that you know: In addition to the regular breakout sessions, we have a number
of interactive &lt;a href="http://wcf.netfx3.com/content/TechEd2006ChalkTalkSchedule.aspx"&gt;chalk
talks&lt;/a&gt; scheduled here at the Connected Systems Technical Learning Center in the
Expo Hall. Come by.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=62b10909-f329-4cc6-8a7e-a9123559a7b9" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,62b10909-f329-4cc6-8a7e-a9123559a7b9.aspx</comments>
      <category>Talks/TechEd US</category>
      <category>Technology</category>
      <category>Technology/Indigo</category>
      <category>Technology/WCF</category>
      <category>Technology/Workflow</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=76e10b03-8d1a-4e17-82c8-32a14f8debae</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,76e10b03-8d1a-4e17-82c8-32a14f8debae.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,76e10b03-8d1a-4e17-82c8-32a14f8debae.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=76e10b03-8d1a-4e17-82c8-32a14f8debae</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is my first TechEd! - as a Microsoft employee. It's of course not my first tech
event in my new job (Egypt, Jordan, UK, France, Switzerland, Holland, Belgium, Denmark,
Las Vegas/USA, Slovenia, and Israel are on the year-to-date list - on top
of three long-distance commutes to Redmond), but the big TechEds are always special.
It'll be fun. Come by the Connected Systems area in the exhibition hall and find me
to chat if you are here in Boston.
</p>
        <p>
Frankly, I didn't expect a Sunday night keynote to be nearly as well attended as it
was, but it looks that experiment mostly worked. The theme of the keynote were <a href="http://www.microsoft.com/presspass/features/2006/jun06/06-11Promises.mspx">Microsoft's
4 Core Promises</a> for IT Pros and Developers nicely wrapped into a video story based
on the TV show "24" and with that show's IT superwoman Chloe O'Brian (actress <a href="http://imdb.com/name/nm0707476/">Mary
Lynn Rajskub</a>) up on stage with Bob Muglia (our team's VP far up above in my chain
of command), who acted as the MC for the show. Finally we got an apology
from a Hollywood character for all the IT idiocy the put up on screen. Thanks, Chloe.
</p>
        <p>
Our team has a lot of very cool stuff to talk about at this show. The first highlight
is John Justice's WCF Intro talk (Session CON208, Room 157ABC) <strong>today at 5:00pm</strong> with
a "meet the team" panel Q&amp;A session at the end. Block the time.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=76e10b03-8d1a-4e17-82c8-32a14f8debae" />
      </body>
      <title>TechEd 2006 U.S. Kicks Off</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,76e10b03-8d1a-4e17-82c8-32a14f8debae.aspx</guid>
      <link>http://vasters.com/clemensv/2006/06/12/TechEd+2006+US+Kicks+Off.aspx</link>
      <pubDate>Mon, 12 Jun 2006 12:48:51 GMT</pubDate>
      <description>&lt;p&gt;
This is my first TechEd! - as a Microsoft employee. It's of course not my first tech
event in my new job (Egypt, Jordan, UK, France, Switzerland, Holland, Belgium, Denmark,
Las Vegas/USA, Slovenia, and Israel&amp;nbsp;are on the year-to-date list -&amp;nbsp;on top
of&amp;nbsp;three long-distance commutes to Redmond), but the big TechEds are always special.
It'll be fun. Come by the Connected Systems area in the exhibition hall and find me
to chat if you are here in Boston.
&lt;/p&gt;
&lt;p&gt;
Frankly, I didn't expect a Sunday night keynote to be nearly as well attended as it
was, but it looks that experiment mostly worked. The theme of the keynote were&amp;nbsp;&lt;a href="http://www.microsoft.com/presspass/features/2006/jun06/06-11Promises.mspx"&gt;Microsoft's
4 Core Promises&lt;/a&gt; for IT Pros and Developers nicely wrapped into a video story based
on the TV show "24" and with that show's&amp;nbsp;IT superwoman&amp;nbsp;Chloe O'Brian (actress &lt;a href="http://imdb.com/name/nm0707476/"&gt;Mary
Lynn Rajskub&lt;/a&gt;) up on stage with Bob Muglia (our team's VP far up above in my chain
of command), who&amp;nbsp;acted as&amp;nbsp;the MC for the show. Finally we got an apology
from a Hollywood character for all the IT idiocy the put up on screen. Thanks, Chloe.
&lt;/p&gt;
&lt;p&gt;
Our team has a lot of very cool stuff to&amp;nbsp;talk about at this show. The first highlight
is John Justice's WCF Intro talk (Session CON208, Room 157ABC) &lt;strong&gt;today at 5:00pm&lt;/strong&gt; with
a "meet the team" panel Q&amp;amp;A session at the end.&amp;nbsp;Block the time.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=76e10b03-8d1a-4e17-82c8-32a14f8debae" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,76e10b03-8d1a-4e17-82c8-32a14f8debae.aspx</comments>
      <category>Technology</category>
      <category>Technology/Indigo</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=a331e585-24be-4c00-bbef-6787e9553097</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,a331e585-24be-4c00-bbef-6787e9553097.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,a331e585-24be-4c00-bbef-6787e9553097.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=a331e585-24be-4c00-bbef-6787e9553097</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I may work for the firm, but ... As a good corporate citizen I just installed
the Windows Update item that got pushed out to me. The "Windows Genuine Advantage
Notification" tool that's supposed to notify me -- I am paraphrasing the decription
that I clicked away already -- whether my copy of Windows is genuine and to help me
acquire a legal copy if it finds out that its not (whatever that might do). I think
I have a bit of an understanding why there's such a tool and why that Windows Genuine
Advantage program exists. Like it or not, we make software that we ask people to buy.
</p>
        <p>
But why, why, why does that particular update want me to reboot my machine after
the install?  
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=a331e585-24be-4c00-bbef-6787e9553097" />
      </body>
      <title>Genuine Advantage Reboot</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,a331e585-24be-4c00-bbef-6787e9553097.aspx</guid>
      <link>http://vasters.com/clemensv/2006/05/30/Genuine+Advantage+Reboot.aspx</link>
      <pubDate>Tue, 30 May 2006 23:09:30 GMT</pubDate>
      <description>&lt;p&gt;
I may work for the firm, but&amp;nbsp;... As a good corporate citizen I just installed
the Windows Update item that got pushed out to me. The "Windows Genuine Advantage
Notification" tool that's supposed to notify me -- I am paraphrasing the decription
that I clicked away already -- whether my copy of Windows is genuine and to help me
acquire a legal copy if it finds out that its not (whatever that might do). I think
I have a bit of an understanding why there's such a tool and why that Windows Genuine
Advantage program exists. Like it or not, we make software that we ask people to buy.
&lt;/p&gt;
&lt;p&gt;
But why, why, why does that&amp;nbsp;particular update want me to reboot my machine after
the install? &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=a331e585-24be-4c00-bbef-6787e9553097" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,a331e585-24be-4c00-bbef-6787e9553097.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p class="Section1">
          <b>Inside the big house....</b>
        </p>
        <p class="Section1">
Back in December of last year and about two weeks before I publicly announced
that I will be working from Microsoft, <a href="http://friends.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx">I
started</a> a nine-part series on REST/POX* programming with <strike>Indigo</strike> WCF. (<span lang="DE"><a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx"><span lang="EN-US"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx">1</span></span></span></span></a></span>, <span lang="DE"><a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx"><span lang="EN-US"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx">2</span></span></span></span></a></span>, <span lang="DE"><a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx"><span lang="EN-US"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx">3</span></span></span></span></a></span>, <span lang="DE"><a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx"><span lang="EN-US"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx"><span title="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx">4</span></span></span></span></a></span>, <a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,3712ee6b-cd80-4db3-a96c-c740491f588e.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,3712ee6b-cd80-4db3-a96c-c740491f588e.aspx">5</a>, <a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,51327201-07c7-4a30-b79c-53842cda1e77.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,51327201-07c7-4a30-b79c-53842cda1e77.aspx">6</a>, <a title="http://staff.newtelligence.net/clemensv/PermaLink,guid,e82c8423-f106-4105-81e4-14410a83315a.aspx" href="http://staff.newtelligence.net/clemensv/PermaLink,guid,e82c8423-f106-4105-81e4-14410a83315a.aspx">7</a>, <a href="http://staff.newtelligence.net/clemensv/PermaLink,guid,7465c74e-6001-4d08-93ae-ad7110dee188.aspx">8</a>, <a href="http://friends.newtelligence.net/clemensv/PermaLink,guid,8fc367b2-a4be-4588-8264-5455c268b94a.aspx">9</a>).
Since then, the WCF object model has seen quite a few feature and usability improvements
across the board and those are significant enough to justify that I rewrite the entire
series to get it up to the February CTP level and I will keep updating it through
Vista/WinFX Beta2 and as we are marching towards our RTM. We've got a few changes/extensions
in our production pipeline to make the REST/POX story for WCF v1 stronger and
I will track those changes with yet another re-release of this series. 
</p>
        <p class="Section1">
Except in one or two occasions, I haven't re-posted a reworked story on my blog. This
here is quite a bit different, because of it sheer size and the things I learned in
the process of writing it and developing the code along the way. So even though it
is relatively new, it's already due for an end-to-end overhaul to represent my current
thinking. It's also different, because I am starting to cross-post content to <a href="http://blogs.msdn.com/clemensv">http://blogs.msdn.com/clemensv</a> with
this post; however <a href="http://friends.newtelligence.net/clemensv">http://friends.newtelligence.net/clemensv</a> remains my
primary blog since that runs my engine ;-)
</p>
        <p class="Section1">
          <strong>Listening</strong>
        </p>
        <p class="Section1">
The "current thinking" is of course very much influenced by now working for the team
that builds WCF instead of being a customer looking at things from the outside. That
changes the perspective quite a bit. One great insight I gained is how non-dogmatic
and customer-oriented our team is. When I started the concrete REST/POX work with
WCF back in last September (on the customer side still working with newtelligence),
the extensions to the HTTP transport that enabled this work were just showing
up in the public builds and they were sometimes referred to as the "<a href="http://pluralsight.com/blogs/tewald">Tim</a>/<a href="http://www.pluralsight.com/blogs/aaron/">Aaaron</a> feature".
Tim Ewald and Aaron Skonnard had beat the drums for having simple XML (non-SOAP) support
in WCF so loudly that the team investigated the options and figured that some minimal
changes to the HTTP transport would enable most of these scenarios**. Based on
that feature, I wrote the set of dispatcher extensions that I've been presenting in the
V1 of this series and <a href="http://newtellivision.tv">newtellivision</a> as
the applied example did not only turn out to be a big hit as a demo,
it also was one of many motivations to give the REST/POX scenario even deeper
consideration within the team. 
</p>
        <p class="Section1">
REST/POX is a scenario we think about as a first-class scenario alongside SOAP-based
messaging - we are working with the ASP.NET Atlas team to integrate WCF with their
AJAX story and we continue to tweak the core WCF product to enable those scenarios
in a more straightforward fashion. Proof for that is that my talk (<a href="http://216.55.183.13/mix06/BTB021_Vasters.ppt">PPT
here</a>) at the <a href="http://www.mix06.com/">MIX06 conference</a> in Las
Vegas two weeks ago was entirely dedicated to the non-SOAP scenarios.
</p>
        <p class="Section1">
What does that say about SOAP? Nothing. There are two parallel worlds of application-level
network communication that live in peaceful co-existence:
</p>
        <div class="Section1">
          <ul>
            <li>
Simple point-to-point, request/response scenarios with limited security requirements
and no need for "enterprise features" along the lines of reliable messaging and transaction
integration. 
</li>
            <li>
Rich messaging scenarios with support for message routing, reliable delivery, discoverable
metadata, out-of-band data, transactions, one-way and duplex, etcetc.</li>
          </ul>
        </div>
        <p>
          <strong>The Faceless Web</strong>
        </p>
        <p>
The first scenario is the web as we know it. Almost. HTTP is an incredibly rich
application protocol once you dig into RFC2616 and look at the methods in detail
and consider response codes beyond 200 and 404. HTTP is strong because it
is well-defined, widely supported and designed to scale, HTTP is weak because it is
effectively constrained to request/response, there is no story for server-to-client
notifications and it abstracts away the inherent reliability of the transmission-control
protocol (TCP). These pros and cons lists are not exhaustive.
</p>
        <p>
What REST/POX does is to elevate the web model above the "you give me <em>text/html</em> or <em>*/*</em> and
I give you <em>application/x-www-form-urlencoded</em>" interaction model. Whether
the server punts up markup in the form of text/html or text/xml or some other angle-bracket
dialect or some raw binary isn't too interesting. What's changing the way applications
are built and what is really creating the foundation for, say, AJAX is that the path
back to the server is increasingly XML'ised. PUT and POST with a content-type
of text/xml is significantly different from <em>application/x-www-form-urlencoded</em>.
What we are observing is the emancipation of HTTP from HTML to a degree that
the "HT" in HTTP is becoming a misnomer. Something like IXTP ("Interlinked XML Transport
Protocol" - I just made that up) would be a better fit by now.
</p>
        <p>
The astonishing bit in this is that there has been been no fundamental technology
change that has been driving this. The only thing I can identify is that browsers
other than IE are now supporting XMLHTTP and therefore created the critical mass
for broad adoption. REST/POX rips the face off the web and enables a separation
of data and presentation in a way that mashups become easily possible and we're driving
towards a point where the browser cache becomes more of an application repository
than merely a place that holds cacheable collateral. When developing the
newtellivision application I have spent quite a bit of time on tuning the caching
behavior in a way that HTML and script are pulled from the server only when necessary
and as static resources and all actual interaction with the backend services happens
through XMLHTTP and in REST/POX style. newtellivision is not really a hypertext website,
it's more like a smart client application that is delivered through the web technology
stack.
</p>
        <p>
          <strong>Distributed Enterprise Computing</strong>
        </p>
        <p>
All that said, the significant investments in SOAP and WS-* that were made my Microsoft
and industry partners such as Sun, IBM, Tibco and BEA have their primary justification
in the parallel universe of highly interoperable, feature-rich intra and inter-application
communication as well as in enterprise messaging. Even though there was a two-way
split right through through the industry in the 1990s with one side adopting the Distributed
Computing Environment (DCE) and the other side driving the Common Object Request Broker
Architecture (CORBA), both of these camps made great advances towards rich, interoperable
(within their boundaries) enterprise communication infrastructures. All of that got
effectively killed by the web gold-rush starting in 1994/1995 as the focus (and investment) in
the industry turned to HTML/HTTP and to building infrastructures that supported the
web in the first place and everything else as a secondary consideration. The direct
consequence of the resulting (even if big) technology islands hat sit underneath the
web and the neglect of inter-application communication needs was that inter-application
communication has slowly grown to become one of the greatest industry problems and
cost factors. Contributing to that is that the average yearly number of corporate
mergers and acquisitions has tripled compared to 10-15 years ago (even though the
trend has slowed in recent years) and the information technology dependency of
today's corporations has grown to become one of the deciding if not the deciding competitive
factor for an ever increasing number of industries.
</p>
        <p>
What we (the industry as a whole) are doing now and for the last few years is that
we're working towards getting to a point where we're both writing the next chapter
of the story of the web and we're fixing the distributed computing story at the same
time by bringing them both onto a commonly agreed platform. The underpinning of that
is XML; REST/POX is the simplest implementation. SOAP and the WS-* standards
elevate that model up to the distributed enterprise computing realm. 
</p>
        <p>
If you compare the core properties of <a href="http://www.w3.org/TR/2003/REC-soap12-part1-20030624/">SOAP</a>+<a href="http://www.w3.org/TR/ws-addr-core/">WS-Adressing</a> and
the <a href="http://www.ietf.org/rfc/rfc2460.txt">Internet Protocol</a> (IP) in an
interpretative fashion side-by-side and then also compare the <a href="http://www.ietf.org/rfc/rfc793.txt">Transmission
Control Protocol</a> (TCP) to <a href="http://msdn.microsoft.com/ws/2005/02/ws-reliablemessaging/">WS-ReliableMessaging</a> it
may become quite clear to you what a fundamental abstraction above the networking
stacks and concrete technology coupling the WS-* specification family has become.
Every specification in the <a href="http://msdn.microsoft.com/webservices/webservices/understanding/specs/default.aspx">long
list</a> of WS-* specs is about converging and unifying formerly proprietary approaches
to messaging, security, transactions, metadata, management, business process management
and other aspects of distributed computing into this common platform.
</p>
        <p>
          <strong>Convergence</strong>
        </p>
        <p>
The beauty of that model is that it is an implementation superset of the
web. SOAP is the out-of-band metadata container for these abstractions. The
key feature of SOAP is SOAP:Header, which provides a standardized facility to
relay the required metadata alongside payloads. If you are willing to constrain out-of-band
metadata to one transport or application protocol, you don't need SOAP. 
</p>
        <p>
There is really very little difference between SOAP and REST/POX in terms of the information
model. SOAP carries headers and HTTP carries headers. In HTTP they are bolted to the
protocol layer and in SOAP they are tunneled through whatever carries the envelope. [In
that sense, SOAP is calculated abuse of HTTP as a transport protocol for the purpose
of abstraction.] You can map WS-Addressing headers from and to HTTP headers. 
</p>
        <p>
The SOAP/WS-* model is richer, more flexible and more complex. The SOAP/WS-* set of
specifications is about infrastructure protocols. HTTP is an application protocol
and therefore it is naturally more constrained - but has inherently defined qualities
and features that require an explicit protocol implementation in the SOAP/WS-* world;
one example is the inherent CRUD (create, read, update, delete) support in HTTP that
is matched by the explicitly composed-on-top WS-Transfer protocol in SOAP/WS-*
</p>
        <p>
The common platform is XML. You can scale down from SOAP/WS-* to REST/POX by putting
the naked payload on the wire and rely on HTTP for your metadata, error and status
information if that suits your needs. You can scale up from REST/POX to SOAP/WS-*
by encapsulating payloads and leverage the WS-* infrastructure for all the
flexibility and features it brings to the table. [It is fairly straightforward to
go from HTTP to SOAP/WS-*, and it is harder to go the other way. That's why I say
"superset".]
</p>
        <p>
Doing the right thing for a given scenario is precisely what are enabling in
WCF. There is a place for REST/POX for building the surface of the mashed and
faceless web and there is a place for SOAP for building the backbone of it - and some
may choose to mix and match these worlds. There are many scenarios and architectural
models that suit them. What we want is 
</p>
        <p align="center">
          <strong>One Way To Program</strong>. 
</p>
        <p>
          <font size="1">* REST=REpresentational State Transfer; POX="Plain-Old XML" or "simple
XML"</font>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c" />
      </body>
      <title>REST/POX with WCF: Version 2, Part 1: Foreword</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c.aspx</guid>
      <link>http://vasters.com/clemensv/2006/04/01/RESTPOX+With+WCF+Version+2+Part+1+Foreword.aspx</link>
      <pubDate>Sat, 01 Apr 2006 12:25:42 GMT</pubDate>
      <description>&lt;p class=Section1&gt;
&lt;b&gt;Inside the big house....&lt;/b&gt;
&lt;/p&gt;
&lt;p class=Section1&gt;
Back in&amp;nbsp;December of last year and about two weeks before I publicly announced
that I will be working from Microsoft, &lt;a href="http://friends.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx"&gt;I
started&lt;/a&gt; a&amp;nbsp;nine-part series on REST/POX* programming with&amp;nbsp;&lt;strike&gt;Indigo&lt;/strike&gt; WCF.&amp;nbsp;(&lt;span lang=DE&gt;&lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx"&gt;&lt;span lang=EN-US&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,2d61b97b-3a6e-46bd-89db-b1b20499ba18.aspx&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span lang=DE&gt;&lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx"&gt;&lt;span lang=EN-US&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,4e2a7d26-342c-4402-8000-a0d15860c5fc.aspx&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span lang=DE&gt;&lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx"&gt;&lt;span lang=EN-US&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,3f40268c-dee2-44eb-829a-f621a4d40fbc.aspx&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span lang=DE&gt;&lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx"&gt;&lt;span lang=EN-US&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx&gt;&lt;span title=http://staff.newtelligence.net/clemensv/PermaLink,guid,c45eb508-2269-4d0e-a730-dbd9c7d5f882.aspx&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, &lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,3712ee6b-cd80-4db3-a96c-c740491f588e.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,3712ee6b-cd80-4db3-a96c-c740491f588e.aspx"&gt;5&lt;/a&gt;, &lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,51327201-07c7-4a30-b79c-53842cda1e77.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,51327201-07c7-4a30-b79c-53842cda1e77.aspx"&gt;6&lt;/a&gt;, &lt;a title=http://staff.newtelligence.net/clemensv/PermaLink,guid,e82c8423-f106-4105-81e4-14410a83315a.aspx href="http://staff.newtelligence.net/clemensv/PermaLink,guid,e82c8423-f106-4105-81e4-14410a83315a.aspx"&gt;7&lt;/a&gt;, &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink,guid,7465c74e-6001-4d08-93ae-ad7110dee188.aspx"&gt;8&lt;/a&gt;, &lt;a href="http://friends.newtelligence.net/clemensv/PermaLink,guid,8fc367b2-a4be-4588-8264-5455c268b94a.aspx"&gt;9&lt;/a&gt;).
Since then, the WCF object model has seen quite a few feature and usability improvements
across the board and those are significant enough to justify that I rewrite the entire
series to get it up to the February CTP level and I will keep updating it through
Vista/WinFX Beta2 and as we are marching towards our RTM. We've got a few changes/extensions
in&amp;nbsp;our production pipeline to make the REST/POX story for WCF v1 stronger and
I will track those changes with yet another re-release of this series. 
&lt;/p&gt;
&lt;p class=Section1&gt;
Except in one or two occasions, I haven't re-posted a reworked story on my blog. This
here is quite a bit different, because of it sheer size and the things I learned in
the process of writing it and developing the code along the way. So even though it
is relatively new, it's already due for an end-to-end overhaul to represent my current
thinking. It's also different, because I am starting to cross-post content to &lt;a href="http://blogs.msdn.com/clemensv"&gt;http://blogs.msdn.com/clemensv&lt;/a&gt;&amp;nbsp;with
this post;&amp;nbsp;however &lt;a href="http://friends.newtelligence.net/clemensv"&gt;http://friends.newtelligence.net/clemensv&lt;/a&gt; remains&amp;nbsp;my
primary blog since that runs my engine ;-)
&lt;/p&gt;
&lt;p class=Section1&gt;
&lt;strong&gt;Listening&lt;/strong&gt;
&lt;/p&gt;
&lt;p class=Section1&gt;
The "current thinking" is of course very much influenced by now working for the team
that builds WCF instead of being a customer looking at things from the outside. That
changes the perspective quite a bit. One&amp;nbsp;great insight I gained is how non-dogmatic
and customer-oriented our team is. When I started the concrete REST/POX work with
WCF back in last September (on the customer side still working with newtelligence),
the extensions to the HTTP transport that&amp;nbsp;enabled this work were just showing
up in the public builds and they were&amp;nbsp;sometimes referred to as the&amp;nbsp;"&lt;a href="http://pluralsight.com/blogs/tewald"&gt;Tim&lt;/a&gt;/&lt;a href="http://www.pluralsight.com/blogs/aaron/"&gt;Aaaron&lt;/a&gt; feature".
Tim Ewald and Aaron Skonnard had beat the drums for having simple XML (non-SOAP) support
in WCF so loudly that the team investigated the options and figured that some minimal
changes to the HTTP transport would enable most of these scenarios**.&amp;nbsp;Based on
that feature, I wrote the set of dispatcher extensions that I've been presenting in&amp;nbsp;the
V1 of this&amp;nbsp;series and &lt;a href="http://newtellivision.tv"&gt;newtellivision&lt;/a&gt; as
the applied example did not only&amp;nbsp;turn out to be a big hit&amp;nbsp;as a&amp;nbsp;demo,
it also was&amp;nbsp;one of many&amp;nbsp;motivations to give the REST/POX scenario even deeper
consideration within the team. 
&lt;/p&gt;
&lt;p class=Section1&gt;
REST/POX is a scenario we&amp;nbsp;think about as a first-class scenario alongside SOAP-based
messaging - we are working with the ASP.NET Atlas team to integrate WCF with their
AJAX story and&amp;nbsp;we continue to tweak the core WCF product to enable those scenarios
in a more straightforward fashion. Proof for that is that my talk (&lt;a href="http://216.55.183.13/mix06/BTB021_Vasters.ppt"&gt;PPT
here&lt;/a&gt;)&amp;nbsp;at the &lt;a href="http://www.mix06.com/"&gt;MIX06 conference&lt;/a&gt; in Las
Vegas two weeks ago was entirely dedicated&amp;nbsp;to the non-SOAP&amp;nbsp;scenarios.
&lt;/p&gt;
&lt;p class=Section1&gt;
What does that say about SOAP? Nothing. There are two parallel worlds of application-level
network communication that live in peaceful co-existence:
&lt;/p&gt;
&lt;div class=Section1&gt;
&lt;ul&gt;
&lt;li&gt;
Simple point-to-point, request/response&amp;nbsp;scenarios with limited security requirements
and no need for "enterprise features" along the lines of reliable messaging and transaction
integration. 
&lt;/li&gt;
&lt;li&gt;
Rich messaging scenarios with support for&amp;nbsp;message routing, reliable delivery,&amp;nbsp;discoverable
metadata, out-of-band data,&amp;nbsp;transactions, one-way and duplex, etcetc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;strong&gt;The Faceless Web&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The first scenario is the web as we know it. Almost.&amp;nbsp;HTTP is an incredibly rich
application protocol once you&amp;nbsp;dig into RFC2616 and look at the methods in detail
and consider response codes beyond 200 and 404.&amp;nbsp;HTTP is&amp;nbsp;strong because it
is well-defined, widely supported and designed to scale, HTTP is weak because it is
effectively constrained to request/response, there is no story for server-to-client
notifications and it abstracts away the inherent reliability of the transmission-control
protocol (TCP).&amp;nbsp;These pros and cons&amp;nbsp;lists are not exhaustive.
&lt;/p&gt;
&lt;p&gt;
What REST/POX does is to elevate the web model above the "you give me &lt;em&gt;text/html&lt;/em&gt; or &lt;em&gt;*/*&lt;/em&gt; and
I give you &lt;em&gt;application/x-www-form-urlencoded&lt;/em&gt;" interaction model. Whether
the server punts up markup in the form of text/html or text/xml or some other angle-bracket
dialect or some raw binary isn't too interesting. What's changing the way applications
are built and what is really creating the foundation for, say, AJAX is that the path
back to the server is increasingly XML'ised.&amp;nbsp;PUT and POST&amp;nbsp;with a content-type
of text/xml is significantly different from &lt;em&gt;application/x-www-form-urlencoded&lt;/em&gt;.
What we are&amp;nbsp;observing is the emancipation of HTTP from HTML to a degree that
the "HT" in HTTP is becoming a misnomer. Something like IXTP ("Interlinked XML Transport
Protocol" - I just made that up) would be a better fit by now.
&lt;/p&gt;
&lt;p&gt;
The astonishing bit in this is that there has been&amp;nbsp;been no&amp;nbsp;fundamental technology
change that has been driving this. The only thing I can identify is that browsers
other than IE are now supporting XMLHTTP and&amp;nbsp;therefore created the critical mass
for&amp;nbsp;broad adoption. REST/POX rips the face off the web and enables a separation
of data and presentation in a way that mashups become easily possible and we're driving
towards a point where the browser cache becomes more of an application repository
than merely a place that holds cacheable collateral.&amp;nbsp;When developing&amp;nbsp;the
newtellivision application I have spent quite a bit of time on tuning the caching
behavior in a way that HTML and script are pulled from the server only when necessary
and as static resources and all actual interaction with the backend services happens
through XMLHTTP and in REST/POX style. newtellivision is not really a hypertext website,
it's more like a smart client application that is delivered through the web technology
stack.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Distributed Enterprise Computing&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
All that said, the significant investments in SOAP and WS-* that were made my Microsoft
and industry partners such as Sun, IBM, Tibco and BEA&amp;nbsp;have their primary justification
in the parallel universe of highly interoperable, feature-rich&amp;nbsp;intra and inter-application
communication as well as in enterprise messaging. Even though there was a two-way
split right through through the industry in the 1990s with one side adopting the Distributed
Computing Environment (DCE) and the other side driving the Common Object Request Broker
Architecture (CORBA), both of these camps made great advances towards rich, interoperable
(within their boundaries) enterprise communication infrastructures. All of that got
effectively killed by the web gold-rush starting in 1994/1995 as the focus (and investment)&amp;nbsp;in
the industry turned to HTML/HTTP and to building infrastructures that supported the
web in the first place and everything else as a secondary consideration. The direct
consequence of the resulting (even if big) technology islands hat sit underneath the
web and the neglect of inter-application communication needs was that inter-application
communication has slowly grown to become&amp;nbsp;one of the greatest industry problems&amp;nbsp;and
cost factors. Contributing to that is that the average yearly number of corporate
mergers and acquisitions has tripled compared to 10-15 years ago (even though the
trend has slowed in recent years) and the information technology&amp;nbsp;dependency of
today's corporations has grown to become one of the deciding if not the deciding competitive
factor for&amp;nbsp;an ever increasing number of industries.
&lt;/p&gt;
&lt;p&gt;
What we (the industry as a whole) are doing now and for the last few years is that
we're working towards getting to a point where we're both writing the next chapter
of the story of the web and we're fixing the distributed computing story at the same
time by bringing them both onto a commonly agreed platform. The underpinning of that
is XML; REST/POX is&amp;nbsp;the simplest implementation. SOAP and the WS-* standards
elevate that model up to the distributed enterprise computing realm. 
&lt;/p&gt;
&lt;p&gt;
If you&amp;nbsp;compare the core properties of &lt;a href="http://www.w3.org/TR/2003/REC-soap12-part1-20030624/"&gt;SOAP&lt;/a&gt;+&lt;a href="http://www.w3.org/TR/ws-addr-core/"&gt;WS-Adressing&lt;/a&gt; and
the &lt;a href="http://www.ietf.org/rfc/rfc2460.txt"&gt;Internet Protocol&lt;/a&gt; (IP) in an
interpretative fashion side-by-side and then also compare the &lt;a href="http://www.ietf.org/rfc/rfc793.txt"&gt;Transmission
Control Protocol&lt;/a&gt; (TCP)&amp;nbsp;to&amp;nbsp;&lt;a href="http://msdn.microsoft.com/ws/2005/02/ws-reliablemessaging/"&gt;WS-ReliableMessaging&lt;/a&gt;&amp;nbsp;it
may become quite clear to you what a fundamental abstraction above the networking
stacks and concrete technology coupling the WS-* specification family has become.
Every specification in the &lt;a href="http://msdn.microsoft.com/webservices/webservices/understanding/specs/default.aspx"&gt;long
list&lt;/a&gt; of WS-* specs is about converging and unifying formerly proprietary approaches
to messaging, security, transactions, metadata, management, business process management
and other aspects of distributed computing into this common platform.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Convergence&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The beauty of that model is that it&amp;nbsp;is an implementation&amp;nbsp;superset of the
web. SOAP is the out-of-band metadata&amp;nbsp;container for&amp;nbsp;these abstractions.&amp;nbsp;The
key&amp;nbsp;feature of SOAP is SOAP:Header, which provides a standardized facility to
relay the required metadata alongside payloads. If you are willing to constrain out-of-band
metadata to one transport or application protocol, you don't need SOAP. 
&lt;/p&gt;
&lt;p&gt;
There is really very little difference between SOAP and REST/POX in terms of the information
model. SOAP carries headers and HTTP carries headers. In HTTP they are bolted to the
protocol layer and in SOAP they are tunneled through whatever carries the envelope.&amp;nbsp;[In
that sense, SOAP is calculated abuse of HTTP as a transport protocol for the purpose
of abstraction.] You can map WS-Addressing headers from and to HTTP headers. 
&lt;/p&gt;
&lt;p&gt;
The SOAP/WS-* model is richer, more flexible and more complex. The SOAP/WS-* set of
specifications is about infrastructure protocols. HTTP is an application protocol
and&amp;nbsp;therefore it is naturally more constrained - but has inherently defined qualities
and features that require an explicit protocol implementation in the SOAP/WS-* world;
one example is the inherent CRUD (create, read, update, delete) support in HTTP that
is matched by the explicitly composed-on-top WS-Transfer protocol in SOAP/WS-*
&lt;/p&gt;
&lt;p&gt;
The common platform is XML. You can scale down from SOAP/WS-* to REST/POX by putting
the naked payload on the wire and rely on HTTP for your metadata, error and status
information if that suits your needs. You can scale up from REST/POX to SOAP/WS-*
by encapsulating payloads and&amp;nbsp;leverage the WS-* infrastructure for&amp;nbsp;all the
flexibility and features it brings to the table. [It is fairly straightforward to
go from HTTP to SOAP/WS-*, and it is harder to go the other way. That's why I say
"superset".]
&lt;/p&gt;
&lt;p&gt;
Doing the right thing for a given scenario&amp;nbsp;is precisely what are enabling in
WCF.&amp;nbsp;There is a place for REST/POX for building the surface of the mashed and
faceless web and there is a place for SOAP for building the backbone of it - and some
may choose to mix and match these worlds. There are many scenarios and&amp;nbsp;architectural
models that suit them. What we want is 
&lt;/p&gt;
&lt;p align=center&gt;
&lt;strong&gt;One Way To Program&lt;/strong&gt;.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=1&gt;* REST=REpresentational State Transfer; POX="Plain-Old XML" or "simple
XML"&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,33c5fdc9-bb07-4c7b-bab7-9726a15c5b2c.aspx</comments>
      <category>Architecture</category>
      <category>Architecture/SOA</category>
      <category>Talks/MIX06</category>
      <category>Technology</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=92eaea8c-778d-4512-af03-d332785f65f5</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,92eaea8c-778d-4512-af03-d332785f65f5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,92eaea8c-778d-4512-af03-d332785f65f5.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=92eaea8c-778d-4512-af03-d332785f65f5</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I kicked off quite a discussion with my <a href="http://friends.newtelligence.net/clemensv/CommentView,guid,0fbf07a9-9e7a-4db4-a305-58250ac57a73.aspx">recent
post</a> on O/R mapping. Some people think I am completely wrong, some say that it
resonates with their experience, some say I wrote this in mean spirit, some are jubilating.
I particularly liked the "<a href="http://www.from9till2.com/PermaLink.aspx?guid=6e734626-29df-4971-b17d-dcaf7a0e6ab1">Architectural
Truthiness</a>" post by David Ing and the comment by "Scott E" in my comments section
who wrote:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <em>I've hiked up the learning curve for Hibernate (the Java flavor) only to find
that what time was saved in mapping basic CRUD functionality got eaten up by out-of-band
custom data access (which always seems to be required) and tuning to get performance
close to what it would have been with a more specialized, hand-coded DAL. </em>
          </p>
        </blockquote>
        <p>
As always, it's a matter of perspective. Here is mine: I went down the O/R mapping
route in a project in '98/'99 when my group at the company I was working for at the
time was building a new business framework. We wrote a complete, fully transparent O/R
mapper in C++. You walked up to a factory which dehydrated objects and you could walk
along the association links and the object graph would either incrementally dehydrate
or dehydrate in predefined segments. We had filtering capabilities that allowed
to constrain 1:N collections with large N's, we could auto-resolve N:M relationships,
had support for inheritance, and all that jazz. The whole framework was written
with code generation in mind. Our generators were fed with augmented UML class diagrams
and spit out the business layer, whereby we had a "partial classes" concept where
we'd keep the auto-gen'd code in one tree and the parts that were supposed to be filled
manually in another part of the code tree. Of course we'd preserve changes across
re-gen's. Pure OO nirvana. 
</p>
        <p>
While the platforms have evolved substantially in the past 7 years, the fundamental
challenges for transparent (fully abstracted) mapping of data to objects remain essentially
the same. 
</p>
        <ul>
          <li>
Given metadata to do the mapping, implementing CRUD functionality with an O/R mapper is quite
easy. We had to put lots of extra metadata into our C++ classes back in the day, but
with .NET and Java the metadata is all there and therefore CRUD O/R mapping is very
low-hanging fruit on both platforms. That's why there's such a large number of projects
and products.</li>
          <li>
Defining and resolving associations is difficult. 1:N is hard, because you need to
know what your N looks like. You don't want to dehydrate 10000 objects to find a value
in one of them or to calculate a sum over a column. That's work that's, quite frankly, best
left in the database. I realize that some people worry how that leads to logic bleeding
into the database, but for me that's a discussion about pureness vs. pragmatism. If
the N is small, grabbing all related objects is relatively easy - unless you support
polymorphism, which forces the mapper into all sorts of weird query trees. 1:N is
so difficult because an object model is inherently about records, while SQL is about
sets. N:M is harder.</li>
          <li>
"Object identity" is a dangerous lure. Every object has its own identifier. In memory
that is its address, on disk that's some form of unique identifier. The idea of making
the persistent identifier also the in-memory identifier often has the design consequence
of an in-memory "running object table" with the goal of avoiding to load the same
object twice but rather linking it appropriately into the object graph. That's a
fantastic concept, but leads to all sort of interesting concurrency puzzles: What
do you do if you happen to find an object you have already loaded as you resolve an
1:N association and realize that the object has meanwhile changed on disk? Another
question is what the scope of the object identity is. Per appdomain/process, per machine
or even a central object server (hope not)?</li>
          <li>
Transactions are hard. Databases are doing a really good job with data concurrency
management, especially with stored procedures. If you are loading and managing
data as object-graphs, how do you manage transaction isolation? How do you identify
the subtree that's being touched by a transaction? How do you manage rollbacks? What
is a transaction, anyways?</li>
          <li>
Changing the underlying data model is hard. I've run into several situations where
existing applications had to be, with the customer willing to put money on the
table, be integrated with existing data models. O/R mapping is relatively easy
of the data model falls out of the object model. If an existing data model
bubbles up against an object model, you often end up writing a DAL or the O/R in stored
procedures.</li>
          <li>
Reporting and data aggregation is hard. I'll use an analogy for that: It's really
easy to write an XPath query against an XML document, but it is insanely difficult
to do the same navigating the DOM.</li>
        </ul>
        <p>
That said, I am not for or against O/R mapping. There are lots of use cases with a
lot of CRUD work where O/R saves a lot of time. However, it is a leaky abstraction.
In fact is is so leaky that we ended up not using all that much of the funkyness we
put into our framework, because "special cases" kept popping up. I am pointing out
that there are a lot of fundamental differences between what an RDBMS does with data
and how OOP treats data. The discussion is in part a discussion about ISAM
vs. RDBMS. 
</p>
        <p>
The number of brain cycles that need to be invested for a clean O/R mapping
of a complex object model in the presence of the fundamental challenges I listed here
(and that list isn't exhaustive) are not automatically less than for a plain-old
data layer. It may be more. YMMV.
</p>
        <p>
Now you can (and some already have) ask how all of that plays with <a href="http://msdn.microsoft.com/netframework/future/linq/">LINQ</a> and,
in particular, <a href="http://download.microsoft.com/download/c/f/b/cfbbc093-f3b3-4fdb-a170-604db2e29e99/DLinq%20Overview.doc">DLINQ</a>.
Mind that I don't work in the LINQ team, but I think to be observing
a subtle but important difference between LINQ and O/R*: 
</p>
        <ul>
          <li>
O/R is object-&gt;relational mapping. 
</li>
          <li>
LINQ is relational-&gt;object mapping. 
</li>
        </ul>
        <p>
LINQ acknowledges the relational nature of the vast majority of data, while O/R attempts
to deny it. LINQ speaks about entities, relations and queries and maps result-sets
into the realm of objects, even cooking up classes on the fly if it needs to. It's
bottom up and the data (from whatever source) is king. Objects and classes are just
tooling. For O/R mapping, the database is just tooling.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=92eaea8c-778d-4512-af03-d332785f65f5" />
      </body>
      <title>O/R mapping; take two</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,92eaea8c-778d-4512-af03-d332785f65f5.aspx</guid>
      <link>http://vasters.com/clemensv/2006/03/14/OR+Mapping+Take+Two.aspx</link>
      <pubDate>Tue, 14 Mar 2006 14:17:53 GMT</pubDate>
      <description>&lt;p&gt;
I kicked off quite a discussion with my &lt;a href="http://friends.newtelligence.net/clemensv/CommentView,guid,0fbf07a9-9e7a-4db4-a305-58250ac57a73.aspx"&gt;recent
post&lt;/a&gt; on O/R mapping. Some people think I am completely wrong, some say that it
resonates with their experience, some say I wrote this in mean spirit, some are jubilating.
I particularly liked the "&lt;a href="http://www.from9till2.com/PermaLink.aspx?guid=6e734626-29df-4971-b17d-dcaf7a0e6ab1"&gt;Architectural
Truthiness&lt;/a&gt;" post by David Ing and the comment by "Scott E" in my comments section
who wrote:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;em&gt;I've hiked up the learning curve for Hibernate (the Java flavor) only to find
that what time was saved in mapping basic CRUD functionality got eaten up by out-of-band
custom data access (which always seems to be required) and tuning to get performance
close to what it would have been with a more specialized, hand-coded DAL. &lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
As always, it's a matter of perspective. Here is mine: I went down the O/R mapping
route in a project in '98/'99 when my group at the company I was working for at the
time was building a new business framework. We wrote&amp;nbsp;a complete, fully transparent&amp;nbsp;O/R
mapper in C++. You walked up to a factory which dehydrated objects and you could walk
along the association links and&amp;nbsp;the object graph would either incrementally dehydrate
or dehydrate in&amp;nbsp;predefined segments. We had filtering capabilities that&amp;nbsp;allowed
to constrain 1:N collections with large N's, we could auto-resolve N:M&amp;nbsp;relationships,
had support for inheritance,&amp;nbsp;and all that jazz. The whole framework was written
with code generation in mind. Our generators were fed with augmented UML class diagrams
and spit out the business layer, whereby we had a "partial classes" concept where
we'd keep the auto-gen'd code in one tree and the parts that were supposed to be filled
manually in another part of the code tree. Of course we'd preserve changes across
re-gen's. Pure OO nirvana. 
&lt;/p&gt;
&lt;p&gt;
While the platforms have evolved substantially in the past 7 years, the fundamental
challenges for transparent (fully abstracted) mapping of data to objects remain essentially
the same. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Given metadata to do the mapping, implementing CRUD functionality with an O/R mapper&amp;nbsp;is&amp;nbsp;quite
easy. We had to put lots of extra metadata into our C++ classes back in the day, but
with .NET and Java the metadata is all there and therefore CRUD O/R mapping is very
low-hanging fruit on both platforms. That's why there's such a large number of projects
and products.&lt;/li&gt;
&lt;li&gt;
Defining and resolving associations is difficult. 1:N is hard, because you need to
know what your N looks like. You don't want to dehydrate 10000 objects to find a value
in one of them or to calculate a sum over a column. That's work that's, quite frankly,&amp;nbsp;best
left in the database. I realize that some people worry how that leads to logic bleeding
into the database, but for me that's a discussion about pureness vs. pragmatism. If
the N is small, grabbing all related objects is relatively easy - unless you support
polymorphism, which forces the mapper into all sorts of weird query trees. 1:N is
so difficult because an object model is inherently about records, while SQL is about
sets. N:M is harder.&lt;/li&gt;
&lt;li&gt;
"Object identity" is a dangerous lure. Every object has its own identifier. In memory
that is its address, on disk that's some form of unique identifier. The idea of making
the persistent identifier also the in-memory identifier often has the design consequence
of an in-memory "running object table" with the goal of avoiding to load the same
object twice but rather linking it appropriately into the object graph. That's&amp;nbsp;a
fantastic concept, but leads to all sort of interesting concurrency puzzles: What
do you do if you happen to find an object you have already loaded as you resolve an
1:N association and realize that the object has meanwhile changed on disk? Another
question is what the scope of the object identity is. Per appdomain/process, per machine
or even a central object server (hope not)?&lt;/li&gt;
&lt;li&gt;
Transactions are hard. Databases are doing a really good job with data concurrency
management, especially with stored procedures.&amp;nbsp;If you are&amp;nbsp;loading and managing
data as object-graphs, how do you manage transaction isolation?&amp;nbsp;How do you identify
the subtree that's being touched by a transaction? How do you manage rollbacks?&amp;nbsp;What
is a transaction, anyways?&lt;/li&gt;
&lt;li&gt;
Changing the underlying data model is hard. I've run into several situations where
existing applications had to be, with the customer&amp;nbsp;willing to put money on the
table,&amp;nbsp;be integrated with existing data models. O/R mapping is relatively easy
of the data model falls out of the object model. If&amp;nbsp;an existing&amp;nbsp;data model
bubbles up against an object model, you often end up writing a DAL or the O/R in stored
procedures.&lt;/li&gt;
&lt;li&gt;
Reporting and data aggregation is hard. I'll use an analogy for that: It's really
easy to write an XPath query against an XML document, but it is insanely difficult
to do the same navigating the DOM.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
That said, I am not for or against O/R mapping. There are lots of use cases with a
lot of CRUD work where O/R saves a lot of time. However, it is a leaky abstraction.
In fact is is so leaky that we ended up not using all that much of the funkyness we
put into our framework, because "special cases" kept popping up. I am pointing out
that there are a lot of fundamental differences between what an RDBMS does with data
and how OOP treats data. The discussion is&amp;nbsp;in part&amp;nbsp;a discussion about ISAM
vs. RDBMS. 
&lt;/p&gt;
&lt;p&gt;
The number of brain cycles that need to be invested&amp;nbsp;for a clean&amp;nbsp;O/R mapping
of a complex object model in the presence of the fundamental challenges I listed here
(and that list isn't exhaustive) are not automatically less than for a&amp;nbsp;plain-old
data layer. It may be more. YMMV.
&lt;/p&gt;
&lt;p&gt;
Now you can (and some already have) ask how all of that plays with &lt;a href="http://msdn.microsoft.com/netframework/future/linq/"&gt;LINQ&lt;/a&gt;&amp;nbsp;and,
in particular, &lt;a href="http://download.microsoft.com/download/c/f/b/cfbbc093-f3b3-4fdb-a170-604db2e29e99/DLinq%20Overview.doc"&gt;DLINQ&lt;/a&gt;.
Mind that I don't work in&amp;nbsp;the LINQ&amp;nbsp;team, but I&amp;nbsp;think to be observing
a subtle but important difference between LINQ and O/R*:&amp;nbsp;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
O/R is object-&amp;gt;relational mapping. 
&lt;/li&gt;
&lt;li&gt;
LINQ is relational-&amp;gt;object mapping. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
LINQ acknowledges the relational nature of the vast majority of data, while O/R attempts
to deny it. LINQ speaks about entities, relations&amp;nbsp;and queries and maps result-sets
into the realm of objects, even cooking up classes on the fly if it needs to. It's
bottom up and the data (from whatever source) is king. Objects and classes are just
tooling. For O/R mapping, the database is just tooling.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=92eaea8c-778d-4512-af03-d332785f65f5" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,92eaea8c-778d-4512-af03-d332785f65f5.aspx</comments>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=4b9d14f4-a6e3-454b-bcaf-35cbd903d393</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,4b9d14f4-a6e3-454b-bcaf-35cbd903d393.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,4b9d14f4-a6e3-454b-bcaf-35cbd903d393.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=4b9d14f4-a6e3-454b-bcaf-35cbd903d393</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <table class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0" width="100%" style="width:100.0%;background:#F3F3F3;border-collapse:collapse;border:none">
            <tr>
              <td width="100%" valign="top" style="width:100.0%;border:solid windowtext 1.0pt;&#xD;&#xA;  padding:0in 5.4pt 0in 5.4pt">
                <p class="MsoNormal">
                  <b>
                    <span style="font-size:8.0pt;font-family:Courier;&#xD;&#xA;  color:blue">private</span>
                  </b>
                  <b>
                    <span style="font-size:8.0pt;font-family:&#xD;&#xA;  Courier">
                      <span style="color:blue">void</span> exitMenuItem
Click(<span style="color:blue">object</span> sender, <span style="color:teal">EventArgs</span> e)<br />
{<br />
    <span style="color:blue;background:yellow">if</span><span style="background:yellow"> (runtime
!= <span style="color:blue">null</span> &amp;&amp; runtime.Running)<br />
    {<br />
        <span style="color:teal">ThreadPool</span>.QueueUserWorkItem(<span style="color:blue">delegate</span>(<span style="color:blue">object</span> obj)<br />
        {</span><br />
            <span style="background:aqua">runtime.Stop();<br />
            Invoke(<span style="color:blue">new</span><span style="color:teal">ThreadStart</span>(<span style="color:blue">delegate</span>()<br />
            {</span><br />
                <span style="color:blue;background:yellow">this</span><span style="background:yellow">.Close();</span><br />
            <span style="background:aqua">}));</span><br />
        });<br />
    <span style="background:yellow">}<br />
    <span style="color:blue">else<br /></span>    {<br />
        <span style="color:blue">this</span>.Close();<br />
    }</span>            
<br />
}</span>
                  </b>
                </p>
              </td>
            </tr>
          </table>
          <p>
Just caught myself coding this up. The shown method is a Windows Forms event handler
for a menu item. The task at hand is to check a local variable and if that’s
set to a specific value, to switch to a different thread and perform an action (that
particular job can’t be done on the Windows Forms STA thread), and to close
the form back on the main STA thread once that’s done. I colored the executing
threads; yellow is the Windows Forms STA thread, blue is an arbitrary pool thread.
Works brilliantly. Sick, eh?
</p>
          <p>
 
</p>
          <p>
[Mind that I am using <i>ThreadStart</i> just because it’s a convenient <i>void
target(void)</i> delegate]
</p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4b9d14f4-a6e3-454b-bcaf-35cbd903d393" />
      </body>
      <title>Sick C# trick of the day</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,4b9d14f4-a6e3-454b-bcaf-35cbd903d393.aspx</guid>
      <link>http://vasters.com/clemensv/2006/01/14/Sick+C+Trick+Of+The+Day.aspx</link>
      <pubDate>Sat, 14 Jan 2006 16:11:22 GMT</pubDate>
      <description>

&lt;div class=Section1&gt;
&lt;table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 width="100%" style='width:100.0%;background:#F3F3F3;border-collapse:collapse;border:none'&gt;
&lt;tr&gt;
&lt;td width="100%" valign=top style='width:100.0%;border:solid windowtext 1.0pt;
  padding:0in 5.4pt 0in 5.4pt'&gt;
&lt;p class=MsoNormal&gt;
&lt;b&gt;&lt;span style='font-size:8.0pt;font-family:Courier;
  color:blue'&gt;private&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style='font-size:8.0pt;font-family:
  Courier'&gt; &lt;span style='color:blue'&gt;void&lt;/span&gt; exitMenuItem
Click(&lt;span style='color:blue'&gt;object&lt;/span&gt; sender, &lt;span style='color:teal'&gt;EventArgs&lt;/span&gt; e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:blue;background:yellow'&gt;if&lt;/span&gt;&lt;span style='background:yellow'&gt; (runtime
!= &lt;span style='color:blue'&gt;null&lt;/span&gt; &amp;amp;&amp;amp; runtime.Running)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:teal'&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem(&lt;span style='color:blue'&gt;delegate&lt;/span&gt;(&lt;span style='color:blue'&gt;object&lt;/span&gt; obj)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='background:aqua'&gt;runtime.Stop();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Invoke(&lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:teal'&gt;ThreadStart&lt;/span&gt;(&lt;span style='color:blue'&gt;delegate&lt;/span&gt;()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:blue;background:yellow'&gt;this&lt;/span&gt;&lt;span style='background:yellow'&gt;.Close();&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='background:aqua'&gt;}));&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='background:yellow'&gt;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:blue'&gt;else&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:blue'&gt;this&lt;/span&gt;.Close();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
}&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
Just caught myself coding this up. The shown method is a Windows Forms event handler
for a menu item. The task at hand is to check a local variable and if that&amp;#8217;s
set to a specific value, to switch to a different thread and perform an action (that
particular job can&amp;#8217;t be done on the Windows Forms STA thread), and to close
the form back on the main STA thread once that&amp;#8217;s done. I colored the executing
threads; yellow is the Windows Forms STA thread, blue is an arbitrary pool thread.
Works brilliantly. Sick, eh?
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
[Mind that I am using &lt;i&gt;ThreadStart&lt;/i&gt; just because it&amp;#8217;s a convenient &lt;i&gt;void
target(void)&lt;/i&gt; delegate]
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4b9d14f4-a6e3-454b-bcaf-35cbd903d393" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,4b9d14f4-a6e3-454b-bcaf-35cbd903d393.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=fdf5f8bf-199c-47c3-8cbb-838fab12f83e</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,fdf5f8bf-199c-47c3-8cbb-838fab12f83e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,fdf5f8bf-199c-47c3-8cbb-838fab12f83e.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=fdf5f8bf-199c-47c3-8cbb-838fab12f83e</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
My blogging efforts this year aren’t really impressive, are they? Well, the first
half of the year I was constantly on the road at a ton of conferences and events and
didn’t really get the time to blog much. After TechEd Europe, I was simply burned
out, took three weeks of vacation to recover somewhat and since then I’ve been trying
to get some better traction with areas of Visual Studio that I hadn’t really looked
at well enough since Beta 2 came out. And of course there’s WinFX with Avalon and
Indigo that I need to track closely. 
</p>
          <p>
Now, of course I have the luxury of being able to dedicate a lot of time to learning,
because taking all the raw information in, distilling it down and making it more accessible
to folks who can’t spend all that time happens to be my job. However, I am finding
myself in this rather unfortunate situation again that I will have to throw some things
overboard and will have to focus on a set of areas. 
</p>
          <p>
At some point rather early in my career I decided that I just can’t track all hardware
innovations anymore. I certainly still know what’s generally going on, but when I
buy a new machine I am just a client for Dell, Siemens or Alienware like the next
guy. I don’t think I could make a qualified enough choice on good hardware components
to build my own PC nowadays and I actually have little interest to do so. All that
stuff comes wrapped in a case and if I don’t really have to open it to put an extension
card in, I have no interest to look inside. The same goes for x86 assembly language.
The platform is still essentially the same even after more than a decade, and whenever
Visual Studio is catching an exception right in the middle of “the land of no source
code”, I can – given I have at least the debug symbols loaded – actually figure out
where I am and, especially if it’s unmanaged code, often figure out what’s failing.
But if someone were ask me about the instruction set innovations of the Pentium 4
processor generation I’ll happily point to someone else. In 2001, I wrote a book on
BizTalk and probably knew the internals and how everything fits together as good as
someone outside of Microsoft possibly could know it. BizTalk 2006 is so far away from
me now that I’d have a hard time giving you the feature delta between the 2004 and
2006 versions. Over time, many things went over board that way; hardware and assembly
being the first and every year it seems like something else needs to go. 
</p>
          <p>
The reason is very simple: Capacity. There’s a limit to how much information an individual
can process and I think that by now, Microsoft managed to push the feature depth to
the point where I can’t fit Visual Studio and related technologies into my head all
at once any longer. In my job, it’s reasonable for people to expect that whenever
I get up on stage or write an article that I give them the 10%-20% of pre-distilled
“essentials” that they need 80% of the time out of a technology and that I know close
to 100% of the stuff that’s underneath, so that they can ask me questions and I can
give them good, well founded answers.  In the VS2003/NETFX 1.1 wave, I’ve done
something (and even if it was just a demo) with every single public namespace and
I am confident that I can answer a broad range of customer questions without having
to guess. 
</p>
          <p>
Enter VS2005 and the summary of trying to achieve the same knowledge density is: “Frustrating”. 
</p>
          <p>
There is so much more to (have to) know, especially given that there’s now Team System
and the Team Foundation Server (TFS). TFS is “designed to be customized” and the product
makes that clear wherever you look. It is a bit like an ERP system in that way. You
don’t really have a solution unless you set up a project to customize the product
for your needs. Hence, “Foundation” is a more than fitting name choice. 
</p>
          <p>
I’ve been in a planning project for the past two weeks where the customer has a well
thought out idea about their analysis, design and development processes and while
TFS seems like a great platform for them, they will definitely need customized events,
a custom-tailored version of MSF Agile with lots of new fields and custom code analysis
and check-in policies, integration with and bi-directional data flow from/into “satellite
products” such as a proper requirements analysis system, a help-desk solution and
a documentation solution, and probably will even want to get into building their own
domain specific language (DSL).  All of that is possible and the extensibility
of Visual Studio and TFS is as broad as the customer would need it to be, but … who
would know? The <a title="http://msdn.microsoft.com/vstudio/extend/SDKDownload/" href="http://msdn.microsoft.com/vstudio/extend/SDKDownload/">Team
System Extensibility Kit</a> has documentation to extend and customize process templates,
work items, source control, the build system, the team explorer, test tools, and reporting
and that’s just the headlines. Add the tools for custom <a title="http://lab.msdn.microsoft.com/teamsystem/workshop/dsltools/default.aspx" href="http://lab.msdn.microsoft.com/teamsystem/workshop/dsltools/default.aspx">domain
specific languages</a> (huge!) and the <a title="http://www.gotdotnet.com/workspaces/workspace.aspx?id=fe72608b-2b28-4cc1-9866-ea6f805f45f3" href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=fe72608b-2b28-4cc1-9866-ea6f805f45f3">class
designer extensibility</a> and you’ve got more than enough stuff to put your head
into complete overflow mode. 
</p>
          <p>
And at that point you haven’t even looked at the news in Windows Forms (where I like
all the new data binding capabilities a lot) and much less at ASP.NET 2.0, which is
an entire planet all by itself. Oh, and of course there is the new deployment model
(aka “ClickOnce”), SQL 2005, with all those new features (whereby SQL/CLR is the least
interesting to me) and BizTalk 2006 and, and, and … 
</p>
          <p>
And of course, my core interest is really with the Windows Vista WinFX technology
wave including of course Indigo (don’t make me use “WCF”) and for me to a lesser degree
Avalon (yes, yes: “WPF”) for which knowing the VS2005/NETFX 2.0 foundation is of course
a prerequisite. 
</p>
          <p>
What kills me with Avalon, for instance, is that I’ve got quite a bit of the 2D stuff
cornered and know how to do things even with just an XML editor in hands, but that
the 3D stuff is nicely integrated and sits right there in front of me and I just don’t
have the necessary knowledge depth about building 3D apps to do the simplest thing
and not the time to acquire that knowledge. And I’ve got such great ideas for using
that stuff.
</p>
          <p>
It looks like it’s time to take some things off the table again and that’s an intensely
frustrating decision to make.
</p>
          <p>
Don’t get me wrong … I am not complaining about Microsoft adding too many features
to the platform. Au contraire! I think that we’re seeing a wave of innovation that’s
absolutely fantastic and will enable us out here to build better, more featured applications. 
</p>
          <p>
But for a development team to benefit from all these technologies, specialization
is absolutely needed. The times when development teams had roughly the same technology
knowledge breadth and everyone could do everything are absolutely coming to an end.
And the number of generalists who have a broad, qualified overview on an entire platform
is rapidly shrinking.
</p>
          <p>
And the development teams will change shape. Come Avalon, and game developers (yes,
game developers) will be in great demand in places that are as far away from gaming
as you could imagine. I’ve just had meetings with a very conservative and large investment
management company and they are thinking hard about adding multi-layer, alpha-blended,
3D data visualizations complete with animations and all that jazz to their trading
system UIs, and they’ve got the business demand for it. Of course, the visualization
experts won’t be data mining and data analysis or software integration specialists;
that’s left for others to do.
</p>
          <p>
For “generalists” like me, these are hard and frustrating times if they’re trying
to stay generalists. Deep and consequent specialization is a great opportunity for
everyone and the gamble is of course to pick the right technology to dig into and
become “the expert” in. If that technology or problem space becomes the hottest thing
everyone must have – you win your bet. Otherwise you might be in trouble. 
</p>
          <p>
Here are some ideas and “predictions” for such sought-after specialists – but, hey,
that’s just my unqualified opinion:
</p>
          <p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in">
            <span style="FONT-FAMILY: Symbol">·<span style="FONT: 7pt 'Times New Roman'">         </span></span>
            <i>Cross-platform
Web service wire doctors</i>. As much as all the vendors will try to make their service
platforms such as Indigo and Web Sphere and Web Logic and Apache interoperable, customers
will try hard to break it all by introducing “absolutely necessary” whacky protocol
extensions and by using every extensibility point fathomable. As if that wasn’t hard
enough already today where most interop happens with more or less bare-bones SOAP
envelopes, just wait until bad ideas get combined with the full WS-* stack, including
reliable messaging, security and routing. These folks of course will have to know
everything about security aspects like federation, single-sign-on, etc.  
</p>
          <p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in">
            <span style="FONT-FAMILY: Symbol">·<span style="FONT: 7pt 'Times New Roman'">         </span></span>
            <i>Visualization
Developers</i>. Avalon is a bit like an advanced 3D gaming engine for business application
developers. While that seems like a whacky thing to say – just wait what’ll happen.
Someone will come along and build a full-blown ERP or CRM package whose data visualization
capabilities and advanced data capture methods will blow everything existing out of
the water and everything with white entry fields on a gray background with boring
fonts and some plain bar charts will suddenly look not much better than a green-screen
app. In 3 years you will have people modeling 3D wire-frames on your development teams
or you are history – and the type of app doesn’t really matter much.
</p>
          <p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in">
            <span style="FONT-FAMILY: Symbol">·<span style="FONT: 7pt 'Times New Roman'">         </span></span>
            <i>Development
Tool and Process Customization Specialists</i>:  I expect Team System to become
the SAP R/3 of software development. No deployment without customization, even if
that only happens over time. Brace for the first product update that comes around
and changes and extends the foundation’s data structures. I fully expect Team System
and the Team Foundation Server to gain substantial market share and I fully expect
that there’ll be a lot of people dying to get customization assistance.
</p>
          <p>
 
</p>
          <p>
That said: I am off to learn more stuff.
</p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=fdf5f8bf-199c-47c3-8cbb-838fab12f83e" />
      </body>
      <title>Visual Studio Overload And The Specialization Gamble</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,fdf5f8bf-199c-47c3-8cbb-838fab12f83e.aspx</guid>
      <link>http://vasters.com/clemensv/2005/08/31/Visual+Studio+Overload+And+The+Specialization+Gamble.aspx</link>
      <pubDate>Wed, 31 Aug 2005 08:53:45 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
My blogging efforts this year aren’t really impressive, are they? Well, the first
half of the year I was constantly on the road at a ton of conferences and events and
didn’t really get the time to blog much. After TechEd Europe, I was simply burned
out, took three weeks of vacation to recover somewhat and since then I’ve been trying
to get some better traction with areas of Visual Studio that I hadn’t really looked
at well enough since Beta 2 came out. And of course there’s WinFX with Avalon and
Indigo that I need to track closely. 
&lt;/p&gt;
&lt;p&gt;
Now, of course I have the luxury of being able to dedicate a lot of time to learning,
because taking all the raw information in, distilling it down and making it more accessible
to folks who can’t spend all that time happens to be my job. However, I am finding
myself in this rather unfortunate situation again that I will have to throw some things
overboard and will have to focus on a set of areas. 
&lt;/p&gt;
&lt;p&gt;
At some point rather early in my career I decided that I just can’t track all hardware
innovations anymore. I certainly still know what’s generally going on, but when I
buy a new machine I am just a client for Dell, Siemens or Alienware like the next
guy. I don’t think I could make a qualified enough choice on good hardware components
to build my own PC nowadays and I actually have little interest to do so. All that
stuff comes wrapped in a case and if I don’t really have to open it to put an extension
card in, I have no interest to look inside. The same goes for x86 assembly language.
The platform is still essentially the same even after more than a decade, and whenever
Visual Studio is catching an exception right in the middle of “the land of no source
code”, I can – given I have at least the debug symbols loaded – actually figure out
where I am and, especially if it’s unmanaged code, often figure out what’s failing.
But if someone were ask me about the instruction set innovations of the Pentium 4
processor generation I’ll happily point to someone else. In 2001, I wrote a book on
BizTalk and probably knew the internals and how everything fits together as good as
someone outside of Microsoft possibly could know it. BizTalk 2006 is so far away from
me now that I’d have a hard time giving you the feature delta between the 2004 and
2006 versions. Over time, many things went over board that way; hardware and assembly
being the first and every year it seems like something else needs to go. 
&lt;/p&gt;
&lt;p&gt;
The reason is very simple: Capacity. There’s a limit to how much information an individual
can process and I think that by now, Microsoft managed to push the feature depth to
the point where I can’t fit Visual Studio and related technologies into my head all
at once any longer. In my job, it’s reasonable for people to expect that whenever
I get up on stage or write an article that I give them the 10%-20% of pre-distilled
“essentials” that they need 80% of the time out of a technology and that I know close
to 100% of the stuff that’s underneath, so that they can ask me questions and I can
give them good, well founded answers. &amp;nbsp;In the VS2003/NETFX 1.1 wave, I’ve done
something (and even if it was just a demo) with every single public namespace and
I am confident that I can answer a broad range of customer questions without having
to guess. 
&lt;/p&gt;
&lt;p&gt;
Enter VS2005 and the summary of trying to achieve the same knowledge density is: “Frustrating”. 
&lt;/p&gt;
&lt;p&gt;
There is so much more to (have to) know, especially given that there’s now Team System
and the Team Foundation Server (TFS). TFS is “designed to be customized” and the product
makes that clear wherever you look. It is a bit like an ERP system in that way. You
don’t really have a solution unless you set up a project to customize the product
for your needs. Hence, “Foundation” is a more than fitting name choice. 
&lt;/p&gt;
&lt;p&gt;
I’ve been in a planning project for the past two weeks where the customer has a well
thought out idea about their analysis, design and development processes and while
TFS seems like a great platform for them, they will definitely need customized events,
a custom-tailored version of MSF Agile with lots of new fields and custom code analysis
and check-in policies, integration with and bi-directional data flow from/into “satellite
products” such as a proper requirements analysis system, a help-desk solution and
a documentation solution, and probably will even want to get into building their own
domain specific language (DSL). &amp;nbsp;All of that is possible and the extensibility
of Visual Studio and TFS is as broad as the customer would need it to be, but … who
would know? The &lt;a title=http://msdn.microsoft.com/vstudio/extend/SDKDownload/ href="http://msdn.microsoft.com/vstudio/extend/SDKDownload/"&gt;Team
System Extensibility Kit&lt;/a&gt; has documentation to extend and customize process templates,
work items, source control, the build system, the team explorer, test tools, and reporting
and that’s just the headlines. Add the tools for custom &lt;a title=http://lab.msdn.microsoft.com/teamsystem/workshop/dsltools/default.aspx href="http://lab.msdn.microsoft.com/teamsystem/workshop/dsltools/default.aspx"&gt;domain
specific languages&lt;/a&gt; (huge!) and the &lt;a title=http://www.gotdotnet.com/workspaces/workspace.aspx?id=fe72608b-2b28-4cc1-9866-ea6f805f45f3 href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=fe72608b-2b28-4cc1-9866-ea6f805f45f3"&gt;class
designer extensibility&lt;/a&gt; and you’ve got more than enough stuff to put your head
into complete overflow mode. 
&lt;/p&gt;
&lt;p&gt;
And at that point you haven’t even looked at the news in Windows Forms (where I like
all the new data binding capabilities a lot) and much less at ASP.NET 2.0, which is
an entire planet all by itself. Oh, and of course there is the new deployment model
(aka “ClickOnce”), SQL 2005, with all those new features (whereby SQL/CLR is the least
interesting to me) and BizTalk 2006 and, and, and … 
&lt;/p&gt;
&lt;p&gt;
And of course, my core interest is really with the Windows Vista WinFX technology
wave including of course Indigo (don’t make me use “WCF”) and for me to a lesser degree
Avalon (yes, yes: “WPF”) for which knowing the VS2005/NETFX 2.0 foundation is of course
a prerequisite. 
&lt;/p&gt;
&lt;p&gt;
What kills me with Avalon, for instance, is that I’ve got quite a bit of the 2D stuff
cornered and know how to do things even with just an XML editor in hands, but that
the 3D stuff is nicely integrated and sits right there in front of me and I just don’t
have the necessary knowledge depth about building 3D apps to do the simplest thing
and not the time to acquire that knowledge. And I’ve got such great ideas for using
that stuff.
&lt;/p&gt;
&lt;p&gt;
It looks like it’s time to take some things off the table again and that’s an intensely
frustrating decision to make.
&lt;/p&gt;
&lt;p&gt;
Don’t get me wrong … I am not complaining about Microsoft adding too many features
to the platform. Au contraire! I think that we’re seeing a wave of innovation that’s
absolutely fantastic and will enable us out here to build better, more featured applications. 
&lt;/p&gt;
&lt;p&gt;
But for a development team to benefit from all these technologies, specialization
is absolutely needed. The times when development teams had roughly the same technology
knowledge breadth and everyone could do everything are absolutely coming to an end.
And the number of generalists who have a broad, qualified overview on an entire platform
is rapidly shrinking.
&lt;/p&gt;
&lt;p&gt;
And the development teams will change shape. Come Avalon, and game developers (yes,
game developers) will be in great demand in places that are as far away from gaming
as you could imagine. I’ve just had meetings with a very conservative and large investment
management company and they are thinking hard about adding multi-layer, alpha-blended,
3D data visualizations complete with animations and all that jazz to their trading
system UIs, and they’ve got the business demand for it. Of course, the visualization
experts won’t be data mining and data analysis or software integration specialists;
that’s left for others to do.
&lt;/p&gt;
&lt;p&gt;
For “generalists” like me, these are hard and frustrating times if they’re trying
to stay generalists. Deep and consequent specialization is a great opportunity for
everyone and the gamble is of course to pick the right technology to dig into and
become “the expert” in. If that technology or problem space becomes the hottest thing
everyone must have – you win your bet. Otherwise you might be in trouble. 
&lt;/p&gt;
&lt;p&gt;
Here are some ideas and “predictions” for such sought-after specialists – but, hey,
that’s just my unqualified opinion:
&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in"&gt;
&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;i&gt;Cross-platform
Web service wire doctors&lt;/i&gt;. As much as all the vendors will try to make their service
platforms such as Indigo and Web Sphere and Web Logic and Apache interoperable, customers
will try hard to break it all by introducing “absolutely necessary” whacky protocol
extensions and by using every extensibility point fathomable. As if that wasn’t hard
enough already today where most interop happens with more or less bare-bones SOAP
envelopes, just wait until bad ideas get combined with the full WS-* stack, including
reliable messaging, security and routing. These folks of course will have to know
everything about security aspects like federation, single-sign-on, etc. &amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in"&gt;
&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;i&gt;Visualization
Developers&lt;/i&gt;. Avalon is a bit like an advanced 3D gaming engine for business application
developers. While that seems like a whacky thing to say – just wait what’ll happen.
Someone will come along and build a full-blown ERP or CRM package whose data visualization
capabilities and advanced data capture methods will blow everything existing out of
the water and everything with white entry fields on a gray background with boring
fonts and some plain bar charts will suddenly look not much better than a green-screen
app. In 3 years you will have people modeling 3D wire-frames on your development teams
or you are history – and the type of app doesn’t really matter much.
&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 0.5in; TEXT-INDENT: -0.25in"&gt;
&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;i&gt;Development
Tool and Process Customization Specialists&lt;/i&gt;: &amp;nbsp;I expect Team System to become
the SAP R/3 of software development. No deployment without customization, even if
that only happens over time. Brace for the first product update that comes around
and changes and extends the foundation’s data structures. I fully expect Team System
and the Team Foundation Server to gain substantial market share and I fully expect
that there’ll be a lot of people dying to get customization assistance.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
That said: I am off to learn more stuff.
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=fdf5f8bf-199c-47c3-8cbb-838fab12f83e" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,fdf5f8bf-199c-47c3-8cbb-838fab12f83e.aspx</comments>
      <category>IT Strategy</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=535d4a96-2cc3-4306-8b56-9a96c7c6fa39</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,535d4a96-2cc3-4306-8b56-9a96c7c6fa39.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,535d4a96-2cc3-4306-8b56-9a96c7c6fa39.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=535d4a96-2cc3-4306-8b56-9a96c7c6fa39</wfw:commentRss>
      <slash:comments>9</slash:comments>
      <title>"SOA" doesn't really exist, does it?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,535d4a96-2cc3-4306-8b56-9a96c7c6fa39.aspx</guid>
      <link>http://vasters.com/clemensv/2005/05/02/SOA+Doesnt+Really+Exist+Does+It.aspx</link>
      <pubDate>Mon, 02 May 2005 13:34:33 GMT</pubDate>
      <description>

&lt;div class=Section1&gt;
&lt;p&gt;
In the past months I&amp;#8217;ve been throwing ideas back and forth with some of my friends
and we&amp;#8217;re slowly realizing that &amp;#8220;Service Oriented Architecture&amp;#8221;
doesn&amp;#8217;t really exist. 
&lt;/p&gt;
&lt;p&gt;
The term &amp;#8220;Service Oriented Architecture&amp;#8221; implies that there is something
special about architecture when it comes to service orientation, Web services, XML,
loose coupling and all the wonderful blessings of the past 5 years in this wave. But
if you look at it, there really isn&amp;#8217;t much special about the good, old, proven
architectural principles once you throw services into the picture. 
&lt;/p&gt;
&lt;p&gt;
I&amp;#8217;ll try to explain what I mean. There are five pillars of software architecture
(this deserves more elaboration, but I will keep it short for now):
&lt;/p&gt;
&lt;p style='margin-left:.5in;text-indent:-.25in'&gt;
&lt;span style='font-family:Symbol'&gt;&amp;middot;&lt;span style='font:7.0pt "Times New Roman"'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;Edges&lt;/b&gt;:
Everything that talks about how the network edge of a software system is shaped, designed,
and implemented. SOAP, WSDL, WS-*, IIOP, RMI, DCOM are at home here, along with API
and message design and ideas about coupling, versioning, and interoperability. 
&lt;/p&gt;
&lt;p style='margin-left:.5in;text-indent:-.25in'&gt;
&lt;span style='font-family:Symbol'&gt;&amp;middot;&lt;span style='font:7.0pt "Times New Roman"'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;Protocols:&lt;/b&gt; Which
information do you exchange between two layers of a system or between systems and
how is that communication shaped? What are the communication patterns, what are the
rules of communication? There are low-level protocols that are technically motivated,
there are high-level protocols that are about punting business documents around. Whether
you render a security token as a binary thing in DCOM or as an angle brackets thing
is an edge concern. The fact that you do and when and in which context is a protocol
thing. Each protocol can theoretically be implemented on any type of edge. If you
were completely insane, you could implement TCP on top of SOAP and WS-Addressing and
some other transport. 
&lt;/p&gt;
&lt;p style='margin-left:.5in;text-indent:-.25in'&gt;
&lt;span style='font-family:Symbol'&gt;&amp;middot;&lt;span style='font:7.0pt "Times New Roman"'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;Runtimes:&lt;/b&gt; How
do you implement a protocol? You pick an appropriate runtime, existing class or function
libraries, and a programming language. That&amp;#8217;s an architectural decision, really.
There are good reasons why people pick C#, Java, Visual Basic, or FORTRAN, and not
all of them are purely technical. Technically, the choice of a runtime and language
is orthogonal to the choice of a protocol and the edge technology/design. That&amp;#8217;s
why I list it as another pillar. You could choose to do everything in Itanium assembly
language and start from scratch. Theoretically, nothing stops you from doing that,
it&amp;#8217;s just not very pragmatic. 
&lt;/p&gt;
&lt;p style='margin-left:.5in;text-indent:-.25in'&gt;
&lt;span style='font-family:Symbol'&gt;&amp;middot;&lt;span style='font:7.0pt "Times New Roman"'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;Control
Flow:&lt;/b&gt; For a protocol to work and really for any program to work, you need concepts
like uni- and bidirectional communication and their flavors such as datagrams, sockets,
and queues, which support communication styles such as monologues, dialogues, multicast,
or broadcast. You need to ideas like parallelization and synchronization, and iterations
and sequences. All of these are abstract ideas. You can implement those on any runtime.
They are not dependent on a special edge. They support protocols, but don&amp;#8217;t
require them. Another pillar.
&lt;/p&gt;
&lt;p style='margin-left:.5in;text-indent:-.25in'&gt;
&lt;span style='font-family:Symbol'&gt;&amp;middot;&lt;span style='font:7.0pt "Times New Roman"'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;State:&lt;/b&gt; This
is why we write software (most of it, at least). We write software to transform a
system from one state to the next. Press the trigger button and a monster in Halo
turns into a meatloaf, and you score. Send a message to a banking system and $100.000
change owners. Keeping track of state, keeping it isolated, current, and consistent
or things to consider. Is it ok to have it far away or do you need it close by? Do
you cache, and replicate it for the purpose? Is it reference data or business data?
Consolidated, preprocessed, or raw? How many concurrent clients have access to the
data and how do you deal with the concurrency? All these are questions that have to
do with state, and only state. None of this is depends on having a special technology
that is being talked through way up above at the edge.
&lt;/p&gt;
&lt;p&gt;
Service orientation only speaks about the edge. Its tenets are about loose coupling,
about independent evolution and versioning of contracts, and about technology-agnostic
metadata exchange. All this is important to make systems interoperate better and to
create systems where the effects of changes to one of its parts to any other part
are minimized. 
&lt;/p&gt;
&lt;p&gt;
But none of the SO tenets really speaks about architecture [Sidenote: The &amp;#8220;autonomy&amp;#8221;
is about autonomous development teams and not about autonomous computing]. When you
look at what&amp;#8217;s being advertised as &amp;#8220;serviced oriented architecture&amp;#8221;,
you see either the marketing-glorified repackaging of Ethernet, TCP/IP, and LDAP (&amp;#8220;Enterprise
Service Bus&amp;#8221;), or architectural blueprints that looks strikingly similar to
things that people have been doing for a long time with DCE, CORBA, J2EE, COM, or
mainframe technologies. What&amp;#8217;s different now is that it is easier, cheaper and
likely more productive to create bridges between systems. And even that comes at a
significant price at this point. Realistically, the (web) services stacks yet have
to catch up with these &amp;#8220;proprietary&amp;#8221; stacks in terms of reliability, security,
and performance. 
&lt;/p&gt;
&lt;p&gt;
There is Service Orientation &amp;#8211; and that&amp;#8217;s good. There is appropriate architecture
for a problem solution &amp;#8211; and that&amp;#8217;s good too. These are two things. Combining
the two is excellent. But &amp;#8220;Service Oriented Architecture&amp;#8221; is not an isolated
practice. I&amp;#8217;ve started to use &amp;#8220;SO/A&amp;#8221; to make clear that I mean architecture
that benefits from service orientation.
&lt;/p&gt;
&lt;p&gt;
I understand that there is an additional architectural tier of &amp;#8220;service orientation&amp;#8221;
that sits at the business/technology boundary. On that meta-level, there could indeed
be something like &amp;#8220;service oriented architecture&amp;#8221; along the lines of the
service convergence that Rafal, Pat and myself were &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=14961"&gt;discussing
on stage&lt;/a&gt; at TechEd Europe last year. But when I see or hear SOA discussed, people
speak mostly about technology and software architecture. In that context, selling
&amp;#8220;SOA&amp;#8221; as a completely new software architecture school does not (no longer)
make sense to me.
&lt;/p&gt;
&lt;p&gt;
Or am I missing something?
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=535d4a96-2cc3-4306-8b56-9a96c7c6fa39" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,535d4a96-2cc3-4306-8b56-9a96c7c6fa39.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=c48dd120-cf19-42b8-ad14-39ad3ec1c3e4</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,c48dd120-cf19-42b8-ad14-39ad3ec1c3e4.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,c48dd120-cf19-42b8-ad14-39ad3ec1c3e4.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=c48dd120-cf19-42b8-ad14-39ad3ec1c3e4</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The little series I am currently <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=3a83d7c0-cded-46f7-a6a6-b6450d66fb56">writing
here</a> on my blog has inspired me to write way too more code than actually necessary
to get my point across ;-) So by now I've got my own MSMQ transport for WSE 2.0
(yes, I know that others have written that already, but I am shooting for
a "enterprise strength" implementation), a WebRequest/WebResponse pair to smuggle
under arbitrary ASMX proxies and I am more than halfway done with a server-side host
for MSMQ-to-ASMX (spelled out: ASP.NET Web Services). 
</p>
        <p>
What bugs me is that WSE 2.0's messaging model is "asynchronous only" and that it <em>always</em> performs
a push/pull translation and that there is no way to push a message through to a service
on the receiving thread. Whenever I grab a message from the queue and put it into
my SoapTransport's "Dispatch()" method, the message gets queued up in an in-memory
queue and that is then, on a concurrent thread, pulled (OnReceiveComplete) by the
SoapReceivers collection and submitted into ProcessMessage() of the SoapReceiver (like
any SoapService derived implementation) matching the target endpoint. So while
I can dequeue from MSMQ within a transaction scope (ServiceDomain), that transaction
scope doesn't make it across onto the thread that will actually execute the action
inside the SoapReceiver/SoapService.
</p>
        <p>
So now I am sitting here, contemplating and trying to figure out a workaround that doesn't
require me to rewrite a big chunk of WSE 2.0 (which I am totally not shy
of if that is what it takes). Transaction marshaling, thread synchronization,
ah, I love puzzles. Once I am know how to solve this and have made the adjustments,
I'll post the queue listener I promised to wrap up the series. The other code I've
written in the process will likely surface in some other way.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=c48dd120-cf19-42b8-ad14-39ad3ec1c3e4" />
      </body>
      <title>Push/Pull Translation and Transactions</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,c48dd120-cf19-42b8-ad14-39ad3ec1c3e4.aspx</guid>
      <link>http://vasters.com/clemensv/2004/12/05/PushPull+Translation+And+Transactions.aspx</link>
      <pubDate>Sun, 05 Dec 2004 15:41:21 GMT</pubDate>
      <description>&lt;p&gt;
The little series I am currently &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=3a83d7c0-cded-46f7-a6a6-b6450d66fb56"&gt;writing
here&lt;/a&gt; on my blog has inspired me to write way too more code than actually necessary
to get my point across&amp;nbsp;;-) So by now I've got my own MSMQ transport for WSE 2.0
(yes, I know&amp;nbsp;that others have&amp;nbsp;written that already, but I am shooting for
a "enterprise strength" implementation), a WebRequest/WebResponse pair to smuggle
under arbitrary ASMX proxies and I am more than halfway done with&amp;nbsp;a server-side&amp;nbsp;host
for MSMQ-to-ASMX&amp;nbsp;(spelled out: ASP.NET Web Services). 
&lt;/p&gt;
&lt;p&gt;
What bugs me is that WSE 2.0's messaging model is "asynchronous only" and that&amp;nbsp;it &lt;em&gt;always&lt;/em&gt; performs
a push/pull translation and that there is no way to push a message through to a service
on the receiving thread. Whenever I grab a message from the queue and put it into
my SoapTransport's "Dispatch()" method, the message gets queued up in an in-memory
queue and that is then, on a concurrent thread, pulled (OnReceiveComplete) by the
SoapReceivers collection and submitted into&amp;nbsp;ProcessMessage() of the SoapReceiver&amp;nbsp;(like
any SoapService derived implementation) matching the target endpoint.&amp;nbsp;So while
I can dequeue from MSMQ within a transaction scope (ServiceDomain), that transaction
scope doesn't make it across onto the thread that will actually execute the action
inside the SoapReceiver/SoapService.
&lt;/p&gt;
&lt;p&gt;
So now I am sitting here, contemplating and trying to figure out a workaround that&amp;nbsp;doesn't
require me to&amp;nbsp;rewrite a big chunk of WSE 2.0 (which I am&amp;nbsp;totally not shy
of if that is what it takes).&amp;nbsp;Transaction marshaling, thread synchronization,
ah, I love puzzles. Once I am know how to solve this and have made the adjustments,
I'll post the queue listener I promised to wrap up the series. The other code I've
written in the process will likely surface in some other way.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=c48dd120-cf19-42b8-ad14-39ad3ec1c3e4" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,c48dd120-cf19-42b8-ad14-39ad3ec1c3e4.aspx</comments>
      <category>Technology</category>
      <category>Technology/Enterprise Services</category>
      <category>Technology/MSMQ</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=514bac78-5c4e-4c57-9c15-e7736c83aa1d</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=514bac78-5c4e-4c57-9c15-e7736c83aa1d</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was a little off when I compared <a href="http://staff.newtelligence.net/clemensv/CommentView.aspx?guid=1214e26d-674e-4a5c-b716-eaa07d327705">my
problem here</a> to a tail call. <a href="http://www.eighty-twenty.net/blog/urn:www-eighty-twenty-net:1250.html">Gordon
Weakliem</a> corrected me with the term "continuation".
</p>
        <p>
The fact that the post got 28 comments shows that this seems to be an interesting
problem and, naming aside, it is indeed a tricky thing to implement in a
framework when the programming language you use (C# in my case) doesn't support the
construct. What's specifically tricky about the concrete case that I have
is that I don't know where I am yielding control to at the time when I make the
respective call. 
</p>
        <p>
I'll recap. Assume there is the following call
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">CustomerService cs = <font color="#0000ff">new</font></font>
            </font>
            <font face="Courier New" size="2"> CustomerService();<br /></font>
            <font size="2">
              <font face="Courier New">cs.FindCustomer(customerId);</font>
            </font>
          </font>
        </p>
        <p>
          <em>FindCustomer </em>is a call that will not return any result as a return value.
Instead, the invoked service comes back into the caller's program at some
completely different place such this:
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">[WebMethod]<br />
public<font color="#000000"></font><font color="#0000ff">void</font></font>
            </font>
            <font face="Courier New">
              <font size="2">
                <font color="#000000"> FindCustomerReply(Customer[]
result)<br /></font>{<br />
   ...<br /></font>
            </font>
            <font size="2">
              <font face="Courier New">}</font>
            </font>
          </font>
        </p>
        <p>
So what we have here is a "duplex" conversation. The result of an operation initiated
by an outbound message (call) is received, some time later, through an inbound
message (call), but not on the same thread and not on the same "object". You
could say that this is a callback, but that's not precisely what it is, because a
"callback" usually happens while the initiating call (as above <em>FindCustomer</em>)
has not yet returned back to its scope or at least while the initiating object (or
an object passed by some sort of reference) is still alive. Here, instead, processing
of the <em>FindCustomer</em> call may take a while and the initiating thread and the
initiating object may be long gone when the answer is ready.
</p>
        <p>
Now, the additional issue I have is that at the time when the <em>FindCustomer</em> call
is made, it is not known what "<em>FindCustomerReply</em>" message handler it
going to be processing the result and it is really not know what's happening next.
The decision about what happens next and which handler is chosen is dependent on several
factors, including the time that it takes to receive the result. If the <em>FindCustomer</em> is
called from a web-page and the service providing <em>FindCustomer</em> drops
a result at the caller's doorstep within 2-3 seconds [1], the <em>FindCustomerReply</em> handler can
go and hijack the initial call's thread (and HTTP context) and render a page
showing the result. If the reply takes longer, the web-page (the caller) may lose
its patience [2] and choose to continue by rendering a page that says "We are sending
the result to your email account." and the message handler with not throw HTML into
an HTTP response on an open socket, but rather render it to an email and send
it via SMTP and maybe even alert the user through his/her Instant Messenger when/if
the result arrives.
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">[1] HTTP Request =&gt; </font>
            </font>
            <font size="2">
              <font face="Courier New">FindCustomer()
=?&gt; "<font color="#000000">FindCustomerReply" =&gt; yield to CustomerList.aspx
=&gt; HTTP Response<br /><font color="#003300">[2] HTTP Request =&gt; </font><font size="2"><font face="Courier New"><font color="#003300">FindCustomer()
=?&gt; </font><font color="#000000">Timeout!           
=&gt; yield to YouWillGetMail.aspx =&gt; HTTP Response<br />
                               T+n =?&gt;
"FindCustomerReply" =&gt; SMTP Mail<br />
                                                          
=&gt; IM Notification</font></font></font></font></font>
            </font>
          </font>
        </p>
        <p>
So, in case [1] I need to correlate the reply with the request and continue processing
on the original thread. In case [2], the original thread continues on a
"default path" without an available reply and the reply is processed on (possibly
two) independent threads and using two different notification channels.
</p>
        <p>
A slightly different angle. Consider a workflow application environment in a bank,
where users are assigned tasks and simply fetch the next thing from the to-do
list (by clicking a link in an HTML-rendered list). The reply that results from "<em>LookupAndDoNextTask</em>" is
a message that contains the job that the user is supposed to do.  
</p>
        <p>
          <font face="Courier New">[1] HTTP Request =&gt; LookupAndDoNextTask<font size="2">()
=?&gt; Job: "<font color="#000000">Call Customer" =&gt; yield to CallCustomer.aspx =&gt;
HTTP Response<br /></font></font></font>
          <font face="Courier New">[2] HTTP Request =&gt; LookupAndDoNextTask<font size="2">()
=?&gt; Job: "<font color="#000000">Review Credit Offer" =&gt; yield to ReviewCredit.aspx =&gt;
HTTP Response<br /><font color="#003300">[3] HTTP Request =&gt; LookupAndDoNextTask</font><font size="2"><font color="#003300">()
=?&gt; Job: "</font><font color="#000000">Approve Mortgage" =&gt; yield to ApproveMortgage.aspx =&gt;
HTTP Response<br /><font color="#003300">[4] HTTP Request =&gt; LookupAndDoNextTask</font><font size="2"><font color="#003300">()
=?&gt; No Job / Timeout</font><font color="#000000"> =&gt; yield to Solitaire.aspx =&gt;
HTTP Response</font></font></font></font></font></font></font>
        </p>
        <p>
In all of these cases, calls to "FindCustomer()" and "LookupAndDoTask()" that are
made from the code that deals with the incoming request will (at least in the theoretical
model) never return to their caller and the thread will continue to execute in a different
context that is "TBD" at the time of the call. By the time the call stack is
unwound and the initiating call (like FindCustomer) indeed returns, the request
is therefore fully processed and the caller may not perform any further
actions. 
</p>
        <p>
So the issue at hand is to make that fact clear in the programming model. In ASP.NET,
there is a single construct called "Server.Transfer()" for that sort of continuation,
but it's very specific to ASP.NET and requires that the caller knows where you want
to yield control to. In the case I have here, the caller knows that it is surrendering
the thread to some other handler, but it doesn't know to to whom, because this is
dynamically determined by the underlying frameworks. All that's visible and should
be visible in the code is a "normal" method call.
</p>
        <p>
          <font size="4">
            <font size="2">
              <font face="Courier New">cs.FindCustomer(customerId) </font>
              <font face="Verdana">might
therefore not be a good name, because it looks "too normal". And of course I
don't have the powers to invent a new statement for the C# language
like </font>
              <font face="Courier New">
                <strong>continue(</strong>cs.FindCustomer(customerId)<strong>)</strong></font>
              <font face="Verdana"> that
would result in a continuation that simply doesn't return to the call location. Since
I can't do that, there has to be a different way to flag it. Sure, I could put an
attribute on the method, but Intellisense wouldn't show that, would it? So it seems
the best way is to have a convention of prefixing the method name.</font>
            </font>
          </font>
        </p>
        <p>
There were a bunch of ideas in the comments for method-name prefixes. Here is a selection: 
</p>
        <ul>
          <li>
            <font face="Courier New">cs.InitiateFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.YieldFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.YieldToFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.InjectFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.PlaceRequestFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.PostRequestFindCustomer(customerId)</font>
          </li>
        </ul>
        <p>
I've got most of the underlying correlation and dispatch infrastructure
sitting here, but finding a good programming model for that sort of behavior
is quite difficult. 
</p>
        <p>
          <em>[Of course, this post won't make it on Microsoft Watch, eWeek or The
Register]</em>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=514bac78-5c4e-4c57-9c15-e7736c83aa1d" />
      </body>
      <title>Naming and Continuations (continued)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</guid>
      <link>http://vasters.com/clemensv/2004/07/21/Naming+And+Continuations+Continued.aspx</link>
      <pubDate>Wed, 21 Jul 2004 08:24:16 GMT</pubDate>
      <description>&lt;p&gt;
I&amp;nbsp;was a little off&amp;nbsp;when I&amp;nbsp;compared&amp;nbsp;&lt;a href="http://staff.newtelligence.net/clemensv/CommentView.aspx?guid=1214e26d-674e-4a5c-b716-eaa07d327705"&gt;my
problem here&lt;/a&gt; to a tail call. &lt;a href="http://www.eighty-twenty.net/blog/urn:www-eighty-twenty-net:1250.html"&gt;Gordon
Weakliem&lt;/a&gt; corrected me with the term "continuation".
&lt;/p&gt;
&lt;p&gt;
The fact that the post got 28 comments shows that this seems to be an interesting
problem and, naming aside, it&amp;nbsp;is indeed a tricky thing to&amp;nbsp;implement in a
framework when the programming language you use (C# in my case) doesn't support the
construct.&amp;nbsp;What's specifically tricky about the&amp;nbsp;concrete case that I have
is that I don't&amp;nbsp;know where I am yielding control to at the time when I make the
respective call. 
&lt;/p&gt;
&lt;p&gt;
I'll recap. Assume there is the following call
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;CustomerService&amp;nbsp;cs = &lt;font color=#0000ff&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; CustomerService();&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;cs.FindCustomer(customerId);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;FindCustomer &lt;/em&gt;is a&amp;nbsp;call that will not return any result as a return value.
Instead,&amp;nbsp;the invoked service&amp;nbsp;comes back into the caller's program at some
completely different place such this:
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;[WebMethod]&lt;br&gt;
public&lt;font color=#000000&gt; &lt;/font&gt;&lt;font color=#0000ff&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; FindCustomerReply(Customer[]
result)&lt;br&gt;
&lt;/font&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp; ...&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So what we have here is a "duplex" conversation. The result of an operation initiated
by an outbound&amp;nbsp;message (call) is received, some time later,&amp;nbsp;through an inbound
message&amp;nbsp;(call), but not on the same thread and not on the same "object".&amp;nbsp;You
could say that this is a callback, but that's not precisely what it is, because&amp;nbsp;a
"callback" usually happens&amp;nbsp;while the&amp;nbsp;initiating call (as above &lt;em&gt;FindCustomer&lt;/em&gt;)
has not yet returned back to its scope or at least while the initiating object (or
an object passed by some sort of reference) is still alive.&amp;nbsp;Here, instead,&amp;nbsp;processing
of the &lt;em&gt;FindCustomer&lt;/em&gt; call may take a while and the initiating thread and the
initiating object may be long gone when the answer is ready.
&lt;/p&gt;
&lt;p&gt;
Now, the additional issue I have is that at the time when the &lt;em&gt;FindCustomer&lt;/em&gt; call
is made, it is not&amp;nbsp;known what "&lt;em&gt;FindCustomerReply&lt;/em&gt;" message handler it
going to be processing the result and it is really not know what's happening next.
The decision about what happens next and which handler is chosen is dependent on several
factors, including the time that it takes to receive the result. If the &lt;em&gt;FindCustomer&lt;/em&gt; is
called from a web-page and the service providing &lt;em&gt;FindCustomer&lt;/em&gt;&amp;nbsp;drops
a result at the caller's doorstep within 2-3 seconds [1], the &lt;em&gt;FindCustomerReply&lt;/em&gt; handler&amp;nbsp;can
go and&amp;nbsp;hijack the initial call's thread (and HTTP context) and render a page
showing the result. If the reply takes longer, the web-page (the caller) may lose
its patience [2] and choose to continue by rendering a page that says "We are sending
the result to your email account." and the message handler with not throw HTML into
an&amp;nbsp;HTTP response on an open socket, but rather render it to an email and send
it via SMTP and maybe even alert the user through his/her Instant Messenger&amp;nbsp;when/if
the result arrives.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;[1] HTTP Request =&amp;gt; &lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;FindCustomer()
=?&amp;gt; "&lt;font color=#000000&gt;FindCustomerReply" =&amp;gt; yield to CustomerList.aspx =&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[2] HTTP Request =&amp;gt; &lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;&lt;font color=#003300&gt;FindCustomer()
=?&amp;gt; &lt;/font&gt;&lt;font color=#000000&gt;Timeout!&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
=&amp;gt; yield to YouWillGetMail.aspx =&amp;gt; HTTP Response&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T+n&amp;nbsp;=?&amp;gt;
"FindCustomerReply" =&amp;gt; SMTP Mail&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
=&amp;gt; IM Notification&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So, in case [1] I need to correlate the reply with the request and&amp;nbsp;continue processing
on the original thread. In&amp;nbsp;case [2], the original thread continues&amp;nbsp;on&amp;nbsp;a
"default path"&amp;nbsp;without an available reply and the reply is processed on (possibly
two) independent threads and using two different notification channels.
&lt;/p&gt;
&lt;p&gt;
A slightly different angle. Consider a workflow application environment in a bank,
where users are assigned tasks and simply fetch the next thing&amp;nbsp;from the to-do
list (by clicking a link in an HTML-rendered list). The reply that results from "&lt;em&gt;LookupAndDoNextTask&lt;/em&gt;"&amp;nbsp;is
a message that contains the job that the user is supposed to do. &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;[1] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;font size=2&gt;()
=?&amp;gt; Job: "&lt;font color=#000000&gt;Call Customer" =&amp;gt; yield to CallCustomer.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;[2] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;font size=2&gt;()
=?&amp;gt; Job: "&lt;font color=#000000&gt;Review Credit Offer" =&amp;gt; yield to ReviewCredit.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[3] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#003300&gt;()
=?&amp;gt; Job: "&lt;/font&gt;&lt;font color=#000000&gt;Approve Mortgage" =&amp;gt; yield to ApproveMortgage.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[4] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#003300&gt;()
=?&amp;gt;&amp;nbsp;No Job / Timeout&lt;/font&gt;&lt;font color=#000000&gt;&amp;nbsp;=&amp;gt; yield to Solitaire.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
In all of these cases, calls to "FindCustomer()" and "LookupAndDoTask()" that are
made from the code that deals with the incoming request will (at least in the theoretical
model) never return to their caller and the thread will continue to execute in a different
context that is&amp;nbsp;"TBD" at the time of the call. By the time the call stack is
unwound and the&amp;nbsp;initiating call (like FindCustomer) indeed returns, the request
is therefore fully processed and the caller&amp;nbsp;may not&amp;nbsp;perform any further
actions.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So the issue at hand is to make that fact clear in the programming model. In ASP.NET,
there is a single construct called "Server.Transfer()" for that sort of continuation,
but it's very specific to ASP.NET and requires that the caller knows where you want
to yield control to.&amp;nbsp;In the case I have here, the caller knows that it is surrendering
the thread to some other handler, but it doesn't know to to whom, because this is
dynamically determined by the underlying frameworks. All that's visible and should
be visible in the code is a "normal" method call.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;cs.FindCustomer(customerId)&amp;nbsp;&lt;/font&gt;&lt;font face=Verdana&gt;might
therefore not be a good name, because&amp;nbsp;it looks "too normal". And of course I
don't have the powers to&amp;nbsp;invent a new&amp;nbsp;statement&amp;nbsp;for the C# language
like&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;continue(&lt;/strong&gt;cs.FindCustomer(customerId)&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font face=Verdana&gt;&amp;nbsp;that
would result in a continuation that simply doesn't return to the call location. Since
I can't do that, there has to be a different way to flag it. Sure, I could put an
attribute on the method, but Intellisense wouldn't show that, would it? So it seems
the best way is to have a convention of prefixing the method name.&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
There were a bunch of ideas in the comments for method-name prefixes. Here is a selection: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.InitiateFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.YieldFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.YieldToFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.InjectFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.PlaceRequestFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.PostRequestFindCustomer(customerId)&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I've got most of the&amp;nbsp;underlying&amp;nbsp;correlation and dispatch infrastructure
sitting here, but finding a good&amp;nbsp;programming model for that sort of behavior
is quite difficult. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;[Of course, this post won't make it on Microsoft Watch,&amp;nbsp;eWeek&amp;nbsp;or The
Register]&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=514bac78-5c4e-4c57-9c15-e7736c83aa1d" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</comments>
      <category>Architecture</category>
      <category>Architecture/SOA</category>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=7eb75a87-bfaa-4ec1-b496-f2c59bc06777</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,7eb75a87-bfaa-4ec1-b496-f2c59bc06777.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,7eb75a87-bfaa-4ec1-b496-f2c59bc06777.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=7eb75a87-bfaa-4ec1-b496-f2c59bc06777</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Achim and myself are currently in a series of very quick rev-cycles for the
first public release of the Microsoft/newtelligence <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=b1d34986-f53b-49c1-a56b-81c5fc042f32">FABRIQ</a> project
that we did with and for Microsoft EMEA HQ and that was conceived,
driven and brillantly managed by my architect colleague <a href="http://msdn.microsoft.com/architecture/community/newsletter/default.aspx#Profile">Arvindra
Sehmi</a>, who gave me the lead architect role for this project.
</p>
        <p>
[<em>Reminder/Disclaimer: this is not a product, but rather a pretty elaborate "how-to"
architecture example that comes with an implementation. Hence it's not a supported
Microsoft or newtelligence "framework" or an attempt at some general, definitive
guidance on how to write services. FABRIQ is an optimized architecture for fast, one-way,
message processing within network-distributed nodes consisting of sequences
of dynamically composed primitive processing steps. This isn't even trying to get
anywhere near the guidance aspirations of <a href="http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=9c29a963-594e-4e7a-9c45-576198df8058">Shadowfax</a>,
or let alone <a href="http://blogs.msdn.com/richturner666/archive/2004/03/05/84834.aspx">all
the</a><a href="http://msdn.microsoft.com/longhorn/understanding/pillars/indigo/migratevideo/">guidance </a>we're
getting from the <a href="http://msdn.microsoft.com/Longhorn/understanding/pillars/Indigo/default.aspx">Indigo</a> team
or even the parallel work I've been doing for MS by building <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=68872086-b344-431b-a6fa-9b358aa386e1">Proseware</a>.</em>]
</p>
        <p>
We've settled on build 1.0.4173 (yesterday) to be the TechEd version, but we still
found a last minute issue where we weren't using WSE 2.0 correctly (not
setting the SoapEnvelope.Context.Destination property for use with a bare WSE2 Pipeline in
the presence of policy) and when I reassembled the distribution I didn't reset
an option that I use for debugging on my machine and that caused installation hiccups over
at Achim's machine. Achim commented the hour-long bug hunt with "Ah, you gotta love
software!". 
</p>
        <p>
There will be <strong>hands-on labs</strong> at TechEd Europe led by Achim and Jörg
that let you play with what we (very much including our friends at Microsoft Argentina
and Microsoft EMEA) have built. And even if you don't have a proper use
for a one-way queuing network architecture, it actually turned into a fun thing
to play with. 
</p>
        <p>
I'll be starting to explain aspects of the spec over the upcoming days and will explain
how the architecture works, how you configure it and what its potential
uses are. Already posted is some relevant information about the great idea
of an <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=4eda9fe7-e36e-4e64-b170-2f29a88621dd">XmlReader-based
message design</a> (which I designed inspired by the Indigo PDC
build) and our use of <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=45606a61-10a0-4790-8938-be3c22787a35">lightweight
transactions</a>. 
</p>
        <p>
I am in the boot phase for the next software project right now (proprietary work)
and I have identified very many good uses for the FABRIQ model in there already (<a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=154">hint</a>).
</p>
        <p>
Once all parties involved are giving their "thumbs up", we'll also make the source
code drop and the binaries available to the public (you) and from there we're looking
forward to your input (and contributions?).
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7eb75a87-bfaa-4ec1-b496-f2c59bc06777" />
      </body>
      <title>Wrapping up the FABRIQ</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,7eb75a87-bfaa-4ec1-b496-f2c59bc06777.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/22/Wrapping+Up+The+FABRIQ.aspx</link>
      <pubDate>Tue, 22 Jun 2004 07:34:36 GMT</pubDate>
      <description>&lt;p&gt;
Achim and myself are&amp;nbsp;currently in a series of very quick rev-cycles for&amp;nbsp;the
first public release of the Microsoft/newtelligence &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=b1d34986-f53b-49c1-a56b-81c5fc042f32"&gt;FABRIQ&lt;/a&gt; project
that we did with and for&amp;nbsp;Microsoft&amp;nbsp;EMEA HQ&amp;nbsp;and that was conceived,
driven&amp;nbsp;and brillantly managed by&amp;nbsp;my architect colleague&amp;nbsp;&lt;a href="http://msdn.microsoft.com/architecture/community/newsletter/default.aspx#Profile"&gt;Arvindra
Sehmi&lt;/a&gt;, who gave me the lead architect role for this project.
&lt;/p&gt;
&lt;p&gt;
[&lt;em&gt;Reminder/Disclaimer: this is not a product, but rather a pretty elaborate "how-to"
architecture example that comes with an implementation.&amp;nbsp;Hence it's not a supported
Microsoft or newtelligence "framework" or an attempt at some&amp;nbsp;general, definitive
guidance on how to write services. FABRIQ is an optimized architecture for fast, one-way,
message processing&amp;nbsp;within network-distributed&amp;nbsp;nodes consisting of&amp;nbsp;sequences
of dynamically composed primitive processing steps. This isn't even trying to get
anywhere near the guidance aspirations of &lt;a href="http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=9c29a963-594e-4e7a-9c45-576198df8058"&gt;Shadowfax&lt;/a&gt;,
or let alone &lt;a href="http://blogs.msdn.com/richturner666/archive/2004/03/05/84834.aspx"&gt;all
the&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/longhorn/understanding/pillars/indigo/migratevideo/"&gt;guidance &lt;/a&gt;we're
getting from the&amp;nbsp;&lt;a href="http://msdn.microsoft.com/Longhorn/understanding/pillars/Indigo/default.aspx"&gt;Indigo&lt;/a&gt;&amp;nbsp;team
or even the parallel work I've been doing for&amp;nbsp;MS by building &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=68872086-b344-431b-a6fa-9b358aa386e1"&gt;Proseware&lt;/a&gt;.&lt;/em&gt;]
&lt;/p&gt;
&lt;p&gt;
We've settled on build 1.0.4173 (yesterday) to be the TechEd version, but we still
found&amp;nbsp;a last minute&amp;nbsp;issue where we weren't using WSE 2.0 correctly (not
setting the SoapEnvelope.Context.Destination property for use with a bare WSE2 Pipeline&amp;nbsp;in
the presence of&amp;nbsp;policy) and when I reassembled the distribution I didn't reset
an option that I use for debugging on my machine and that caused installation hiccups&amp;nbsp;over
at&amp;nbsp;Achim's machine. Achim commented the hour-long bug hunt with "Ah, you gotta&amp;nbsp;love
software!". 
&lt;/p&gt;
&lt;p&gt;
There will be &lt;strong&gt;hands-on labs&lt;/strong&gt; at TechEd Europe led by Achim and J&amp;#246;rg
that let you play with what we (very much including our friends at Microsoft Argentina
and Microsoft EMEA)&amp;nbsp;have built. And&amp;nbsp;even if you don't have a proper use
for a one-way queuing network architecture, it actually turned into a fun&amp;nbsp;thing
to play with.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I'll be starting to explain aspects of the spec over the upcoming days and will explain
how the&amp;nbsp;architecture&amp;nbsp;works, how you configure it&amp;nbsp;and what its potential
uses are. Already posted is some relevant information about&amp;nbsp;the&amp;nbsp;great idea
of an &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=4eda9fe7-e36e-4e64-b170-2f29a88621dd"&gt;XmlReader-based
message design&lt;/a&gt;&amp;nbsp;(which I&amp;nbsp;designed&amp;nbsp;inspired by&amp;nbsp;the Indigo PDC
build) and our use of &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=45606a61-10a0-4790-8938-be3c22787a35"&gt;lightweight
transactions&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
I am in the boot phase for the next software project right now (proprietary work)
and I have identified very many good uses for the FABRIQ model in there already (&lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=154"&gt;hint&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Once all parties involved are giving&amp;nbsp;their "thumbs up", we'll also make the source
code drop and the binaries available to the public (you) and from there we're looking
forward to your input (and contributions?).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7eb75a87-bfaa-4ec1-b496-f2c59bc06777" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,7eb75a87-bfaa-4ec1-b496-f2c59bc06777.aspx</comments>
      <category>Architecture</category>
      <category>Talks/TechEd Europe</category>
      <category>Technology</category>
      <category>Technology/FABRIQ</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=cc228a09-d9f2-4629-8f58-97025aca1366</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,cc228a09-d9f2-4629-8f58-97025aca1366.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,cc228a09-d9f2-4629-8f58-97025aca1366.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=cc228a09-d9f2-4629-8f58-97025aca1366</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You read it here first. Kimberly Tripp <a href="http://www.sqlskills.com/blogs/kimberly">blogs</a> (<a href="http://www.sqlskills.com/blogs/kimberly/rss.ashx">rss</a>).
If you do anything with SQL Server: Subscribe! 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=cc228a09-d9f2-4629-8f58-97025aca1366" />
      </body>
      <title>The SQL Goddess Blogs</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,cc228a09-d9f2-4629-8f58-97025aca1366.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/08/The+SQL+Goddess+Blogs.aspx</link>
      <pubDate>Tue, 08 Jun 2004 20:05:35 GMT</pubDate>
      <description>&lt;p&gt;
You&amp;nbsp;read it here first.&amp;nbsp;Kimberly Tripp &lt;a href="http://www.sqlskills.com/blogs/kimberly"&gt;blogs&lt;/a&gt; (&lt;a href="http://www.sqlskills.com/blogs/kimberly/rss.ashx"&gt;rss&lt;/a&gt;).
If you do anything with SQL Server: Subscribe! 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=cc228a09-d9f2-4629-8f58-97025aca1366" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,cc228a09-d9f2-4629-8f58-97025aca1366.aspx</comments>
      <category>Blog</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=2639bfcf-a32a-4326-b49e-0ebd919d1675</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,2639bfcf-a32a-4326-b49e-0ebd919d1675.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,2639bfcf-a32a-4326-b49e-0ebd919d1675.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=2639bfcf-a32a-4326-b49e-0ebd919d1675</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft urgently needs to consolidate all the APIs that are required for provisioning
services or sites. The amount of knowledge you need to have and the number APIs you
need to use in order to lock down a Web service or Enterprise Services application
programmatically at installation time in order to have it run under an isolated
user account (with a choice of local or domain account) that has the precise rights
to do what it needs to do (but nothing else) is absolutely insane. 
</p>
        <p>
You need to set ACLs on the file system and the registry, you need to modify the local
machine's security policy, you need to create accounts and add them to local groups,
you must adhere to password policies with your auto-generated passwords, you need
to conbfigure identities on Enterprise Services applications and IIS application pools,
you need to set ACLs on Message Queues (if you use them), and you need to write WS-Policy
documents to secure your WS front. Every single of these tasks uses a different API
(and writing policies has none) and most of these jobs require explicit Win32
or COM interop. I have a complete wrapper for that functionality for my app now (which
took way too long to write), but that really needs to be fixed on a platform level.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=2639bfcf-a32a-4326-b49e-0ebd919d1675" />
      </body>
      <title>Secure deployment is just too hard, Microsoft</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,2639bfcf-a32a-4326-b49e-0ebd919d1675.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/07/Secure+Deployment+Is+Just+Too+Hard+Microsoft.aspx</link>
      <pubDate>Mon, 07 Jun 2004 09:45:52 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft urgently needs to consolidate all the APIs that are required for provisioning
services or sites. The amount of knowledge you need to have and the number APIs you
need to use in order to lock down a Web service or Enterprise Services application
programmatically at installation time&amp;nbsp;in order to&amp;nbsp;have it run under an isolated
user account (with a choice of local or domain account) that has the precise rights
to do what it needs to do (but nothing else) is absolutely insane.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
You need to set ACLs on the file system and the registry, you need to modify the local
machine's security policy, you need to create accounts and add them to local groups,
you must adhere to password policies with your auto-generated passwords, you need
to conbfigure identities on Enterprise Services applications and IIS application pools,
you need to set ACLs on Message Queues (if you use them), and you need to write WS-Policy
documents to secure your WS front. Every single of these tasks uses a different API
(and writing policies has none) and most of these jobs&amp;nbsp;require explicit Win32
or COM interop. I have a complete wrapper for that functionality for my app now (which
took way too long to write), but that really needs to be fixed on a platform level.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=2639bfcf-a32a-4326-b49e-0ebd919d1675" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,2639bfcf-a32a-4326-b49e-0ebd919d1675.aspx</comments>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
      <category>Technology/Enterprise Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's inevitable, its security improvements are absolutely necessary and it might break
your code. I would strongly suggest that you install a test box with XP SP2 now if
you haven't already done so. I've had some interesting surprises today.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5" />
      </body>
      <title>XP SP2 is the Y2K of Windows</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/05/XP+SP2+Is+The+Y2K+Of+Windows.aspx</link>
      <pubDate>Sat, 05 Jun 2004 17:07:37 GMT</pubDate>
      <description>&lt;p&gt;
It's inevitable, its security improvements are absolutely necessary and it might break
your code. I would strongly suggest that you install a test box with XP SP2 now if
you haven't already done so. I've had some interesting surprises today.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,0a7b5d89-d0b1-41eb-9e15-dcc8637e96a5.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=acb494ba-0297-4713-b091-6b4ab1324be7</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,acb494ba-0297-4713-b091-6b4ab1324be7.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,acb494ba-0297-4713-b091-6b4ab1324be7.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=acb494ba-0297-4713-b091-6b4ab1324be7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you are even nearly as ignorant as every other developer including myself about any
administrative aspect of SQL Server 2000 beyond the default install, <a href="http://www.microsoft.com/downloads/details.aspx?displayla%20ng=en&amp;familyid=B352EB1F-D3CA-44EE-893E-9E07339C1F22&amp;displaylang=en">this
tool may be for you</a>. I just installed it and I hate the tool already for what
it tells me. Good sign.  (Thanks to still-blogless SQL Goddess <a href="http://www.sqlskills.com">Kimberly
Tripp</a> for the link)
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=acb494ba-0297-4713-b091-6b4ab1324be7" />
      </body>
      <title>SQL Server Best Practices Analyzer</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,acb494ba-0297-4713-b091-6b4ab1324be7.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/03/SQL+Server+Best+Practices+Analyzer.aspx</link>
      <pubDate>Thu, 03 Jun 2004 17:55:07 GMT</pubDate>
      <description>&lt;p&gt;
If you are even nearly as ignorant as every other developer including myself about&amp;nbsp;any
administrative aspect of&amp;nbsp;SQL Server 2000 beyond the default install, &lt;a href="http://www.microsoft.com/downloads/details.aspx?displayla%20ng=en&amp;amp;familyid=B352EB1F-D3CA-44EE-893E-9E07339C1F22&amp;amp;displaylang=en"&gt;this
tool may be for you&lt;/a&gt;. I just installed it and I hate the tool already for what
it tells me. Good sign.&amp;nbsp; (Thanks to still-blogless SQL Goddess &lt;a href="http://www.sqlskills.com"&gt;Kimberly
Tripp&lt;/a&gt; for the link)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=acb494ba-0297-4713-b091-6b4ab1324be7" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,acb494ba-0297-4713-b091-6b4ab1324be7.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=896f4b48-2189-49f6-83b1-1b9d0e691ef8</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,896f4b48-2189-49f6-83b1-1b9d0e691ef8.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,896f4b48-2189-49f6-83b1-1b9d0e691ef8.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=896f4b48-2189-49f6-83b1-1b9d0e691ef8</wfw:commentRss>
      <slash:comments>10</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.neward.net/ted/weblog/index.jsp?date=20040601#1086154951687">Ted
Neward</a> has a crusade against DataSets going on on his blog. At this point in time,
I really only ever use them <strong>inside a service</strong> and only at times when
I am horribly lazy or when I code under the influence. Otherwise I just go through
the rather quick and mostly painless process of mapping plain data structures (generated
from schema) to and from stored procedure calls myself. More control, more interoperability,
less weight. I really like when my code precisely states how my app interacts
with one of the most important components: the data store.
</p>
        <p>
I don't even use DataSets on ASP.NET web pages anymore. The data binding logic allows
to bind against <em>anything</em> and if I have a public or protected property
"Customer" on my page class that is a data structure, I can simply have an expression
like &lt;%# Customer.Name %&gt; on my page and all is good. Likewise, a DataGrid
happily binds against anything that is an ICollection (Array, ArrayList, ...) and
the DataGridItem.DataItem property will then contain the individual element.  It's
just that the design-time support in VS.NET is very DataSet focused and messes
things up when you click the wrong things. 
</p>
        <p>
DataSets are really cool for Windows Forms apps. By now I've reached a point
where I simply conclude that the DataSet class should be banned from the server-side.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=896f4b48-2189-49f6-83b1-1b9d0e691ef8" />
      </body>
      <title>DataSet -- Taking a stance.</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,896f4b48-2189-49f6-83b1-1b9d0e691ef8.aspx</guid>
      <link>http://vasters.com/clemensv/2004/06/02/DataSet+Taking+A+Stance.aspx</link>
      <pubDate>Wed, 02 Jun 2004 08:46:07 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.neward.net/ted/weblog/index.jsp?date=20040601#1086154951687"&gt;Ted
Neward&lt;/a&gt; has a crusade against DataSets going on on his blog. At this point in time,
I really only ever use them &lt;strong&gt;inside a service&lt;/strong&gt; and only at times when
I am horribly lazy or when I code under the influence. Otherwise I just go through
the rather quick and mostly painless process of mapping plain data structures (generated
from schema) to and from stored procedure calls myself. More control, more interoperability,
less weight. I really like when my code precisely states&amp;nbsp;how my app interacts
with one of the most important components: the data store.
&lt;/p&gt;
&lt;p&gt;
I don't even use DataSets on ASP.NET web pages anymore. The data binding logic allows
to bind against &lt;em&gt;anything&lt;/em&gt;&amp;nbsp;and if I have a public or protected property
"Customer" on my page class that is a data structure, I can simply have an expression
like &amp;lt;%# Customer.Name %&amp;gt;&amp;nbsp;on my page and all is good. Likewise, a DataGrid
happily binds against anything that is an ICollection (Array, ArrayList, ...) and
the DataGridItem.DataItem property will then contain the&amp;nbsp;individual element.&amp;nbsp;&amp;nbsp;It's
just that the design-time support in VS.NET is very DataSet focused and&amp;nbsp;messes
things up when you click the wrong things.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
DataSets are really cool for&amp;nbsp;Windows Forms apps. By now I've reached a point
where I simply conclude that the DataSet class should be banned from the server-side.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=896f4b48-2189-49f6-83b1-1b9d0e691ef8" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,896f4b48-2189-49f6-83b1-1b9d0e691ef8.aspx</comments>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=f0a763b9-2e24-44be-9245-b615e1057407</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,f0a763b9-2e24-44be-9245-b615e1057407.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,f0a763b9-2e24-44be-9245-b615e1057407.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=f0a763b9-2e24-44be-9245-b615e1057407</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's rare that I give "must have" tool recommendations, but here is one: If you do
any regular expressions work with the .NET Framework, go and get <a href="http://weblogs.asp.net/rosherove/">Roy
Osherove</a>'s <a href="http://royo.is-a-geek.com/iserializable/regulator/">Regulator</a>.
Roy consolidated a lot of the best things from various free regex tools and added
his own wizardry into a pretty cool "RegEx IDE".
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=f0a763b9-2e24-44be-9245-b615e1057407" />
      </body>
      <title>The Regulator</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,f0a763b9-2e24-44be-9245-b615e1057407.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/19/The+Regulator.aspx</link>
      <pubDate>Wed, 19 May 2004 21:51:48 GMT</pubDate>
      <description>&lt;p&gt;
It's rare that I give "must have" tool recommendations, but here is one: If you do
any regular expressions&amp;nbsp;work with the .NET Framework, go and get &lt;a href="http://weblogs.asp.net/rosherove/"&gt;Roy
Osherove&lt;/a&gt;'s &lt;a href="http://royo.is-a-geek.com/iserializable/regulator/"&gt;Regulator&lt;/a&gt;.
Roy consolidated a lot of the best&amp;nbsp;things from various free regex tools and added
his own wizardry into a pretty cool "RegEx IDE".
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=f0a763b9-2e24-44be-9245-b615e1057407" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,f0a763b9-2e24-44be-9245-b615e1057407.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=4dac8a1e-b7dd-4aba-aa02-01c1961881cc</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,4dac8a1e-b7dd-4aba-aa02-01c1961881cc.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,4dac8a1e-b7dd-4aba-aa02-01c1961881cc.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=4dac8a1e-b7dd-4aba-aa02-01c1961881cc</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://weblogs.asp.net/dburke/archive/2004/05/17/133453.aspx">This here</a> reminds
me of the box that's quietly humming in my home office and serves as my domain controller,
firewall, RAS and DSL gateway. I upgraded the machine (a rather old 400 MHz Compaq)
to Windows Server 2003 the day before I flew to TechEd Malaysia last
year (August 23rd, 2003). I configured it to auto-update from Windows Update and reboot
at 3:00AM in case updates have been applied. 
</p>
        <p>
Guess what: I got back home from that trip (which included 4 days touring the Angkor
temples in Cambodia and another 10 days hanging out at the beach on Thailand's
Ko Samui island) and realized that I forgot the Administrator password. Tried to get
in to no avail. I've got rebuilding the box on my task list, but there's no
rush. I haven't really touched or switched off the machine ever since. It
keeps patching itself every once in a while and otherwise simply does its job.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4dac8a1e-b7dd-4aba-aa02-01c1961881cc" />
      </body>
      <title>The forgotten Windows Server 2003</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,4dac8a1e-b7dd-4aba-aa02-01c1961881cc.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/17/The+Forgotten+Windows+Server+2003.aspx</link>
      <pubDate>Mon, 17 May 2004 20:21:22 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://weblogs.asp.net/dburke/archive/2004/05/17/133453.aspx"&gt;This here&lt;/a&gt; reminds
me of the box that's quietly humming in my home office and serves as my domain controller,
firewall, RAS&amp;nbsp;and DSL gateway. I upgraded the machine (a rather old 400 MHz Compaq)
to Windows Server 2003&amp;nbsp;the day&amp;nbsp;before I&amp;nbsp;flew to TechEd Malaysia last
year (August 23rd, 2003). I configured it to auto-update from Windows Update and reboot
at 3:00AM in case updates have been applied. 
&lt;/p&gt;
&lt;p&gt;
Guess what: I got back home from that trip (which included 4 days touring the Angkor
temples in Cambodia and another 10 days hanging out at the beach&amp;nbsp;on Thailand's
Ko Samui island) and realized that I forgot the Administrator password. Tried to get
in to no avail. I've got rebuilding the box on my task list, but&amp;nbsp;there's&amp;nbsp;no
rush.&amp;nbsp;I haven't really touched or switched off the&amp;nbsp;machine ever since. It
keeps patching itself every once in a while and otherwise simply does its job.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4dac8a1e-b7dd-4aba-aa02-01c1961881cc" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,4dac8a1e-b7dd-4aba-aa02-01c1961881cc.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
I am not a “smart client” programmer and probably not even a smart client
programmer and this trick has probably been around for ages, but …
</p>
          <p>
For someone who’s been doing WPARAM and LPARAM acrobatics for years and still
vividly recalls what (not necessarily good) you can do with WM NCPAINT and WM NCMOUSEMOVE
(all that before I discovered the blessings of the server-side), it’s pretty
annoying that Windows Forms doesn’t bubble events – mouse events specifically.
It is actually hard to believe that that wouldn’t work. But I’ve read
somewhere that bubbling events is “new in Whidbey”, so it is probably
not my ignorance. Anyways … include the following snippet in your form (add
MouseDown, MouseUp, … variants at your leisure), bind the respective events
of all labels, panels and all the other “dead stuff” to this very handler
(yes, all the controls share that handler) and that’ll have the events bubble
up to your form in case you need them. I am just implementing custom resizing and
repositioning for some user controls in a little tool and that’s how I got trapped
into this. Voilá. Keep it.
</p>
          <p>
 
</p>
          <p class="MsoNormal">
            <span style="font-size:10.0pt;font-family:&quot;Lucida Console&quot;;&#xD;&#xA;color:blue">protected</span>
            <span style="font-size:10.0pt;font-family:&quot;Lucida Console&quot;">
              <span style="color:blue">void</span> BubbleMouseMove(<span style="color:blue">object</span> sender,
System.Windows.Forms.MouseEventArgs e)<br />
{<br />
Point pt = <span style="color:blue">this</span>.PointToClient(((Control)sender).PointToScreen(<span style="color:blue">new</span> Point(e.X,e.Y)));<br />
MouseEventArgs me = <span style="color:blue">new</span> MouseEventArgs(e.Button,e.Clicks,pt.X,pt.Y,e.Delta);<br />
OnMouseMove(sender,me);<br />
}<br /><br /></span>
          </p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55" />
      </body>
      <title>Bubbling Mouse Events in Windows Forms</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/17/Bubbling+Mouse+Events+In+Windows+Forms.aspx</link>
      <pubDate>Mon, 17 May 2004 19:13:42 GMT</pubDate>
      <description>

&lt;div class=Section1&gt;
&lt;p&gt;
I am not a &amp;#8220;smart client&amp;#8221; programmer and probably not even a smart client
programmer and this trick has probably been around for ages, but &amp;#8230;
&lt;/p&gt;
&lt;p&gt;
For someone who&amp;#8217;s been doing WPARAM and LPARAM acrobatics for years and still
vividly recalls what (not necessarily good) you can do with WM NCPAINT and WM NCMOUSEMOVE
(all that before I discovered the blessings of the server-side), it&amp;#8217;s pretty
annoying that Windows Forms doesn&amp;#8217;t bubble events &amp;#8211; mouse events specifically.
It is actually hard to believe that that wouldn&amp;#8217;t work. But I&amp;#8217;ve read
somewhere that bubbling events is &amp;#8220;new in Whidbey&amp;#8221;, so it is probably
not my ignorance. Anyways &amp;#8230; include the following snippet in your form (add
MouseDown, MouseUp, &amp;#8230; variants at your leisure), bind the respective events
of all labels, panels and all the other &amp;#8220;dead stuff&amp;#8221; to this very handler
(yes, all the controls share that handler) and that&amp;#8217;ll have the events bubble
up to your form in case you need them. I am just implementing custom resizing and
repositioning for some user controls in a little tool and that&amp;#8217;s how I got trapped
into this. Voilá. Keep it.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style='font-size:10.0pt;font-family:"Lucida Console";
color:blue'&gt;protected&lt;/span&gt;&lt;span style='font-size:10.0pt;font-family:"Lucida Console"'&gt; &lt;span style='color:blue'&gt;void&lt;/span&gt; BubbleMouseMove(&lt;span style='color:blue'&gt;object&lt;/span&gt; sender,
System.Windows.Forms.MouseEventArgs e)&lt;br&gt;
{&lt;br&gt;
Point pt = &lt;span style='color:blue'&gt;this&lt;/span&gt;.PointToClient(((Control)sender).PointToScreen(&lt;span style='color:blue'&gt;new&lt;/span&gt; Point(e.X,e.Y)));&lt;br&gt;
MouseEventArgs me = &lt;span style='color:blue'&gt;new&lt;/span&gt; MouseEventArgs(e.Button,e.Clicks,pt.X,pt.Y,e.Delta);&lt;br&gt;
OnMouseMove(sender,me);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,dd28d0f3-2f91-4e05-9b6b-6384b0eb4c55.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=7624014a-c9d9-4924-bad2-fdcf054c5185</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=7624014a-c9d9-4924-bad2-fdcf054c5185</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I didn't spend much time for anything except writing, coding, travel, speaking and
being at geek parties in the past weeks. Hence, I am sure I am the last one to notice,
but I find it absolutely revolutionary that the Microsoft Visual C++ 2003 command
line compiler (Microsoft C/C++ Version 13.1) is <a href="http://msdn.microsoft.com/visualc/vctoolkit2003/">now
a freebie</a>. 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7624014a-c9d9-4924-bad2-fdcf054c5185" />
      </body>
      <title>Scusi? Visual C++ Compiler for free? Woo!</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/16/Scusi+Visual+C+Compiler+For+Free+Woo.aspx</link>
      <pubDate>Sun, 16 May 2004 07:46:49 GMT</pubDate>
      <description>&lt;p&gt;
I didn't spend much time for anything except writing, coding, travel, speaking and
being at geek parties in the past weeks. Hence, I am sure I am the last one to notice,
but I find it absolutely revolutionary that the&amp;nbsp;Microsoft Visual C++ 2003 command
line compiler (Microsoft C/C++ Version 13.1) is &lt;a href="http://msdn.microsoft.com/visualc/vctoolkit2003/"&gt;now
a freebie&lt;/a&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7624014a-c9d9-4924-bad2-fdcf054c5185" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</comments>
      <category>Technology</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=318d0710-bcf5-4ff6-af07-37b40446d006</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,318d0710-bcf5-4ff6-af07-37b40446d006.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,318d0710-bcf5-4ff6-af07-37b40446d006.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=318d0710-bcf5-4ff6-af07-37b40446d006</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I talked about transactions on several events in the last few weeks and the sample
that I use to illustrate that transactions are more than just a database technology
is the little tile puzzle that I wrote a while back. For those interested who
can't find it, here's <a href="/clemensv/PermaLink.aspx?guid=b598b91f-bb97-4aad-9404-bceb3aff08c9">the
link</a> again. The WorkSet class that is included in the puzzle is a fully functional,
lightweight, in-memory 2 phase-commit transaction manager that's free for you to use.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=318d0710-bcf5-4ff6-af07-37b40446d006" />
      </body>
      <title>Lightweight transactions (repost)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,318d0710-bcf5-4ff6-af07-37b40446d006.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/14/Lightweight+Transactions+Repost.aspx</link>
      <pubDate>Fri, 14 May 2004 09:03:33 GMT</pubDate>
      <description>&lt;p&gt;
I talked about transactions on several events in the last few weeks and the sample
that I use to illustrate that transactions are more than just a database&amp;nbsp;technology
is&amp;nbsp;the little tile puzzle that I wrote a while back. For those interested who
can't find it, here's &lt;a href="/clemensv/PermaLink.aspx?guid=b598b91f-bb97-4aad-9404-bceb3aff08c9"&gt;the
link&lt;/a&gt; again. The WorkSet class that is included in the puzzle is a fully functional,
lightweight, in-memory 2 phase-commit transaction manager that's free for you to use.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=318d0710-bcf5-4ff6-af07-37b40446d006" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,318d0710-bcf5-4ff6-af07-37b40446d006.aspx</comments>
      <category>Architecture</category>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
            <img height="289" hspace="12" src="/clemensv/content/binary/image002123.jpg" width="257" align="right" />Sometimes
you’re trying to fix a problem for ages (months in our case) and while
the solution is really simple, you only find it by complete accident and while looking
for something completely different.
</p>
          <p>
(And yes, I do think that we need to finally get a network admin to take care
of those things) 
</p>
          <p>
For several months, our Exchange server “randomly” denied communicating
with several of our partner’s mail servers. There were several of our partners
who were not able to send us email and their emails would always bounce, although
we could communicate wonderfully with the rest of the world. What was stunning is
that there wasn’t any apparent commonality between the denied senders and the problem
came and went and sometimes it would work and sometimes it wouldn’t. 
</p>
          <p>
First we thought that something was broken about our DNS entries and specifically
about our MX record and how it was mapped to the actual server host record. So we
reconfigured that – to no avail. Then we thought it’d be some problem
with the SMTP filters in the firewall and spent time analyzing that. When that didn’t
go anywhere, we suspected something was fishy about the network routing – it
wasn’t any of that either. I literally spent hours looking at network traces
trying <img height="237" hspace="12" src="/clemensv/content/binary/image00312.jpg" width="296" align="left" />to
figure out what the problem was – nothing.
</p>
          <p>
Yesterday, while looking for something totally different, I found the issue. Some
time ago, during one of the email worm floods, we put in an explicit “deny”
access control entry into the SMTP service for one Korean and one Japanese SMTP server
that were sending us hundreds of messages per minute. The error that we made was to
deny access <b>by the server DNS name </b>and not by their concrete IP address.
</p>
          <p>
What happened was that because of this setting our SMTP server would turn around and
try to resolve every sender’s IP address back to a host name to perform that
check and that’s <b>independent</b> of the “Perform reverse DNS lookup
on incoming messages” setting in the “Delivery”/“Advanced
Delivery” dialog. It would then simply deny access to all those servers for
which it could not find a host name by reverse lookup. I removed those two entries
and now it all works again.<img height="244" hspace="12" src="/clemensv/content/binary/image004.jpg" width="248" align="right" /></p>
          <p>
Of course, the error isn’t really ours, but the problem was. What’s broken
is that the whole reverse DNS lookup story is something that seems (is) really hard
to set up and that quite a few mail servers simply don’t reversely resolve into
any host name. DNS sucks.
</p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b" />
      </body>
      <title>Our "I can't send you email" mystery; or: Worm fallout; or: DNS sucks</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/14/Our+I+Cant+Send+You+Email+Mystery+Or+Worm+Fallout+Or+DNS+Sucks.aspx</link>
      <pubDate>Fri, 14 May 2004 08:51:10 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
&lt;img height=289 hspace=12 src="/clemensv/content/binary/image002123.jpg" width=257 align=right&gt;Sometimes
you&amp;#8217;re&amp;nbsp;trying to fix a problem for ages (months in our case) and while
the solution is really simple, you only find it by complete accident and while looking
for something completely different.
&lt;/p&gt;
&lt;p&gt;
(And yes,&amp;nbsp;I do think that we need to finally get a network admin to take care
of those things)&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
For several months, our Exchange server &amp;#8220;randomly&amp;#8221; denied communicating
with several of our partner&amp;#8217;s mail servers. There were several of our partners
who were not able to send us email and their emails would always bounce, although
we could communicate wonderfully with the rest of the world. What was stunning is
that there wasn&amp;#8217;t any apparent commonality between the denied senders and the&amp;nbsp;problem
came and went and sometimes it would work and sometimes it wouldn&amp;#8217;t. 
&lt;/p&gt;
&lt;p&gt;
First we thought that something was broken about our DNS entries and specifically
about our MX record and how it was mapped to the actual server host record. So we
reconfigured that &amp;#8211; to no avail. Then we thought it&amp;#8217;d be some problem
with the SMTP filters in the firewall and spent time analyzing that. When that didn&amp;#8217;t
go anywhere, we suspected something was fishy about the network routing &amp;#8211; it
wasn&amp;#8217;t any of that either. I literally spent hours looking at network traces
trying &lt;img height=237 hspace=12 src="/clemensv/content/binary/image00312.jpg" width=296 align=left&gt;to
figure out what the problem was &amp;#8211; nothing.
&lt;/p&gt;
&lt;p&gt;
Yesterday, while looking for something totally different, I found the issue. Some
time ago, during one of the email worm floods, we put in an explicit &amp;#8220;deny&amp;#8221;
access control entry into the SMTP service for one Korean and one Japanese SMTP server
that were sending us hundreds of messages per minute. The error that we made was to
deny access &lt;b&gt;by the server DNS name &lt;/b&gt;and not by their concrete IP address.
&lt;/p&gt;
&lt;p&gt;
What happened was that because of this setting our SMTP server would turn around and
try to resolve every sender&amp;#8217;s IP address back to a host name to perform that
check and that&amp;#8217;s &lt;b&gt;independent&lt;/b&gt; of the &amp;#8220;Perform reverse DNS lookup
on incoming messages&amp;#8221; setting in the &amp;#8220;Delivery&amp;#8221;/&amp;#8220;Advanced
Delivery&amp;#8221; dialog. It would then simply deny access to all those servers for
which it could not find a host name by reverse lookup. I removed those two entries
and now it all works again.&lt;img height=244 hspace=12 src="/clemensv/content/binary/image004.jpg" width=248 align=right&gt;
&lt;/p&gt;
&lt;p&gt;
Of course, the error isn&amp;#8217;t really ours, but the problem was. What&amp;#8217;s broken
is that the whole reverse DNS lookup story is something that seems (is) really hard
to set up and that quite a few mail servers simply don&amp;#8217;t reversely resolve into
any host name. DNS sucks.
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,4dc1fcf5-63bf-4e63-9dfd-909f397f7b8b.aspx</comments>
      <category>Technology</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=3f2c3ee2-4100-4e0a-8898-422d291abbfc</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,3f2c3ee2-4100-4e0a-8898-422d291abbfc.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,3f2c3ee2-4100-4e0a-8898-422d291abbfc.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=3f2c3ee2-4100-4e0a-8898-422d291abbfc</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
On our 4 hour taxi ride from Portoroz in Slovenia to Zagreb in Croatia, I decided
to make some significant changes to my Indigo slide deck for the tour. David Chappell
called my talk an “impossible problem”, mostly because the scope of the
talks we are doing is so broad, ranging from the big picture of Longhorn over Avalon
and WinFS to the Whidbey innovations and I am stuck in the middle with a technology
that solves problems most event attendees don’t consider to have.
</p>
          <p>
So I took a rather dramatic step: I dropped almost all of the slides that explain
how Indigo works. What’s left is mostly only the Service Model’s programming
surface. For the eight slides I dropped, I added and modified six slides from the
“Scalability” talk written by Steve Swartz and myself for last year’s
“Scalable Applications Tour”, which now front the talk. Until about 20
minutes into the “new” talk, I don’t speak about Indigo, at all.
And that turned out to be a really good idea.
</p>
          <p>
As I’ve written before, many people who attend the events on this tour have
no or little experience in writing distributed applications. In reality, the classic
2-tier client/server model where all user-code sits on one tier (let it be Windows
Forms, VB6, ASP or ASP.NET) and the other tier is the database does still rule the
world. And, no, the browser doesn’t count as a tier for me; it’s just
a “remote display surface” for the presentation tier.
</p>
          <p>
Instead of talking about features, I now talk about motivation. Using two use-case
scenarios and high-level architectural overviews modeled after Hotmail and Amazon
(that everybody knows) I explain the reasons for why distributing work across multiple
systems is a good thing, how such systems can be separated so that each of them can
scale independently and what sort of services infrastructure is needed to implement
them. And it works great. Once I have the audience nodding to the obvious goodness
I can continue and map the requirements to Indigo features and explain the respective
aspects of the service model. The flow of the talk is much better and the attendees
get more and immediate value out of it. If I weren’t so time constrained I would
probably map it to Enterprise Services (now) and Indigo (future) all in the same talk
and also show to do the transition. I am sure that I can do that sort of talk at some
event this year.
</p>
          <p>
Lesson learned: Less features, more why. With the majority of developers the challenge
isn’t about showing them how distributed systems are being improved; it’s
about getting them to understand and possibly adopt the idea in the first place.
</p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3f2c3ee2-4100-4e0a-8898-422d291abbfc" />
      </body>
      <title>My Indigo Talk Version 2.0: The "Why" trumps the "How"</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,3f2c3ee2-4100-4e0a-8898-422d291abbfc.aspx</guid>
      <link>http://vasters.com/clemensv/2004/02/08/My+Indigo+Talk+Version+20+The+Why+Trumps+The+How.aspx</link>
      <pubDate>Sun, 08 Feb 2004 09:44:48 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
On our 4 hour taxi ride from Portoroz in Slovenia to Zagreb in Croatia, I decided
to make some significant changes to my Indigo slide deck for the tour. David Chappell
called my talk an &amp;#8220;impossible problem&amp;#8221;, mostly because the scope of the
talks we are doing is so broad, ranging from the big picture of Longhorn over Avalon
and WinFS to the Whidbey innovations and I am stuck in the middle with a technology
that solves problems most event attendees don&amp;#8217;t consider to have.
&lt;/p&gt;
&lt;p&gt;
So I took a rather dramatic step: I dropped almost all of the slides that explain
how Indigo works. What&amp;#8217;s left is mostly only the Service Model&amp;#8217;s programming
surface. For the eight slides I dropped, I added and modified six slides from the
&amp;#8220;Scalability&amp;#8221; talk written by Steve Swartz and myself for last year&amp;#8217;s
&amp;#8220;Scalable Applications Tour&amp;#8221;, which now front the talk. Until about 20
minutes into the &amp;#8220;new&amp;#8221; talk, I don&amp;#8217;t speak about Indigo, at all.
And that turned out to be a really good idea.
&lt;/p&gt;
&lt;p&gt;
As I&amp;#8217;ve written before, many people who attend the events on this tour have
no or little experience in writing distributed applications. In reality, the classic
2-tier client/server model where all user-code sits on one tier (let it be Windows
Forms, VB6, ASP or ASP.NET) and the other tier is the database does still rule the
world. And, no, the browser doesn&amp;#8217;t count as a tier for me; it&amp;#8217;s just
a &amp;#8220;remote display surface&amp;#8221; for the presentation tier.
&lt;/p&gt;
&lt;p&gt;
Instead of talking about features, I now talk about motivation. Using two use-case
scenarios and high-level architectural overviews modeled after Hotmail and Amazon
(that everybody knows) I explain the reasons for why distributing work across multiple
systems is a good thing, how such systems can be separated so that each of them can
scale independently and what sort of services infrastructure is needed to implement
them. And it works great. Once I have the audience nodding to the obvious goodness
I can continue and map the requirements to Indigo features and explain the respective
aspects of the service model. The flow of the talk is much better and the attendees
get more and immediate value out of it. If I weren&amp;#8217;t so time constrained I would
probably map it to Enterprise Services (now) and Indigo (future) all in the same talk
and also show to do the transition. I am sure that I can do that sort of talk at some
event this year.
&lt;/p&gt;
&lt;p&gt;
Lesson learned: Less features, more why. With the majority of developers the challenge
isn&amp;#8217;t about showing them how distributed systems are being improved; it&amp;#8217;s
about getting them to understand and possibly adopt the idea in the first place.
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3f2c3ee2-4100-4e0a-8898-422d291abbfc" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,3f2c3ee2-4100-4e0a-8898-422d291abbfc.aspx</comments>
      <category>Talks</category>
      <category>Talks/EMEA Longhorn Preview</category>
      <category>Technology</category>
      <category>Technology/Indigo</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Don says that BEA's Deputy CTO <a href="http://www.gotdotnet.com/team/dbox/default.aspx?key=2004-01-24T09:58:46Z">has
missed the cluetrain</a>. I absolutely agree with Don's opinion on <a href="http://www.itnews.com.au/storycontent.asp?ID=8&amp;Art_ID=17952">this
article</a> and what's even worse than the things said is what the article implies.
If that is BEA's official position, this is nothing less than an outing that they
are passengers in the backseat of a car that is driven by IBM and Microsoft (switching
drivers every once in a while) and that they're neither behind the spirit of the whole
undertaking nor do they fully understand the specifications they have put their names
on. Integration or standardization on the API level has failed miserably in countless
attempts and any middleware company (including BEA) that is out there to compete on
features must go beyond the least common denominator approach to win over customers.
Does BEA have Indigo envy?
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433" />
      </body>
      <title>BEA missing the cluetrain</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433.aspx</guid>
      <link>http://vasters.com/clemensv/2004/01/24/BEA+Missing+The+Cluetrain.aspx</link>
      <pubDate>Sat, 24 Jan 2004 21:45:04 GMT</pubDate>
      <description>&lt;p&gt;
Don says that BEA's Deputy CTO&amp;nbsp;&lt;a href="http://www.gotdotnet.com/team/dbox/default.aspx?key=2004-01-24T09:58:46Z"&gt;has
missed the cluetrain&lt;/a&gt;. I absolutely agree with Don's opinion on &lt;a href="http://www.itnews.com.au/storycontent.asp?ID=8&amp;amp;Art_ID=17952"&gt;this
article&lt;/a&gt;&amp;nbsp;and what's even worse than the things said is what the article implies.
If that is BEA's official position, this is nothing less than an outing that they
are passengers in&amp;nbsp;the backseat of a car that is driven by IBM and Microsoft (switching
drivers every once in a while) and that they're neither behind the spirit of the whole
undertaking nor do they fully understand the specifications they have put their names
on.&amp;nbsp;Integration or standardization on the API level has failed miserably in countless
attempts and any middleware company (including BEA) that is out there to compete on
features must go beyond the least common denominator approach to win over customers.
Does BEA have Indigo envy?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,3cc8d1e3-d7da-41c1-b8c7-c5d4cdfee433.aspx</comments>
      <category>Technology</category>
      <category>Technology/Indigo</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=4eda9fe7-e36e-4e64-b170-2f29a88621dd</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,4eda9fe7-e36e-4e64-b170-2f29a88621dd.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,4eda9fe7-e36e-4e64-b170-2f29a88621dd.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=4eda9fe7-e36e-4e64-b170-2f29a88621dd</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The evolution of in-memory concept of messages in the managed Microsoft Web Services
stack(s) is quite interesting to look at. When you compare the concepts of System.Web.Services
(ASMX), Microsoft.Web.Services (WSE) and System.MessageBus (Indigo M4), you'll find
that this most fundamental element has undergone some interesting changes and that
the Indigo M4 incarnation of "Message" is actually a bit surprising in its design. 
</p>
        <p>
          <strong>ASMX</strong>
        </p>
        <p>
In the core ASP.NET Web Services model (nicknamed ASMX), the concept of an in-memory
message doesn't really surface anywhere in the programming model unless you use the
ASMX <a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebservicesprotocolssoapextensionclasstopic.asp">extensibility
mechanism</a>. The abstract <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebServicesProtocolsSoapMessageClassTopic.asp">SoapMessage</a> class,
which comes in concrete SoapClientMessage and SoapServerMessage flavors has two fundamental
states that depend on the message stage that the message is inspected in: The message
is either unparsed or parsed (some say "cracked"). 
</p>
        <p>
If it's parsed you can get at the parameters that are being passed to the server or
are about to be returned to the client, but the original XML data stream of the message
is no longer available and all headers have likewise either been mapped onto objects
or lumped into a "unknown headers" array. if the message is unparsed, all you get
is an text stream that you'll have to parse yourself. If you want to add, remove or
modify headers while processing a message in an extension, you will have to read and
parse your copy of the input stream (the message text) and write the resulting mesage
to an output stream that's handed onwards to the next extension or to the infrastructure.
In essence that means that if you had two or three ASMX-style SOAP extensions that
implement security, addressing and routing functionality, you'd be parsing the message
three times and serializing it three times just so that the infrastructure would parse
it yet again. Not so good.
</p>
        <p>
          <strong>WSE</strong>
        </p>
        <p>
          <a href="http://msdn.microsoft.com/webservices/building/wse/default.aspx">The Web
Services Enhancements</a> (WSE) have a simple, but very effective fix for that problem.
The WSE team needed to use the ASMX extensibility point but found that if they'd build
all their required extensions using the ASMX model, they'd run into that obvious performance
problem. Therefore, WSE has its <a href="http://msdn.microsoft.com/library/en-us/dnwebsrv/html/insidewsepipe.asp">own
pipeline</a> and its own extensibility mechanism that plugs as one big extension into
ASMX and when you write extensions (handlers) for WSE, you don't get a stream but
an in-memory info-set in form of a SoapEnvelope (that is derived from System.Xml.XmlDocument
and therefore a DOM). Parsing the XML text just once and have all processing steps
work on a shared in-memory object-model seems optimal. Can it really get any better
than "parse once" as WSE does it? 
</p>
        <p>
          <strong>Indigo</strong>
        </p>
        <p>
When you look at the Indigo concept of <a href="http://longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.messagebus/c/message/message.aspx">Message</a> (the
Message class in the next milestone will be the same in spirit, similar in concept
and different in detail and simpler as a result), you'll find that it doesn't contain
a reference to an XmlDocument or some other DOM-like structure. The Indigo message
contains a collection of headers (which in the M4 milestone also come in an "in-memory
only" flavor) and a content object, which has, as its most important member, an XmlReader-typed <a href="http://longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.messagebus/c/messagecontent/p/reader.aspx">Reader</a> property.
</p>
        <p>
When I learned about this design decision a while ago, I was a bit puzzled why that's
so. It appeared clear to me that if you kept the message parsed in a DOM, you'd have
a good solution if you want to hand the message down a chain of extensibility points,
because you don't need to reparse. The magic sentence that woke me up was "We need
to support streaming". And then it clicked.
</p>
        <p>
Assume you want to receive a 1GB video stream over an Indigo TCP multicast or UDP
connection (even if you think that's a silly idea - work with me here). Because Indigo
will represent the message containing that video as an XML Infoset (mind that this
doesn't imply that we're talking about base64-encoded content in an UTF-8 angle bracket
document and therefore 2GB on the wire), we've got some problems if there was a DOM
based solution. A DOM like XmlDocument is only ready for business when it has seen
the end tag of its source stream. This is not so good for streams of that size, because
you surely would want to see the video stream as it downloads and, if the video stream
is a live broadcast, there may simply be no defined end: The message may have a virtually
infinite size with the "end-tag" being expected just shortly before judgment day. 
</p>
        <p>
There's something philosophically interesting about a message relaying a 24*7*365
video stream where the binary content inside the message body starts with the current
video broadcast bits as of the time the message is generated and then never ends.
The message can indeed be treated as being well-formed XML because there is always
a theoretical end to it. The end-tag just happens to be a couple of "bit-years" away.
</p>
        <p>
Back to the message design: When Indigo gets its hands on a transport stream it layers
a Message object over the raw bits available on the message using an XmlReader. Then
it peeks into the message and parses soap:Envelope and everything inside soap:Header.
The headers it finds go into the in-memory header collection. Once it sees soap:Body,
Indigo stops and backs off. The result of this is a partially parsed in-memory message
for which all headers are available in memory and the body of the message is left
sitting in an XmlReader. When the XmlReader sits on top of a NetworkStream, we now
have a construct where Indigo can already work on the message and its control information
(headers) while the network socket is still open and the rest of the message is still
arriving (or portions haven't even been sent by the other party).
</p>
        <p>
Unless an infrastructure extension must touch the body (in-message body encryption
or signature do indeed spoil the party here), Indigo can process the message, just
ignore the body portion and hand it to the application endpoint for processing as-is.
When the application endpoint reads the message through the XmlReader it therefore
pulls the bits directly off the wire. Another variant of this, and the case where
it really gets interesting, is that using this technique, arbitrary large data streams
can be routed over multiple Indigo hops using virtualized WS-Addressing addressing
where every intermediary server just forwards the bits to the next hop as they arrive.
Combine this with publish and subscribe services and Indigo's broadcasting abilities
and this is getting really sexy for all sorts of applications that need to traverse
transport-level obstacles such as firewalls or where you simply can't use IP.      
</p>
        <p>
For business applications, this support for very large messages is not only very interesting
but actually vital for a lot of applications. In our BizTalk workshops we've had quite
a few customers who exchange catalogs for engineering parts with other parties. These
catalogs easily exceed 1GB in size on the wire. If you want to expand those messages
up into a DOM you've got a problem. Consequently, neither WSE nor ASMX nor BizTalk
Server nor any other DOM based solution that isn't running on a well equipped 64-bit
box can successfully handle such real-customer-scenario messages. Once messages support
streaming, you have that sort of flexibility.
</p>
        <p>
The problem that remains with XmlReader is that once you touch the body, things get
a bit more complex than with a DOM representation. The XmlReader is a "read once"
construct that usually can't be reset to its initial state. That is specifically true
if the reader sits on top of a network stream and returns the translated bits as they
arrive. Once you touch the message content is the infrastructure, the message is therefore
"consumed" and can't be used for further processing. The good news is, though, that if
you buffer the message content into a DOM, you can layer an XmlNodeReader over the
DOM's document element and forward the message with that reader. If you
only need to read parts of the message or if you don't want to use the DOM, you can
layer a custom XML reader over a combination of your buffer data and the original
XmlReader.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4eda9fe7-e36e-4e64-b170-2f29a88621dd" />
      </body>
      <title>Indigo: The evolution of the in-memory message</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,4eda9fe7-e36e-4e64-b170-2f29a88621dd.aspx</guid>
      <link>http://vasters.com/clemensv/2004/01/24/Indigo+The+Evolution+Of+The+Inmemory+Message.aspx</link>
      <pubDate>Sat, 24 Jan 2004 19:37:53 GMT</pubDate>
      <description>&lt;p&gt;
The evolution of in-memory concept of messages in the managed Microsoft Web Services
stack(s) is quite interesting to look at. When you compare the concepts of System.Web.Services
(ASMX), Microsoft.Web.Services (WSE) and System.MessageBus (Indigo M4), you'll find
that this most fundamental element has undergone some interesting changes and that
the Indigo M4 incarnation of "Message" is actually a bit surprising in its design. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;ASMX&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In the core ASP.NET Web Services model (nicknamed ASMX), the concept of an in-memory
message doesn't really surface anywhere in the programming model unless you use the
ASMX &lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebservicesprotocolssoapextensionclasstopic.asp"&gt;extensibility
mechanism&lt;/a&gt;. The abstract &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebServicesProtocolsSoapMessageClassTopic.asp"&gt;SoapMessage&lt;/a&gt; class,
which comes in concrete SoapClientMessage and SoapServerMessage flavors has two fundamental
states that depend on the message stage that the message is inspected in: The message
is either unparsed or parsed (some say "cracked"). 
&lt;/p&gt;
&lt;p&gt;
If it's parsed you can get at the parameters that are being passed to the server or
are about to be returned to the client, but the original XML data stream of the message
is no longer available and all headers have likewise either been mapped onto objects
or lumped into a "unknown headers" array. if the message is unparsed, all you get
is an text stream that you'll have to parse yourself. If you want to add, remove or
modify headers while processing a message in an extension, you will have to read and
parse your copy of the input stream (the message text) and write the resulting mesage
to an output stream that's handed onwards to the next extension or to the infrastructure.
In essence that means that if you had two or three ASMX-style SOAP extensions that
implement security, addressing and routing functionality, you'd be parsing the message
three times and serializing it three times just so that the infrastructure would parse
it yet again. Not so good.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;WSE&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/webservices/building/wse/default.aspx"&gt;The Web
Services Enhancements&lt;/a&gt; (WSE) have a simple, but very effective fix for that problem.
The WSE team needed to use the ASMX extensibility point but found that if they'd build
all their required extensions using the ASMX model, they'd run into that obvious performance
problem. Therefore, WSE has its &lt;a href="http://msdn.microsoft.com/library/en-us/dnwebsrv/html/insidewsepipe.asp"&gt;own
pipeline&lt;/a&gt; and its own extensibility mechanism that plugs as one big extension into
ASMX and when you write extensions (handlers) for WSE, you don't get a stream but
an in-memory info-set in form of a SoapEnvelope (that is derived from System.Xml.XmlDocument
and therefore a DOM). Parsing the XML text just once and have all processing steps
work on a shared in-memory object-model seems optimal. Can it really get any better
than "parse once" as WSE does it? 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Indigo&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
When you look at the Indigo concept of &lt;a href="http://longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.messagebus/c/message/message.aspx"&gt;Message&lt;/a&gt; (the
Message class in the next milestone will be the same in spirit, similar in concept
and different in detail and simpler as a result), you'll find that it doesn't contain
a reference to an XmlDocument or some other DOM-like structure. The Indigo message
contains a collection of headers (which in the M4 milestone also come in an "in-memory
only" flavor) and a content object, which has, as its most important member, an XmlReader-typed &lt;a href="http://longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.messagebus/c/messagecontent/p/reader.aspx"&gt;Reader&lt;/a&gt; property.
&lt;/p&gt;
&lt;p&gt;
When I learned about this design decision a while ago, I was a bit puzzled why that's
so. It appeared clear to me that if you kept the message parsed in a DOM, you'd have
a good solution if you want to hand the message down a chain of extensibility points,
because you don't need to reparse. The magic sentence that woke me up was "We need
to support streaming". And then it clicked.
&lt;/p&gt;
&lt;p&gt;
Assume you want to receive a 1GB video stream over an Indigo TCP multicast or UDP
connection (even if you think that's a silly idea - work with me here). Because Indigo
will represent the message containing that video as an XML Infoset (mind that this
doesn't imply that we're talking about base64-encoded content in an UTF-8 angle bracket
document and therefore 2GB on the wire), we've got some problems if there was a DOM
based solution. A DOM like XmlDocument is only ready for business when it has seen
the end tag of its source stream. This is not so good for streams of that size, because
you surely would want to see the video stream as it downloads and, if the video stream
is a live broadcast, there may simply be no defined end: The message may have a virtually
infinite size with the "end-tag" being expected just shortly before judgment day. 
&lt;/p&gt;
&lt;p&gt;
There's something philosophically interesting about a message relaying a 24*7*365
video stream where the binary content inside the message body starts with the current
video broadcast bits as of the time the message is generated and then never ends.
The message can indeed be treated as being well-formed XML because there is always
a theoretical end to it. The end-tag just happens to be a couple of "bit-years" away.
&lt;/p&gt;
&lt;p&gt;
Back to the message design: When Indigo gets its hands on a transport stream it layers
a Message object over the raw bits available on the message using an XmlReader. Then
it peeks into the message and parses soap:Envelope and everything inside soap:Header.
The headers it finds go into the in-memory header collection. Once it sees soap:Body,
Indigo stops and backs off. The result of this is a partially parsed in-memory message
for which all headers are available in memory and the body of the message is left
sitting in an XmlReader. When the XmlReader sits on top of a NetworkStream, we now
have a construct where Indigo can already work on the message and its control information
(headers) while the network socket is still open and the rest of the message is still
arriving (or portions haven't even been sent by the other party).
&lt;/p&gt;
&lt;p&gt;
Unless an infrastructure extension must touch the body (in-message body encryption
or signature do indeed spoil the party here), Indigo can process the message, just
ignore the body portion and hand it to the application endpoint for processing as-is.
When the application endpoint reads the message through the XmlReader it therefore
pulls the bits directly off the wire. Another variant of this, and the case where
it really gets interesting, is that using this technique, arbitrary large data streams
can be routed over multiple Indigo hops using virtualized WS-Addressing addressing
where every intermediary server just forwards the bits to the next hop as they arrive.
Combine this with publish and subscribe services and Indigo's broadcasting abilities
and this is getting really sexy for all sorts of applications that need to traverse
transport-level obstacles such as firewalls or where you simply can't use IP.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
For business applications, this support for very large messages is not only very interesting
but actually vital for a lot of applications. In our BizTalk workshops we've had quite
a few customers who exchange catalogs for engineering parts with other parties. These
catalogs easily exceed 1GB in size on the wire. If you want to expand those messages
up into a DOM you've got a problem. Consequently, neither WSE nor ASMX nor BizTalk
Server nor any other DOM based solution that isn't running on a well equipped 64-bit
box can successfully handle such real-customer-scenario messages. Once messages support
streaming, you have that sort of flexibility.
&lt;/p&gt;
&lt;p&gt;
The problem that remains with XmlReader is that once you touch the body, things get
a bit more complex than with a DOM representation. The XmlReader is a "read once"
construct that usually can't be reset to its initial state. That is specifically true
if the reader sits on top of a network stream and returns the translated bits as they
arrive. Once you touch the message content is the infrastructure, the message is therefore
"consumed" and can't be used for further processing. The good news is, though, that&amp;nbsp;if
you&amp;nbsp;buffer the message content into a DOM, you can layer an XmlNodeReader over&amp;nbsp;the
DOM's document element and&amp;nbsp;forward the&amp;nbsp;message with that reader. If you
only need to read parts of the message or if you don't want to use the DOM, you can
layer a custom XML reader over a combination of your buffer data and the original
XmlReader.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4eda9fe7-e36e-4e64-b170-2f29a88621dd" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,4eda9fe7-e36e-4e64-b170-2f29a88621dd.aspx</comments>
      <category>Technology</category>
      <category>Technology/Indigo</category>
      <category>Technology/Web Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=b022adcb-db90-4956-890c-f852592f9a4b</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,b022adcb-db90-4956-890c-f852592f9a4b.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,b022adcb-db90-4956-890c-f852592f9a4b.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=b022adcb-db90-4956-890c-f852592f9a4b</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The suggested answer to the <a href="http://www.techinterviews.com/index.php?p=65&amp;more=1&amp;c=1">first
question</a> is incorrect and illustrates a security problem.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=b022adcb-db90-4956-890c-f852592f9a4b" />
      </body>
      <title>Eh?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,b022adcb-db90-4956-890c-f852592f9a4b.aspx</guid>
      <link>http://vasters.com/clemensv/2003/12/23/Eh.aspx</link>
      <pubDate>Tue, 23 Dec 2003 09:32:28 GMT</pubDate>
      <description>&lt;p&gt;
The suggested answer to the &lt;a href="http://www.techinterviews.com/index.php?p=65&amp;amp;more=1&amp;amp;c=1"&gt;first
question&lt;/a&gt;&amp;nbsp;is incorrect and illustrates a security problem.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=b022adcb-db90-4956-890c-f852592f9a4b" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,b022adcb-db90-4956-890c-f852592f9a4b.aspx</comments>
      <category>Technology</category>
    </item>
  </channel>
</rss>