<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Udi Dahan - The Software Simplist &#187; SOA</title>
	<atom:link href="http://www.udidahan.com/category/soa/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.udidahan.com</link>
	<description>Enterprise Development Expert &#38; SOA Specialist</description>
	<lastBuildDate>Sun, 08 Jan 2012 12:45:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Why you should be using CQRS almost everywhere…</title>
		<link>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/</link>
		<comments>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 20:45:44 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1551</guid>
		<description><![CDATA[… but differently than the way most people have been using it.
I think I’ve just about drove everybody crazy now with my apparent zigzagging on CQRS.
Some people heard about CQRS first from one of my presentations and got all excited about it. Then I did some blogging which further drove people to CQRS (as did [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/grass.jpg" alt="grass" title="grass" width="200" height="150" style="float:right; margin-left:10px; margin-bottom:10px;" />… but differently than the way most people have been using it.</p>
<p>I think I’ve just about drove everybody crazy now with my apparent zigzagging on CQRS.</p>
<p>Some people heard about CQRS first from one of my presentations and got all excited about it. Then I did some blogging which further drove people to CQRS (as did Greg Young and some others). As CQRS was just about to hit its stride with the Early Adopters, I started pushing a more balanced view – CQRS not as an answer, but as one of many questions. More recently I’ve pushed more strongly back against CQRS saying that it should be used rarely.</p>
<h3>So what’s the missing piece?</h3>
<p>If you’re in the Domain-Driven Design camp (as many doing CQRS are), then it’s Bounded Contexts.</p>
<p>If you’re in the Event-Driven SOA camp (a much smaller camp to be sure), then it’s Services.</p>
<p>The problem is the naming, because the DDD guys have their kinds of services which do not fit the definition for Service of the Event-Driven SOA approach.</p>
<p>Let me propose the term Autonomous Business Component for the purposes of this blog post to describe that thing which is both a DDD Bounded Context (have the shared BC part of the acronym) and an SOA Autonomous Services. Resulting in the nice short form:  ABC (and everyone knows you need to have a good acronym if you want something to catch on).</p>
<h3>What does this have to do with CQRS?</h3>
<p>Nothing just yet. Well, at least, nothing directly to do with CQRS.</p>
<p>Although some proponents of CQRS have stated that it can and should be used as the top-most architectural pattern, both myself and Greg Young (arguably the first two to talk about it and the two who ultimately collaborated on naming it – and now Google knows we didn’t means “cars”) always recommended it as a pattern to be used one level down. </p>
<p>Although Greg and I have had many long discussions on the topic and do agree very much about what the overall structure should look like, I’ll try to avoid putting words in his mouth from this point on.</p>
<p>Before talking more about ABCs, let’s discuss the principle upon which they rest: The Single Responsibility Principle (SRP).</p>
<h3>What does SRP have to with CQRS?</h3>
<p>Many developers are familiar with SRP and have seen good results from using it. What we’re going to do is take this principle to the next level.</p>
<p>In Object Orientation (OO), data is encapsulated in an object. A good object does not expose its data to other objects to do with as they wish. Rather, it exposes methods that other objects can invoke, and those methods operate on the internal data.</p>
<p>SRP would guide us to not have the same data exist in two objects. For example, if we saw the customer’s first name as an internal data member of two objects, we’d be right to question that kind of duplication and move to refactor it away. However, when we see two systems doing the exact same thing – somehow that gets excused.</p>
<blockquote><p>“Of course we need to be able to see the customer’s first name in the front-end website as well as in the back-end fulfillment system. How could we NOT have the customer’s first name in both those code-bases?”</p></blockquote>
<p>And there’s the catch.</p>
<p>Who said that a system should be a single code-base?</p>
<h3>But what about integration?</h3>
<p>Although many times we do need to integrate existing systems together, sometimes we have the ability to change those systems. More importantly, when going to create a new solution, we can avoid getting ourselves into the problems that integration tries to solve.</p>
<p>Integrating with a system that cannot be changed can be done also by composing multiple ABCs, but that’s a topic for another post.</p>
<p>It is better to think of integration as a necessary evil – kind of like regular expressions and multi-threading; things to be avoided unless absolutely necessary.</p>
<p>“If you have a problem that you decide to use a regular expression to solve, you now have 2 problems.” Or so the saying goes. With multi-threading, you have a non-deterministic number of problems to solve.</p>
<p>If you thought you had duplicate responsibilities with 2 systems operating on the same data, how will introducing a 3rd code base (also known as “integration”) help? Remember that Single Responsibility Principle – our goal is to get it down to one.</p>
<h3>OK, so how do ABCs do that?</h3>
<p>In order for us to get back into alignment with SRP, that would require us to have responsibility for a single piece of data exist in one code base. Note that SRP makes no statements about how many physical places a given code base can be deployed to. Nor does it state that only a single technology can be in play – code that emits HTML can be packaged at design time together with rich-client code in the same solution.</p>
<p>If an ABC is responsible for a piece of data, it is responsible for it everywhere, and forever. No other ABC should see that data. That data should not travel between ABCs via remote procedure call (RPC) or via publish/subscribe. It is the ultimate level of encapsulation – SRP applied at the highest level of granularity.</p>
<p>This results in systems which are the result of deploying the components of multiple ABCs to the same physical place. The ABC which owns the customer name would have the necessary web code to render it in the e-commerce front-end and in the shipping back-end for printing on labels. This would mean that practically every screen in any UI is a composite of widgets owned by their respective ABCs.</p>
<p>This is ultimately what keeps the complexity of each ABC’s code base to a minimum. </p>
<h3>But why not just use CQRS as the top-level pattern? ABCs are weird.</h3>
<p>Imagine trying to create a single denormalized view model for the entire Amazon.com product page – product name, price, inventory, editorial review, customer comments, other products that customers viewed, other products that customers bought, etc. </p>
<p>Pretty complex, right?</p>
<p>How much duplication would you have for the page shown after you add an item to a cart? Once again, you need to show other products that customers bought, their names, images, prices, and inventory. </p>
<p>And then on the home page – items you might be interested in, names, images, prices.</p>
<p>And that’s only in the front-end system.</p>
<p>It’s not just the duplication, but how complex the code is for each one.</p>
<p>Instead of the duplication that top-level CQRS would bring you, consider an ABC responsible for products names and images that has just about the same view model composed on each of the above screens. The same with another ABC responsible for price.</p>
<p>You may be thinking that this would result in more queries to get the data to show on a page, and you’d be right. But it isn’t necessarily a classical N+1 Select problem, as the queries are bounded to the number of ABCs. Secondly, consider the ability to have well-tuned caching at the granularity of an ABC – something that would be much more difficult when dealing with everything as a single monolithic view model. In short, not only will it not be a performance problem, often it will actually improve performance.</p>
<h3>OK – that explains “everywhere”, what about “forever”?</h3>
<p>Forever is where things get interesting – or more accurately, when they get interesting.</p>
<p>Let’s talk about things like invoices.</p>
<p>One of the requirements in this area is that immutability. If the customer’s name was Jane Smith when they made their purchase, it doesn’t matter that they’ve since changed their name to Jane Jones, the invoice should still show Jane Smith.</p>
<p>Often developers push these types of requirements on the data warehouse guys – that’s where history gets handled. The only thing is that if your ABC owns the customer’s name, then no other code base can deal with it. If it’s your data, you have to handle all historical representations of it.</p>
<p>On the one hand, this would seem to kill the data warehouse. On the other hand, it means that the principles of data warehouses are now core to every code-base.</p>
<p>This means you don’t ever delete data (see my <a href="http://www.udidahan.com/2009/09/01/dont-delete-just-dont/">previous blog post</a> on the subject), and you definitely don’t overwrite it with an update – even if you think you’re in a simple CRUD domain. The only case where you can get away with traditional CRUD is if we’re talking about private data – data that is only ever acted on by a single actor.</p>
<h3>This sounds like the collaboration you talk about with CQRS</h3>
<p>It’s similar in principle but different in practice.</p>
<p>In a collaborative domain, an inherent property of the domain is that multiple actors operate in parallel on the same set of data. A reservation system for concerts would be a good example of a collaborative domain – everyone wants the “good seats” (although it might be better call that competitive rather than collaborative, it is effectively the same principle).</p>
<p>A customer’s name would not fall under that category. It isn’t an inherent property of the domain for multiple actors to operate on that data. While there can be multiple readers, one can easily enforce a single writer without any adverse effects. Doing that with a reservation system would cause the online system to behave as if users were lining up in front of a box office – not a desirable outcome.</p>
<p>Private data would be something like a user’s shopping cart. Until they make a purchase, that data doesn’t need to be visible anywhere. Here you could theoretically do simple CRUD – that is, until the business realizes that there’s extremely valuable information to be extracted from the historical record of things people do with their carts.</p>
<h3>I think you’re ready to make your point, so just make it already</h3>
<p>OK – so we now realize that Update and Delete don’t exist in their traditional form. Delete is really just a kind of update, and update is effectively an “upsert” – a combination of update and insert to retain history. This can be done by having ValidFrom and ValidTo columns for our data.</p>
<p>In which case, Create is really just a special case of Upsert, which looks like this:</p>
<blockquote><p>UPDATE Something SET ValidTo = NOW() WHERE Id=@Id AND ValidTo = NULL; INSERT INTO Something SET { regular values }, Id=@Id, ValidTo = NULL;</p></blockquote>
<p>And then we’d have 2 forms of Read – reading the current state (ValidTo = NULL), and reading history (ValidFrom <= Instant AND (ValidTo >= Instant OR ValidTo = NULL))</p>
<p>Here we don’t need fancy N-Tier architectures, data transfer objects, service layers, or domain models. A simple 2-Tier approach could probably suffice. We don’t need a task-based UI, events, denormalized view models, or any of that CQRS stuff. This was at the crux of my previous <a href="http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/">anti-CQRS post</a>.</p>
<p>The only thing is that this is exactly CQRS.</p>
<h3>Say what?</h3>
<p>Have we not effectively separated the responsibility of commands/upserts and queries/reads?</p>
<p>As Greg Young has said before, “the creation of 2 objects where there previously was one”.</p>
<p>Effectively 2 paths through our ABC.</p>
<p>CQRS.</p>
<p>Let me give you a second to gather your thoughts.</p>
<p>*</p>
<p>You see, CQRS is an approach, a mind-set – not a cookie cutter solution. Frameworks that guide you to applying CQRS exactly the same way everywhere are taking you in the wrong direction. The fact is that you couldn’t possibly know what your Aggregate Roots were before you figured out how to break your system down into ABCs. Attempting to create commands and events for everything will make you overcomplicate your solution.</p>
<h3>So the built-in history of this model is event-sourcing?</h3>
<p>Well, it’s not event-sourcing in the sense that we don’t necessarily have events. It achieves many of the benefits of event-sourcing by giving us the full history of what happened.</p>
<p>On the whole issue of replaying events to fix bugs – that’s a bit problematic, logically, unless we have a closed system. A closed system is one that doesn’t interact with anything else – no other systems, no users, nothing. As such, closed systems aren’t that common.</p>
<p>In an open system, one with users, let’s say there was a bug. This bug could have caused the wrong data to be written and/or shown to users. As such, users could have submitted subsequent commands based on that erroneous data that they would not have submitted otherwise. There’s no way for us to know.</p>
<p>The problem with replaying events when we fix the bug is that we’re in essence rewriting history – making it as if the user didn’t see the wrong data. The only problem is that we can’t know which events not to replay – we can’t automatically come up with the right events that should have come afterwards. We could try to sit together with our users and have them try to revise history manually, but our organization often isn’t in a bubble. Our users interacted with customers and suppliers. It isn’t feasible to try to undo the real-world impacts of this situation.</p>
<h3>Why didn’t you just tell us this from the very beginning?</h3>
<p>I did, you just weren’t listening.</p>
<p>You wanted a cookie cutter, and until you tried CQRS out as cookie cutter (and saw it create a bunch of complexity) you wouldn’t listen to anything else. </p>
<p>As developers, we’re trained to solve problems – the faster the better. Unfortunately, this causes us to be blind to things that don’t immediately present themselves as solutions.</p>
<p>When applying CQRS with ABCs, the solutions you end up with are very simple, but the process of getting there is quite hard and takes practice. Finding the boundaries of ABCs such that data isn’t duplicated between them and that data doesn’t travel between them either via RPC or publish/subscribe – it may feel impossible the first several times you try. Keep at it – it is almost always possible.</p>
<p>We haven’t touched on the whole saga/aggregate-root thing yet, but that isn’t as important until you can successfully apply the principles described here.</p>
<p>Also, this post has already gotten long enough, so it looks like now would be a good time to stop.</p>
<p>Until next time…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>Inconsistent data, poor performance, or SOA &#8211; pick one</title>
		<link>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/</link>
		<comments>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 16:52:17 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Reliability]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1527</guid>
		<description><![CDATA[One of the things that surprises some developers that I talk to is that you don&#8217;t always get consistency even with end-to-end synchronous communication and a single database. This goes beyond things like isolation levels that some developers are aware of and is particularly significant in multi-user collaborative domains.
The problem
Let&#8217;s start with an image to [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things that surprises some developers that I talk to is that you don&#8217;t always get consistency even with end-to-end synchronous communication and a single database. This goes beyond things like isolation levels that some developers are aware of and is particularly significant in multi-user collaborative domains.</p>
<h3>The problem</h3>
<p>Let&#8217;s start with an image to describe the scenario:</p>
<p><img src="http://www.udidahan.com/wp-content/uploads/Inconsistency1.gif" alt="Inconsistency" title="Inconsistency" width="600" height="285" class="aligncenter size-full wp-image-1533" /><br />
<center>Image 1. 3 transactions working in parallel on 3 entities</center></p>
<p>The main issue we have here is that the values transaction 2 gets for A and B are those from T0 &#8211; before either transaction 1 or 3 completed. The reason this is an issue is that these old values (usually together with some message data) are used to calculate what the new state of C should be. </p>
<p>Traditional optimistic concurrency techniques won&#8217;t detect any problem if we don&#8217;t touch A or B in transaction 2.</p>
<p>In short, systems today are causing inconsistency.</p>
<h3>Some solutions</h3>
<p>1. Don&#8217;t have transactions which operate on multiple entities (which probably isn&#8217;t possible for some of your most important business logic).</p>
<p>2. Turn on <a href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control">multi-version concurrency control</a> &#8211; this is called snapshot isolation in MS Sql Server.</p>
<p>Yes, you need to turn it on. It&#8217;s off by default.</p>
<p>The good news is that this will stop the writing of inconsistent data to your database.<br />
The bad news is that it will probably cause your system many more exceptions when going to persist.</p>
<p>For those of you who are using transaction messaging with automatic retrying, this will end up as &#8220;just&#8221; a performance problem (unless you follow the recommendations below). For those of you who are using regular web/wcf services (over tcp/http), you&#8217;re &#8220;cross cutting&#8221; exception management will likely end up discarding all the data submitted in those requests (but since that&#8217;s what you&#8217;re doing when you run into deadlocks this shouldn&#8217;t be news to you).</p>
<h3>The solution to the performance issues</h3>
<p>Eventual consistency.</p>
<p>Funny isn&#8217;t it &#8211; all those people who were afraid of eventual consistency got <b>inconsistency</b> instead.</p>
<p>Also, it&#8217;s not enough to just have eventual consistency (like between the command and query sides of CQRS). You need to drastically decrease the size of your entities. And the best way of doing that is to partition those entities across multiple business services (also known in DDD lingo as Bounded Contexts) each with its own database.</p>
<p>This is yet another reason why I say that CQRS shouldn&#8217;t be the top level architectural breakdown. Very useful within a given business service, yes &#8211; though sometimes as small as just some sagas.</p>
<h3>Next steps</h3>
<p>It may seem unusual that the title of this post implies that SOA is the solution, yet the content clearly states that traditional HTTP-based web services are a problem. Even REST wouldn&#8217;t change matters as it doesn&#8217;t influence how transactions are managed against a database.</p>
<p>The SOA solution I&#8217;m talking about here is the one I&#8217;ve spent the last several years <a href="http://www.udidahan.com/category/soa/">blogging about</a>. It&#8217;s a different style of SOA which has services stretch up to contain parts of the UI as well as down to contain parts of the database, resulting in a composite UI and multiple databases. This is a drastically different approach than much of the literature on the topic &#8211; especially Thomas Erl&#8217;s books.</p>
<p>Unfortunately there isn&#8217;t a book out there with all of this in it (that I&#8217;ve found), and I&#8217;m afraid that with my schedule (and family) writing a book is pretty much out of the question. Let&#8217;s face it &#8211; I&#8217;m barely finding time to blog.</p>
<p>The one thing I&#8217;m trying to do more of is provide training on these topics. I&#8217;ve just finished a course in London, doing another this week in Aarhus Denmark, and another next month in San Francisco (which is now sold out). The next openings this year will be in Stockholm, London; Sydney Australia and Austin Texas will be coming in January of next year. I&#8217;ll be coming over to the US more next year so if you missed San Francisco, keep an eye out.</p>
<p>I wish there was more I could do, but I&#8217;m only one guy.</p>
<p>Hmm, maybe it&#8217;s time to change that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>The Danger of Centralized Workflows</title>
		<link>http://www.udidahan.com/2011/07/13/the-danger-of-centralized-workflows/</link>
		<comments>http://www.udidahan.com/2011/07/13/the-danger-of-centralized-workflows/#comments</comments>
		<pubDate>Wed, 13 Jul 2011 08:05:19 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[BPM]]></category>
		<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1493</guid>
		<description><![CDATA[It isn&#8217;t uncommon for me to have a client or student at one of my courses ask me about some kind of workflow tool. This could be Microsoft Workflow Foundation, BizTalk, K2, or some kind of BPEL/orchestration engine. The question usually revolves around using this tool for all workflows in the system as opposed to [...]]]></description>
			<content:encoded><![CDATA[<p>It isn&#8217;t uncommon for me to have a client or student at one of my courses ask me about some kind of workflow tool. This could be Microsoft Workflow Foundation, BizTalk, K2, or some kind of BPEL/orchestration engine. The question usually revolves around using this tool for all workflows in the system as opposed to the SOA-EDA-style publish/subscribe approach I espouse.</p>
<h3>The question</h3>
<p>The main touted benefit of these workflow-centric architectures is that we don&#8217;t have to change the code of the system in order to change its behavior resulting in ultimate flexibility!</p>
<p>Some of you may have already gone down this path and are shaking your heads remembering how your particular road to hell was paved with the exact same good intentions.</p>
<p>Let me explain why these things tend to go horribly wrong.</p>
<h3>What&#8217;s behind the curtain</h3>
<p>It starts with the very nature of workflow &#8211; a flow chart, is procedural in nature. First do this, then that, if this, then that, etc. As we&#8217;ve experienced first hand in our industry, procedural programming is fine for smaller problems but isn&#8217;t powerful enough to handle larger problems. That&#8217;s why we&#8217;ve come up with object-oriented programming.</p>
<p>I have yet to see an object-oriented workflow drag-and-drop engine. Yes, it works great for simple demo-ware apps. But if you try to through your most complex and volatile business logic at it, it will become a big tangled ball of spaghetti &#8211; just like if you were using text rather than pictures to code it.</p>
<p>And that&#8217;s one of the fundamental fallacies about these tools &#8211; you are still writing code. The fact that it doesn&#8217;t look like the rest of your code doesn&#8217;t change that fact. Changing the definition of your workflow in the tool IS changing your code. </p>
<h3>On productivity</h3>
<p>Sometimes people mention how much more productive it would be to use these tools than to write the code &#8220;by hand&#8221;. Occasionally I hear about an attempt to have &#8220;the business&#8221; use these tools to change the workflows themselves &#8211; without the involvement of developers (&#8221;imagine how much faster we could go without those pesky developers!&#8221;).</p>
<p>For those of us who have experienced this first-hand, we know that&#8217;s all wrong. </p>
<p>If &#8220;the business&#8221; is changing the workflows without developer involvement, invariably something breaks, and then they don&#8217;t know what to do. They haven&#8217;t been trained to think the way that developers have &#8211; they don&#8217;t really know how to debug. So the developers are brought back in anyway and from that point on, the business is once again giving requirements and the devs are the one implementing it.</p>
<p>Now when it comes to developer productivity, I can tell you that the keyboard is at least 10x more productive than the mouse. I can bang out an if statement in code much faster than draggy-dropping a diamond on the canvas, and two other activities for each side of the clause.</p>
<h3>On maintainability</h3>
<p>Sometimes the visualization of the workflow is presented as being much more maintainable than &#8220;regular code&#8221;. </p>
<p>When these workflows get to be to big/nested/reused, it ends up looking like the wiring diagram of an Intel chip (or worse). Check out the following diagram taken from the DailyWTF on a <a href="http://thedailywtf.com/Articles/The_Customer-Friendly_System.aspx">customer friendly system</a>:</p>
<p><img src="http://www.udidahan.com/wp-content/uploads/stateModel.gif" alt="stateModel" title="stateModel" width="500" height="564" /></p>
<p>The bigger these get, the less maintainable they are.</p>
<p>Now, some would push back on this saying that a method with 10,000 lines of code in it may be just as bad, if not worse. The thing is that these workflow tools guide developers down a path where it is very likely to end up with big, monolithic, procedural, nested code. When working in real code, we know we need to take responsibility for the cleanliness of our code using object-orientation, patterns, etc and refactoring things when they get too messy.</p>
<p>Here is where I&#8217;d bring up the SOA/pub-sub approach as an alternative &#8211; there is no longer this idea of a centralized anything. You have small pieces of code, each encapsulating a single business responsibility, working in concert with each other &#8211; reacting to each others events.</p>
<h3>Productivity take 2: testing and version control</h3>
<p>If you&#8217;re going to take your most complex and volatile business logic and put it into these workflow tools, have you thought about how your going to test it? How do you know that it works correctly? It tends to be VERY difficult to unit-test these kinds of workflows.</p>
<p>When a developer is implementing a change request, how do they know what other workflows might have been broken? Do they have to manually go through each and every scenario in the system to find out? How&#8217;s that for productivity?</p>
<p>Assuming something did break and the developer wants to see a diff &#8211; what&#8217;s different in the new workflow from the old one, what would that look like? When working with a team, the ability to diff and merge code is at the base of the overall team productivity.</p>
<p>What would happen to your team if you couldn&#8217;t diff or merge code anymore?<br />
In this day and age, it should be considered irresponsible to develop without these version control basics.</p>
<h3>In closing</h3>
<p>There are some cases where these tools might make sense, but those tend to be much more rare than you&#8217;d expect (and there are usually better alternatives anyway). Regardless, the architectural analysis should start without the assumption of centralized workflow, database, or centralized anything for that matter.</p>
<p>If someone tries to push one of these tools/architectures on you, don&#8217;t walk away &#8211; run!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/07/13/the-danger-of-centralized-workflows/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>Service Boundaries Aren&#8217;t Process Boundaries</title>
		<link>http://www.udidahan.com/2011/07/03/service-boundaries-arent-process-boundaries/</link>
		<comments>http://www.udidahan.com/2011/07/03/service-boundaries-arent-process-boundaries/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 12:23:37 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1482</guid>
		<description><![CDATA[Richard Veryard blogged about the topic of service boundaries in SOA, specifically asking why aren&#8217;t more people talking about service boundaries &#8211; especially if they&#8217;re such a core principle in SOA.
I can only speak for myself on this one, but I guess it&#8217;s that there&#8217;s just so many times you can repeat yourself.
So, why this [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/fence1_14.jpg" alt="boundaries" title="boundaries" width="286" height="217" style="float:right; margin-left:10px; margin-bottom:10px;" />Richard Veryard <a href="http://rvsoapbox.blogspot.com/2011/07/service-boundaries-in-soa.html">blogged</a> about the topic of service boundaries in SOA, specifically asking why aren&#8217;t more people talking about service boundaries &#8211; especially if they&#8217;re such a core principle in SOA.</p>
<p>I can only speak for myself on this one, but I guess it&#8217;s that there&#8217;s just so many times you can repeat yourself.</p>
<p>So, why this post?</p>
<p>Well, Richard was able to dig up an old (2004) presentation I gave about SOA in which I said:</p>
<blockquote><p>&#8220;Services run in a separate process from their clients<br />
A boundary must be crossed to get from the client to the service – network, security, …&#8221;</p></blockquote>
<p>And 7 years later I can say, hand on heart, <b>I was wrong</b>.</p>
<p>Luckily, I&#8217;ve spent much of those past 7 years trying to correct that recommendation. One blog post in which I tried to do that (in mid-2007) was <a href="http://www.udidahan.com/2007/05/19/on-intermediation-and-soa/">On Intermediation and SOA</a> in which I described the relationship between systems (i.e process boundaries) and services:</p>
<blockquote><p>&#8220;all of these “systems” might just end up within the same service, or having parts of them being used by multiple services</p></blockquote>
<p>There can also be multiple services (or, more accurately, parts of multiple services) deployed together in the same system/process. </p>
<p>And this is nothing new &#8211; in the <a href="http://en.wikipedia.org/wiki/4%2B1_Architectural_View_Model">4+1 Architectural View Model</a> by Philippe Kruchten (1995) we can see very clearly the differentiation between the Logical View (our services) and the Physical View (a.k.a the Deployment View). </p>
<p>These views are orthogonal to each other &#8211; multiple elements from one view can map to a single element in another view (and vice versa).</p>
<p>This, if anything, makes it that much harder to identify service boundaries &#8211; if they have nothing to do with the existing applications and systems, then what are they? In my blog post on <a href="http://www.udidahan.com/2010/11/15/the-known-unknowns-of-soa/">The Known Unknowns of SOA</a> I point to the fact that <b>Business Capabilities</b> are much more appropriate constructs than, say, web services which (as it says in the referenced post) &#8220;[are] merely a standardized approach to accessing functionality on remote systems&#8221;.</p>
<p>As I bring this post to a close, I&#8217;m feeling more comfortable rehashing material I&#8217;ve published before:</p>
<p><a href="http://www.udidahan.com/2010/11/08/logical-and-physical-architecture/">Logical and Physical Architecture</a></p>
<p>and the rest of the SOA category on my blog <a href="http://www.udidahan.com/category/soa/">here</a>.</p>
<p>Happy boundary hunting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/07/03/service-boundaries-arent-process-boundaries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When to avoid CQRS</title>
		<link>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/</link>
		<comments>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 20:32:50 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1441</guid>
		<description><![CDATA[It looks like that CQRS has finally &#8220;made it&#8221; as a full blown &#8220;best practice&#8221;.
Please accept my apologies for my part in the overly-complex software being created because of it.
I&#8217;ve tried to do what I could to provide a balanced view on the topic with posts like Clarified CQRS and Race Conditions Don&#8217;t Exist.
It looks [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/image20.png" alt="which way?" title="which way?" style="float:right; margin-left:10px; margin-bottom:10px;" />It looks like that CQRS has finally &#8220;made it&#8221; as a full blown &#8220;best practice&#8221;.</p>
<p>Please accept my apologies for my part in the overly-complex software being created because of it.</p>
<p>I&#8217;ve tried to do what I could to provide a balanced view on the topic with posts like <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">Clarified CQRS</a> and <a href="http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/">Race Conditions Don&#8217;t Exist</a>.</p>
<p>It looks like that wasn&#8217;t enough, so I&#8217;ll go right out and say it:</p>
<p>Most people using CQRS (and <a href="http://codebetter.com/gregyoung/2010/02/20/why-use-event-sourcing/">Event Sourcing</a> too) shouldn&#8217;t have done so.</p>
<h3>Should we really go back to N-Tier?</h3>
<p>When not using CQRS (which is the majority of the time), you don&#8217;t need N-Tier either.</p>
<p>You see, if you&#8217;re not in a collaborative domain then you don&#8217;t have multiple writers to the same logical set of data as an inherent property of your domain. As such, having a single database where all data lives isn&#8217;t really necessary. </p>
<p>Data is inherently partitioned by who owns it.</p>
<p>Let&#8217;s take the online shopping cart as an example. There aren&#8217;t any use cases where users operate on each others&#8217; carts &#8211; ergo, not collaborative, therefore not a good candidate for CQRS. Same goes for user profiles, and tons of other cases.</p>
<p>So why is it that we need a separate tier to run our business logic?</p>
<p>Originally, the application server tier was introduced for improved scalability, but specifically around managing the connection pool to the database. Increasing numbers of clients (when each had its own user/account for connecting to the database) caused problems. Luckily, most web applications side-step this problem &#8211; that is, until someone got the idea that the web server was only supposed to run the UI layer, and the Business Logic layer would be on a separate application server tier.</p>
<p>Rubbish &#8211; see Fowler&#8217;s First Law of Distribution: Don&#8217;t.</p>
<p>Keep it all on one tier. Same goes for smart clients.<br />
No, Silverlight, you don&#8217;t count &#8211; architecturally speaking, you&#8217;re a glorified browser.</p>
<h3>But what about scalability?</h3>
<p>In a non-collaborative domain, where you can horizontally add more database servers to support more users/requests/data at the same time you&#8217;re adding web servers &#8211; there is no real scalability problem (caveat, until you&#8217;re Amazon/Google/Facebook scale). </p>
<p>Database servers can be cheap &#8211; if using MySQL/SQL Express/others. </p>
<h3>But what about the built-in event-log CQRS/ES gives us?</h3>
<p>Architectural gold-plating / stealing from the business.</p>
<p>Who put you in a position to decide that development time and resources should be diverted from short-term business-value-adding features to support a non-functional requirement that the business didn&#8217;t ask for?</p>
<p>If you sat down with them, explaining the long-term value of having an archive of all actions in the system, and they said OK, build this into the system from the beginning, that would be fine. Most people who ask me about CQRS and/or Event Sourcing skip this step.</p>
<p>Finally, you can usually implement this specific requirement with some simple interception and logging. Don&#8217;t over-engineer the solution. If using messaging, you can get this by turning on journaling, or if you want to centralize this archive, NServiceBus can forward all messages to a specific queue. </p>
<p>Don&#8217;t forget that this storage has a cost &#8211; including administration. Nothing is free.</p>
<h3>What about the &#8220;proof of correctness&#8221; in Event Sourcing</h3>
<p>I&#8217;ve heard statements made that when you use the events that flowed into/through your system <b>AS</b> your system&#8217;s data, rather than transforming those events to some other schema (relational or otherwise) and storing the result &#8211; you can prove that your system behaves correctly.</p>
<p>Let me put it this way:</p>
<p>No programming technique used by humans will prevent those same humans from creating bugs.<br />
No testing technique used by humans will prevent those same humans from not catching those bugs.<br />
* Automated tests &#8211; see programming technique.</p>
<p>While having a full archive of all events can allow us to roll the system back to some state, fix a bug, and roll forwards, that assumes that we&#8217;re in a closed system. We have users which are outside the system. If a user made a decision based on data influenced by the bug, there&#8217;s no automated way for us to know that, or correct for it as we roll forwards.</p>
<p>In short, we&#8217;re interested in the business&#8217; behavior &#8211; as composed of user and system behavior. No proof can exist.</p>
<h3>Umm, so where should we use it</h3>
<p>If you&#8217;ve uncovered a scenario where you&#8217;re wondering &#8220;first-one-wins, or last-one-wins&#8221;, that&#8217;s often a good candidate for a place where CQRS <b>could</b> make sense. Then re-read my <a href="http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/">Race Conditions Don&#8217;t Exist post</a>.</p>
<p>Also, CQRS should not be your top-level architectural pattern &#8211; that would be SOA.<br />
CQRS, if used at all, would be used inside a service boundary only.</p>
<p>Given that SOA guides us away from having a given 3rd normal form entity exist in any one service, it is unlikely that the building blocks of your CQRS design will be those kinds of entities. Most 3rd normal form one-to-many and many-to-many relationships simply do not exist when doing SOA and CQRS properly.</p>
<p>Therefore, I&#8217;m sorry to say that most sample application you&#8217;ll see online that show CQRS are architecturally wrong. I&#8217;d also be extremely wary of frameworks that guide you towards an entity-style aggregate root CQRS model.</p>
<h3>In Summary</h3>
<p>So, when should you avoid CQRS?</p>
<p>The answer is most of the time.</p>
<p>Here&#8217;s the strongest indication I can give you to know that you&#8217;re doing CQRS correctly: Your aggregate roots are sagas.</p>
<p>And the biggest caveat &#8211; the above are generalizations, and can&#8217;t necessarily be true for every specific scenario. If you&#8217;re Greg Young, then you probably can (and will) decide on your own on these matters. For everybody else, please take these warnings to heart. There have been far too many clients that have come to me all mixed up with their use CQRS in areas where it wasn&#8217;t warranted.</p>
<p>If you want to know everything you need to know to apply CQRS appropriately, please come to <a href="http://www.udidahan.com/training/#Advanced_Distributed_System_Design">my course</a> &#8211; there is so much unlearning to do first that just can&#8217;t happen via a series of blog posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Integration: How and Where</title>
		<link>http://www.udidahan.com/2011/04/08/integration-how-and-where/</link>
		<comments>http://www.udidahan.com/2011/04/08/integration-how-and-where/#comments</comments>
		<pubDate>Fri, 08 Apr 2011 09:18:41 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1428</guid>
		<description><![CDATA[One of the topics that comes up a lot in the context of an Enterprise Service Bus (ESB) is that of integration. Unfortunately, many people take their ideas of reuse and design their integration as being done from a single place &#8211; both logical and physical. That unfortunately creates a bottleneck for all integration activities, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/integration.jpg" alt="integration" title="integration" width="200" height="150" style="float:right; margin-left:10px; margin-bottom:10px;" />One of the topics that comes up a lot in the context of an Enterprise Service Bus (ESB) is that of integration. Unfortunately, many people take their ideas of reuse and design their integration as being done from a single place &#8211; both logical and physical. That unfortunately creates a bottleneck for all integration activities, where some are likely to be higher priority than others.</p>
<h3>The ugly truth</h3>
<p>You don&#8217;t need an ESB for integration.</p>
<p>There. I&#8217;ve said it. </p>
<p>Most of the ESB products on the market, in focusing on integration, are addressing the wrong problem.</p>
<h3>What integration is about</h3>
<p>There are three primary components to integration &#8211; data format translation, protocol bridging, and logic. Let&#8217;s take the Agile &#8220;simplest solution that could possibly work&#8221; motto and apply it to these elements:</p>
<ol>
<li>Data format translation<br/>
<ul>
<li>Use something like <a href="http://www.altova.com/mapforce.html">MapForce</a> (from Altova, the guys behind XMLSpy).</li>
<li>At under $1200 for a dev license and handling mapping to/from XML, EDI, flat files, and relational databases, you can host the resulting mapping in any endpoint, as XSLT or even Java/C# &#8211; no need to have &#8220;the bus&#8221; do this for you.</li>
</ul>
</li>
<li>Protocol bridging<br/>
<ul>
<li>Use something like <a href="http://www.nsoftware.com/subscriptions/">/n software</a></li>
<li>At about $1500 for a dev license, you get solutions for FTP, HTTP, SMTP, POP, IMAP, LDAP, DNS, RSS, SMS, Jabber, SOAP, WebDav, etc and, again &#8211; you can host the DLLs in any endpoint you want. Don&#8217;t need expensive buses for this</li>
</ul>
</li>
<li>Logic<br/><br />
This is all you &#8211; no technology can do this for you. If anything, the most important thing is to get all the ugly mapping and protocol bridging stuff out of the way and let you focus on your logic. This is Single Responsibility Principle (un)common sense.
</li>
</ol>
<h3>Digging deeper into the logic</h3>
<p>The interesting thing about most of the protocol stuff mentioned above is that they&#8217;re inherently <b>unreliable</b> and also their performance at runtime is unknowable due to the total load on the target server.</p>
<p>We wouldn&#8217;t want any of the above situations to cause our integration to &#8220;get stuck&#8221;. As such, it is best we think of our integration logic as a long-running process that manages other endpoints which do the actual protocol bridging and data transformations.</p>
<p>This is one of the areas where NServiceBus, with its <a href="http://www.nservicebus.com/Sagas.aspx">sagas</a> can actually help a lot. Just like the other pieces of integration mentioned above, these sagas can run on any endpoint.</p>
<p>You could alternatively look at other technologies like BizTalk and Business Process Execution Language (BPEL) engines, though many of those are designed to be physically centralized (just like many of the ESBs out there).</p>
<p>By the way, if you do want to use NServiceBus together with BizTalk, Michael Stephenson has published some great white papers on getting the two to work together. His latest is about integrating NServiceBus into BizTalk&#8217;s RFID processes &#8211; <a href="http://social.technet.microsoft.com/wiki/contents/articles/biztalk-rfid-amp-nservicebus.aspx">check it out</a>.</p>
<h3>Putting it all together</h3>
<p>When we take all of these pieces and look at them in a cohesive architecture, here&#8217;s what it can look like:</p>
<p><img src="http://www.udidahan.com/wp-content/uploads/DistributedIntegration.jpg" alt="Distributed Integration" title="Distributed Integration" width="600" height="385" class="alignnone size-full wp-image-1432" /></p>
<p>As you can see, integration is physically distributed across multiple endpoints.</p>
<p>Not only that, but the integration logic is kept separate from the protocol bridging and data transformation, enabling independent versioning of each. Just as important, it makes it <b>much</b> easier to unit test that the integration logic is correct as we don&#8217;t have to simulate the target technologies.</p>
<h3>Costs</h3>
<p>As you can see, you can get integration capabilities just as powerful as if you went with something like BizTalk, but without creating a single point of failure in your architecture. In terms of costs, it&#8217;s also quite a bit cheaper.</p>
<p>For a high availability BizTalk deployment, you&#8217;ll be paying <a href="http://www.microsoft.com/biztalk/en/us/pricing-licensing.aspx">over $40,000 per CPU</a> for the Enterprise Edition, not including the extra $7000 per CPU for SQL Server Standard Edition (clustered). For a clustered 4-CPU mid-size deployment, you&#8217;d be in the area of $200,000.</p>
<p>For the distributed integration solution above, you&#8217;d be paying around $2700 in dev licenses (for /n software and Altova MapForce), and $500 per core for NServiceBus Standard Edition. The reason there&#8217;s per-core licensing for NServiceBus is that in a virtualized environment, you&#8217;ll be provisioning virtual cores to your virtual machines. No reason to pay for a quad-core CPU when all you&#8217;re using is a single core. You can also use any number of cores running NServiceBus Express Edition at no cost, so a mid-size deployment with say 8 cores running Standard Edition, and another 24 cores running Express Edition would cost (with the volume discount) an additional $3800 &#8211; a total cost of $6,500.</p>
<p>BizTalk: $200,000 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NServiceBus: $6,500</p>
<p>&#8216;Nuff said.</p>
<h3>In closing</h3>
<p>We&#8217;ve been bitten by centralized architectures before.</p>
<p>By having our integration distributed, we can version, upgrade, and scale each piece independently.</p>
<p>You&#8217;ve seen how we can use simple, lightweight, and inexpensive technologies to create distributed integration solutions just as powerful and robust as the centralized ESB vendor-offerings out there, but at a tiny fraction of the cost.</p>
<p>Next time the topic of integration is brought up, you&#8217;ll know not to be suckered in by re-branded EAI brokers.</p>
<p><a href="http://www.nservicebus.com/">Learn more about NServiceBus</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/04/08/integration-how-and-where/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Bus and Broker Pub/Sub Differences</title>
		<link>http://www.udidahan.com/2011/03/24/bus-and-broker-pubsub-differences/</link>
		<comments>http://www.udidahan.com/2011/03/24/bus-and-broker-pubsub-differences/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 21:22:13 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[MSMQ]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1421</guid>
		<description><![CDATA[One of the things which often confuses people using NServiceBus for the first time is that it only allows an endpoint to subscribe to a given event from a single other publishing endpoint. The rule that there can only be a single publisher for a given event type is one of the things that differentiates [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/difference_of_opinion.jpg" alt="differences" title="differences" width="250" height="150" style="float:right; margin-left:10px; margin-bottom:10px;" />One of the things which often confuses people using NServiceBus for the first time is that it only allows an endpoint to subscribe to a given event from a single other publishing endpoint. The rule that there can only be a single publisher for a given event type is one of the things that differentiates buses from brokers, though both obviously allow you to have multiple subscribers.</p>
<h3>Brokers</h3>
<p>Message brokers, more broadly known and used on the Java platform, don&#8217;t come with this constraint. For example, when using ActiveMQ, you can have any number of endpoints come to the broker and publish a message under a given topic. </p>
<p>So where&#8217;s the problem?</p>
<p>It&#8217;s all about accountability.</p>
<p>Let&#8217;s say you&#8217;ve subscribed to a given topic, and have received two events &#8211; one telling you that the price of bananas next week will be $1/kg and another telling you that it&#8217;ll be $2/kg. </p>
<p>Which one is right?</p>
<p>Especially given that those events may have been published by any other endpoint via the broker.</p>
<p>Is it first one wins? Last one wins? How about first one sent vs. first one received? Ditto for last. As a subscriber, can you really be held accountable for having the logic to choose the right one? Shouldn&#8217;t this responsibility have fallen to the publishing side?</p>
<p>This is one of the big drawbacks of the broker, hub and spoke architecture. No responsibility. No single source of truth &#8211; unless everybody&#8217;s going to some central database, in which case &#8211; what&#8217;s the point of all this messaging anyway?</p>
<h3>Buses</h3>
<p>The Bus Architectural Style is all about accountability. If you are going to publish an event, you are accountable for the correctness of the data in that event &#8211; there is no central database that a subscriber can go to &#8220;just in case&#8221;. And the only way that you can be held accountable, is if you have full responsibility &#8211; ergo, you&#8217;re the only one who can publish that type of event.</p>
<p>If you say bananas are going to cost $1/kg next week, that&#8217;s that. Subscribers will not hear from anybody else on that topic.</p>
<p>Now, this is not to say that you can&#8217;t have more than one <b>physical</b> publishing endpoint.</p>
<p>You see, buses differentiate between the logical and the physical. Brokers tend to assume that the physical hub-and-spoke topology is also the logical.</p>
<p>In a bus, while there can only be one <b>logical</b> endpoint publishing a given type of event, that endpoint can be physically scaled out across multiple machines. It is the responsibility of the bus to provide infrastructure facilities to allow for that to happen in such a way that to subscribers, it still appears as if there is really only one publishing endpoint.</p>
<p>The same is true about the subscriber &#8211; one logical subscribing endpoint may be scaled out across multiple machines.</p>
<h3>Product Mix-ups</h3>
<p>Unfortunately, there are many broker-style technologies out there that are being marketed under the banner of the Enterprise Service Bus. While some products have the ability to be deployed in both a centralized and distributed fashion (sometimes called &#8220;federated&#8221; or &#8220;embedded&#8221; mode), many do not enforce the &#8220;single publishing endpoint per event-type&#8221; rule.</p>
<p>Without this constraint, it is just too easy to make mistakes.</p>
<h3>NServiceBus</h3>
<p>By enforcing this constraint, we see the same kind of question appear on the discussion group time and time again:</p>
<p>&#8220;I have an Audit event that I&#8217;d like all of my machines to publish, and have one machine subscribe to them all, but NServiceBus won&#8217;t let me. How do I make NServiceBus support this scenario?&#8221;</p>
<p>And the answer is the same every time:</p>
<p>&#8220;You should have all the machines <b>Send</b> the Audit message (configured to go to the single machine handling that message), and not Publish. It is not an event until its been handled by the endpoint responsible for it.&#8221;</p>
<p>The semantics of the message matter a lot.</p>
<p>When looking at Service-Oriented Architecture, these messages are the contract and, as any lawyer will tell you, contracts need to be explicit and the intentions really need to be spelled out &#8211; otherwise the contract is practically worthless.</p>
<h3>In closing</h3>
<p>Friction is sometimes a good thing &#8211; it prevents us from making mistakes. It keeps cars on the road. And because that&#8217;s not enough friction, we introduce curbs as well.</p>
<p>If you&#8217;re looking for a service bus technology for your next project, check that it&#8217;ll give you the friction that you need to keep everybody safe. Really check what it is that the vendors are offering you &#8211; more often than not, it&#8217;s some ESB lipstick on a broker pig.</p>
<p>To learn more about how NServiceBus supports this kind of publish/subscribe, <a href="http://www.nservicebus.com/PubSub.aspx">click here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/03/24/bus-and-broker-pubsub-differences/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Careful with Content-Based Routing</title>
		<link>http://www.udidahan.com/2011/03/20/careful-with-content-based-routing/</link>
		<comments>http://www.udidahan.com/2011/03/20/careful-with-content-based-routing/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 15:32:00 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1416</guid>
		<description><![CDATA[Every once in a while I get clients who ask me why NServiceBus doesn&#8217;t support content-based routing. My answer sometimes surprises them, &#8220;because it is a dangerous pattern that should usually be avoided&#8221;.
Content-Based Routing and ESBs
Since content-based routing often appears on feature lists for various ESBs, many people consider them to be a necessary part [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while I get clients who ask me why NServiceBus doesn&#8217;t support content-based routing. My answer sometimes surprises them, &#8220;because it is a dangerous pattern that should usually be avoided&#8221;.</p>
<h2>Content-Based Routing and ESBs</h2>
<p>Since content-based routing often appears on feature lists for various ESBs, many people consider them to be a necessary part of systems built on SOA principles. The pattern also appears in the book Enterprise Integration Patterns, which apparently is also a convincing reason to use it, even though the book <a href="http://www.eaipatterns.com/ContentBasedRouter.html">specifically states</a>:</p>
<blockquote><p>
&#8220;When implementing a Content-Based Router, special caution should be taken to make the routing function easy to maintain as the router can become a point of frequent maintenance.&#8221;
</p></blockquote>
<p>That&#8217;s right &#8211; maintenance nightmare.</p>
<h2>For Example</h2>
<p>Let&#8217;s take a real-world example &#8211; a trading system where users can put orders for stock and for forex (money from other countries). </p>
<p>We&#8217;d start by creating a message that can be sent by a client:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">class</span> PlaceOrder : IMessage
{
    <span class="kwrd">public</span> OrderTypeEnum OrderType { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">string</span> Code { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">double</span> Amount { get; set; }
}

<span class="kwrd">public</span> <span class="kwrd">enum</span> OrderTypeEnum
{
    Stock,
    Forex
}</pre>
<p>Clients would send messages by using code like the following:</p>
<pre class="csharpcode">
Bus.Send&lt;PlaceOrder&gt;(m =&gt; {
    m.OrderType = OrderTypeEnum.Stock;
    m.Code = <span class="str">"MSFT"</span>;
    m.Amount = 300;
    m.SetHeader("AccountId", myAccountId);
});</pre>
<p>The header is the way that clients identify themselves in the system.</p>
<p>Let&#8217;s say that the logic for handling the different types of orders is different, but also that we&#8217;d like the logic to be deployed to different endpoints. One reason we might want to do this is so that we can independently scale each of these endpoints. This is where it would appear we&#8217;d need some content-based routing &#8211; having some code that looks at the OrderType property and decides where to route based on its value.</p>
<p>Before we get into solutions, let&#8217;s make this more involved.</p>
<p>Not only do we want to route based on OrderType, but we want to use the account ID in the header to check in our database (or via a web service) if the account belongs to one of our VIP customers, and if so, it should be given higher priority. </p>
<h2>Content-Based Routing and Brokers</h2>
<p>We can see that if we were to go with a content-based routing solution, this would drive our architecture to a hub-and-spoke model where the hub becomes quite large and complex, as well as likely becoming a bottleneck in terms of performance.</p>
<p>This logically centralized place through which all communication flows defines the Broker architectural style &#8211; not that of a Bus. In the Bus architectural style, there is no logical (or physical) hub. You can think of it as a kind of peer-to-peer setup. Just like you wouldn&#8217;t want ethernet getting involved in applicative routing decisions, neither should your bus get involved.</p>
<h2>Business-Topology Mapping Solutions</h2>
<p>Instead, when following the Bus architectural style &#8211; we look at mapping stable business characteristics to bus-level topology. At one level, that would mean defining two different message types for our different types of trades:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> PlaceOrder
{
    <span class="kwrd">public</span> <span class="kwrd">string</span> Code { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">double</span> Amount { get; set; }
}

<span class="kwrd">public</span> <span class="kwrd">class</span> PlaceStockOrder : PlaceOrder { }

<span class="kwrd">public</span> <span class="kwrd">class</span> PlaceForexOrder : PlaceOrder { }</pre>
<p>Once we have two different message types, then we can configure the client to have those statically sent to different endpoints like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">&lt;</span><span class="html">UnicastBusConfig</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">MessageEndpointMappings</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">Messages</span><span class="kwrd">="Messages.PlaceStockOrder, Messages"</span> <span class="attr">Endpoint</span><span class="kwrd">="Stock"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">Messages</span><span class="kwrd">="Messages.PlaceForexOrder, Messages"</span> <span class="attr">Endpoint</span><span class="kwrd">="Forex"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">MessageEndpointMappings</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">UnicastBusConfig</span><span class="kwrd">&gt;</span></pre>
<p>And when it comes to handling our VIP customers, the recommendation would be to have those customers be served by a different set of web servers &#8211; we wouldn&#8217;t want a sudden flux in regular customers stealing all the HTTP connections from our VIP customers. Then we&#8217;d statically configure our VIP front-end to talk to our VIP back-end like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">&lt;</span><span class="html">UnicastBusConfig</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">MessageEndpointMappings</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">Messages</span><span class="kwrd">="Messages.PlaceStockOrder, Messages"</span> <span class="attr">Endpoint</span><span class="kwrd">="VIP_Stock"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">Messages</span><span class="kwrd">="Messages.PlaceForexOrder, Messages"</span> <span class="attr">Endpoint</span><span class="kwrd">="VIP_Forex"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">MessageEndpointMappings</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">UnicastBusConfig</span><span class="kwrd">&gt;</span></pre>
<p>And the logic to identify VIP customers would be done in the login screen which, from there, would direct the user to the appropriate web server farm.</p>
<h2>Static vs. Dynamic</h2>
<p>It may appear that the above statically configured solution is less flexible then the afore-mentioned hub-and-spoke content-based routing solution. And that&#8217;s probably correct. But the question is, are the business requirements (better called &#8220;objectives&#8221; in this case) likely to change? If we make the technological solution 10x more flexible than the business needs, but at the cost of maintainability (read time to market), we probably haven&#8217;t used the right tool for the job.</p>
<p>Many times we can find stable business objectives and align the topology of our solution with them. Not all that is dynamic and flexible is necessarily better than that which is static.</p>
<p>I&#8217;d go so far to say that if a solution makes heavy use of content-based routing, it is likely a more fragile solution as implementations of stable business objectives and volatile requirements are mixed up together. </p>
<h2>In Closing</h2>
<p>NServiceBus intentionally does not support content-based routing so as not to make it easy for developers to make architectural blunders that could require full-system rewrites a couple of years down the road.</p>
<p>If you want to learn more about these kinds of architectural principles, I suggest coming to my <a href="http://www.udidahan.com/training/">course</a>. I&#8217;m afraid that New York City is already sold out, but I&#8217;ll be coming back to the US again around October. Stockholm, London, Sydney, and Oslo are now all open for registration.</p>
<p>Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/03/20/careful-with-content-based-routing/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>The Known Unknowns of SOA</title>
		<link>http://www.udidahan.com/2010/11/15/the-known-unknowns-of-soa/</link>
		<comments>http://www.udidahan.com/2010/11/15/the-known-unknowns-of-soa/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 13:44:40 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1364</guid>
		<description><![CDATA[One of the better known analysts in the enterprise software area, JP Morgenthal, wrote this post about the relationship between SOA, BPM, and EA. In it he defines SOA as follows:
&#8220;SOA is a practice that focuses on modeling the entities, and relationships between entities, that comprise the business as a set of services. This can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/rumsfeld120804.jpg" alt="rumsfeld" title="rumsfeld" width="162" height="225" style="float:right; margin-left:10px; margin-bottom:10px;" />One of the better known analysts in the enterprise software area, JP Morgenthal, wrote this post about <a href="http://soa.dzone.com/news/relationship-between-soa-bpm">the relationship between SOA, BPM, and EA</a>. In it he defines SOA as follows:</p>
<blockquote><p>&#8220;SOA is a practice that focuses on modeling the entities, and relationships between entities, that comprise the business as a set of services. This can be done on a small or large scale. Typically, the relationships in this model represent consumer/provider relationships.&#8221;</p></blockquote>
<p>I have some serious concerns about the ramifications of this definition/description.</p>
<p>First of all, when reading &#8220;entities&#8221;, many people will interpret that to mean the entities found in Entity Relationship Diagrams [<a href="http://en.wikipedia.org/wiki/Entity-relationship_model">ERD</a>] or in Object Oriented Analysis &#038; Design [<a href="http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design">OOAD</a>]. In both, these entities are identified as the &#8220;nouns&#8221; of the domain. Examples of these ERD/OOAD-type entities include things like Customer, Order, and Product.</p>
<p>These are almost always the wrong place to start for identifying services in SOA.</p>
<p>Second, on the consumer/provider relationship: on the one had, this fits very well with how web services can consume (or call) other web services. However, the downsides of using web services as services in SOA is becoming well enough known that even in the same post we see this warning:</p>
<blockquote><p>&#8220;Web Services is not SOA, it is merely a standardized approach to accessing functionality on remote systems.&#8221;</p></blockquote>
<p>But the question remains, if a producer/consumer relationship is OK for SOA-type services, why doesn&#8217;t that hold for web services? And the answer is&#8230; it depends on the type of producer/consumer relationship. The typical relationship is one of synchronous calls from consumer to producer, this is not OK for SOA-type services either. </p>
<p>You see, this synchronous producer/consumer implies a model where services are not able to fulfill their objectives without calling other services. In order for us to achieve the IT/Business alignment promised by SOA, we need services which are autonomous, ie. able to fulfill their objectives without that kind of external help.</p>
<p>Instead, we need to look for a more loosely coupled producer/consumer relationship &#8211; like publish/subscribe, where the producer emits events, and the consumer subscribes and handles those events. The reason that this kind of relationship doesn&#8217;t hurt autonomy is that it disconnects services on the dimension of time. In order for a service to be able to make a decision autonomously without synchronously calling any other service, using only information provided by events it received in the past, it must be strongly aligned with the business.</p>
<p>Most projects which bandy about the SOA acronym aren&#8217;t actually made up of services &#8211; they&#8217;re made up of XML over HTTP functions calling other XML over HTTP functions, eventually calling XML over HTTP databases. You can layer as much XML and HTTP as you want on top of it, but at the end of the day, most projects are just functions calling functions calling databases &#8211; in other words, procedural programming in the large, and no amount of SOAP will wash away the stink.</p>
<p>Here&#8217;s a different definition of services for SOA that may communicate a bit better what it&#8217;s all about:</p>
<blockquote><p>A service is the technical authority for a specific business capability.<br />
Any piece of data or rule must be owned by only one service.</p></blockquote>
<p>What this means is that even when services are publishing and subscribing to each other&#8217;s events, we always know what the authoritative source of truth is for every piece of data and rule. </p>
<p>Also, when looking at services from the lense of business capabilities, what we see is that many user interfaces present information belonging to different capabilities &#8211; a product&#8217;s price alongside whether or not it&#8217;s in stock. In order for us to comply with the above definition of services, this leads us to an understanding that such user interfaces are actually a mashup &#8211; with each service having the fragment of the UI dealing with its particular data.</p>
<p>Ultimately, process boundaries like web apps, back-end, batch-processing are very poor indicators of service boundaries. We&#8217;d expect to see multiple business capabilities manifested in each of those processes.</p>
<p>I know that this may be more confusing than the traditional web services approach but, to paraphrase Donald Rumsfeld, it is better to know that you don&#8217;t know, than to not know that you don&#8217;t know <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/11/15/the-known-unknowns-of-soa/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Logical and Physical Architecture</title>
		<link>http://www.udidahan.com/2010/11/08/logical-and-physical-architecture/</link>
		<comments>http://www.udidahan.com/2010/11/08/logical-and-physical-architecture/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 19:14:04 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1355</guid>
		<description><![CDATA[One architectural misunderstanding I see repeatedly in my work with clients is in the relationship between logical and physical architecture. The most common building-block of these misunderstandings is the web service (or it&#8217;s &#8220;upgraded&#8221; .net counterpart &#8211; the WCF service).
Don&#8217;t get me wrong, sometimes there is a place for a web service, just not everywhere.
So, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/orthogonal1.jpg" alt="orthogonal" title="orthogonal" width="300" height="237" style="float:right; margin-left:10px; margin-bottom:10px;" />One architectural misunderstanding I see repeatedly in my work with clients is in the relationship between logical and physical architecture. The most common building-block of these misunderstandings is the web service (or it&#8217;s &#8220;upgraded&#8221; .net counterpart &#8211; the WCF service).</p>
<p>Don&#8217;t get me wrong, sometimes there is a place for a web service, just not everywhere.</p>
<p>So, what&#8217;s the problem?</p>
<p>Well, when developers and architects use web services as the building blocks of their designs, they are creating the same architecture for both the logical and physical elements of their system. Back in 1995, Philippe Kruchten documented his <a href="http://en.wikipedia.org/wiki/4%2B1_Architectural_View_Model">4 + 1 Architectural View Model</a> in which he outlined 4 + 1 different views that should be used to describe an architecture.</p>
<p>Even though since 1995 the number and types of recommended views of software architecture has evolved (with things like the <a href="http://en.wikipedia.org/wiki/Zachman_Framework">Zachman Framework</a> for enterprise architecture numbering some 30 views), there is broad agreement that (at the very least) the logical and physical artifacts should likely be designed differently.</p>
<p>Just because two distinct logical components have been identified in the architecture, that doesn&#8217;t necessarily mean they should be hosted separately (for example by making each one a web/wcf service). In fact, there are significant <b>disadvantages</b> to doing so (as described in the <a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">Fallacies of Distributed Computing</a>).</p>
<p>In some cases, this mistake is exacerbated by a mistaking these components with SOA-type services, resulting in an attempt by developers to have each component have its own contract, which can then be independently versioned. This often results in the need for transformation between the structure of these so-called contracts, but not within the components themselves (oh-no, they&#8217;re &#8220;autonomous&#8221;), but rather in between them using some kind of &#8220;ESB&#8221; technology.</p>
<p>This architectural style is known as the Broker, Hub and Spoke, Mediator, and most importantly &#8211; not SOA. If you find a technology that fits this style perfectly (like BizTalk), that technology is not a Bus, not a Service Bus, and definitely not an Enterprise Service Bus.</p>
<p>One of the problems of this approach is that when any &#8220;service&#8221; contract changes, you have to change all the transformations in your broker that involve it. Unfortunately, most brokers have no unit-testing facility so it&#8217;s very much trial and error, and error, and error. The matter is even more serious since most brokers don&#8217;t enable you to have your transformations or orchestrations in source control, so you can&#8217;t diff to see what changed from the previous version.</p>
<p>It&#8217;s really amazing how much pain can be traced back to that one original misunderstanding. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/11/08/logical-and-physical-architecture/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>NServiceBus Presentation Now Online</title>
		<link>http://www.udidahan.com/2010/06/09/nservicebus-presentation-now-online/</link>
		<comments>http://www.udidahan.com/2010/06/09/nservicebus-presentation-now-online/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 21:43:51 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1298</guid>
		<description><![CDATA[Last April I was in Bergen Norway for some consulting and training and I also gave my first NServiceBus presentation to a user group. I don&#8217;t particularly like giving NServiceBus-specific presentations, preferring to talk about the patterns and concepts of service-based architectures and service buses &#8211; NServiceBus is just an implementation. Ultimately, that&#8217;s what happened [...]]]></description>
			<content:encoded><![CDATA[<p>Last April I was in Bergen Norway for some consulting and training and I also gave my first NServiceBus presentation to a user group. I don&#8217;t particularly like giving NServiceBus-specific presentations, preferring to talk about the patterns and concepts of service-based architectures and service buses &#8211; NServiceBus is just an implementation. Ultimately, that&#8217;s what happened in the presentation &#8211; in the first half (or so) I talked about the theory, and in the second I demonstrated that theory with NServiceBus.</p>
<p>Currently, the video is being graciously hosted by Jon Torresdal on his blog, so let&#8217;s hope that the bandwidth holds up.</p>
<p>Get it <a href="http://blog.torresdal.net/2010/06/08/NNUGPresentationUdiDahanOnNServiceBus.aspx">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/06/09/nservicebus-presentation-now-online/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[Article] EDA: SOA through the looking glass</title>
		<link>http://www.udidahan.com/2009/09/29/article-eda-soa-through-the-looking-glass/</link>
		<comments>http://www.udidahan.com/2009/09/29/article-eda-soa-through-the-looking-glass/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 11:05:33 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1117</guid>
		<description><![CDATA[

My latest article has been published in issue 21 of the Microsoft Architecture Journal:
EDA: SOA Through The Looking Glass

While event-driven architecture (EDA) is a broadly known topic, both giving up ACID integrity guarantees and introducing eventual consistency make many architects uncomfortable. Yet it is exactly these properties that can direct architectural efforts toward identifying coarsely [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/architecture/aa699424.aspx"><br />
<img src="http://www.udidahan.com/wp-content/uploads/arcjournal21.png" style="float:right; margin-left:20px; margin-bottom:10px; border:1px solid black" alt="Microsoft Architecture Journal" title="Microsoft Architecture Journal" /></a></p>
<p>My latest article has been published in issue 21 of the Microsoft Architecture Journal:</p>
<p><u>EDA: SOA Through The Looking Glass</u></p>
<div style="font-size:12px">
While event-driven architecture (EDA) is a broadly known topic, both giving up ACID integrity guarantees and introducing eventual consistency make many architects uncomfortable. Yet it is exactly these properties that can direct architectural efforts toward identifying coarsely grained business-service boundaries—services that will result in true IT-business alignment.</p>
<p>Business events create natural temporal boundaries across which there is no business expectation of immediate consistency or confirmation. When they are mapped to technical solutions, the loosely coupled business domains on either side of business events simply result in autonomous, loosely coupled services whose contracts explicitly reflect the inherent publish/subscribe nature of the business.</p>
<p>This article will describe how all of these concepts fit together, as well as how they solve thorny issues such as high availability and fault tolerance.</p>
<p><a href="http://msdn.microsoft.com/en-us/architecture/aa699424.aspx">Continue reading&#8230;</a>
</div>
<p>Please leave questions and comments here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/09/29/article-eda-soa-through-the-looking-glass/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Hanselminutes on NServiceBus</title>
		<link>http://www.udidahan.com/2009/08/21/hanselminutes-on-nservicebus/</link>
		<comments>http://www.udidahan.com/2009/08/21/hanselminutes-on-nservicebus/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 19:53:11 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[MSMQ]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1087</guid>
		<description><![CDATA[
Yesterday me and Scott virtually sat down to have a chat about NServiceBus and service buses in general. While we didn&#8217;t get in to many of the more advanced parts, you may find it an interesting introduction to the topic as well as saving yourself the costly mistake of implementing a broker instead of a [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.hanselman.com/blog/images/author.jpg" style="float:right; margin-left:10px; margin-bottom:10px;" /><br />
Yesterday me and Scott virtually sat down to have a chat about NServiceBus and service buses in general. While we didn&#8217;t get in to many of the more advanced parts, you may find it an interesting introduction to the topic as well as saving yourself the costly mistake of implementing a broker instead of a bus (yes &#8211; they&#8217;re actually two different things).</p>
<p><a href="http://www.hanselminutes.com/default.aspx?showID=194">Take a listen.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/08/21/hanselminutes-on-nservicebus/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Saga Persistence and Event-Driven Architectures</title>
		<link>http://www.udidahan.com/2009/04/20/saga-persistence-and-event-driven-architectures/</link>
		<comments>http://www.udidahan.com/2009/04/20/saga-persistence-and-event-driven-architectures/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 11:50:44 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=992</guid>
		<description><![CDATA[When working with clients, I run into more than a couple of people that have difficulty with event-driven architecture (EDA). Even more people have difficulty understanding what sagas really are, let alone why they need to use them. I&#8217;d go so far to say that many people don&#8217;t realize the importance of how sagas are [...]]]></description>
			<content:encoded><![CDATA[<p><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 10px 10px; border-right-width: 0px" height="128" alt="image" src="http://www.udidahan.com/wp-content/uploads/saga_persistence.jpg" width="200" align="right" border="0" />When working with clients, I run into more than a couple of people that have difficulty with event-driven architecture (EDA). Even more people have difficulty understanding what sagas really are, let alone why they need to use them. I&#8217;d go so far to say that many people don&#8217;t realize the importance of how sagas are persisted in making it all work (including the Workflow Foundation team).</p>
<h3>The common e-commerce example</h3>
<p>We accept orders, bill the customer, and then ship them the product.</p>
<p>Fairly straight-forward.</p>
<p>Since each part of that process can be quite complex, let&#8217;s have each step be handled by a service:</p>
<p>Sales, Billing, and Shipping. Each of these services will publish an event when it&#8217;s done its part. Sales will publish OrderAccepted containing all the order information &#8211; order Id, customer Id, products, quantities, etc. Billing will publish CustomerBilledForOrder containing the customer Id, order Id, etc. And Shipping will publish OrderShippedToCustomer with its data.</p>
<p>So far, so good. EDA and SOA seem to be providing us some value.</p>
<h3>Where&#8217;s the saga?</h3>
<p>Well, let&#8217;s consider the behavior of the Shipping service. It shouldn&#8217;t ship the order to the customer until it has received the CustomerBilledForOrder event as well as the OrderAccepted event. In other words, Shipping needs to hold on to the state that came in the first event until the second event comes in. And this is exactly what sagas are for.</p>
<p>Let&#8217;s take a look at the saga code that implements this. In order to simplify the sample a bit, I&#8217;ll be omitting the product quantities.</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> ShippingSaga : Saga&lt;ShippingSagaData&gt;,</pre>
<pre><span class="lnum">   2:  </span>        ISagaStartedBy&lt;OrderAccepted&gt;,</pre>
<pre class="alt"><span class="lnum">   3:  </span>        ISagaStartedBy&lt;CustomerBilledForOrder&gt;</pre>
<pre><span class="lnum">   4:  </span>    {</pre>
<pre class="alt"><span class="lnum">   5:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Handle(OrderAccepted message)</pre>
<pre><span class="lnum">   6:  </span>        {</pre>
<pre class="alt"><span class="lnum">   7:  </span>            <span class="kwrd">this</span>.Data.ProductIdsInOrder = message.ProductIdsInOrder;</pre>
<pre><span class="lnum">   8:  </span>        }</pre>
<pre class="alt"><span class="lnum">   9:  </span>&nbsp;</pre>
<pre><span class="lnum">  10:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Handle(CustomerBilledForOrder message)</pre>
<pre class="alt"><span class="lnum">  11:  </span>        {</pre>
<pre><span class="lnum">  12:  </span>             <span class="kwrd">this</span>.Bus.Send&lt;ShipOrderToCustomer&gt;(</pre>
<pre class="alt"><span class="lnum">  13:  </span>                (m =&gt;</pre>
<pre><span class="lnum">  14:  </span>                {</pre>
<pre class="alt"><span class="lnum">  15:  </span>                    m.CustomerId = message.CustomerId;</pre>
<pre><span class="lnum">  16:  </span>                    m.OrderId = message.OrderId;</pre>
<pre class="alt"><span class="lnum">  17:  </span>                    m.ProductIdsInOrder = <span class="kwrd">this</span>.Data.ProductIdsInOrder;</pre>
<pre><span class="lnum">  18:  </span>                }</pre>
<pre class="alt"><span class="lnum">  19:  </span>                ));</pre>
<pre><span class="lnum">  20:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  21:  </span>            <span class="kwrd">this</span>.MarkAsComplete();</pre>
<pre><span class="lnum">  22:  </span>        }</pre>
<pre class="alt"><span class="lnum">  23:  </span>&nbsp;</pre>
<pre><span class="lnum">  24:  </span>        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Timeout(<span class="kwrd">object</span> state)</pre>
<pre class="alt"><span class="lnum">  25:  </span>        {</pre>
<pre><span class="lnum">  26:  </span>            </pre>
<pre class="alt"><span class="lnum">  27:  </span>        }</pre>
<pre><span class="lnum">  28:  </span>    }</pre>
</div>
<p>First of all, this looks fairly simple and straightforward, which is good.<br/><br />
It&#8217;s also wrong, which is not so good.</p>
<p>One problem we have here is that events may arrive out of order &#8211; first CustomerBilledForOrder, and only then OrderAccepted. What would happen in the above saga in that case? Well, we wouldn&#8217;t end up shipping the products to the customer, and customers tend not to like that (for some reason).</p>
<p>There&#8217;s also another problem here. See if you can spot it as I go through the explanation of ISagaStartedBy&lt;T&gt;.</p>
<h3>Saga start up and correlation</h3>
<p>The &#8220;ISagaStartedBy&lt;T&gt;&#8221; that is implemented for both messages indicates to the infrastructure (NServiceBus) that when a message of that type arrives, if an existing saga instance cannot be found, that a new instance should be started up. Makes sense, doesn&#8217;t it? For a given order, when the OrderAccepted event arrives first, Shipping doesn&#8217;t currently have any sagas handling it, so it starts up a new one. After that, when the CustomerBilledForOrder event arrives for that same order, the event should be handled by the saga instance that handled the first event &#8211; not by a new one.</p>
<p>I&#8217;ll repeat the important part: &#8220;the event should be handled by the saga instance that handled the first event&#8221;.</p>
<p>Since the only information we stored in the saga was the list of products, how would we be able to look up that saga instance when the next event came in containing an order Id, but no saga Id?</p>
<p>OK, so we need to store the order Id from the first event so that when the second event comes along we&#8217;ll be able to find the saga based on that order Id. Not too complicated, but something to keep in mind.</p>
<p>Let&#8217;s look at the updated code:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> ShippingSaga : Saga&lt;ShippingSagaData&gt;,</pre>
<pre><span class="lnum">   2:  </span>        ISagaStartedBy&lt;OrderAccepted&gt;,</pre>
<pre class="alt"><span class="lnum">   3:  </span>        ISagaStartedBy&lt;CustomerBilledForOrder&gt;</pre>
<pre><span class="lnum">   4:  </span>    {</pre>
<pre class="alt"><span class="lnum">   5:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Handle(CustomerBilledForOrder message)</pre>
<pre><span class="lnum">   6:  </span>        {</pre>
<pre class="alt"><span class="lnum">   7:  </span>            <span class="kwrd">this</span>.Data.CustomerHasBeenBilled = <span class="kwrd">true</span>;</pre>
<pre><span class="lnum">   8:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   9:  </span>            <span class="kwrd">this</span>.Data.CustomerId = message.CustomerId;</pre>
<pre><span class="lnum">  10:  </span>            <span class="kwrd">this</span>.Data.OrderId = message.OrderId;</pre>
<pre class="alt"><span class="lnum">  11:  </span>&nbsp;</pre>
<pre><span class="lnum">  12:  </span>            <span class="kwrd">this</span>.CompleteIfPossible();</pre>
<pre class="alt"><span class="lnum">  13:  </span>        }</pre>
<pre><span class="lnum">  14:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  15:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Handle(OrderAccepted message)</pre>
<pre><span class="lnum">  16:  </span>        {</pre>
<pre class="alt"><span class="lnum">  17:  </span>            <span class="kwrd">this</span>.Data.ProductIdsInOrder = message.ProductIdsInOrder;</pre>
<pre><span class="lnum">  18:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  19:  </span>            <span class="kwrd">this</span>.Data.CustomerId = message.CustomerId;</pre>
<pre><span class="lnum">  20:  </span>            <span class="kwrd">this</span>.Data.OrderId = message.OrderId;</pre>
<pre class="alt"><span class="lnum">  21:  </span>&nbsp;</pre>
<pre><span class="lnum">  22:  </span>            <span class="kwrd">this</span>.CompleteIfPossible();</pre>
<pre class="alt"><span class="lnum">  23:  </span>        }</pre>
<pre><span class="lnum">  24:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  25:  </span>        <span class="kwrd">private</span> <span class="kwrd">void</span> CompleteIfPossible()</pre>
<pre><span class="lnum">  26:  </span>        {</pre>
<pre class="alt"><span class="lnum">  27:  </span>            <span class="kwrd">if</span> (<span class="kwrd">this</span>.Data.ProductIdsInOrder != <span class="kwrd">null</span> &amp;&amp; <span class="kwrd">this</span>.Data.CustomerHasBeenBilled)</pre>
<pre><span class="lnum">  28:  </span>            {</pre>
<pre><span class="lnum">  29:  </span>                <span class="kwrd">this</span>.Bus.Send&lt;ShipOrderToCustomer&gt;(</pre>
<pre class="alt"><span class="lnum">  30:  </span>                   (m =&gt;</pre>
<pre><span class="lnum">  31:  </span>                   {</pre>
<pre class="alt"><span class="lnum">  32:  </span>                       m.CustomerId = <span class="kwrd">this</span>.Data.CustomerId;</pre>
<pre><span class="lnum">  33:  </span>                       m.OrderId = <span class="kwrd">this</span>.Data.OrderId;</pre>
<pre class="alt"><span class="lnum">  34:  </span>                       m.ProductIdsInOrder = <span class="kwrd">this</span>.Data.ProductIdsInOrder;</pre>
<pre><span class="lnum">  35:  </span>                   }</pre>
<pre class="alt"><span class="lnum">  36:  </span>                   ));</pre>
<pre><span class="lnum">  37:  </span>                <span class="kwrd">this</span>.MarkAsComplete();</pre>
<pre class="alt"><span class="lnum">  38:  </span>            }</pre>
<pre><span class="lnum">  39:  </span>        }</pre>
<pre class="alt"><span class="lnum">  40:  </span>    }</pre>
</div>
<p>And that brings us to&#8230;</p>
<h3>Saga persistence</h3>
<p>We already saw why Shipping needs to be able to look up its internal sagas using data from the events, but what that means is that simple blob-type persistence of those sagas is out. NServiceBus comes with an NHibernate-based saga persister for exactly this reason, though any persistence mechanism which allows you to query on something other than saga Id would work just as well.</p>
<p>Let&#8217;s take a quick look at the saga data that we&#8217;ll be storing and see how simple it is:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> ShippingSagaData : ISagaEntity</pre>
<pre><span class="lnum">   2:  </span>    {</pre>
<pre class="alt"><span class="lnum">   3:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> Guid Id { get; set; }</pre>
<pre><span class="lnum">   4:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">string</span> Originator { get; set; }</pre>
<pre class="alt"><span class="lnum">   5:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> Guid OrderId { get; set; }</pre>
<pre><span class="lnum">   6:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> Guid CustomerId { get; set; }</pre>
<pre class="alt"><span class="lnum">   7:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> List&lt;Guid&gt; ProductIdsInOrder { get; set; }</pre>
<pre><span class="lnum">   8:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">bool</span> CustomerHasBeenBilled { get; set; }</pre>
<pre class="alt"><span class="lnum">   9:  </span>    }</pre>
</div>
<p>You might have noticed the &#8220;Originator&#8221; property in there and wondered what it is for. First of all, the ISagaEntity interface requires the two properties Id and Originator. Originator is used to store the return address of the message that started the saga. Id is for what you think it&#8217;s for. In this saga, we don&#8217;t need to send any messages back to whoever started the saga, but in many others we do. In those cases, we&#8217;ll often be handling a message from some other endpoint when we want to possibly report some status back to the client that started the process. By storing that client&#8217;s address the first time, we can then &#8220;ReplyToOriginator&#8221; at any point in the process.</p>
<p>The manufacturing sample that comes with <a href="http://www.NServiceBus.com">NServiceBus</a> shows how this works.</p>
<h3>Saga Lookup</h3>
<p>Earlier, we saw the need to search for sagas based on order Id. The way to hook into the infrastructure and perform these lookups is by implementing &#8220;IFindSagas&lt;T&gt;.Using&lt;M&gt;&#8221; where T is the type of the saga data and M is the type of message. In our example, doing this using NHibernate would look like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> ShippingSagaFinder : </pre>
<pre><span class="lnum">   2:  </span>        IFindSagas&lt;ShippingSagaData&gt;.Using&lt;OrderAccepted&gt;,</pre>
<pre class="alt"><span class="lnum">   3:  </span>        IFindSagas&lt;ShippingSagaData&gt;.Using&lt;CustomerBilledForOrder&gt;</pre>
<pre><span class="lnum">   4:  </span>    {</pre>
<pre class="alt"><span class="lnum">   5:  </span>        <span class="kwrd">public</span> ShippingSagaData FindBy(CustomerBilledForOrder message)</pre>
<pre><span class="lnum">   6:  </span>        {</pre>
<pre class="alt"><span class="lnum">   7:  </span>            <span class="kwrd">return</span> FindBy(message.OrderId)</pre>
<pre><span class="lnum">   8:  </span>        }</pre>
<pre class="alt"><span class="lnum">   9:  </span>&nbsp;</pre>
<pre><span class="lnum">  10:  </span>        <span class="kwrd">public</span> ShippingSagaData FindBy(OrderAccepted message)</pre>
<pre class="alt"><span class="lnum">  11:  </span>        {</pre>
<pre><span class="lnum">  12:  </span>            <span class="kwrd">return</span> FindBy(message.OrderId)</pre>
<pre class="alt"><span class="lnum">  13:  </span>        }</pre>
<pre><span class="lnum">  14:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  15:  </span>        <span class="kwrd">private</span> ShippingSagaData FindBy(Guid orderId)</pre>
<pre><span class="lnum">  16:  </span>        {</pre>
<pre class="alt"><span class="lnum">  17:  </span>            <span class="kwrd">return</span> sessionFactory.GetCurrentSession().CreateCriteria(<span class="kwrd">typeof</span>(ShippingSagaData))</pre>
<pre><span class="lnum">  18:  </span>                .Add(Expression.Eq(<span class="str">"OrderId"</span>, orderId))</pre>
<pre class="alt"><span class="lnum">  19:  </span>                .UniqueResult&lt;ShippingSagaData&gt;();</pre>
<pre><span class="lnum">  20:  </span>        }</pre>
<pre class="alt"><span class="lnum">  21:  </span>&nbsp;</pre>
<pre><span class="lnum">  22:  </span>        <span class="kwrd">private</span> ISessionFactory sessionFactory;</pre>
<pre class="alt"><span class="lnum">  23:  </span>&nbsp;</pre>
<pre><span class="lnum">  24:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> ISessionFactory SessionFactory</pre>
<pre class="alt"><span class="lnum">  25:  </span>        {</pre>
<pre><span class="lnum">  26:  </span>            get { <span class="kwrd">return</span> sessionFactory; }</pre>
<pre class="alt"><span class="lnum">  27:  </span>            set { sessionFactory = <span class="kwrd">value</span>; }</pre>
<pre><span class="lnum">  28:  </span>        }</pre>
<pre class="alt"><span class="lnum">  29:  </span>    }</pre>
</div>
<p>For a performance boost, we&#8217;d probably index our saga data by order Id.</p>
<h3>On concurrency</h3>
<p>Another important note is that for this saga, if both messages were handled in parallel on different machines, the saga could get stuck. The persistence mechanism here needs to prevent this. When using NHibernate over a database with the appropriate isolation level (Repeatable Read &#8211; the default in NServiceBus), this &#8220;just works&#8221;. If/When implementing your own saga persistence mechanism, it is important to understand the kind of concurrency your business logic can live with.</p>
<p>Take a look at Ayende&#8217;s example for <a href="http://ayende.com/Blog/archive/2009/01/23/rhino-dht-concurrency-handling-example-ndash-the-phone-billing-system.aspx">mobile phone billing</a> to get a feeling for what that&#8217;s like.</p>
<h3>Summary</h3>
<p>In almost any event-driven architecture, you&#8217;ll have services correlating multiple events in order to make decisions. The saga pattern is a great fit there, and not at all difficult to implement. You do need to take into account that events may arrive out of order and implement the saga logic accordingly, but it&#8217;s really not that big a deal. Do take the time to think through what data will need to be stored in order for the saga to be fault-tolerant, as well as a persistence mechanism that will allow you to look up that data based on event data.</p>
<p>If you feel like giving this approach a try, but don&#8217;t have an environment handy for this, download <a href="http://www.NServiceBus.com">NServiceBus</a> and take a look at the samples. It&#8217;s really quick and easy to get set up.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/04/20/saga-persistence-and-event-driven-architectures/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Backwards-Compatibility: Why Most Versioning Problems Aren&#8217;t</title>
		<link>http://www.udidahan.com/2009/04/10/backwards-compatibility-why-most-versioning-problems-arenrsquot/</link>
		<comments>http://www.udidahan.com/2009/04/10/backwards-compatibility-why-most-versioning-problems-arenrsquot/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 13:17:17 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2009/04/10/backwards-compatibility-why-most-versioning-problems-arenrsquot/</guid>
		<description><![CDATA[
I’ve been to too many clients where I’ve been brought in to help them with their problems around service versioning when the solution I propose is simply to have version N+1 of the system be backwards-compatible with version N. If two adjacent versions of a given system aren’t compatible with each other, it is practically [...]]]></description>
			<content:encoded><![CDATA[<p><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 10px 10px; border-right-width: 0px" height="244" alt="image" src="http://www.udidahan.com/wp-content/ServicesVersioningPubSubandMultipleInher_11E4C/image.png" width="244" align="right" border="0" />
<p>I’ve been to too many clients where I’ve been brought in to help them with their problems around service versioning when the solution I propose is simply to have version N+1 of the system be backwards-compatible with version N. If two adjacent versions of a given system aren’t compatible with each other, it is practically impossible to solve versioning issues.</p>
<p>Here’s what happens when versions aren’t compatible:</p>
<blockquote><p>Admins stop the system from accepting any new requests, and wait until all current requests are done processing. They take a backup/snapshot of all relevant parts of the system (like data in the DB). Then, bring down the system – all of it. Install the new version on all machines. Bring everything back up. Let the users back in.</p></blockquote>
<p>If, heaven-forbid, problems were uncovered with the new version (since some problems only appear in production), the admins have to roll back to the previous version – once again bringing everything down.</p>
<p>This scenario is fairly catastrophic for any company that requires not-even high availability, but pretty continuous availability – like public facing web apps.</p>
<p>If adjacent versions were compatible with each other, we could upgrade the system piece-meal – machine by machine, where both the old and new versions will be running side by side, communicating with each other. While the system’s performance may be sub-optimal, it will continue to be available throughout upgrades as well as downgrades.</p>
<p>This isn’t trivial to do.</p>
<p>It impacts how you decide what is (and more importantly, what isn’t) nullable.</p>
<p>It may force you to spread certain changes to features across more versions (aka releases).</p>
<p>As such, you can expect this to affect how you do release and feature planning.</p>
<p>However, if you do not take these factors into account, it’s almost a certainty that your versioning problems will persist and no technology (new or old) will be able to solve them.</p>
<p>Coming next… Units of versioning – inside and outside a service.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/04/10/backwards-compatibility-why-most-versioning-problems-arenrsquot/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Messaging ROI</title>
		<link>http://www.udidahan.com/2009/02/22/messaging-roi/</link>
		<comments>http://www.udidahan.com/2009/02/22/messaging-roi/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 10:12:59 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Scalability]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2009/02/22/messaging-roi/</guid>
		<description><![CDATA[There&#8217;s been some recent discussion as to the &#8220;cost&#8221; of messaging:
Greg Young asserts: 
&#8220;I believe that this shows there to be a rather negligible cost associated with the use of such a model. There is however a small cost, this cost however I believe only exists when one looks at the system in isolation.&#8221;

Ayende adds [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been some recent discussion as to the &#8220;cost&#8221; of messaging:</p>
<p>Greg Young <a href="http://codebetter.com/blogs/gregyoung/archive/2009/02/09/cost.aspx">asserts</a>:<a href="http://codebetter.com/blogs/gregyoung/archive/2009/02/09/cost.aspx"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="79" alt="image" src="http://www.udidahan.com/wp-content/uploads/image54.png" width="79" align="right" border="0"></a> </p>
<blockquote><p>&#8220;I believe that this shows there to be a rather negligible cost associated with the use of such a model. There is however a small cost, this cost however I believe only exists when one looks at the system in isolation.&#8221;</p>
</blockquote>
<p>Ayende adds <a href="http://ayende.com/Blog/archive/2009/02/09/the-cost-of-messaging.aspx">his perspective</a>:<a href="http://ayende.com/Blog/archive/2009/02/09/the-cost-of-messaging.aspx"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="77" alt="image" src="http://www.udidahan.com/wp-content/uploads/image55.png" width="85" align="right" border="0"></a> </p>
<blockquote><p>&#8220;The cost of messaging, and a very real one, comes when you need to understand the system. In a system where message exchange is the form of communication, it can be significantly harder to understand what is going on.&#8221;</p>
</blockquote>
<p>Of course, both these intelligent fellows are right. The reason for the apparent disparity in viewpoints has to do with which part of the following graph you look at. Ayende zooms in on the left side:</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="225" alt="left graph" src="http://www.udidahan.com/wp-content/uploads/image56.png" width="404" border="0"> </p>
<p>As systems get larger, though, the only way to understand them is by working at higher levels of abstraction. That&#8217;s where messaging really shines, as the incremental complexity remains the same by maintaining the same modularity as before:</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="232" alt="full graph" src="http://www.udidahan.com/wp-content/uploads/image57.png" width="404" border="0"> </p>
<p>In Ayende&#8217;s post, he follows the design I described a while back on using messaging for user management and <a href="http://www.udidahan.com/2007/11/10/asynchronous-high-performance-login-for-web-farms/">login for a high-scale web scenario</a>. In his comments, he agrees with the above stating:</p>
<blockquote><p>&#8220;I certainly think that a similar solution using RPC would be much more complex and likely more brittle.&#8221;</p>
</blockquote>
<p>I feel quite conservative in saying the most enterprise solutions fall on the right side of the intersection in the graph.</p>
<p>That being said, don&#8217;t underestimate the learning curve developers go through with messaging. While the mechanics are similar, the mindset is very different. Think about it like this:<a href="http://www.udidahan.com/wp-content/uploads/image58.png"><img style="border-right: 0px; border-top: 0px; margin: 5px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="100" alt="image" src="http://www.udidahan.com/wp-content/uploads/image-thumb36.png" width="80" align="right" border="0"></a> </p>
<blockquote><p>You&#8217;ve driven a car for years in the US. It&#8217;s practically second nature. Then you fly to the UK, rent a car, and all of a sudden, your brain is in meltdown. (or vice versa for those going from the UK to the US)</p>
</blockquote>
<h3>Summary</h3>
<p>If you are going down the messaging route, please be aware that there are shades of gray there as well. You don&#8217;t <em>have</em> to implement your user management and login the way I outlined in my post if you don&#8217;t require such high levels of scalability, but even lower levels of scalability can benefit from messaging.</p>
<p>Just as there isn&#8217;t a single correct design for non-messaging solutions, the same is true for those using messaging. Finding the right balance is tricky, and critical. </p>
<p>When the code is simple in every part of the system, and the asynchronous interactions are what provide for the necessary complexity the problem domain requires, that&#8217;s when you know you&#8217;ve got it just right.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/02/22/messaging-roi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SOA, REST, and Pub/Sub</title>
		<link>http://www.udidahan.com/2008/12/15/soa-rest-and-pubsub/</link>
		<comments>http://www.udidahan.com/2008/12/15/soa-rest-and-pubsub/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 08:34:24 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Integrated Simplicity]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Scalability]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/12/15/soa-rest-and-pubsub/</guid>
		<description><![CDATA[From Integrated Simplicity:
 
The question of how web-based (or 3rd party) consumers can work with pub/sub based services comes up a lot.
Many developers are used to implementing web services exposing methods on them like GetAllCustomers.
When moving to pub/sub and other more loosely coupled messaging patterns, developers look to implement the same pattern, opting for something [...]]]></description>
			<content:encoded><![CDATA[<p>From <a href="http://www.IntegratedSimplicity.com">Integrated Simplicity</a>:</p>
<p><a href="http://www.udidahan.com/wp-content/uploads/image49.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px; border-left: 0px; border-bottom: 0px" height="277" alt="SOA &amp; Web" src="http://www.udidahan.com/wp-content/uploads/image-thumb34.png" width="526" border="0"></a> </p>
<p>The question of how web-based (or 3rd party) consumers can work with pub/sub based services comes up a lot.</p>
<p>Many developers are used to implementing web services exposing methods on them like GetAllCustomers.</p>
<p>When moving to pub/sub and other more loosely coupled messaging patterns, developers look to implement the same pattern, opting for something like duplex GetCustomersRequest and GetCustomersResponse. The reasoning is simple and straightforward &#8211; it is difficult to push data over the web to consumers.</p>
<p>However, there are still ways to disconnect the preparation of the data from its usage thus gaining many of the advantages of pub/sub.</p>
<p>By employing REST principles and modelling our customer list as an explicit resource, web-based consumers would simply perform regular HTTP GET operations on the URI to get the list of customers.</p>
<p>The resource itself could be a simple XML file &#8211; it wouldn&#8217;t need to be dynamic at all.</p>
<p>You can get all the scalability benefits of pub/sub for web based consumers. All you need is a bit of REST <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/12/15/soa-rest-and-pubsub/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Self-Contained Events and SOA</title>
		<link>http://www.udidahan.com/2008/12/13/self-contained-events-and-soa/</link>
		<comments>http://www.udidahan.com/2008/12/13/self-contained-events-and-soa/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 23:35:08 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Master Data Management]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/12/13/self-contained-events-and-soa/</guid>
		<description><![CDATA[In the architectural principle of fully self contained messages, events &#8220;can &#8211; instantly and in future &#8211; be interpreted as the respective event without the need to rely on additional data stores that would need to be in time-sync with the event during message-processing.&#8221;
Also, &#8220;passing reference data in a message makes the message-consuming systems dependent [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="237" alt="diamond" src="http://www.udidahan.com/wp-content/uploads/diamond.jpg" width="214" align="right" border="0">In <a href="http://soa-eda.blogspot.com/2008/11/architectural-principle-of-fully-self.html">the architectural principle of fully self contained messages</a>, events &#8220;can &#8211; instantly and in future &#8211; be interpreted as the respective event without the need to rely on additional data stores that would need to be in time-sync with the event during message-processing.&#8221;</p>
<p>Also, &#8220;passing reference data in a message makes the message-consuming systems dependent on the knowledge and availability of actual persistent data that is stored “somewhere”. This data must separately be accessed for the sake of understanding the event that is represented by the message.&#8221; </p>
<p>The discussion of self-contained events can be compared to <a href="http://martinfowler.com/bliki/IntegrationDatabase.html">integration databases</a> vs <a href="http://martinfowler.com/bliki/ApplicationDatabase.html">application databases</a>. </p>
<h3>Centralized Integration &#8211; Pros &amp; Cons</h3>
<p>If everything in a system can access a central datastore, it is enough for one party to publish an event containing only the ID of an entity that that party previously entered/updated. Upon receiving that event, a subscriber would go to the central datastore and get the fields its interested in for that ID. The advantage of this approach is that the minimal amount of data necessary crosses the network, as subscribers only retrieve the fields that interest them. Martin Fowler describes the disadvantages as:</p>
<blockquote><p>&#8220;An integration database needs a schema that takes all its client applications into account. The resulting schema is either more general, more complex or both. The database usually is controlled by a separate group to the applications and database changes are more complex because they have to be negotiated between the database group and the various applications.&#8221;</p>
</blockquote>
<p>This is far from being aligned with the principle of autonomy so important to SOA. In that respect, the architectural principle of self-contained messages points us away from those problems and towards more autonomous services.</p>
<p>However, once we have these autonomous business services in place, we may find that we don&#8217;t need 100% fully self-contained messages anymore. </p>
<h3>A Real-World Example</h3>
<p>Let&#8217;s say we have 3 business services, Sales, Fulfillment, and Billing.</p>
<p>Sales publishes an OrderAccepted event when it accepts an order. That event contains all the order information.</p>
<p>Both Fulfillment and Billing are subscribed to this event, and thus receive it. </p>
<p>Fulfillment does not ship products to the customer until the customer has been billed, so it just stores the order information internally, and is done.</p>
<p>Billing starts the process of billing the customer for their order, possibly joining several orders into a single bill. After completing this process, it publishes a CustomerBilled event containing all billing information, as well as the IDs of the orders in that bill. It does not put all the order information in that event, as it is not the authoritative owner of that data.</p>
<p>When Fulfillment receives the CustomerBilled event, it uses the IDs of the orders contained in the event to find the order information it previously stored internally. It does not need to call the Sales service for this information or contact some central Master Data Management system. It uses the data it has, and goes about fulfilling the orders and shipping the products to the customer, finally publishing its own OrderShipped event.</p>
<p>Notice, as well, that in the original OrderAccepted event there were the IDs of products the customer ordered. These product IDs originated from another service, Merchandising, responsible for the product catalog. The same thing can be said for the customer ID originating from another service &#8211; Customer Care.</p>
<h3>The Issue of Time</h3>
<p>One could argue that since subscribers use previously cached data when processing new events, that data might not be up to date. Also, we may have race conditions between our services. In the above example, if Billing was extremely fast and more highly available than Fulfillment. Billing could have received the OrderAccepted event, processed it, and published the CustomerBilled event before Fulfillment had received the OrderAccepted event. In short, the CustomerBilled and OrderAccepted messages could be out of order in Fulfillment’s queue.</p>
<p>What would Fulfillment do when trying to process the CustomerBilled message when it doesn’t have the order information?
<p>Well, it knows that the world is parallel and non-sequential, so it does NOT return/log an error, but rather puts that message in the back of the queue to be processed again later (or maybe in some other temporary holding area). This enables the OrderAccepted message to be processed before the CustomerBilled message is retried. When the retry occurs, well, everything’s OK – it’s worked itself out over time.
<p>In the case where we retry again and again and things don’t work themselves out (maybe the OrderAccepted event was lost), we move that message off to a different queue for something else to resolve the conflict (maybe a person, maybe software). If/when the conflict is resolved (got the Sales system / messaging system to replay the OrderAccepted event), the conflict resolver returns the CustomerBilled message to the queue, and now everything works just fine.
<p>As all of this is occurring, the only thing that’s visible to external parties is that it happens to be taking longer than usual for the OrderShipped event to be published. In other words, time is the only difference.<br />
<h3>&nbsp;</h3>
<h3>Summary</h3>
<p>The problem of non-self-contained events is mitigated first and foremost by business services in SOA, and the apparent issue of time-synchronization by business logic inside these services.</p>
<p>Don&#8217;t be afraid to put IDs in your messages and events.</p>
<p>Do be afraid of using those IDs to access datastores shared by multiple &#8220;services&#8221;.</p>
<p>Using IDs to correlated current events to data from previous events is not only OK, it&#8217;s to be expected.</p>
<p>The architectural principle of fully self-contained messages steers us away from the problems of Integration Databases and towards Application Databases, autonomous services, and a better SOA implementation. From there, following the principle of autonomy from a business perspective, will lead us to services not publishing data in their messages that is owned by other services, taking us the next step of our journey to SOA.</p>
<hr size="1">
<h3> Related Content</h3>
<blockquote><p><a href="http://www.udidahan.com/2008/01/01/podcast-message-ordering-is-it-cost-effective/">[Podcast] Message Ordering &#8211; Is it cost effective?</a></p>
<p><a href="http://www.udidahan.com/2007/08/16/dont-eda-between-existing-systems/">Don&#8217;t EDA between existing systems</a></p>
<p><a href="http://www.udidahan.com/2007/05/31/podcast-handling-dependencies-between-subscribers-in-soa/">[Podcast] Handling dependencies between subscribers in SOA</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/12/13/self-contained-events-and-soa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lost Notifications? No Problem.</title>
		<link>http://www.udidahan.com/2008/12/07/lost-notifications-no-problem/</link>
		<comments>http://www.udidahan.com/2008/12/07/lost-notifications-no-problem/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 09:46:05 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[Reliability]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/12/07/lost-notifications-no-problem/</guid>
		<description><![CDATA[ One of the most common questions I get on the topic of pub/sub messaging is what happens if a notification is lost. Interestingly enough, there are some who almost entirely write-off this pattern because of this issue, preferring the control of request/response-exception. So, what should be done about lost messages? The short answer is [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="148" alt="" src="http://www.udidahan.com/wp-content/uploads/image48.png" width="240" align="right" border="0"> One of the most common questions I get on the topic of pub/sub messaging is what happens if a notification is lost. Interestingly enough, there are some who almost entirely write-off this pattern because of this issue, preferring the control of request/response-exception. So, what should be done about lost messages? The short answer is durable messaging. The long answer is design.</p>
<h3>Durable Messaging</h3>
<p>In order to prevent a message from being lost when it is sent from a publisher to a subscriber, the message is written to disk on the publisher side, and then forwarded to the subscriber, where it is also written to disk. This store-and-forward mechanism enables our systems to gracefully recover from either side being temporarily unavailable.</p>
<p>In my <a href="http://msdn.microsoft.com/en-us/magazine/cc663023.aspx">MSDN article on this topic</a>, I outlined some problems with this approach. These problems are exacerbated for publishers. Imagine a publisher with 40 subscribers, publishing 10 messages a second, each containing 1MB of XML. If 10 of the subscribers are unavailable, that&#8217;s 100MB of data being written to the publisher&#8217;s disk every second, 6GB every minute. That&#8217;s liable to bring down a publisher before an administrator brews a cup of coffee.</p>
<p>Publishers have no choice but to throw away messages after a certain period of time.</p>
<h3>Publisher Contracts</h3>
<p>The whole issue of contracts and schema is considered one of the better understand parts of SOA. Unfortunately, the operational aspects of service contracts is hardly ever taken into account.</p>
<p>On top of the schema of the messages a service publishers, additional information is needed in the contract:</p>
<ol>
<li>How big will this message be?
<li>How often will it be published?
<li>How long will this message be stored if a subscriber is unavailable?</li>
</ol>
<p>This first two pieces of information are important for subscribers to do load and capacity planning. The last one is the most important as it dictates the required availability and fault-tolerance characteristic of subscribers.</p>
<h3>For Example</h3>
<p>In the canonical retail scenario, when our sales service accepts an order, it publishes an order accepted event. Other services subscribed to this event include shipping, billing, and business intelligence.</p>
<p>While shipping and billing are highly available and able to keep up with the rate at which orders are accepted, the business intelligence service is not. BI has two main parts to it &#8211; a nightly batch that does the number crunching, and a UI for reporting off of the results of that number crunching. Some even do the reporting in a semi-offline fashion, emailing reports back to the user when they&#8217;re ready.</p>
<p>Furthermore, nobody&#8217;s going to invest in servers for making BI highly available.</p>
<p>And wasn&#8217;t the whole point of this publish/subscribe messaging to keep our services autonomous? That not all services have to have the same level uptime?</p>
<p>Houston, do we have a problem.?</p>
<h3>Data Freshness</h3>
<p>There is a glimmer of light in all this doom and gloom.</p>
<p>Not all services have the same data freshness requirements.</p>
<p>The business intelligence service above doesn&#8217;t need to know about orders the second they&#8217;re accepted. A daily roll-up would be fine, and an hourly roll-up bring us that much closer to &#8220;real time business intelligence&#8221;.</p>
<p>So, while BI is ready to accept the sales message schema, it would like a slightly different contract around it &#8211; less messages per unit of time, more data in each message.</p>
<p>From the operational perspective of the sales service, it would be cost effective to have less &#8220;online&#8221; subscribers. It could even take things a few steps further. Instead of using the regular messaging backbone for transmitting these hourly messages, it could use FTP. The data could even be zipped to take up even less space. Since the total data size is less than the corresponding online stream, is stored on cheaper, large storage, and the number of subscribers for this zipped, hourly update is fairly small, these messages can be kept around far longer.</p>
<p>If you&#8217;ve heard about <a href="http://martinfowler.com/articles/consumerDrivenContracts.html">consumer-driven contracts</a>, this is it.</p>
<p>Note that we&#8217;re still talking about the same logical message schema.</p>
<h3>Summary</h3>
<p>It&#8217;s not that lost notifications aren&#8217;t a problem.</p>
<p><a href="http://en.wikipedia.org/wiki/Tesseract"><img style="margin: 0px 0px 10px 10px" src="http://upload.wikimedia.org/wikipedia/commons/5/55/Tesseract.gif" align="right"></a>
<p>It&#8217;s that they feed the design process in such a way that the resulting service ecosystem is set up in such a way that notifications won&#8217;t get lost. I know that that sounds kind of recursive, but that&#8217;s how it works. Either subscribers take care of their SLA allowing them to process the online stream of events, or they should subscribe to a different pipe (which will have different SLA requirements, but maybe they can deal with those).</p>
<p>It make sense to have multiple pipes for the same logical schema.</p>
<p>It&#8217;s practically a necessity to make pub/sub a feasible solution.</p>
<p>&nbsp;</p>
<hr size="1">
<h3>Related Content</h3>
<blockquote><p><a href="http://msdn.microsoft.com/en-us/magazine/cc663023.aspx">MSDN article on messaging and lost messages</a></p>
<p><a href="http://www.udidahan.com/2008/07/17/durable-messaging-dilemmas/">Durable messaging dilemmas</a></p>
<p><a href="http://www.udidahan.com/2008/10/22/additional-logic-required-for-service-autonomy/">Additional logic required for service autonomy</a></p>
<p><a href="http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/">More in depth example on events and pub/sub between services</a></p>
<p><a href="http://martinfowler.com/articles/consumerDrivenContracts.html">Consumer-Driven Contracts</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/12/07/lost-notifications-no-problem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SOA, EDA, and CEP a winning combo</title>
		<link>http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/</link>
		<comments>http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 22:57:14 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/</guid>
		<description><![CDATA[ There&#8217;s been some discussion on the SOA yahoo group around the connection between SOA, EDA, and CEP (complex event processing) since Jack&#8217;s original post on the topic. I&#8217;ve been waiting for the right opportunity to jump in and it seems to have come.
Dennis asked this:

There are different design choices in a SOA, even when [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="240" alt="jump in" src="http://www.udidahan.com/wp-content/uploads/image46.png" width="320" align="right" border="0"> There&#8217;s been some discussion on the SOA yahoo group around the connection between SOA, EDA, and CEP (complex event processing) since Jack&#8217;s <a href="http://soa-eda.blogspot.com/2008/10/eda-versus-cep-and-soa.html">original post</a> on the topic. I&#8217;ve been waiting for the right opportunity to jump in and it seems to have come.
<p>Dennis asked this:<br />
<blockquote>
<p>There are different design choices in a SOA, even when you already have identified the services. I have a simple example that I would like to share:</p>
<p>Imagine a order-to-cash process. One part of that process is to register an order. Suppose we have two services, Order Service and Inventory Service. The task is to register the order and make a corresponding reservation of the stock level. I would be pleased to have the groups view on the following 3 design options (A, B, C):</p>
<p>A.<br />1. The &#8220;process/application&#8221; sends a message (sync or async) to &#8220;registerOrder&#8221; on the Order Service.<br />2. The &#8220;process/application&#8221; sends another message (sync or async) to &#8220;reserveStock&#8221; on the the Inventory Service.</p>
<p>B.<br />1. The &#8220;process/application&#8221; sends a message (sync or async) to &#8220;registerOrder&#8221; on the Order Service.<br />2. The Order Service sends a message (sync or async) to &#8220;reserveStock&#8221; on the the Inventory Service.</p>
<p>C.<br />1. The &#8220;process/application&#8221; sends a message (sync or async) to &#8220;registerOrder&#8221; on the Order Service.<br />2. The Order Service publishes an &#8220;orderReceived&#8221; event.<br />3. The Inventory Service subscribes to the &#8220;orderReceived&#8221; event .</p>
</blockquote>
<p>On the whole &#8220;already identified the services&#8221; thing &#8211; naming a service doesn&#8217;t mean much. It&#8217;s all about allocating responsibility, and until that&#8217;s been done, those &#8220;services&#8221; don&#8217;t give us very much information.
<p>&nbsp;<br />
<h3>Business Services</h3>
<p>If we were to view this example in light of business services, and look at the business events that make up this process, maybe we’d get a different perspective.<br />
<blockquote>
<p>Three business services: <strong>Sales</strong>, <strong>Inventory</strong>, and <strong>Shipping</strong>.</p>
</blockquote>
<p>In Sales, many applications and people may operate, including the person and the application he used to submit the order. When the order is submitted and goes through all the internal validation stuff, Sales raises an OrderTentativelyAccepted event.<br />
<h4>Inventory and Orders</h4>
<p>Inventory, which is subscribed to this event, checks if it has everything in stock for the order. For every item in the order on stock, it allocates that stock to the order and publishes the InventoryAllocatedToOrder event for it. For items/quantities not in stock, it starts a long running process which watches for inventory changes.
<p>When an InventoryChanged event occurs, it matches that against orders requiring allocation – if it finds one that requires stock, based on some logic to choose which order gets precedence, it publishes the InventoryAllocatedToOrder event.
<p>Sales, which is subscribed to the InventoryAllocatedToOrder event, upon receiving all events pertaining to the order tentatively accepted, will publish an OrderAccepted event.<br />
<h4>Orders and Shipping</h4>
<p>When Inventory receives the OrderAccepted event, it generates the pick list to bring all the stock from the warehouses to the loading docks, finally publishing the PickListGenerated event containing target docks.
<p>When Shipping receives the PickListGenerated event, it starts the yard management necessary to bring the needed kinds of trucks to the docks.
<p>&nbsp;<br />
<h3>What else is possible</h3>
<p>I could go on, talking about things like the maximum amount of time stock of various kinds can wait to be loaded on trucks, subscribing to earlier events to employ all kinds of optimization and prediction algorithms, having a Customer Care service notifying the customer about what’s going on with their order (probably different for different kinds of customers and preferred communication definitions). Obviously, we&#8217;d need a Billing service to handle the various kinds of billing procedures, whether or not the customer has credit, pays upon delivery, etc.
<p>It turns out that many business domains map very well to this join of SOA and EDA.
<p>&nbsp;<br />
<h3>What an ESB is for</h3>
<p>When we have these kinds of business services primarily publishing events and subscribing to those of other services, you don&#8217;t need much else from your &#8220;enterprise service bus&#8221;. All sorts of transformation, routing, and orchestration capabilities don&#8217;t come into play at all.
<p>In all truthfullness, those bits of functionality are really just a historical artifact of their broker heritage.
<p>Don&#8217;t get me wrong, sometimes a broker is a nice thing to have &#8211; behind a service boundary in order to perform some complex integration between existing legacy applications.
<p>Just keep that stuff in its place &#8211; not between services.<br />
<h3>&nbsp;</h3>
<h3>Complex Event Processing</h3>
<p>We can look at how Sales transitions an order from being tentatively accepted to being accepted as requiring event correlation around InventoryAllocatedToOrder events. This isn&#8217;t exactly &#8220;complex&#8221; in its own right. If there were some kind of CEP engine that did this for us out of the box, it might be a possible technology choice for implementing this logic within our service.
<p>As we add more concerns, like time, we may find new ways to make use of this engine. For instance, if the time to provide the order to the customer is approaching, we may choose to split the order into two &#8211; accepting one for which we have all the stock allocated, and leaving the second as tentatively accepted.<br />
<h3>&nbsp;</h3>
<h3>Summary</h3>
<p>While it is difficult to move forward on service responsibility without discussing the events it raises and those it subscribe to, the whole issue of CEP can be postponed for a while.
<p>Although there aren&#8217;t many who would say that EDA is necessary for driving down coupling in SOA, or that SOA won&#8217;t likely provide much value without EDA, or that SOA is necessary for providing the right boundaries for EDA, it&#8217;s been my experience that that is exactly the case.
<p>CEP, while being a challenging engineering field, and managing the technical risks around it necessary for a project to succeed in some circumstances, and really shines when used under the SOA/EDA umbrella, it should not be taken by itself and used at the topmost architectural levels.
<p>&nbsp;</p>
<hr size="1">
<h3>Related Content</h3>
<blockquote><p><a href="http://www.udidahan.com/2008/04/23/visual-cobol-enterprise-processes-and-soa/">SOA and Enterprise Processes</a></p>
<p><a href="http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/">How client interaction fits with SOA</a></p>
<p><a href="http://www.udidahan.com/2008/04/20/time-dimension-necessary-for-successful-soa-data-strategy/">Time and SOA</a></p>
<p><a href="http://www.udidahan.com/2008/01/09/durable-messaging-is-not-enough/">Durable Messaging for Fault-Tolerant Services</a></p>
</blockquote>
<p>And if you&#8217;re wondering about how to handle all that complexity inside services (different kinds of billing, periodic tests for electronics inventory, etc), you might like listening to this <a href="http://www.udidahan.com/2006/08/28/podcast-business-and-autonomous-components-in-soa/">podcast about business components</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/11/01/soa-eda-and-cep-a-winning-combo/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Additional Logic Required For Service Autonomy</title>
		<link>http://www.udidahan.com/2008/10/22/additional-logic-required-for-service-autonomy/</link>
		<comments>http://www.udidahan.com/2008/10/22/additional-logic-required-for-service-autonomy/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 22:12:06 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/10/22/additional-logic-required-for-service-autonomy/</guid>
		<description><![CDATA[Of the tenets of Service Orientation, the tenet of Autonomy is one that many understand intuitively. Interestingly enough, many in that same intuitive category don&#8217;t see pub/sub as a necessity for that autonomy.
Watch that first step
Although sometimes described as the first step of an organization moving to SOA, web-service-izing everything results in synchronous, blocking, request/response [...]]]></description>
			<content:encoded><![CDATA[<p>Of the tenets of Service Orientation, the tenet of Autonomy is one that many understand intuitively. Interestingly enough, many in that same intuitive category don&#8217;t see pub/sub as a necessity for that autonomy.</p>
<h3>Watch that first step</h3>
<p>Although sometimes described as the first step of an organization moving to SOA, web-service-izing everything results in synchronous, blocking, request/response interaction between services. The problem being that if one service were to become unavailable, all consumers of that service would not be able to perform any work. With the deep service &#8220;call stacks&#8221; this architectural style condones, the availability and performance of the entire organization will be dictated by the weakest link.</p>
<p>&nbsp;<img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 100px; border-right-width: 0px" height="93" alt="weak link" src="http://www.udidahan.com/wp-content/uploads/image45.png" width="382" border="0"> </p>
<p>So, while I&#8217;d agree that many organizations do need to take this step, I&#8217;d caution against going into production at this step.</p>
<h3>Pub/Sub Considered Helpful</h3>
<p>When services interact with each other using publish/subscribe semantics we don&#8217;t have that technical problem of blocking. Subscribers cache the data published to them (either in memory or durably depending on their fault-tolerance requirements) thus enabling them to function and process requests even if the publisher is unavailable.</p>
<p>Consider the following scenario:</p>
<p>Let&#8217;s say we have an e-commerce site, a part of our Sales service responsible for selling products. Another service, let&#8217;s call it merchandising, is responsible for the catalog of products, and how much each product costs. Sales is subscribed to price update events published by Merchandising and saves (caches) those prices in its own database. When a customer orders some products on the site, Sales does not need to call Merchandising to get the price of the product and just uses the previously saved (cached) price. Thus, even if Merchandising is unavailable, Sales is able to accept orders. This is a big win as our merchandising application is not nearly as robust as our sales systems.</p>
<p>Yet, there are scenarios where data freshness requirements prevent this.</p>
<h3>Too Much of a Good Thing?</h3>
<p>Technically, the above story is accurate. There is nothing technically preventing Sales from accepting orders. Yet consider a scenario where Merchandising is down or unavailable for an extended period of time. While this may not be entirely likely for two servers in the same data center, consider physical kiosks which customers can use to buy products. Those kiosks may not receive updates for days. Should they accept orders?</p>
<p>That&#8217;s really a question to the business. If pricing data is stale for a time period greater than X, do not sell that item. The value of X may even be different for different kinds of products. Keep in mind that this issue only arose since we architected our services to be fully autonomous. In a synchronous systems architecture, this issue would not come up. As such, it is our responsibility as architects to go digging for these requirements as well as explaining to the business what the tradeoffs are.</p>
<p>In order to have more up to date data, we need to invest in more available hardware, networks, and infrastructure. This needs to be balanced against the predicted increase in revenue that more up to date (read higher) prices would give us.</p>
<h3>You Can Get What You Pay For</h3>
<p>Beyond the additional cost of writing that additional logic, and the perceived increased complexity, another difference to note between this architectural style and the synchronous/traditional one is that it puts control of spending back in the hands of business. </p>
<p>In a synchronous architecture, in order to achieve required performance and availability, all systems need to be performant requiring across the board investments in servers, networks, and storage. Without investing everywhere, the weakest link is liable to undo all other investments. In other words, your developers have made your investment choices for you. Scary, isn&#8217;t it.</p>
<p>A more prudent investment strategy would prefer spending on services that give the biggest bang for the buck, better known as return on investment. A pub/sub based architecture allows investing in data-freshness where it makes the most sense. For example, in sales of high profit products to strategic customers rather than inventory management of raw materials for products slated to be decommissioned. </p>
<p>That sounds a lot like IT-Business Alignment.</p>
<p>Maybe there&#8217;s something to this SOA thing after all&#8230;</p>
<hr size="1">
<p> Read more about:</p>
<blockquote><p><a href="http://www.udidahan.com/2008/05/16/7-simple-questions-for-service-selection/">7 Questions for Service Selection</a></p>
<p><a href="http://www.udidahan.com/2008/04/20/time-dimension-necessary-for-successful-soa-data-strategy/">7 Questions around data freshness</a>&nbsp;</p>
<p><a href="http://www.udidahan.com/2007/08/16/dont-eda-between-existing-systems/">Event-Driven Architecture and Legacy Applications</a></p>
<p><a href="http://www.udidahan.com/2007/02/20/autonomous-services-and-enterprise-entity-aggregation/">Autonomous Services and Enterprise Entity Aggregation</a></p>
</blockquote>
<p>Or listen to a podcast describing Business Components, <a href="http://www.udidahan.com/2006/08/28/podcast-business-and-autonomous-components-in-soa/">the connection of pub/sub and SOA</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/10/22/additional-logic-required-for-service-autonomy/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Services Don&#8217;t Serve</title>
		<link>http://www.udidahan.com/2008/08/23/services-dont-serve/</link>
		<comments>http://www.udidahan.com/2008/08/23/services-dont-serve/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 14:42:36 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/08/23/services-dont-serve/</guid>
		<description><![CDATA[Another prominent SOA practitioner and blogger, Steve Jones, shows that, when you&#8217;re identifying your top level business services you shouldn&#8217;t be thinking about who&#8217;s going to consume them.
&#8220;We have three high level business services: Engagement, Management, [and] Production. [...] they represent different operational ambitions. Engagement is all about quantity and then filtering. Management is about [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="412" alt="image" src="http://www.udidahan.com/wp-content/uploads/image42.png" width="227" align="right" border="0">Another prominent SOA practitioner and blogger, Steve Jones, <a href="http://service-architecture.blogspot.com/2008/08/setting-high-level-services.html">shows that</a>, when you&#8217;re identifying your top level business services you shouldn&#8217;t be thinking about who&#8217;s going to consume them.</p>
<blockquote><p>&#8220;We have three high level business services: Engagement, Management, [and] Production. [...] they represent <i>different operational ambitions</i>. Engagement is all about quantity and then filtering. Management is about the quality and Production is about realising the benefits.&#8221;</p>
</blockquote>
<p>Services are not about &#8220;are you being served?&#8221;</p>
<p>They&#8217;re not about re-use, and barely about use. Events are what it&#8217;s all about.</p>
<p>Each service has its own responsibility and does what it needs to do, business-wise, to achieve its goals. Whether it&#8217;s about increasing the number of leads, ensuring high-profile clients get good service, or maximizing equipment utilization, services take responsibility.</p>
<p>I know I harp on this a lot.</p>
<p>It&#8217;s because it&#8217;s <em>that</em> important.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/08/23/services-dont-serve/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Command Query Separation and SOA</title>
		<link>http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/</link>
		<comments>http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/#comments</comments>
		<pubDate>Mon, 11 Aug 2008 13:18:40 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Smart Client]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/</guid>
		<description><![CDATA[One of the common questions I receive from people starting to use nServiceBus is how one-way messaging fits with showing the user a grid (or list) of data. Thinking about publish/subscribe usually just gets them even more confused. Trying to resolve all this with Service Oriented Architecture leaves them wondering &#8211; why bother?

In regular client-server [...]]]></description>
			<content:encoded><![CDATA[<p>One of the common questions I receive from people starting to use nServiceBus is how one-way messaging fits with showing the user a grid (or list) of data. Thinking about publish/subscribe usually just gets them even more confused. Trying to resolve all this with Service Oriented Architecture leaves them wondering &#8211; why bother?</p>
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="267" alt="client server" src="http://www.udidahan.com/wp-content/uploads/image38.png" width="477" border="0" /></p>
<p>In regular client-server development, the server is responsible for providing the client with all CRUD (create, read, update, and delete) capabilities. However, when users look at data they do not often require it to be up to date to the second (given that they often look at the same screen for several seconds to minutes at a time). As such, retrieving data from the same table as that being used for highly consistent transaction processing creates contention resulting in poor performance for all CRUD actions under higher load.</p>
<h4>A Scalable Solution </h4>
<p>One of the common answers to this question is for the server/service to publish a message when data changes (say, as the result of processing a message) and for clients to subscribe to these messages. When such a notification arrives at a client, the client would cache the data it needs. Then, when the user wants to see a grid of data, that data is already on the client. Of course, this solution doesn&#8217;t work so well for older client machines (like some point of service devices) or if there are millions of rows of data.</p>
<p>The thing is that this solution is one implementation of a more general pattern &#8211; command query separation (CQS).</p>
<h4>Command Query Separation</h4>
<p>Wikipedia <a href="http://en.wikipedia.org/wiki/Command-query_separation">describes</a> CQS as a pattern where &quot;&#8230; every method should either be a <i>command</i> that performs an action, or a <i>query</i> that returns data to the caller, but not both. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.&quot;</p>
<p>Martin Fowler is less strict about the use of CQS <a href="http://martinfowler.com/bliki/CommandQuerySeparation.html">allowing for exceptions</a>: &quot;Popping a stack is a good example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I&#8217;m prepared to break it to get my pop.&quot;</p>
<p>So, how does separating commands from queries and SOA help at all in getting data to and from a UI? The answer is based on Pat Helland&#8217;s thinking as described in his article <a href="http://msdn.microsoft.com/en-us/library/ms954587.aspx">Data on the Inside vs. Data on the Outside</a>.</p>
<h4>Services Cross Boxes </h4>
<p>The biggest lie around SOA is that services run.</p>
<p>Let that sink in a second.</p>
<p>Sure services have runnable components, but that&#8217;s not why they&#8217;re important. </p>
<p>I&#8217;ll skip the <a href="http://www.udidahan.com/first-time-here/#soa">books of background</a> and cut to the chase:</p>
<blockquote><p>Services communicate with each other using publish/subscribe and one-way messaging. Services have components inside them. Inside a service, these components can communicate with each using synchronous RPC, or any other mechanism. Also, <em>these components can reside on different machines</em>.</p>
</blockquote>
<p>This is broader than just scaling out a service. There can be service components running on the client as well as the server.</p>
<h4>SOA &amp; CQS</h4>
<p>Combining these two concepts together, here&#8217;s what comes out:</p>
<p><img src="http://www.nservicebus.com/img/CQS.png" /> </p>
<p>In this solution there are two services that span both client and server &#8211; one in charge of commands (create, update, delete), the other in charge of queries (read). These services communicate only via messages &#8211; one cannot access the database of the other. </p>
<p>The command service publishes messages about changes to data, to which the query service subscribes. When the query service receives such notifications, it saves the data in its own data store which may well have a different schema (optimized for queries like a star schema).</p>
<p>The client component which is in charge of showing grids of data to the user behaves the same as it would in a regular layered/tiered architecture, using synchronous blocking request/response to get its data &#8211; SOA doesn&#8217;t change that.</p>
<h4>Composite Applications </h4>
<p>Although the client side components of both the command and query services are hosted in the same process, they are very much independent of each other. That being said, from an interoperability perspective (the one that most people attribute to SOA), all of the client-side components will likely be developed using the same technology &#8211; although there are already ways to <a href="http://www.udidahan.com/2007/05/28/netjava-interop-is-not-a-reason-for-soa/">host Java code in .NET</a> and vice-versa. </p>
<p>Of course, once we talk about web UI&#8217;s things are a bit different &#8211; but still similar. While web-server-side there may be a level of independence, for browser side inter-component communications we&#8217;re still likely to target javascript. There, I&#8217;ve managed to say something technical supporting mashups and SOA without lying through my teeth.</p>
<p>On the Microsoft side with the recent release of the Composite Application Guidance &amp; Library (pronounced &quot;<a href="http://www.codeplex.com/CompositeWPF">prism</a>&quot;) I hope that more of these principles will be reaching the &quot;smart client&quot;. The command pattern is especially critical in maintaining the separation while enabling communication to still occur so I&#8217;m glad that, as one of the Prism advisors, I was able to simplify that part (<a href="http://codebetter.com/blogs/glenn.block/">Glenn</a> still has nightmares about that rooftop conversation).</p>
<h4>Publish / Subscribe</h4>
<p>In the &quot;scalable solution&quot; section up top I mentioned how publish/subscribe to the smart client is really just one implementation of CQS and SOA. So, how different is it really?</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="241" alt="smart client pub/sub" src="http://www.udidahan.com/wp-content/uploads/image39.png" width="554" border="0" /> </p>
<p>Well, there will probably be a different technology mapping. Instead of a star-schema OLAP product, we might simply store the published data in memory on the client. That is, if you designed your components to be technology agnostic.</p>
<p>In terms of the use of nServiceBus, the same component is going to be subscribing to the same type of message &#8211; all that&#8217;s different is that now every client will be having data pushed to them rather than this occurring server-side only. </p>
<p>You could have the same code deployed differently in the same system &#8211; stronger clients subscribing themselves, weaker ones using a remote server. Web servers would probably be considered stronger clients. This kind of flexible deployment has proven to be extremely valuable for my larger clients. The added benefit of enabling users to work (view data) even while offline (somewhere there&#8217;s no WIFI) is just icing on the cake.</p>
<h4>A Word of Warning</h4>
<p>Once the client starts receiving notifications, and handling those on a background thread (as it should) the code becomes susceptible to deadlocks and data races. Juval does a good job of outlining <a href="http://www.udidahan.com/2008/04/11/wcf-smart-clients-and-deadlocks/">some of those</a> with respect to the use of WCF. Prism <a href="http://www.udidahan.com/2008/06/09/prism-occasionally-connected/">doesn&#8217;t provide any assurances</a> in this area either.</p>
<h4>Summary</h4>
<p>NServiceBus is not designed to be used for any and all types of communication in a given architecture. In the examples above, nServiceBus handles the publish/subscribe but leaves the synchronous RPC to existing solutions like WCF. Not only that, but synchronous RPC does have its place in architecture, just not across service boundaries. In all cases, data is served to users from a store different from that which transaction processing logic uses.</p>
<p>Command Query Separation is not only a good idea at the method/class level but has advantages at the SOA/System level as well &#8211; yet another good idea from 20 years ago that services build upon. Making use of CQS requires understanding your data and its uses &#8211; SOA builds on that by looking into data volatility and the freshness business requirements around it.</p>
<p>Finally, designing the components of your services in such a way that their dependency on technology is limited buys a lot of flexibility in terms of deployment and, consequently, significant performance and scalability gains.</p>
<p>Simple, it is. Easy, it is not.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>7 Simple Questions for Service Selection</title>
		<link>http://www.udidahan.com/2008/05/16/7-simple-questions-for-service-selection/</link>
		<comments>http://www.udidahan.com/2008/05/16/7-simple-questions-for-service-selection/#comments</comments>
		<pubDate>Fri, 16 May 2008 22:21:09 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/05/16/7-simple-questions-for-service-selection/</guid>
		<description><![CDATA[&#8220;So, which services do I need?&#8221;
This innocuous question comes up a lot. Usually I get this question after a short problem domain description. One of these came up on the nServiceBus discussion groups. Ayende took it and ran with it turning it into a nice blog post, An exercise in designing SOA systems. I&#8217;ve been [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;So, which services do I need?&#8221;</p>
<p>This innocuous question comes up a lot. Usually I get this question after a short problem domain description. One of these came up on the nServiceBus discussion groups. Ayende took it and ran with it turning it into a nice blog post, <a href="http://ayende.com/Blog/archive/2008/04/08/An-exercise-in-designing-SOA-systems.aspx">An exercise in designing SOA systems</a>. I&#8217;ve been meaning to write something myself. Bill put up a response already in his <a href="http://bill-poole.blogspot.com/2008/05/service-granularity-example.html">Service Granularity Example</a>. So, I&#8217;m late to the party, again, but here we go.</p>
<p>It&#8217;s almost impossible to know, right away, which services are appropriate.</p>
<p>So, I&#8217;m going to focus more on the process of getting there, rather than describing the solution itself.</p>
<p>The domain deals with a placement agency placing physicians in positions at hospitals. <a href="http://udidahan.weblogs.us/wp-content/uploads/doctor.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="244" alt="doctor" src="http://udidahan.weblogs.us/wp-content/uploads/doctor-thumb.png" width="225" align="right" border="0"></a> </p>
<h3>1. So, what does it actually <em>do</em>?</h3>
<p>In Ayende&#8217;s post, he describes several services, but I&#8217;d rather look at them as use cases: registering an open position, registering a candidate, verifying their credentials, etc. It&#8217;s worth going through this <em>requirements</em> process. It doesn&#8217;t necessarily translate immediately to services, but there&#8217;s value in it.</p>
<h3>2. What does it do it <em>to</em>?</h3>
<p>We should also be looking at the data model, an entity relationship diagram (ERD) , where we see that we may have placed a certain physician at a number of positions. It&#8217;s also important for us to know about under which circumstances a physician finished their employment at a previous position before, say, trying to place them at a position in the same hospital or chain of hospitals. Don&#8217;t go thinking that this what the database schema will look like, it&#8217;s all about understanding connections between various bits of data.</p>
<h3>3. When does that happen?</h3>
<p>The next step is to map the uses cases above to the entities in the ERD, which entity is used in which use case. It&#8217;s also important to differentiate between entities (or even more importantly, specific fields of entities) that are used in a read-only fashion within a given use case. For instance, when registering a new position, we&#8217;ll want to check that against other open positions in the same hospital so we don&#8217;t end up registering the same position twice. Also, we might want to suggest verified physicians whose credentials match the position&#8217;s requirements. Data we wouldn&#8217;t be interested in might be which other physicians we placed at that hospital.</p>
<h3>4. What just happened?</h3>
<p>Another valuable perspective on the problem domain is the business process view &#8211; what are the interesting business events in the system and how they unfold over time. For instance, physician registered, position opened, physician&#8217;s credentials verified, and physician placed in position (or position filled by physician) are events that describe a different business perspective than use cases.<a href="http://udidahan.weblogs.us/wp-content/uploads/image20.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 0px 10px; border-left: 0px; border-bottom: 0px" height="241" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb17.png" width="244" align="right" border="0"></a></p>
<h3>5. How do I decide? </h3>
<p>Once we know what events there are, we can start looking at what kind of decisions we might want to make when those events occur and what data we&#8217;d need to make those decisions. These decisions may be as simple as updating a database or sending an email to a user. They also may include more advanced logic like when the profitability of an agreement with a specific hospital chain changes, prefer placing physicians in positions in that chain over others.</p>
<h3>6. How do I deal with all this information?</h3>
<p>After we have all of this information, we can start looking for cohesive bunching across all of these axes using these rules:</p>
<ul>
<li>Data that is modified by a use case gets published as an event.</li>
<li>Data that is required by a use case for read-only purposes, arrives as the result of subscribing to some event.</li>
</ul>
<p>Look for rules that differentiate behaviour based on the properties of data. Look for a correlation to some business concept. For instance, physicians probably won&#8217;t be changing their specialization, and open positions often deal with a certain specialization. Therefore, specific data instances tied to two different specializations can be said to be loosely coupled.</p>
<h3><strong>7. Which property slices across the domain?<a href="http://udidahan.weblogs.us/wp-content/uploads/image21.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="161" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb18.png" width="244" align="right" border="0"></a> </strong></h3>
<p>Even though the ERD may not have made it clear, and the use cases didn&#8217;t show any particular break-down, nor did the events call out this point, the key to finding the way a business domain decomposes into services lies in decoupling specific data instances.</p>
<p>Actually, at this point we can clump autonomous components (mere technical bits) that handle a single message, into more granular business components.</p>
<blockquote><p>If you think about it, it makes a lot of sense. The kind of credential checking you&#8217;d do for physicians specializing in brain surgery would likely be different than for general practitioners. The kind of information you&#8217;d store would, therefore, also be different.</p>
</blockquote>
<h3>But, which services do I need?</h3>
<p>Quite frankly, I don&#8217;t have enough information to know. </p>
<p>But if we had continued this conversation, going through issues like transactional consistency, availability requirements, and other non-functional issues we could have&nbsp; gotten there. </p>
<p>If there&#8217;s one thing that I hope you got out of this, it&#8217;s that the questions are what&#8217;s important. The iterative process of looking at the problem domain from various perspectives, incorporating the new-found knowledge, and asking more questions is what leads us to a solution. But we don&#8217;t stop there. We keep looking for characteristics which split services apart into business components, and for consistency requirements that brings autonomous components together into services.</p>
<p>It&#8217;s not easy, but by focusing on these simple questions, you can get to a coherent service oriented architecture.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/05/16/7-simple-questions-for-service-selection/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Abbott &amp; Costello of SOA</title>
		<link>http://www.udidahan.com/2008/05/02/the-abbott-costello-of-soa/</link>
		<comments>http://www.udidahan.com/2008/05/02/the-abbott-costello-of-soa/#comments</comments>
		<pubDate>Fri, 02 May 2008 22:37:16 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[ESB]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/05/02/the-abbott-costello-of-soa/</guid>
		<description><![CDATA[My long-time readers will no doubt remember Bill, he who has sent me so many great questions around SOA and gotten me to put some of my best podcast episodes out. Well, Bill&#8217;s now got a blog and he&#8217;s putting up a lot of great information on SOA (and that&#8217;s saying quite a bit, I [...]]]></description>
			<content:encoded><![CDATA[<p>My long-time readers will no doubt remember Bill, he who has sent me so many great questions around SOA and gotten me to put some of my best <a href="http://udidahan.weblogs.us/ask-udi/">podcast</a> episodes out. Well, Bill&#8217;s now got a <a href="http://bill-poole.blogspot.com/">blog</a> and he&#8217;s putting up a lot of great information on SOA (and that&#8217;s saying quite a bit, I barely agree with myself when it comes to SOA). In his post on <a href="http://bill-poole.blogspot.com/2008/04/publish-subscribe-with-legacy.html">Publish-Subscribe with Legacy Applications</a> he discusses some ways to do the integration, but I want to talk here about WHO does the integration.</p>
<h3>What&#8217;s on first?<a href="http://udidahan.weblogs.us/wp-content/uploads/image19.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 10px; border-left: 0px; border-bottom: 0px" height="179" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb16.png" width="227" align="right" border="0"></a> </h3>
<p>Many times I see SOA projects integrate existing/legacy systems focusing only on getting those systems to talk to the ESB (bits flowing) using the right structures (canonical schema, oy). However, little attention is often given to where that integration code runs &#8211; in other words, which endpoint does the rest of the system talk to? Who&#8217;s in charge of the integration?</p>
<p>The answer is usually muddled &#8211; sometimes its the <a href="http://udidahan.weblogs.us/category/esb">ESB</a> itself (serving more as an EAI broker at that point), sometimes its some DLL that the calling service uses, but I VERY rarely hear anything about the actual process that&#8217;s hosting that code, the endpoint itself, or anything that will help us deal with Service-Level Agreements.</p>
<h3>No. What&#8217;s on second.</h3>
<p>If you can&#8217;t (or don&#8217;t want to) change the legacy application at all, I suggest setting up a new endpoint and an additional process which listens on that endpoint. That process is in charge of communicating with the legacy application and translating whatever is going on to the messaging semantics of the SOA environment. Not everything may be publish/subscribe &#8211; other systems may send command messages to the endpoint, resulting in API calls on the legacy application. </p>
<p>One of the things that the process can/should do, is to subscribe to events/messages from other services and feed the relevant information to the legacy application. At times this will be done on an as-needed basis from the legacy application&#8217;s perspective &#8211; it will call some API/web service that will need to communicate with the afore-mentioned process, and the process will return the data needed.</p>
<h3>How is playing a different game</h3>
<p>From the perspective of all the other services, the legacy application might as well not even be there &#8211; they communicate via the regular messaging semantics with everything.</p>
<p>What is important to understand is that developing that kind of process is not a trivial undertaking. In <a href="http://udidahan.weblogs.us/category/ddd">DDD</a> terms, it can be called an Anti-Corruption Layer, as it prevents the legacy from influencing the structure of any other service. This procedure is one of the ways one can go about slowly getting data and functionality off of mainframes and into more versionable and change-friendly (and cheaper) environments.</p>
<h3>I don&#8217;t give a darn!</h3>
<p><a href="http://www.baseball-almanac.com/humor4.shtml">Oh, that&#8217;s our esb</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/05/02/the-abbott-costello-of-soa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

