<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The Freak Parade</title>
	
	<link>http://www.thefreakparade.com</link>
	<description>Strange noises from the mind of Nathan Stults...</description>
	<pubDate>Sat, 08 Nov 2008 11:09:10 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/TheFreakParade" type="application/rss+xml" /><item>
		<title>You Can’t Fill an Imaginary Hole</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/446410307/</link>
		<comments>http://www.thefreakparade.com/2008/11/you-cant-fill-an-imaginary-hole/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 11:09:10 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/11/you-cant-fill-an-imaginary-hole/</guid>
		<description><![CDATA[I’m having trouble sleeping this evening, so I thought I’d try to pacify my mind with a little midnight rambling. I’m probably in pretty good company right about now – I recently saw on a Discovery channel program that a ridiculously high proportion of Americans have a sleeping disorder of some kind, primarily some form [...]]]></description>
			<content:encoded><![CDATA[<p>I’m having trouble sleeping this evening, so I thought I’d try to pacify my mind with a little midnight rambling. I’m probably in pretty good company right about now – I recently saw on a Discovery channel program that a ridiculously high proportion of Americans have a sleeping disorder of some kind, primarily some form of chronic insomnia. That jives with my general experience. Most adults I know have trouble sleeping at least a few nights a week.</p>
<p>I don’t think the reason for this phenomenon is any great mystery – as our culture continues to accelerate and radiate increasing quantities of noise (in the form of information and technology driven social interactions), our minds become exponentially busier in order to keep up, yet our lifestyles don’t often permit sufficient time to “decompress”&#160; so we have trouble sleeping. Our minds simply can’t stop twitching when we turn off the lights and close our eyes. </p>
<p>If you have any doubt that the pace of change is accelerating in our society, <a href="http://www.youtube.com/watch?v=nteiqLgZFOU">watch this</a>. Actually, watch it anyway, it is a fascinating presentation. Our natural tendency, when we reflect on our rapidly changing culture, is to judge it as either <a href="http://www.theatlantic.com/doc/200807/google">robbing us of our souls</a> or as the <a href="http://news.cnet.com/Tech-doesnt-dumb-us-down,-it-frees-our-minds/2100-1025_3-6246641.html">righteous march of human progress</a>. In reality, however, whether or not this change is good or bad is a meaningless question. Nothing can hinder or contribute to the phenomenon by some application of our will, such change is outside the realm of human control.</p>
<p>Even so, just because we can’t alter the onslaught of cultural entropy doesn’t mean we have to be utterly swept away by it, simply accepting as inevitable fact that we’ll be sleeping less and less year after year.</p>
<p>The video I just referenced asks this question at its conclusion: “What does it all mean?” This question, of course, is not <em>a</em> question, but <em>the</em> Question. Christian mythology holds that Man fell from grace when Eve ate from the fruit of knowledge and thus launched all of human history. The fruit of knowledge needed only to transmit to mankind that single Question to have its effect. It isn’t an opposable thumb or the ability to make tools that defines and sets our species apart from the rest of the animal kingdom, it is that Question, the relentless pursuit of which has given birth to the entirety of human culture. Furthermore, our inability to answer that Question accounts for our uniquely human suffering – the widening spiritual hole in our experience of life that our consumerist culture is scrambling harder and harder to fill, by way of technology and mass production. This is perfectly captured in <a href="http://www.socialsignal.com/image/wwj-buy">this cartoon</a>:</p>
<p><img src="http://www.socialsignal.com/system/files/images/2008-09-20-spiritual_0.gif" />&#160; </p>
<p>As a side note, I highly recommend subscribing to the <a href="http://feeds.feedburner.com/RobCottinghamCartoons">Noise to Signal RSS feed</a> – a desperately needed dose of perspective in the form of very funny cartoons. Anyway, my intention is not to be critical of our culture, but simply to consider it in order to aware of it so as to find a way to live in it without being utterly enslaved by it. I believe this is critical, because while the acceleration of our culture may be inevitable, it is accelerating towards increasingly unsatisfying ways of approaching our thirst for meaning.</p>
<p>My belief is that the answer to the question “What does it all mean?” is the question itself - “it” means to be aware of the utterly un-resolvable <a href="http://www.bamboointhewind.org/chant_sandokai.html">mystery</a> that is human experience, and to explore and study this mystery as long as we live. Our culture is fundamentally unsatisfying (from a spiritual perspective) because it is oriented towards blindly trying to find a salve for some illusory spiritual wound, it does not approach the Question directly, and so it won’t ever have a chance at answering it, or of quenching our thirst. Of course as any Zen Buddhist will tell you the Question is a trick question to begin with – it is the metaphysical phrasing of the joke “Who is buried in Grant’s tomb?” – Grant of course. “What does it all mean?” – it means itself. The goal of a Zen student’s practice is to “get the joke” – not intellectually, which is trivial, but viscerally, experientially, which is not so trivial. Anyway, for those of us who are not Zen students, that doesn’t help much. Even so, I urge you to not forget about the mystery – if we lose the context of the Mystery, or the Question, then our accelerating culture will eventually eat us alive or at least wear us down, but as long as we remain aware of the Mystery and the Question, and attend to them both on a regular basis, then any pace of change or mutation of our culture will be both endurable and enjoyable. Of course, this is easier said than done, which is why I’m up at three in the morning philosophizing instead of sleeping peacefully next to my wife <img src='http://www.thefreakparade.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=2X4XN"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=2X4XN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=aX8En"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=aX8En" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=UQIBn"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=UQIBn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=Wozzn"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=Wozzn" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/446410307" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/11/you-cant-fill-an-imaginary-hole/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/11/you-cant-fill-an-imaginary-hole/</feedburner:origLink></item>
		<item>
		<title>I don’t know but I’ve been told, ETL is gettin’ mighty old. BAM! BAM! EDA! I want my data right away!</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/430518645/</link>
		<comments>http://www.thefreakparade.com/2008/10/i-dont-know-but-ive-been-told-etl-is-gettin-mighty-old-bam-bam-eda-i-want-my-data-right-away/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 08:50:35 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/10/i-dont-know-but-ive-been-told-etl-is-gettin-mighty-old-bam-bam-eda-i-want-my-data-right-away/</guid>
		<description><![CDATA[The pace of change in the business world is accelerating at a rather alarming rate, as you may have noticed. The mighty Internet is compressing time, geographical distance and even our attention spans with ruthless disregard for our spiritual well being. As the pace of change increases the ability of any given organization to navigate [...]]]></description>
			<content:encoded><![CDATA[<p>The pace of change in the business world is accelerating at a rather alarming rate, as you may have noticed. The mighty Internet is compressing time, geographical distance and <a href="http://en.wikipedia.org/wiki/Extract,_transform,_load">even our attention spans</a> with ruthless disregard for our spiritual well being. As the pace of change increases the ability of any given organization to navigate skillfully in such frantic waters won&#8217;t remain a mere competitive advantage but will soon become a matter of survival, if it isn&#8217;t already.</p>
<p><a href="http://www.thefreakparade.com/wp-content/uploads/2008/10/image1.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="168" alt="image" src="http://www.thefreakparade.com/wp-content/uploads/2008/10/image-thumb1.png" width="260" align="right" border="0" /></a>Gone are the days of blissfully sailing across the open sea gleefully screaming &quot;Fire!&quot; one minute and hitting the deck the next as your competitor&#8217;s logo-imprinted cannon balls whiz overhead. We must continue the battle,&#160; of course, but the open sea has been replaced by the thin edge of an epic vortex that keeps growing larger, spinning faster. When everyone is always talking about increasing &quot;Business Agility,&quot; whether it be through implementing a well-governed SOA or by calling upon the power of Satan, what they are really talking about is finding some way to keep from sliding down the side of the whirlpool and into the gaping maw of a giant squid.</p>
<p>Melodrama and nautical fantasy aside, the operating environment of the modern business <em>is</em> changing. Businesses are becoming increasingly sensitive to their environments as &quot;<a href="http://en.wikipedia.org/wiki/Business_intelligence">Business Intelligence</a>&quot; - the buzz word that refers to actually making some use of the torrents of data flowing through our IT systems - begins to permeate our organizations.</p>
<p><a href="http://www.thefreakparade.com/wp-content/uploads/2008/10/image2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="120" alt="image" src="http://www.thefreakparade.com/wp-content/uploads/2008/10/image-thumb2.png" width="160" align="left" border="0" /></a> Originally Business Intelligence (transactional data processed and presented for analysis) was employed primarily at the executive level to allow decision makers to analyze the past in order to make predictions (and therefore decisions) about the future. The current trend, however, is to push this kind of processed, aggregated and integrated data deeper and deeper into the organization, sometimes right down the the line level worker. This is being called &quot;Operational Business Intelligence.&quot; Operational Business Intelligence is not at all strategic - it is intended to provide fast, objective feedback to operational units in order to improve real time or near real time decision making. Well, this kind of business intelligence isn&#8217;t your granddaddy&#8217;s business intelligence - it&#8217;s value is derived directly from its immediacy, its freshness and its narrow relevance. It isn&#8217;t a map for the Generals to study while they sip whiskey and play with plastic figurines. Rather, it is the static filled screams of &quot;<a href="http://www.youtube.com/watch?v=AeDq_tCCj3o">OH MY GOD THEY&#8217;RE COMING THROUGH THE FUCKING WIRE - I NEED AIR COVER NOW!</a>&quot; bellowing from the field lieutenants radio. It does little good to see such data on a report a day or two (or even an hour or two in some cases) after it is generated. This kind of data shouldn&#8217;t even be called analytics; it is direct feedback from living business processes and the good old fashioned <a href="http://en.wikipedia.org/wiki/Extract,_transform,_load">ETL</a> based nightly batch process that does some pretty math and coarse grained aggregations and takes forever to process just doesn&#8217;t cut the mustard. That kind of business intelligence it is too general and too damned old to be useful for making in the moment operational decisions.</p>
<p><a href="http://www.dmreview.com/issues/20040301/8177-1.html">Business Activity Monitoring</a> (BAM) <a href="http://www.youtube.com/watch?v=3gNNJQkb2Dg">to the rescue</a>! The acronym and the term were invented by some highfalutin <a href="http://www.gartner.com/resources/105500/105562/105562.pdf">Gartner analysts awhile back ago</a> and refer to business intelligence systems which aggregate, correlate, and report (usually via live dashboards and other more immediate alert mechanisms) real time or near real time business data as it is generated by the transactional systems that run the business. Additionally, BAM systems will often employ a rules engine to detect actionable scenarios in the incoming event feeds and either initiate an automated response to such scenarios or alert an appropriate human who can take some appropriate action.</p>
<p>As you can probably imagine, the architecture and design of a BAM system must be dramatically different from that of a batch based, ETL powered system. Furthermore, simply populating the data warehouse isn&#8217;t enough - BAM systems deal with real time business events and data feeds and therefore must be prepared to detect and act upon (even if simply via some kind of alert or dashboard dashboard alarm) various business conditions. This kind of task is something data warehouses are ill equipped to address. </p>
<p>Rather than processing data at some interval, BAM solutions monitor business events and aggregate, process and act on those events as they are occurring. This style of processing lends itself almost perfectly to an <a href="http://www.infoq.com/news/Event-Driven">Event Driven Architecture</a>, or EDA. In an EDA distributed systems communicate with each other indirectly by raising &quot;events&quot; whenever some interesting state change occurs in the domain. These events are usually just messages placed on a Message Bus, or <a href="http://en.wikipedia.org/wiki/Enterprise_service_bus">ESB</a>, to which any other system also connected to the message bus can subscribe. At any given time, there may be hundreds or thousands or millions of &quot;business events&quot; flowing through an organizations message bus, providing a perfect opportunity for a BAM system to tap in and do its groovy business. </p>
<p>An Event Driven Architecture or <a href="http://www.eaipatterns.com/MessageBus.html">Message Bus</a> are not strictly required for a BAM system to work. BizTalk, for example, provides a BAM API which it expects LOB systems (or BizTalk orchestrations) to call into at various stages of processing to directly inform the core BizTalk BAM database of any interesting business activity. Somewhat more robustly, some of the enterprise BAM solutions provide a wide array of adapters that can allow transactional systems to publish events directly to the BAM software. I don&#8217;t think it would be fair to call this kind of arrangement an Event Driven Architecture; even though events are being piped directly out of transactional systems and into the BAM system, the event notifications are essentially a private conversation between each transactional system and the BAM system.</p>
<p>Even so, just because you can have BAM without an EDA and an EDA without BAM, the two technologies (or architectures) are perfectly suited for one another. BAM provides a layer of intelligence and analysis over real time business events, and an EDA provides a conduit for transactional systems to publish their business events to the broader enterprise in blissful ignorance of who else may be watching, including the BAM system. An EDA also provides a completely natural way for the BAM system to distribute information or initiate action when it detects the need to do so - it can just raise its own derived events, to which a dashboard, human notification system, etc. can happily subscribe. Put the two together and BAM! You have a closed feedback loop that will enable your operational managers and line level decision makers to successfully keep your Ship of Commerce out of the tentacles of a giant squid, and maybe even sink a few enemy galleons along the way.</p>
<p>Well, all this is just fascinating stuff, but if you aren&#8217;t a big enterprisey company with deep pockets, you will be pretty disappointed when you get to the BAM store with your fist full of change and your head full of high hopes. Most of the existing BAM vendors have been swallowed up by the infrastructure giants like IBM, Progress Software (Sonic ESB) and the like. Probably top notch solutions, but I wouldn&#8217;t know because I work for an SMB. Their salespeople generally won&#8217;t even acknowledge that companies like ours exist. The one free standing BAM vendor I could find, Systar, also prefers to sell to the big fish, or, as their &quot;business development&quot; guy put it, &quot;Tier 1 Companies who pay licensing fees that <em>start</em> at a quarter of a million dollars&quot;. I&#8217;m not 100% sure what a Tier 1 company is, but based on the fact that he tried to convince me we didn&#8217;t really need a BAM solution, I&#8217;m guessing we&#8217;re not one of them :)&#160; So, as usual, that leaves us SMB&#8217;s alone at the bar sitting next to a Microsoft solution, in this case BizTalk, trying to decide if we should just head home alone and take care of business ourselves, or down a few more shots of Tequila, heave a deep, forlorn sigh of resignation, turn to BizTalk and say &quot;<a href="http://www.youtube.com/watch?v=dc2Z7CL4Cv0">How you doin&#8217;</a>?&quot;</p>
<p>I should have more to say about that soon as we&#8217;ll be implementing a BAM/EDA solution over the next few months. Will a bag-over-its-head be enough to stomach an ongoing relationship with the BizTalk BAM product, or will we be able to stitch something together from open source tools and good old fashioned grit, piss and vinegar? <a href="http://en.wikipedia.org/wiki/The_Shadow">Only The Shadow knows</a>&#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=dYCvM"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=dYCvM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=mFJtm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=mFJtm" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=FW8Lm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=FW8Lm" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=Qu2jm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=Qu2jm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/430518645" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/10/i-dont-know-but-ive-been-told-etl-is-gettin-mighty-old-bam-bam-eda-i-want-my-data-right-away/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/10/i-dont-know-but-ive-been-told-etl-is-gettin-mighty-old-bam-bam-eda-i-want-my-data-right-away/</feedburner:origLink></item>
		<item>
		<title>Be Prepared To Be Surprised</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/417602227/</link>
		<comments>http://www.thefreakparade.com/2008/10/be-prepared-to-be-surprised/#comments</comments>
		<pubDate>Sat, 11 Oct 2008 08:34:50 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/10/be-prepared-to-be-surprised/</guid>
		<description><![CDATA[ So this crazy metaphysical debate about how or why you (or your team) should learn TDD rages on, reaching a fevered philosophical pitch. There is a heavy drumbeat coming out of the ALT.NET encampment that is  becoming increasingly difficult to ignore, and we&#8217;re finding ourselves torn on how to react. Do we have [...]]]></description>
			<content:encoded><![CDATA[<p> So this crazy metaphysical debate about how or why you (or your team) should learn TDD rages on, reaching a fevered philosophical pitch. There is a heavy drumbeat coming out of the ALT.NET encampment that is <a href="http://www.thefreakparade.com/wp-content/uploads/2008/10/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.thefreakparade.com/wp-content/uploads/2008/10/image-thumb.png" width="157" align="right" border="0" /></a> becoming increasingly difficult to ignore, and we&#8217;re finding ourselves torn on how to react. Do we have a moral imperative to march along? Is it enough to tap our feet under our desks and keep doing business as usual? Or should we tear off our clothes, paint our faces with the ALT.NET war paint, and take our place by the campfire? Ian Cooper <a href="http://codebetter.com/blogs/ian_cooper/archive/2008/10/10/on-project-learning.aspx">recently pointed out</a> that what is at question here is not TDD but the imperative for us, as an industry, to accept change as a fundamental aspect of our practice. </p>
<p>Change is nothing new. In fact, change is all there is. We all attempt to resist it in one way or another, but it is a useless effort, like trying to stand still in a rushing river. There is no such thing as &quot;resisting&quot; change - the best you can do is to pretend it doesn&#8217;t exist, but you can&#8217;t stand still. Even though you may not alter your behavior, your environment will change around you and your relationship to your environment will change despite your stubbornness, it can&#8217;t be helped. Whether change is good or bad is a meaningless question, and the question of whether to accept it or ignore it isn&#8217;t really a question of &quot;self improvement&quot; but a question of how much you will enjoy your profession and your life. </p>
<p>So while the call to change coming from ALT.NET is extraordinarily valuable, the relentless emphasis on the tangible business results of some particular change, such as a guaranteed suite of regression rests resulting from a move to TDD, creates a limiting environment in which to accept it meaningfully and realize its full value. The <em><strong>only</strong> </em>way to accept change is to experience it with an open mind and feel its value for yourself. An emphasis on quantitative results is absolutely necessary for arousing interest in some new technique or methodology, but it should not be the only emphasis. Once interest is aroused the emphasis should immediately shift from the expected benefits which, at this stage only reinforces preconceptions and inhibits the learning process, to remaining observant, alert and curious about the <em>actual</em> experience and <em>actual</em> results the technique or methodology provide.</p>
<p>TDD is a perfect example because everybody is always talking about its objective benefits, such as a safety net for major refactorings, enabling collective code ownership, cleaner API&#8217;s resulting from testable API&#8217;s, but the real value of TDD is a complex mix of all of these things and more. You can listen with your jaw agape to&#160; someone extolling its benefits for days at a time but until you actually start to practice it you can&#8217;t really have any understanding of it at all. This is true with <em>everything, </em>but with TDD the effect is very dramatic, and therefore very instructive. People are always saying &quot;it&#8217;s about design, not testing&quot; but then they go on to describe benefits that are often mostly about testing. This is because the design aspect of TDD is something you will feel when you try it with an open mind, it is extremely difficult to articulate. The results are not so hard to articulate, such as decreased coupling or increased isolation, but an understanding of why these benefits result from TDD is more visceral than intellectual.</p>
<p>People talk about learning curves as if they were impediments to obtaining the bountiful rewards of some shiny new methodology, but the learning curve is exactly what produces the rewards. The learning curve IS the primary value. The moment the learning curve flattens out is the moment you will find a new methodology to replace the old one. Ian said in his post that change results from the pain of a process outweighing our natural resistance to change, but I completely disagree. I believe change is the fundamental and most basic aspect of our professional lives, the very reason we enjoy what we do as much as we do, and that methodologies evolve not at the last possible moment when we can&#8217;t stand the agony any longer but at the first possible moment, the very moment we suspect our current practices cannot evolve any further. A work environment where nothing changes, where technologies are frozen at some arbitrary point in time and previously established development practices have taken on the aura of biblical law are most developers worst nightmare.</p>
<p>Yet, as <a href="http://www.udidahan.com/2008/09/30/unit-testing-for-developers-and-managers/">Udi Dahan</a> points out, we often feel we are not at liberty to go off experimenting with change at the expense of pressing business realities. And this is true to a large extent, and I agree with his conclusions - TDD or any other new process should be introduced into an environment responsibly, ensuring an appropriate level of safety for the business as well as the team, or the results could well end in disaster. The danger, though, is to use that as an excuse to avoid accepting change altogether. While it is suicide to ram some new methodology into the gears of a running machine, a more sinister form of suicide is to neglect change entirely because no time ever feels like the right time. Consciously and constantly adapting to change should be built into the foundation of your business culture and your development culture. This is the responsibility of the management <em>and</em> line level developers alike. If your company is not interested in continuously evolving along with the software industry and therefore does not provide a safe (if controlled) environment for experimenting with and adopting new technologies, practices and methodologies then you should find another job. Conversely if a developer on your team is not interested in adapting to change then you should transition them off your team, either out of the company or into a support role.</p>
<p>Finally, all this highlights for me the need to emphasize that business results are not why we come to work every day. You may like to believe that you invest yourself as deeply as you do in your career because you want to contribute to the success of your business, or provide the best possible experience for your users, or streamline business processes, and these things mean something, but you know and I know that those reasons aren&#8217;t the real reason you show up at your keyboard. You love your job because it is mysterious and fascinating and full of creative possibilities and interesting logical puzzles which give you immense pleasure to solve and explore. You love to create something out of nothing. Fortunately, this kind of enjoyment usually aligns, or can be made to align, quite well with business objectives. But the point is motivation - yes developers want to be efficient, yes developers want to deliver maximum business value, but even more than that they want to maximize their creative possibilities and they want to enjoy the time they spend in front of their computers. So if you want to sell TDD, Agile, IoC, or whatever it is, don&#8217;t forget to sell that aspect of things as well as the objective, tangible efficiency or quality gains.</p>
<p>My team recently attended an <a href="http://en.wikipedia.org/wiki/Open_Space_Technology">Open Space</a> conference, Open Agile 2008, which is a sort of new age, ad-hoc, self organizing meeting of passionate people. An Open Space conference has a number of principals, but the one that really caught my attention was the commandment to &quot;Be Prepared To Be Surprised.&quot; What is meant is this: put aside your pre-conceptions and expectations and expect to learn something new at any given moment, and in unexpected ways. This applies equally well to a new technology or methodology such as TDD: &quot;You will come away with full test suites that will dramatically improve the quality of your software, your designs will have lower coupling and a cleaner API and fewer defects. Oh, and be prepared to be surprised.&quot; </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=RiMpM"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=RiMpM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=XeEDm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=XeEDm" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=kPqlm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=kPqlm" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=dyPbm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=dyPbm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/417602227" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/10/be-prepared-to-be-surprised/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/10/be-prepared-to-be-surprised/</feedburner:origLink></item>
		<item>
		<title>Google Chrome, I could kiss you! (Or, multi-process browsers are a really good idea)</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/408673222/</link>
		<comments>http://www.thefreakparade.com/2008/10/google-chrome-i-could-kiss-you-or-multi-process-browsers-are-a-really-good-idea/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 22:43:16 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/10/google-chrome-i-could-kiss-you-or-multi-process-browsers-are-a-really-good-idea/</guid>
		<description><![CDATA[Recently I&#8217;ve been doing most of my web browsing using Chrome, because it is new and fast and I generally don&#8217;t use a lot of plug-ins. Currently I have about 20 tabs open in the browser because I&#8217;m doing research on a few topics at once. Probably like most people, when I find some content [...]]]></description>
			<content:encoded><![CDATA[<p><img height="87" src="http://www.google.com/tools/dlpage/res/chrome/images/chrome-205_noshadow.png" width="87" align="left" />Recently I&#8217;ve been doing most of my web browsing using <a href="http://www.google.com/chrome">Chrome</a>, because it is new and fast and I generally don&#8217;t use a lot of plug-ins. Currently I have about 20 tabs open in the browser because I&#8217;m doing research on a few topics at once. Probably like most people, when I find some content I know I&#8217;ll want to read, I <img src="http://www.amnh.org/education/resources/rfl/web/earthmag/mundo/images/poof.gif" align="right" />continue my further explorations in a new tab expecting to go through all the tabs later to read what I want to read or to catalog my findings using <a href="http://www.laterloop.com/">LaterLoop</a> or <a href="http://delicious.com/">Delicious</a>. This works really well, except that every once in awhile something runs afoul in a particular web page and <em>poof</em> goes the browser. In IE 7, well, sucks to be me when that happens. My tabs were almost never restored. In FireFox 3 an unexpected crash did restore tabs upon reload, but the browser crashed a *lot* and starting a new instance and waiting for the tabs to load all at once is slow and rather painful. Worse, the web page that caused the crash would&#160; be usually be marked for restore, so very often after a crash choosing to restore the previous session would result in a new crash, in an endless loop until I gave up on restoring the session or managed to get to the offending tab with a mad dash of my mouse and close it before it loaded the poisoned part of the page. </p>
<p>Well, those days of agony and uncertainty are gone with the introduction of &quot;process-per-tab&quot; browsing found in Chrome. I believe the newest version if IE will also support this model. Anyway, my computer suddenly slowed to a crawl, and task manager showed Chrome as the culprit. But not Chrome in general, just a tab in chrome. Actually, not a tab in chrome either, a window inside a tab in chrome that was hosting a flash animation, which had run amuck. Chrome actually has its own task manger, so the solution to my problem? Right click on the Chrome tool bar, choose task manager, look for excess processor usage, kill said process - and all is well. All 20 tabs breathed a collective sigh of relief, and I un-wet my pants and kissed my monitor. The damage? A portion of one of the web pages I had open showed a broken plugin graphic and a nice little notice at the top of the page said something like &quot;A flash plug-in has crashed.&quot; A single tear rolled down my cheek for the poor, lonely flash animation I was forced to kill, but many more lives were saved. Thus is the price of progress.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=U3EtM"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=U3EtM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=Uydum"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=Uydum" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=Fmj7m"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=Fmj7m" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=CGlnm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=CGlnm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/408673222" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/10/google-chrome-i-could-kiss-you-or-multi-process-browsers-are-a-really-good-idea/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/10/google-chrome-i-could-kiss-you-or-multi-process-browsers-are-a-really-good-idea/</feedburner:origLink></item>
		<item>
		<title>New Open Source .NET CMS/EPS Platform Released Today: Sense/Net 6.0 Beta 1</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/408647325/</link>
		<comments>http://www.thefreakparade.com/2008/10/sensenet-60-cmsenterprise-portal-beta-1-released/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 22:07:07 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/10/sensenet-60-cmsenterprise-portal-beta-1-released/</guid>
		<description><![CDATA[A while ago I did a survey of some the CMS solutions available for the .NET platform. While there are currently a very large number of both commercial and open source CMS solutions available, the one that really caught my attention wasn&#8217;t available at the time for public review. Now it is not only available [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://wiki.sensenet.hu/images/wikilogo.png" align="right" />A while ago <a href="http://www.thefreakparade.com/2008/07/content-management-systems-cms-for-the-net-platform/">I did a survey</a> of some the CMS solutions available for the .NET platform. While there are currently a very large number of both commercial and open source CMS solutions available, the one that really caught my attention wasn&#8217;t available at the time for public review. Now it is not only available for download in either source or binary format, but is backed by what at first blush appears to be pretty extensive documentation via a dedicated wiki. </p>
<p>I&#8217;ll be taking a closer look at this over the next few weeks, but my general feeling is that this product will add tremendous value to the community, despite the many existing CMS products already available, and I am very excited to kick the tires. </p>
<h2>Project Links</h2>
<h3><strong></strong></h3>
<p><strong>* Main Product Page: </strong><a href="http://www.sensenet.hu/engine.aspx"><strong>http://www.sensenet.hu/engine.aspx</strong></a></p>
<p><strong>* CodePlex site: </strong><a href="http://www.codeplex.com/sensenet"><strong>http://www.codeplex.com/sensenet</strong></a></p>
<p><strong>* Documentation Wiki: </strong><a href="http://wiki.sensenet.hu/index.php?title=Main_Page"><strong>http://wiki.sensenet.hu/index.php?title=Main_Page</strong></a></p>
<p><strong>* Discussion Forum: </strong><a href="http://forum.sensenet.hu/"><strong>http://forum.sensenet.hu/</strong></a></p>
<h2>Sample Sites</h2>
<p>Additionally, they have two case studies already of full blown, production sites built on their new system. The case studies give a brief overview of the projects and link to the live sites. Both of the case study web sites are Hungarian, though, so the experience is a bit awkward (unless you can read Hungarian, of course), but still gives you a flavor for the CMS. [Update] - the Invitel site has an English version here: <a href="http://english.invitel.hu">english.invitel.hu</a></p>
<p>&#160;</p>
<p><a style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" href="http://www.sensenet.hu/engine.aspx?page=tv-2"><img src="http://www.sensenet.hu/resource.aspx?ResourceID=refshot-tv2" /></a><a style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" href="http://www.sensenet.hu/engine.aspx?page=Invitel"><img src="http://www.sensenet.hu/resource.aspx?ResourceID=refshot-invitel" /></a></p>
<p>&#160;</p>
</p>
<p><a href="http://www.sensenet.hu/engine.aspx?page=Invitel"></a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=kZYKM"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=kZYKM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=lEeam"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=lEeam" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=hzYdm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=hzYdm" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=wV3Dm"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=wV3Dm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/408647325" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/10/sensenet-60-cmsenterprise-portal-beta-1-released/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/10/sensenet-60-cmsenterprise-portal-beta-1-released/</feedburner:origLink></item>
		<item>
		<title>What Lao Tse thinks of TDD</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/400546531/</link>
		<comments>http://www.thefreakparade.com/2008/09/what-lao-tse-thinks-of-tdd/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 06:57:02 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[Agile]]></category>

		<category><![CDATA[Sermons]]></category>

		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/09/what-lao-tse-thinks-of-tdd/</guid>
		<description><![CDATA[Summer is tumbling into fall and apparently it has stirred the technology muses because the last few days seem to have invoked a collective urge to wax philosophical about development practices in the small corner of the blogosphere that I follow. Jimmy Bogard started the ball rolling comparing  TDD to living a more healthy lifestyle, [...]]]></description>
			<content:encoded><![CDATA[<p>Summer is tumbling into fall and apparently it has stirred the technology muses because the last few days seem to have invoked a collective urge to wax <img src="http://blogs.itworldcanada.com/shane/files/2007/12/thinker.jpg" alt="" width="197" height="276" align="right" />philosophical about development practices in the small corner of the blogosphere that I follow. Jimmy Bogard started the ball rolling <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/09/18/tdd-design-trade-offs-and-junk-food.aspx">comparing  TDD to living a more healthy lifestyle</a>, Ayende expressed his understanding of the true, <a href="http://ayende.com/Blog/archive/2008/09/20/that-agile-thing.aspx">sensitive core of Agile</a>, Kyle Bailey wondered aloud if the <a href="http://codebetter.com/blogs/kyle.baley/archive/2008/09/20/do-the-right-thing-assuming-you-know-what-that-is.aspx">ALT.NET horse is pulling too far ahead of the cart</a>, Rod Cottingham of ReadWriteWeb briefly awakened from his Social Media junky trance to <a href="http://www.readwriteweb.com/archives/spirituality_and_technology.php">wonder if there wasn&#8217;t more to life</a> before pushing in the plunger once more and sinking back into the carpet, and the usual band of roaming ALT.NET monks came to the <a href="http://davybrion.com/blog/2008/09/is-teaching-tdd-worth-it/">vigorous</a> <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/09/21/ten-tips-to-maximize-the-return-on-your-tdd-investment.aspx">defense</a> of <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/09/22/a-tdd-investment-addendum.aspx">TDD</a>, which was apparently issued a challenge on the ALT.NET mailing list. All this in addition to the usual, melodious gospel music emanating from <a href="http://www.lostechies.com/blogs/">Los Techies</a> and <a href="http://www.lostechies.com/blogs/">CodeBetter.com</a>.</p>
<p>For me, it was quite a treat. In addition to being a rabid technologist, I am also an armchair philosopher, so this kind of material is food for me. I will have more to say about the enormous question so fleetingly put in <a href="http://www.readwriteweb.com/archives/spirituality_and_technology.php">Rod Cottingham&#8217;s post</a> another time, but today I want to think a little bit about the flurry of emotion regarding TDD, because while the passion its practitioners exhibit for the methodology is in itself compelling I don&#8217;t feel they are otherwise expressing its true value very effectively to those who I presume they are speaking, which is to say to me, the layman and the novice.</p>
<p>I myself have only just begun to experiment with Test Driven Development in particular and Agile methodologies in general, along with the rest of my small and equally inexperienced team. Speaking from such a demographic, I can confirm that TDD is a difficult discipline to become comfortable with. Speaking from a project management perspective, I can also confirm that starting from standing still getting up to cruising speed with TDD is, at least superficially, expensive from a productivity standpoint. I believe every member of my team is both talented and passionate about the mystical process of creating quality software, but taking up TDD is nevertheless quite challenging.</p>
<p>Even so, our limited and amateurish experience with TDD so far has deeply impressed all of us, so much so that the productivity cost of the learning curve has never once felt like anything but an investment. To wonder whether or not the cost is worth the benefit is perplexing to me, I can&#8217;t imagine having that emotion. Maybe I&#8217;m spoiled by the talent and passion of my colleagues, maybe if you find yourself alone amongst a crew of 9 - 5 clock punchers the row is much tougher to hoe, but you don&#8217;t have to scratch very deep into the surface of TDD to find its extraordinary value, even though it does require constant discipline (which often falters, by the way) to continue using it, at least at the early stages we are in.</p>
<p>What is this great value that outweighs the effort?</p>
<p>Well, there isn&#8217;t any point in my spelling out the tangible, objective benefits. <em>That</em> the TDD monks express quite well, and anyway I&#8217;m a layman, so I wouldn&#8217;t be able to do it effectively in any case. What I find strange, though, is how TDD seems to always be discussed outside of its Agile context - as if it were a side dish you could have with any kind of meal without it losing any of its overall value. Rather, I see TDD as the chorus to the Agile song - it may be beautiful to sing in isolation, but it grew out of, and belongs to, a larger melody, and to really understand its value an experience and understanding of the larger context is of the utmost importance.</p>
<p>The larger context? Iterative, outside in development, of course. Agile is a highly iterative development methodology that focuses first on the need and then on the implementation in short repetitive cycles. It has the potential to transform software development from a giant thought experiment in which we attempt to construct  tightly fitting, complicated wardrobes of clothes for our customers by asking them to describe the shapes of their bodies in perfect detail and list up front every social function they will ever need to attend, to one in which we take small, precise measurements, create one article of clothing at a time, try it on the customer, have them spin in front the mirror, and make adjustments accordingly: to the patterns, to the materials, to our tools and our processes.</p>
<p>The universe itself is rhythmic, cyclical and defined by nothing if not constant change, and so therefore are our lives, our work and the needs of our businesses. Software, unlike other more traditional engineering disciplines that deal with physical space and universal themes, must keep constant pace with the rhythm and change of human activity for it to be useful. Not only that, but the complex needs software aims to serve cannot simply be measured, like a plot of land or the gorge a bridge must cross, it must intersect usefully with myriad human minds rather than relatively predictable physical material, and the human mind is famous for not knowing itself very well.</p>
<p><img src="http://images.encarta.msn.com/xrefmedia/aencmed/targets/images/scp/T014300A.gif" alt="" align="right" />So Agile attempts to adjust for this by addressing human need in an interactive way - assess the general outline of the need first, build a little something, see how it fits, make adjustments here and there, fill the general shape of the need, add the detail in layers as it is discovered. It brings to my mind an image of a potters wheel - the clay spins always, an iteration at a time, you shape a vessel first with your fingers, relying as much on tactile feedback as you do your logical understanding. Then you apply detail, little by little, and when it is finished you can fire it in the kiln and paint it, but not before. If you build the detail too soon, it will quickly get rubbed away as the true need emerges, or worse, it will remain because you&#8217;ve put the thing in the kiln too soon, but it won&#8217;t be appropriate to the piece you&#8217;re creating, so you cover it up with fresh clay and fire it again, and you end up with something structurally unsound, or ugly, or altogether useless.</p>
<p>What does all this melodrama have to do with TDD? TDD is your fingers in the clay. Code <em>is</em> clay, after all, not gears and pistons and fittings, it has constraints, of course, but is largely pliable imagination. TDD is what finds an ideal shape for the code that is elegant, appropriate and capable of realizing the emerging and actual (not theoretical) needs of your customers as they are incrementally uncovered by the larger Agile process. TDD feels out, <em>does not deduce via thought experiment</em>, an appropriate API. This has been my takeaway from our limited experiments with the methodology, at any rate. TDD as the smallest possible step, the smallest possible rhythm, red-green-refactor, red-green-refactor, you rely predominantly on a sense of practical aesthetic, an ability of the mind to find a natural shape for things, a process that is usually expressed in terms of &#8220;reducing friction&#8221; by the community of vocal practitioners. Of course this <em>is</em> a logical process too, of course, not just an artistic one, there are general rules and guidelines, it is a strange coupling of mathematics and logic with imagination and creativity and pseudo-tactile feedback. Your mind is clicking along in a scientific way, but a larger part of the brain is enlisted to participate, a part that, as engineers, we too often discount, more than just the cold eye of logic with too little information at its disposal and too high an opinion of itself. In the end its all very <a href="http://www.religioustolerance.org/taoism.htm">Taoist</a> <img src='http://www.thefreakparade.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> The <a href="http://www.tomthumb.org/taoisttales.shtml">Taoist butcher</a>, as you may know, never has to sharpen his knives because he always cuts his meat precisely along the grain - he isn&#8217;t cutting at all, actually, but merely separating the material along its natural seams. TDD aims to find those seams in the seemingly solid material of a programming language as it applied to a complex human problem and the result is often of very high quality, both aesthetically and functionally, and the secret is both qualities are the same quality when approached in this way.</p>
<p>Anyway, that was a lot of grandiose hoo ha, and I&#8217;d be surprised if any of you left brained technologists have made it this far. Whether or not I&#8217;ve made any sense, my main point is that when practitioners are always saying TDD is about design and not about testing, I think this is in essence what they mean. Even if it isn&#8217;t, that distinction - the distinction between &#8220;design&#8221; and &#8220;testing&#8221; is tragically under-emphasized, or at least under-explained, and that distinction, in my mind, is the crux of the whole matter, is the first thing that should be said about TDD to anyone who is interested in listening. In that context, the question of &#8220;is it worth the cost&#8221; is almost nonsensical.</p>
<p>If by some miracle you have read this far, I&#8217;d love to hear what you think - what is your understanding of TDD? Or, do I simply need to lay off <a href="http://en.wikipedia.org/wiki/Hookah">the hookah</a>?</p>
<p> </p>
<div style="background-color: cornsilk">
<p><strong>The Butcher</strong></p>
<p>There was once a butcher who was carving a joint of meat for a customer who had been coming for many years.</p>
<p> </p>
<p>“Pardon me,” the customer asked, “But isn’t that the same knife you had last year? Do you need to sharpen it often?”</p>
<p>“It’s the same knife I’ve had for the last 17 years,” the butcher replied, “And I haven’t had to sharpen it even once. For, when I cut the meat, I allow the knife to find its own way through the flesh without effort or stress.</p>
<p>“And when I come to a tricky bit with lots of cartilage, I just slow down and allow the mystery to solve itself and in no time the meat falls right off the blade.”</p>
<p><em>If there’s one thing the Taoists love, it’s getting things done without any effort at all</em></p>
<p> </p></div>
<p>Replace &#8220;Toaist&#8221; with &#8220;Programmer&#8221; in that last sentence and you have the essence of our industry <img src='http://www.thefreakparade.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=xr4PL"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=xr4PL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=mzV3l"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=mzV3l" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=1DtXl"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=1DtXl" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=bBk0l"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=bBk0l" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/400546531" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/09/what-lao-tse-thinks-of-tdd/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/09/what-lao-tse-thinks-of-tdd/</feedburner:origLink></item>
		<item>
		<title>Rule Based Access Control using an Expression Evaluator</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/395947491/</link>
		<comments>http://www.thefreakparade.com/2008/09/rule-based-access-control-using-an-expression-evaluator/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 06:44:16 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[DSL]]></category>

		<category><![CDATA[Identity]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/09/rule-based-access-control-using-an-expression-evaluator/</guid>
		<description><![CDATA[I&#8217;ve written previously about &#8220;claims based authorization,&#8221; and how I believe it will eventually become a ubiquitous approach to identity management as the world of online digital identity reinvents itself in order to avoid implosion. If you aren&#8217;t familiar with the concept of claims based identity, I recommend checking out the post linked above or [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a href="http://www.thefreakparade.com/2008/08/identitys-new-identity-part-2-the-lay-of-the-land/">written previously</a> about &#8220;claims based authorization,&#8221; and how I believe it will eventually become a ubiquitous approach to identity management as the world of online digital identity reinvents itself in order <a href="http://www.thefreakparade.com/2008/08/identitys-new-identity-part-1-a-birds-eye-view/">to avoid implosion</a>. If you aren&#8217;t familiar with the concept of claims based identity, I recommend checking out the post linked above or following some of the links from <a href="http://www.thefreakparade.com/2008/08/identitys-new-identity-part-4-the-links-or-identity-for-net-hyperlink-acupuncture/">this post</a>.  If you just want to examine the sample code for this post, <a href="http://www.codeplex.com/IdentityAtRest/SourceControl/ListDownloadableCommits.aspx">it is here</a>.</p>
<p>In this post I&#8217;m interested in how a set of claims presented by a user when making a service call can be evaluated against specific authorization rules to determine whether or not the user has access to the requested resource.</p>
<p>The details of how a user is associated with such claims, how they are secured, and how claims are embedded inside calls to your service are beyond the scope of this post, but the links listed above should provide a place to put the tip of that chisel. For the purposes of this post I will assume that claims are presented via a list of IClaim objects, and an IClaim is nothing but a Name/Value pair - IList&lt;IClaim&gt;. This is very similar to how Micrisofts new Zermatt Identity Framework represents claims, and this was intentional as I believe that Zermatt is probably the future of Identity Management on the .NET platform.</p>
<p>So then, given IList&lt;IClaim&gt; claims, how can we make rational authorization decisions, such as &#8220;I only want users who are in the Premium Members role and whose age is older than 21 to access this (probably seedy) service method.&#8221; One obvious, simple approach would be to evaluate the claims programmatically. Some simple extension methods can make this much easier:</p>
<pre>
<pre name="code" class="csharp">

public static class ClaimsExtensions
{
   public static T GetClaimValue&lt;t&gt;(this IList&lt;iclaim&gt; claims, string claimType)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               return TypeNormalizer.EnsureType&lt;t&gt;(claim.Value, default(T));
           }
       }
       return default(T);
   }

   public static bool ClaimEqualsAny(this IList&lt;iclaim&gt; claims, string claimType, string claimValue)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               if (claim.Value.Equals(claimValue, StringComparison.InvariantCultureIgnoreCase))
                   return true;
           }
       }
       return false;
   }

   public static bool EvaluateClaim&lt;t&gt;(this IList&lt;iclaim&gt; claims, string claimType, Func&lt;t , bool&gt; eval)
   {
       var claimValue = claims.GetClaimValue&lt;/t&gt;&lt;t&gt;(claimType);
       return eval(claimValue);
   }
}
</pre>
<p></t></iclaim></t></iclaim></t></iclaim></t></pre>
<p>Then, from within a method that needs protecting, you can easily do something like this:</p>
<pre>
<pre name="code" class="csharp">

public void MyServiceMethod()
{
    if (CurrentUser.Claims.EvaluateClaim&lt;int&gt;(CustomClaimTypes.AgeInYears,age =&gt; age &lt; 21) ||
        CurrentUser.Claims.ClaimEqualsAny(CustomClaimTypes.Role,&quot;Premium User&quot;) == false)
    {
	//Whatever you do when someone isn&#039;t authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}
</pre>
</pre>
<p>If you were clever, you could probably figure out a way to use LINQ expressions to make the syntax even cleaner. This is all good and well, but it has at least one major problem - authorization rules are probably likely to change far more frequently than your application code. Even worse, you may wish your power users to be able to manage their own authorization rules for certain kinds of access or for named permissions. Using the technique described above, any change to any authorization rule will require you compile and deploy your application.</p>
<p>One common solution to conundrums such as these is to use a DSL (Domain Specific Language). And while you certainly could write a custom DSL to implement your authorization rules, authorization rules have an interesting characteristic: they always resolve to a discrete value, a true or a false. They are simply boolean expressions.</p>
<p>There are a number of Expression Evaluators available from the open source community that will fit the bill perfectly. An Expression Evaluator will allow you to specify your authorization rules as simple strings, which means they can be stored in a configuration file or a database or some other persistent store and modified and run-time as needed. They are also serializable by definition and can easily be requested by and cached at the user interface to allow the user interface to use the same authorization logic  to render itself appropriately with respect to the permissions of the currently logged in user that the server will use to authorize access to its API without (necessarily) having any code in common other than a reference to the same expression evaluator library.</p>
<p>In this example I will be using <a href="http://www.thefreakparade.com/2008/08/simple-expression-evaluator-project-now-on-codeplex/">Simple Expression Evaluator</a> available <a href="http://www.codeplex.com/SimpleExpressionEval">on Codeplex</a>. I chose this library purely out of nepotism, because I wrote it, but you should be able to use any expression evaluator that catches your fancy. A number of options for .NET are <a href="http://www.thefreakparade.com/2008/07/evaluating-expressions-at-runtime-in-net-c/">listed here</a>.</p>
<p>Using an Simple Expression Evaluator we could rewrite the above authorization rule like this:</p>
<pre>AgeInYears &gt;= 21 and MatchesAny(Role = "Premium User")</pre>
<p>In the sample project I added a custom function, IsInRole, allowing this syntax:</p>
<pre>AgeInYears &gt;= 21 and IsInRole("Premium User")</pre>
<p>To make this happen, Simple Expression Evaluator will need a little help in interpreting claim names. The main reason behind this is that claims are usually represented by a URI, such as http://thefreakparade.com/claims/role, but accessed through code using string constants, such as</p>
<pre>
<pre name="code" class="csharp">

public static class CustomClaimTypes
{
     public const string Role = &quot;http://thefreakparade.com/claims/role&quot;;
     //...more...
}
</pre>
</pre>
<p>and therefore accessed in code like this:</p>
<pre>
<pre name="code" class="csharp">

var claim = new Claim(CustomClaimTypes.AgeInYears,43);
</pre>
</pre>
<p>The expression evaluator will interperet something like AgeInYears to be a variable, and the name AgeInYears won&#8217;t naturally correspond to anything, because it&#8217;s really just a property name, the real claim is represented by a URI that would be far too ugly to stick in an expression. The solution is to give the expression evaluator a little help when evaluating variables, like so:</p>
<pre>
<pre name="code" class="csharp">

public bool Authorize(IList&lt;iclaim&gt; claims,string authExpression)
{
    var context = new ExpressionContext(claims);

    context.ResolveUnknownVariable +=
        (sender, args) =&gt;
            {
               args.VariableValue =
                 claims.GetClaimValue(_claimAliases[args.VariableName]);

            };

    context.ResolveMissingFunction +=
        (sender, args) =&gt;
            {
                if (args.FunctionName.Equals(&quot;IsInRole&quot;,StringComparison.OrdinalIgnoreCase))
                {
                    args.Function = (funcArgs) =&gt; IsInRole(claims,funcArgs);
                }
            };

    return ExpressionEvaluator.EvaluateExpression(authExpression,context);    

}
</pre>
<p></iclaim></pre>
<p>This method was modified a little from the actual sample to the purpose of clarity, but the general idea is the same. Also demonstrated is the technique required to add an IsInRole method to the expression language. The actual implementation of the IsInRole functionality is implemented off screen, see the sample for the actual code. This method also relies on a hashtable called _claimAliases being pre-populated with a mapping between the URI of a claim type and the friendly name the expression language will use. In the sample app, I simply used reflection to load the alias table with a mapping between the field name of each const and the actual URI.</p>
<p>Now, if you simple use the expression evaluator an call Authorize from within your service methods, like this:</p>
<pre>
<pre name="code" class="csharp">

public void MyServiceMethod()
{
    if (AuthorizationHelper.Authorize(
           CurrentUser.Claims,&quot;AgeInYears &gt;= 21 and IsInRole(&#039;Premium User&#039;)&quot; == false)
    {
	//Whatever you do when someone isn&#039;t authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}
</pre>
</pre>
<p>Then all we added with the dynamic expression was complexity - your rules are still defined inline in your code. What you really want is a syntax like this:</p>
<pre>
<pre name="code" class="csharp">

public void MyServiceMethod()
{
    if (AuthorizationManager.Authorize(CurrentUser.Claims,Permissions.CanAccessServiceMethod) == false)
    {
        //no access
    }
    //service code
}
</pre>
</pre>
<p>Where Permissions.CanAccessServiceMethod will key into a persistent authorization rule store such as a config file or database, so that the rule expressions themselves can be dynamically loaded at runtime and therefore modified outside of the code. The sample application takes advantage of a very simplified implementation of the <a href="http://martinfowler.com/eaaCatalog/repository.html">Repository pattern</a> and introduces an IAuthorizationRuleRepository to solve that issue. If you were really, really smart you could get to a syntax like this without much extra effort. Note this sample application does not quite go this far, but it shouldn&#8217;t be a stretch for you get there yourself if you care to:</p>
<pre>
<pre name="code" class="csharp">

[RequiresPermission(Permissions.CanAccessServiceMethod)]
public void MyServiceMethod()
{
    //service code
}
</pre>
</pre>
<p>The only caveat with an attribute based approach is that access to your protected method is all or nothing. You can&#8217;t return a set of records filtered one way when one permission level is present, and another for a lower level of permission. But nothing would prevent you from mixing an attribute based approach with an inline-code based approach as appropriate.</p>
<p>Finally, here is a sample of the actual authorization syntax as implemented by the Identity at Rest sample application:</p>
<pre>
<pre name="code" class="csharp">

public List&lt;monkey&gt; ListAllMonkeys()
{
    //Only administrators can list all monkeys.
    //Everyone else can just list shaved monkeys.
    if (AuthorizeFor(
            Permissions.MonkeyShavingService.CanViewUnshavedMonkeys) == false)
    {
        return ListMonkeysByStatus(MonkeyStatus.ShavedClean.ToString());
    }

    return _monkeys;
}
</pre>
<p></monkey></pre>
<p>And that&#8217;s about it. If you&#8217;ve made it this far, your very well aware that this post is describing a general approach to claims based authorization using an expression oriented DSL - the code samples listed here aren&#8217;t detailed enough to get you from point A to point B in an actual implementation. However, the <a href="http://www.codeplex.com/IdentityAtRest">included sample application</a>, which is an evolution of the Identity At Rest sample application provided for <a href="http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-2-a-solution/">this post</a>, does provide an end to end application that fully implements the concepts discussed here. The sample comes with a &#8220;smart client&#8221; Winforms application that uses WCF to communicate with a remote  REST based API. All API calls are secured using the above described techniques.</p>
<p>I would be the last one to suggest that this approach is a &#8220;best practice&#8221; in managing claims based authorization, but it made sense to us and seems to work pretty well so far.  As always, I&#8217;d love to hear about any other approaches that you may be using.</int></pre>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=PGFFL"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=PGFFL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=p54Ql"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=p54Ql" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=wLftl"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=wLftl" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=Vme3l"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=Vme3l" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/395947491" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/09/rule-based-access-control-using-an-expression-evaluator/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/09/rule-based-access-control-using-an-expression-evaluator/</feedburner:origLink></item>
		<item>
		<title>CrapOverflow? Really? Oooooooook then… (Or, the fallacy of elitism)</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/392126624/</link>
		<comments>http://www.thefreakparade.com/2008/09/crapoverflow-really-oooooooook-then-or-the-fallacy-of-elitism/#comments</comments>
		<pubDate>Sun, 14 Sep 2008 07:13:57 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[Sermons]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/09/crapoverflow-really-oooooooook-then-or-the-fallacy-of-elitism/</guid>
		<description><![CDATA[I noticed an incoming link to this blog today coming from a site called crapoverflow.com, and since I know you&#8217;ll never guess it on your own I&#8217;ll just come out and tell you that it is a play on the name of the new programming Q + A web site stackoverflow.com (which I posted about [...]]]></description>
			<content:encoded><![CDATA[<p>I noticed an incoming link to this blog today coming from a site called <a href="http://www.crapoverflow.com">crapoverflow.com</a>, and since I know you&#8217;ll never guess it on your own I&#8217;ll just come out and tell you that it is a play on the name of the new programming Q + A web site <a href="www.stackoverflow.com">stackoverflow.com</a> (<a href="http://www.thefreakparade.com/2008/08/stackoverflowcom-first-impressions/">which I posted about</a> <a href="http://www.google.com/search?hl=en&amp;client=firefox-a&amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;hs=wcj&amp;q=%22a+while+back+ago%22&amp;btnG=Search">a while back ago</a>).</p>
<p>The crapoverflow.com web site seems to be just one page. In addition to the razor sharp wit of the name itself, crapoverflow sports a simply side splitting logo that lampoons the stackoverflow logo by making it look like the &#8220;stack&#8221; might be &#8220;crap&#8221; coming out of a toilet. Although my description should be vivid enough to elicit an HD quality image in your minds eye, I&#8217;ll paste the sites header into the post for those of you lacking imagination:</p>
<p><img src="http://crapoverflow.com/crapoverflow-300.png" alt="logo" /><br />
<em>Ask programming questions. Get answers&#8230; just not good ones.<br />
Stack Overflow is by programmers, for mediocre programmers — regardless of platform, or language.<br />
Jump in and share your lack of software engineering expertise! No accuracy or evidence is required. Ever.</em></p>
<p>The rest of the page is quotes from blog reviews, like the one from my (mostly positive) write up. All the quotes say something un-complimentary about stackoverflow.com. Before I continue, though, I would like to emphasize a few things: I am not writing this to defend stackoverflow.com from this  odd attack. I have little interest in stackoverflow.com personally and could care less about that  Also, I am not writing this to condemn the utterly juvenile author of crapoverflow.com for being utterly juvenile. Whoever took the time to register a domain name, create a logo and dig up any possible hint of a negative mention of stackoverflow.com was clearly slighted in a personal way by either the community that inhabits stackoverflow.com or Jeff Atwood or Joel Spolskey or a combination thereof. While I am tempted to say &#8220;time to grow up you sad, humiliated creature&#8221; I kind of think this kind of outlet is preferable to  showing up at the stackoverflow.com offices with a semi-automatic and a backpack full of pipe bombs.</p>
<p><a href="http://www.thefreakparade.com/wp-content/uploads/2008/09/image1.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://www.thefreakparade.com/wp-content/uploads/2008/09/image-thumb1.png" border="0" alt="image" width="156" height="122" align="right" /></a>So what <em>is</em> my point? A noble one: I will rise to the defense of the poor, downtrodden mediocrity. The &#8220;mediocre programmer&#8221; gets a lot of hate mail these  days, and it makes my skin crawl every time I see it. First of all, by definition, most programmers are mediocre. Even if most programmers were capable of hacking into NASA and re-programming the space shuttle to swing through a McDonalds drive through and bring them a happy meal, they would still be mediocre because most programmers <em>must</em> be mediocre, mathematics and the English language are very insistent in that regard. So mathematics and the English language being what they are, when a community develops on the Internet and begins to thrive, and it turns out that this community is made up of mostly *gasp* mediocre programmers, whose business is it to issue condemnations?</p>
<h3>Closet Mediocrity</h3>
<p>First, I&#8217;ve yet to meet the programmer who would classify themselves as mediocre. And yet statistically most of us are in those ranks. That means more than a few mediocre programmers are erroneously counting themselves among the elite. So unless you have some sort of proof (beyond the cajoling whisperings of your own ego) that your light shines brighter than that of the status quo, you better keep your yap shut on the matter.</p>
<h3>Community is Community</h3>
<p>If you start a Q + A site and the experts don&#8217;t show up, should the rest then lay down and die? Or rend their tunics and make sacrificial offerings hoping they will show up after all? If most of us are mediocre by definition, and we get together to help one another out as best we can, who is the victim? Let&#8217;s have a thought experiment shall we &#8230; let&#8217;s say I asked for some help and I received some advice and the advice turned out to be mediocre. Even so, despite its impurity, it helped me through my problem. It wasn&#8217;t the way an <em>expert</em> would have solved the problem, to be sure, but the expert never showed up to gift me with her genius, and yet things turned out OK in the end anyway. The solution to my problem, thanks to the mediocre chap that answered my mediocre question, was squarely mediocre. Actually since I myself am mediocre the solution fit in nicely with the rest of my mediocre project. It doesn&#8217;t strike terror into my heart to contemplate such a scenario, nor does it make me snigger condescendingly and count my lucky stars <em>I&#8217;m</em> not mediocre. It makes me glad such communities exist, because if the elite programmers are too busy writing software to lend a hand they may as well not exist, and yet we must march on, mediocre or not.</p>
<h3>Actually, We&#8217;re All Mediocre</h3>
<p>Whoever you are, you too are mediocre. Even if your genius in matters of programming is unparalleled then in your personal relationships, or your spiritual life, or in the sack, whatever, mediocrity has set a place for you at its table. But let&#8217;s reel it in a little and assume you&#8217;re not one of the half dozen most brilliant programmers in the world - in that case, I can make you an utterly mediocre programmer no matter who you are just by choosing the set of programmers in which you are to be counted. So mediocrity then is entirely relative, and therefore an illusion. To look down your nose at the man treading water down stream from you is to ignore the countless others who have already passed you by a mile. If the fellow is struggling and it distresses you, lend a hand. If you can&#8217;t be bothered, then don&#8217;t, he&#8217;ll do just fine. But it is vulgar and absurd to shout an insult at him, or to preach to others that its people like him who are keeping us from reaching our full potential.</p>
<h3>Is this the part where you say &#8220;Amen&#8221; and hand out the little crackers?</h3>
<p>Sooooo&#8230;thats it really. To be fair, the vast majority of people in the programming communites I haunt that I would consider to be &#8220;elite&#8221; expend vast amounts of effort feeding the community the fruits of their knowledge and insight, and usually with a reasonable amount of humility. It&#8217;s even a little <a href="http://www.thefreakparade.com/2008/07/beginners-mind/">awe inspiring</a> sometimes. It is usually the false-prophet, the average Joe that fancies himself a rock star, that is likely to make some pointless attack on the imaginary ranks of the mediocre (what I like to call  &#8220;spitting on Mort&#8221;). Even so, each time someone does this it leaks a little poison in the water supply we all depend on for survival, even though it is almost always unintentional. So if I had a particular point, I guess it would be to try to keep a few things in mind, especially when you feel the urge to jump onto a soap box and start talking down to people:</p>
<p>1. We&#8217;re <em>all</em> doing the <em>best</em> we can. Really. What else could we do?</p>
<p>2. Everybody has a right to lend a helping hand, to ask for help, to discuss a technology, to offer an opinion, to <em>participate</em>. If we all had to be experts and 100% sure of what we say in order to participate in the community you&#8217;d hear nothing but crickets, I guarantee it. If you encounter an error someone has made through inexperience, be generous and correct it, don&#8217;t complain about it, it makes you look ugly and as a result you won&#8217;t get laid without having to pay for it.</p>
<p>3. However smart you may be you&#8217;re a bumbling idiot compared to someone. Just keep that in mind and not only will you be more pleasant to be around but you&#8217;ll be more useful to the world and you&#8217;ll learn faster as well.</p>
<p><a href="http://www.thefreakparade.com/wp-content/uploads/2008/09/image2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://www.thefreakparade.com/wp-content/uploads/2008/09/image-thumb2.png" border="0" alt="image" width="134" height="111" /></a></p>
<p>Amen. Here is the body, and here is the blood. See you next Sunday.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=lTT9L"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=lTT9L" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=ZNBOl"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=ZNBOl" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=LQnOl"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=LQnOl" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=xnQil"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=xnQil" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/392126624" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/09/crapoverflow-really-oooooooook-then-or-the-fallacy-of-elitism/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/09/crapoverflow-really-oooooooook-then-or-the-fallacy-of-elitism/</feedburner:origLink></item>
		<item>
		<title>A Response to "On Passion"</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/384920253/</link>
		<comments>http://www.thefreakparade.com/2008/09/a-response-to-on-passion/#comments</comments>
		<pubDate>Sat, 06 Sep 2008 09:48:51 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[Sermons]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/09/a-response-to-on-passion/</guid>
		<description><![CDATA[Jimmy Bogard recently gave an interesting sermon on the topic of passion in software development. I always enjoy posts like this. While I love the technical insights that flow like a river from the software development community, there is an under-served but very real need to pan out from time to time and reflect on [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lostechies.com/blogs/jimmy_bogard/default.aspx">Jimmy Bogard</a> recently gave an <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/09/04/on-passion.aspx">interesting sermon</a> on the topic of passion in software development. I always enjoy posts like this. While I love the technical insights that flow like a river from the software development community, there is an under-served but very real need to pan out from time to time and reflect on the larger experience.</p>
<p>Software developers are an interesting breed - on the one hand we are technicians and engineers, a left-brained, puzzle solving people, and yet the medium in which we work is almost pure imagination. We sculpt more than we build, and yet we focus so intently on the mechanics and the techniques that I think we have a tendency to de-emphasize the broader creative process and the very human aspects of what we are really doing all day with these wonderful machines. So a discussion of passion, and particularly an encouragement to extend our passion beyond the realm of simply solving interesting logical puzzles, is refreshing and needed.</p>
<p>In his post Jimmy calls out the tendency of software developers to practice in an unbalanced way, to practice in a way that is obsessively, even selfishly focused on the self-gratifying enjoyment of technology for its own sake. If we were a self contained community of artists then it would be alright for us to practice in such a narrow minded way, we could revel in our technology with reckless abandon. But of course that is not the case. As a profession we are simply an organ in a much larger organism and we depend on the health and prosperity of the organism for our survival as much as it depends on us, despite our legendary hubris.</p>
<p>Observing this, Jimmy suggests that our ultimate success relies on our being as passionate about the domains we serve as we are about the software itself. He separates passion for &#8220;our craft&#8221; from passion for &#8220;the domain.&#8221; While I wholeheartedly agree with the underlying principal of what he is saying, I think his separating &#8220;the domain&#8221; from &#8220;the craft&#8221; and demanding software developers apply passion in equal measures to both does a great disservice to &#8220;the craft&#8221; and would be impossible to achieve for most of us in any event.</p>
<p>Any programmer reading Jimmy&#8217;s blog probably has little if any passion to spare. Software practitioners of an ilk that read blogs like those found at <a href="http://www.lostechies.com/">Los Techies</a> are not looking for new outlets through which to direct our energies; we are already giving all we can (and often more) to &#8220;our craft.&#8221; Asking us to become passionate about the domains we serve is like asking someone running a marathon to pull a rickshaw full of tourists while they&#8217;re at it. Is it possible? Maybe. But it&#8217;s also absurd.</p>
<p>However, I certainly don&#8217;t think it is healthy, sustainable or ethical for us to fornicate with our technology at the expense of our patrons. I agree with Jimmy that such an approach to software development cannot end in success. I do, however, believe that a more appropriate mental framework would be to expand the scope of what we mean by &#8220;our craft&#8221; instead of relegating &#8220;our craft&#8221; to the realm of technology and layering on the additional responsibility of &#8220;the domain.&#8221; Most of us cannot be passionate about &#8220;the domain&#8221; anyway - if we could, we would have different careers. But we can, and we should, be passionate about shaping software that best contributes to the health and prosperity of the businesses in which we operate. This may seem similar to being passionate about &#8220;the domain&#8221;, but it is not at all the same thing. We should be passionate about <em>our </em>domain, but <em>our </em>domain is not technology any more than an artists domain is paint. An artist obsessed with paint may create some very beautiful colors, but uninteresting paintings. No, our domain is software, and software is about nothing if it isn&#8217;t about people. So we <em>do</em> have to understand the domains we serve through and through, we <em>do</em> have to place the user experience above technological self-gratification, but we should not dilute our passion by attempting to extend it beyond creating delightful, functional software.</p>
<p>In the end I think Mr. Bogard and I are saying the same thing - I don&#8217;t think he actually meant to suggest that we truly become passionate about, say, medical billing or real time currency trading, or whatever world you happen to be working in, but that we become passionate not just about technology but also (and predominantly) about sculpting software systems that enable those that <em>are</em> passionate about those things to achieve ever increasing levels performance and creativity. And I couldn&#8217;t agree more.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=venuL"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=venuL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=gnCol"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=gnCol" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=DVa5l"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=DVa5l" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=2xM5l"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=2xM5l" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/384920253" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/09/a-response-to-on-passion/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/09/a-response-to-on-passion/</feedburner:origLink></item>
		<item>
		<title>Flowing Identity from a Client to a Service when using RESTful WCF Part 2 - A Solution</title>
		<link>http://feeds.feedburner.com/~r/TheFreakParade/~3/381065441/</link>
		<comments>http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-2-a-solution/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 05:14:26 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
		
		<category><![CDATA[Identity]]></category>

		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-2-a-solution/</guid>
		<description><![CDATA[This post will describe a technique to transparently insert a custom HTTP header into all requests generated by a WCF REST proxy, as well as a technique to extract that HTTP header from the request at the service for the purpose of flowing the digital identity of an authenticated user from a REST client to [...]]]></description>
			<content:encoded><![CDATA[<p>This post will describe a technique to transparently <a href="http://weblogs.manas.com.ar/waj/2007/05/13/rest-pox-client-with-wcf/">insert a custom HTTP header into all requests</a> generated by a WCF REST proxy, as well as a technique to extract that HTTP header from the request at the service for the purpose of flowing the digital identity of an authenticated user from a REST client to a REST service. In this case, digital identity is represented by an authorization token, which is just a string. You can read a detailed description of the problem in <a href="http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-1-the-problem/">Part 1</a> of this post. A <a href="http://www.codeplex.com/IdentityAtRest/Wiki/View.aspx?title=Home">complete sample project</a> containing the full source code of the solution is on CodePlex.</p>
<p>The basic idea is to insert a custom action into the WCF message pipeline that will extract a security token representing the identity of the currently logged in user and add the value of that token (just a string) to the outgoing API call (an HTTP request) by way of a custom HTTP header. Once the request is received by the service, a custom action inserted into the receive pipeline checks for the custom header and, upon finding it, de-serializes the identity token and uses the claims contained within it to set an appropriate security context (in this case by setting Thread.CurrentPrincipal).</p>
<h3>Setting a Custom HTTP Header - The Easy Way</h3>
<p>On the client side, I am making the assumption that a user has been authenticated somehow, is associated with a set of claims, and that a representation of the user along with her claims can be found at Thread.CurrentPrincipal. In anticipation of using Microsoft&#8217;s new <a href="http://www.thefreakparade.com/2008/08/identitys-new-identity-part-3-the-technology/">Zermatt Identity framework</a>, which introduces IClaimsPrincipal and IClaimsIdentity, we implemented our own versions of these interfaces. They will eventually be replaced by the Zermatt types once we start integrating Zermatt into our application. IClaimsPrincipal maintains a reference to IClaimsIdentity, which has a property of type IList&lt;IClaim&gt; that represents all the authorization relevant attributes of a user. Please see <a href="http://www.thefreakparade.com/2008/08/identitys-new-identity-part-2-the-lay-of-the-land/">this post</a> for a discussion of claims based identity management. The interface IClaim is pretty much just a name value pair.</p>
<p>Adding a custom header to a request is trivial if you add the header in the same scope as the service call made on the proxy. You can just wrap the entire call in an OperationContextScope using statement, and use the Headers property of WebOperationContext.Current:</p>
<pre>
<pre name="code" class="csharp">

using (var factory = new WebChannelFactory&lt;imyservice&gt;())
{
  IMyService proxy = factory.CreateChannel();
  using (new OperationContextScope((IClientChannel) proxy))
  {
    WebOperationContext.Current.OutgoingRequest.Headers.Add(&#039;x-mycompany-auth&#039;,
                                                            &#039;tokenString&#039;);
    proxy.DoItToIt();
  }
}
</pre>
<p></imyservice></pre>
<p>That technique works, and would probably be just fine if you only needed to add the authorization token to a few select calls. However, in our scenario, we want to add the token to *every* call, so wrapping each API call with all that scoping garbage isn&#8217;t going to cut it. It&#8217;s ugly and about as un-DRY as it gets.</p>
<h3>Extending WCF - The Transparent Way</h3>
<p>The solution, of course, is to take advantage of the <a href="http://msdn.microsoft.com/en-us/magazine/cc163302.aspx">WCF extensibility points available to both the client and the server</a>. We want to choose spots in the messaging pipelines as close to the actual delivery/receipt of the message as possible.That would be the the Message Inspection phase on the client and the Operation Context Initialization phase on the server.</p>
<p>WCF can be made to jump through our hoops by following these steps:</p>
<p><strong>On the client side we need to</strong></p>
<p>1. Define the MessageInspector</p>
<p>2. Create a behavior to register the MessageInspector</p>
<p>3. Install the behavior on the channel factory.</p>
<p><strong>On the service side we need to</strong></p>
<p>4. Define a OperationContextInitializer</p>
<p>5. Create a behavior to register the extension</p>
<p>6. Apply the behavior to the service.</p>
<p>The end result is that Thread.CurrentPrincipal on the service side will always reference an IClaimsPrincipal with the same claims associated with the Thread.CurrentPrincipal on the service consumer, and we can test those claims to authorize access, as demonstrated in</p>
<p>7. Use.</p>
<p><strong>1. The MessageInspector</strong></p>
<pre>
<pre name="code" class="csharp">

 public class ClientAuthMessageInspector : IClientMessageInspector
 {
        #region IClientMessageInspector Members

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            //Get the HttpRequestMessage property from the Message
            var httpRequest =
                request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

            //Make sure we have a valid property, or create one
            if (httpRequest == null)
            {
                httpRequest = new HttpRequestMessageProperty();
                request.Properties.Add(HttpRequestMessageProperty.Name, httpRequest);
            }

            //Add your token to the header. Simple as that.
            //In real life, we injected an ITokenProvider using an IoC,
            //instead of using static methods directly, but that was
            //overkill for a sample.
            httpRequest.Headers.Add(AuthenticationHelper.AUTH_TOKEN_HEADER_NAME,
                                    AuthenticationHelper.GetAuthTokenForCurrentUser());

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            //nop
        }

        #endregion
 }
</pre>
</pre>
<p><strong>2. The Behavior</strong></p>
<pre>
<pre name="code" class="csharp">

public class ClientAuthBehavior : IEndpointBehavior
{
        private readonly ClientAuthMessageInspector _messageInspector;

        public ClientAuthBehavior(ClientAuthMessageInspector messageInspector)
        {
            _messageInspector = messageInspector;
        }

        #region IEndpointBehavior Members

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            //Install the message inspector
            clientRuntime.MessageInspectors.Add(_messageInspector);
        }

        //no-op method implementations elided for clarity.
	//See the sample project for the complete
	//code listing.

        #endregion
}
</pre>
</pre>
<p><strong>3. Apply</strong></p>
<pre>
<pre name="code" class="csharp">

 private void InitializeChannelFactory()
 {
    _channelFactory = new WebChannelFactory&lt;imonkeyshavingservice&gt;(&quot;shavingService&quot;);
    _channelFactory.Endpoint.Behaviors.Add(new ClientAuthBehavior());
 }
</pre>
<p></imonkeyshavingservice></pre>
<p><strong>4. On the Service Side&#8230;OperationContextInitializer</strong></p>
<pre>
<pre name="code" class="csharp">

 public class ClaimsAuthContextInitializer : ICallContextInitializer
 {
     #region ICallContextInitializer Members
      public Object BeforeInvoke(InstanceContext instanceContext,
                                IClientChannel channel,
                                Message message)
     {
         DetectCurrentUser();
         return null;
     }

     public void AfterInvoke(Object correlationState)
     {
     }
     #endregion

     private static void DetectCurrentUser()
     {
         if (WebOperationContext.Current == null)
             throw new InvalidOperationException(&quot;Only HTTP web requests are supported for this version of the API&quot;);

          string authToken = WebOperationContext.Current
             .IncomingRequest
             .Headers[AuthenticationHelper.AUTH_TOKEN_HEADER_NAME];

         if (AuthenticationHelper.SetCurrentUserFromAuthToken(authToken) == false)
         {
             WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
                throw new UnauthorizedAccessException(
                 &quot;No authentication token was found in the headers of the current request.&quot;);
         }
    }
 }
</pre>
</pre>
<p><strong>5. The Behavior</strong></p>
<pre>
<pre name="code" class="csharp">

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class ClaimsAuthServiceBehavior : Attribute, IServiceBehavior
    {
        #region IServiceBehavior Members

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
                                         Collection&lt;serviceendpoint&gt; endpoints,
                                         BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;

                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {

                        foreach (var dispatchOperation in
                            ed.DispatchRuntime.Operations)
                        {
                            dispatchOperation.CallContextInitializers
                                .Add(new ClaimsAuthContextInitializer());
                        }

                    }
                }
            }
        }

        #endregion
</pre>
<p></serviceendpoint></pre>
<p><strong>6. Apply</strong></p>
<pre>
<pre name="code" class="csharp">

 static void Main(string[] args)
 {
      _host = new WebServiceHost(typeof(MonkeyShavingService),
                                 new Uri(&quot;http://localhost:8000&quot;));

      _host.Description.Behaviors.Add(new ClaimsAuthServiceBehavior());

       var binding = new WebHttpBinding();
       _host.AddServiceEndpoint(typeof(IMonkeyShavingService), binding, &quot;&quot;);

       _host.Open();

       Console.WriteLine(&quot;Press any key to exit.&quot;);
       Console.ReadKey();
 }
</pre>
</pre>
<p><strong>7. Last but not least, Use (this is a sample service method that restricts access to certain users)</strong></p>
<pre>
<pre name="code" class="csharp">

 public Monkey PutMonkeyInShaver(Monkey monkey)
 {
      //Only authenticated users can add monkeys to the shaver
      if (CurrentUser == null)
      {
       SetStatusCode(HttpStatusCode.Forbidden,
                     &quot;Only authenticated users can put monkeys in the shaver.&quot;);
       return null;
      }

      _monkeys.Add(monkey);
      ShaveMonkey(monkey);
      return monkey;
 }

 private IClaimsPrincipal CurrentUser
 {
     get { return Thread.CurrentPrincipal as IClaimsPrincipal; }
 }
</pre>
</pre>
<p><strong>It works, but&#8230;</strong></p>
<p>Our ultimate solution does not extend or take advantage of any of the claims based security features built into WCF. While it may be possible to do so, it wasn&#8217;t immediately obvious to us how to go about it, so the solution presented here handles authorization out of band from the built in WCF authorization mechanisms.</p>
<p>As you may have guessed, I am NOT a WCF expert. That means that the approach outlined here could very well be a cheap hack for a problem solvable in a much more elegant way. If by some chance you happen across this post and know that to be the case, I&#8217;d love to hear your thoughts on the subject <img src='http://www.thefreakparade.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> I wasn&#8217;t able to find any guidance during my own research that hinted at a more appropriate approach to solving this problem, but that certainly doesn&#8217;t mean one doesn&#8217;t exist.</p>
<p><strong>About the Sample Application</strong></p>
<p>The sample application <a href="http://www.codeplex.com/IdentityAtRest/Wiki/View.aspx?title=Home">can be downloaded here</a> and includes a complete, end to end REST API implemented in WCF. It includes separate DLL&#8217;s to represent the Service, the Contracts, the Client, a Service Host and a Utility DLL that contains shared authentication and authorization code. To get the most from the sample you should run the Service Consumer project, a Windows Forms application that allows you to invoke various operations of the API while impersonating users with various roles. In addition to demonstrating a possible approach to flowing a claims-based security token through a REST API, the sample demonstrates a fully functional, RESTful WCF service, which may be useful to you in its own right.</p>
<p>Here is a screen shot of the sample Windows Forms service client:</p>
<p><img src="http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=IdentityAtRest&amp;DownloadId=42979" alt="" /></p>
<p><strong>What&#8217;s Next</strong></p>
<p>In the future I will be enhancing the sample to demonstrate <a href="http://www.thefreakparade.com/2008/09/rule-based-access-control-using-an-expression-evaluator/">our approach to defining authorization policies</a> that operate against a set of claims using our <a href="http://www.thefreakparade.com/2008/08/simple-expression-evaluator-project-now-on-codeplex/">Simple Expression Evaluator project</a>, <a href="http://www.codeplex.com/SimpleExpressionEval">currently on CodePlex</a>. This technique will show how a simple but powerful and flexible claims-aware rules engine can easily be constructed using any expression evaluator and a set of claims.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/TheFreakParade?a=oQxkO"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=oQxkO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=dcOYo"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=dcOYo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=6iSmo"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=6iSmo" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/TheFreakParade?a=0Z20o"><img src="http://feeds.feedburner.com/~f/TheFreakParade?i=0Z20o" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/TheFreakParade/~4/381065441" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-2-a-solution/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client-to-a-service-when-using-restful-wcf-part-2-a-solution/</feedburner:origLink></item>
	</channel>
</rss>
