<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Simon says... architecture!</title>
	
	<link>http://simon-says-architecture.com</link>
	<description>Szymon Pobiega about software engineering and architecture</description>
	<lastBuildDate>Fri, 03 Feb 2012 07:37:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/szymonpobiega" /><feedburner:info uri="szymonpobiega" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Automated deployment security concerns</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/-T_g6hZRYnw/</link>
		<comments>http://simon-says-architecture.com/2012/02/03/automated-deployment-security/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 07:37:11 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[continuous delivery]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=957</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>This post is a part of automated deployment story
One of the blockers to widespread adoption of automated deployment tools is the fear that they cause greater security risk than humans executing a written deployment procedure. The greatest of fears is that an attacker would be able to push a malicious version of binaries to the production [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p><em>This post is a part of <a href="http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story">automated deployment story</a></em></p>
<p>One of the blockers to widespread adoption of automated deployment tools is the fear that they cause greater security risk than humans executing a written deployment procedure. The greatest of fears is that an attacker would be able to push a malicious version of binaries to the production environment.</p>
<p>If you want to succeed implementing an automated deployment solution you must ensure at least same level of security as when humans manually copy binaries.</p>
<h3>Who can deploy?</h3>
<p>When there is no automation, the deployment is performed by designated humans. For testing environment it can be the QA manager, for production it is usually an operations team. They (and only they) are in possession of credentials required to log on to the target environment machines to copy the binaries and perform other deployment-related tasks.</p>
<p>People who have just begun automating the deployment tend to think that, since everything can be automated, the deployment process can be started straight from the build agent without any human action. This was also true in my case. Fortunately some wiser people reminded me about how important is to be able to name the person (not a machine) who was responsible for particular deployment.</p>
<p>The rule of thumb is, you can (and should) automate <strong>everything, but two things</strong>. First is starting the whole procedure. There should be a person that has to hit <strong>ENTER</strong> key in order to start deployment. We&#8217;ll be the one to blame if something goes wrong (for example upgrading the production site during peak usage hours). The second thing not to be automated is authentication. You should <strong>never</strong> store production (or even testing) environment credentials in order to be automatically used by the script. Whenever credentials are required, the script should ask the user to provide them. Sometimes it is possible to store them temporarily in memory so that user does not get prompted for same credentials twice.</p>
<h3>What can be deployed?</h3>
<p>Usually the more layers of security, the better. Should one get compromised, the other can prevent the disaster. Beside controlling who can deploy, it is also worth controlling what can be deployed. The easiest thing (and this is what we have actually implemented) is digital signature-based verification. A binary package is signed using a certificate stored on the build agent. The corresponding public key along with a <em>gateway</em> script is securely installed on all machines of the environment.</p>
<p>The only remotely accessible endpoint that is exposed by target environment machines is the aforementioned <em>gateway</em> script. This ensures that an attacker can&#8217;t bypass the security measures put in place. One can only trigger the deployment on the machine via this script and the script ensures that deployment package signature is verified against stored public key of the build agent.</p>
<h3>Tools</h3>
<p>Unfortunately there is no command-line tool to sign and verify signature built into Windows. That&#8217;s why <a href="https://github.com/SzymonPobiega/PackMan">PackMan</a> was born. I mentioned this tool before in context of <a href="http://simon-says-architecture.com/2012/01/05/building-the-deployment-package">building a package</a>. When building a package, PackMan also calculates the hash of the data and encrypts it using private key from provided certificate. It can be done with a command like this (MSBuild variable syntax)</p>
<pre class="brush: powershell; title: ; notranslate">
PackMan.exe -i d:$(PackageDir) -o $(OutDir)\Package-$(BuildVersion).zip --cn DeployerCert -a create
</pre>
<p>When asked to unpack, PackMan first verifies the signature using a provided public key (PowerShell variable syntax)</p>
<pre class="brush: powershell; title: ; notranslate">
PackMan.exe -p ${package_store}\${package_file} --vcn DeployerCert -a unpack -d ${tmp_package_dir}
</pre>
<p>This ensures that package is authentic and not corrupted.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=-T_g6hZRYnw:OprC0jfhe38:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=-T_g6hZRYnw:OprC0jfhe38:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/-T_g6hZRYnw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2012/02/03/automated-deployment-security/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2012/02/03/automated-deployment-security/</feedburner:origLink></item>
		<item>
		<title>Deploy based on external description of the environment</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/WYc_gmXC_ns/</link>
		<comments>http://simon-says-architecture.com/2012/01/24/deploy-based-on-external-description-of-the-environment/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 08:27:55 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[continuous delivery]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=945</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>This post is a part of automated deployment story
On of the problems with many simple deployment solutions is, the structure of the target environment is embedded into the deployment scripts. This was also the case with the previous, batch based, version of my deployment process. With the advent of PowerShell, everything changed.
Commas
CSV is one of the [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p><em>This post is a part of <a href="http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story">automated deployment story</a></em></p>
<p>On of the problems with many simple deployment solutions is, the structure of the target environment is embedded into the deployment scripts. This was also the case with the previous, batch based, version of my deployment process. With the advent of PowerShell, everything changed.</p>
<h3>Commas</h3>
<p>CSV is one of the simplest formats for representing tabular data. It&#8217;s easy to read, easy to edit (also in Notepad) and it behaves nicely when stored in VCS. All these properties make it an ideal candidate to be used to describe the deployment environment. Last but not least, PowerShell has very nice built-in features for handling CSV files: <code class="syntaxhighlighter plain" style="display: inline;">Import-Csv</code>, <code class="syntaxhighlighter plain" style="display: inline;">Export-Csv</code>, <code class="syntaxhighlighter plain" style="display: inline;">ConvertTo-Csv</code> and <code class="syntaxhighlighter plain" style="display: inline;">ConvertFrom-Csv</code>. The most interesting one is <code class="syntaxhighlighter plain" style="display: inline;">Import-Csv</code> as it allows to load data stored in file into an object form with one object per row and one property per column. It makes loading entire environment description file as easy as</p>
<pre class="brush: powershell; title: ; notranslate">
$machines = Import-Csv environments.txt
</pre>
<p>The structure of the file is also quite simple. Because I deploy to DEV environment quite frequently (10+ times a day) and that it is done by an automated process, I&#8217;ve chosen to store credentials straight in the config file.</p>
<pre class="brush: plain; title: ; notranslate">
IP, Environment, Roles, User, Password
192.168.0.1, DEV, Web|App, devUser, p@ssw0rd
192.168.1.1, TEST, Web,,
192.168.1.2, TEST, App,,
</pre>
<p>Given these, you can imagine that getting the list of machines in particular environment (you need it to know where to deploy) can be done in another one-liner</p>
<pre class="brush: powershell; title: ; notranslate">
$target_machines = $machines | Where-Object { $_.Environment = $target_environment }
</pre>
<h3>Roles</h3>
<p>You have probably noticed a column called &#8216;Roles&#8217; in the description file. A concept of role is key to my deployment strategy. I borrowed the name from cloud computing lingo but the meaning is slightly different. My role is a named set of things that are deployed together and form a logical whole. The current list of roles in my application include web, tools (which is an odd name for application server stuff), tests (this role is installed only on DEV) and db.</p>
<p>As you can see in the sample environment description, a DEV machine serves both roles while in test environment there&#8217;s dedicated machine for each role. You can imagine, that production would probably have 3 or 4 machines serving web role and maybe 2 for application role. Having a simple file that has all this information really helps organize things.</p>
<h3>Orchestration</h3>
<p>Looking from 10.000 ft, the process of deploying one role to one machine is following</p>
<ul>
<li>stop the role</li>
<li>update the binaries for this role</li>
<li>start the role</li>
<li>(optional) verify health of the role</li>
</ul>
<p>Given that we have multiple machines, each of which potentially serving multiple roles, the question arises how do we orchestrate the whole process so we minimize the down time. The answer, as for all difficult questions, is, it depends. Because it depends, we want to abstract away the concrete orchestration and be able to pick the actual implementation based on requirements at hand. In my project I&#8217;ve identified two distinct cases.</p>
<p>If I don&#8217;t have to change the structure of transaction database, I can upgrade the machines one by one. To achieve zero downtime I need to fake the response for balancer&#8217;s health enquiry telling it that the machine is down before is actually is. This way clients will be served normally before load balancer picks up the faked &#8216;down&#8217; response and actually removes the machine from the cluster. Then I can safely upgrade this one machine. Last but not least, I have to wait some time before load balancer figures out the machine is up. Voilà! A super-simple zero-downtime deployment.</p>
<p>In case I don&#8217;t need to change the structure (and assuming I can&#8217;t write code that can work with both structures) I want to upgrade all machines in the environment as quickly as possible. This is where PowerShell v2 jobs come in handy. You can use <code class="syntaxhighlighter plain" style="display: inline;">Start-Job</code> to virtually deploy to each machine in a separate thread of execution. Because the bulk of work is done not on the coordinating machine but on the target machine, this literally cuts the deployment time to the amount it takes to deploy to one machine. Cool, isn&#8217;t it?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=WYc_gmXC_ns:K2BMjh3Gz8E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=WYc_gmXC_ns:K2BMjh3Gz8E:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/WYc_gmXC_ns" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2012/01/24/deploy-based-on-external-description-of-the-environment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2012/01/24/deploy-based-on-external-description-of-the-environment/</feedburner:origLink></item>
		<item>
		<title>The release candidate repository</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/qNSfwMIkvNc/</link>
		<comments>http://simon-says-architecture.com/2012/01/19/the-release-candidate-repository/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 16:53:49 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[continuous delivery]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[oss]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=933</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>This post is a part of automated deployment story
I am sorry you have to wait so long for a new episode of the story. The truth is, this episode was written a week ago and saved as a draft. Just before publishing I got an e-mail from the IT department that the solution I proposed (using SharePoint [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p><em>This post is a part of <a href="http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story">automated deployment story</a></em></p>
<p>I am sorry you have to wait so long for a new episode of the story. The truth is, this episode was written a week ago and saved as a draft. Just before publishing I got an e-mail from the IT department that the solution I proposed (using SharePoint site) is not acceptable from the security point of view. They are not going to allow any access to the site from an automated process accounts. Period. So the blog post went to trash but not the idea. Here it is, reborn, better than ever!</p>
<h3>Release candidate repository</h3>
<p>I&#8217;ve taken the idea of release candidate repository from the <a href="http://continuousdelivery.com/">Continuous Delivery</a> book. The idea is, <em>release candidate</em> is not a term describing a binary package generate just before releasing, waiting for final tests and go-live flag. Instead, a <em>Release candidate</em> is every binary that passes unit tests (or <em>commit stage tests</em> how book authors tend to call them). The candidate then goes through various stages of the deployment pipeline, passing (or failing) integration tests, automated user acceptance tests, load tests, usability tests etc. During this journey, a candidate is deployed to various environments. Finally, a successful candidate ends up being deployed to production. As you probably expect, I was in desperate need of a tool that could track my RCs from the very beginning to the end of their lifetime. Buying an expensive and have-it-all tool was, of course, not an option.</p>
<h3>Release Candidate Tracker</h3>
<p>It took me one afternoon to hack a quick and dirty solution. As always, you can <a href="https://github.com/SzymonPobiega/ReleaseCandidateTracker">download it from github</a>. Please don&#8217;t complain about the code quality. I know it&#8217;s not the cleanest code on the planet, but it works (or sort-of). RCT uses an embedded <a href="http://ravendb.net/">RavenDB</a> database to store information. The database files are stored in the App_Data folder. If I understand Raven&#8217;s license correctly, you can use RCT anywhere you want, also in commercial environment.</p>
<h3>Workflow</h3>
<p>Here&#8217;s the workflow describing the typical usage scenario of RCT. First, the build script (MSBuild in my case) creates a release candidate after successfully running unit (commit stage) tests. To achieve this, it uses <a href="http://curl.haxx.se/">curl</a> tool to call RCT API.</p>
<pre class="brush: powershell; title: ; notranslate">
$id = .\curl -s --data &quot;State=${state}&amp;VersionNumber=${version}&amp;ProductName=${product}&quot; &quot;${server}/ReleaseCandidate/Create&quot;
if ($id -ne $null) {
    .\curl -s --upload-file $scipt_file &quot;${server}/ReleaseCandidate/AttachScript/${id}&quot;
}
</pre>
<p>The first call creates a RC entity while the second one attaches a generated deployment bootstrap script. At this point, a candidate is in initial <em>UnitTestsPassed</em> state. You can see it on the release candidate list</p>
<p><a href="http://simon-says-architecture.com/wp-content/uploads/2012/01/RCT-list.png"><img class="aligncenter size-large wp-image-938" title="RCT - list" src="http://simon-says-architecture.com/wp-content/uploads/2012/01/RCT-list-1024x435.png" alt="" width="1024" height="435" /></a></p>
<p>The subsequent stages exercise the candidate using various test suites: integration, user acceptance and so on. However, before the candidate can be tested, it has to be deployed to a suitable test environment. Here comes another feature of RCT &#8212; the deployment bootstrap script. You can download it simply by clicking a &#8216;Deploy&#8217; link on the candidate list. If you want, you can even associate the <em>.ps1</em> extension with PowerShell so that it will be automatically executed. The script (which will be covered in detail in later episodes) starts the deployment process. Eventually, a deployment script completes the deployment and updates the state of the candidate.  There&#8217;s another API call and another script that does this</p>
<pre class="brush: powershell; title: ; notranslate">
.\curl -s --data &quot;Environment=${environment}&amp;VersionNumber=${version}&quot; &quot;${server}/ReleaseCandidate/MarkAsDeployed&quot;
</pre>
<p>After executing the tests, the state of the candidate needs to be updated to reflect the result. Here&#8217;s a script for this task</p>
<pre class="brush: powershell; title: ; notranslate">
.\curl -s --data &quot;State=${state}&amp;VersionNumber=${version}&quot; &quot;${server}/ReleaseCandidate/UpdateState&quot;
</pre>
<p>Eventually, is the candidate manages to successfully pass all the tests, it can be potentially deployed to production. Of course not every successful candidate ends up on production. Each change of candidate state is reflected on its detail view page</p>
<p><a href="http://simon-says-architecture.com/wp-content/uploads/2012/01/RCT-details.png"><img class="aligncenter size-large wp-image-940" title="RCT - details" src="http://simon-says-architecture.com/wp-content/uploads/2012/01/RCT-details-1023x569.png" alt="" width="1023" height="569" /></a></p>
<p>Any contributions to RCT are, of course, more than welcome. Happy deploying!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=qNSfwMIkvNc:uEamq-tUljU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=qNSfwMIkvNc:uEamq-tUljU:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/qNSfwMIkvNc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2012/01/19/the-release-candidate-repository/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2012/01/19/the-release-candidate-repository/</feedburner:origLink></item>
		<item>
		<title>Building the deployment package</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/_ZXg5KpdXK0/</link>
		<comments>http://simon-says-architecture.com/2012/01/05/building-the-deployment-package/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 09:24:56 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[continuous delivery]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=911</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>This post is a part of the automated deployment story.
The first custom step of my build process is building the deployment package. Starting from two applications in the solution it is impractical to just copy over a bunch of DLLs. Much better idea is to package them somehow so they can be easily handled as [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p><em>This post is a part of the <a href="http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story">automated deployment story</a>.</em></p>
<p>The first custom step of my build process is building the deployment package. Starting from two applications in the solution it is impractical to just copy over a bunch of DLLs. Much better idea is to package them somehow so they can be easily handled as a whole. There is a number of packaging technologies available for .NET applications, including:</p>
<ul>
<li><a href="http://nuget.org/">NuGet</a></li>
<li><a href="http://www.openwrap.org/">OpenWrap</a></li>
<li><a href="http://www.iis.net/download/webdeploy">Web Deploy</a></li>
</ul>
<p>None of them is a complete and perfect solution. First two are biased towards packaging and managing reusable libraries so they put emphasis on versioning and enabling usage of packages in IDE and in the build process. Web Deploy is focused on, well, web deployment and it is lacking good support for any other application type.</p>
<h3>Web Deploy</h3>
<p>In my solution I&#8217;ve chosen Web Deploy because it few reasons. First, it was already there since it was the foundation of old deployment scripts. Second, it has a very nice feature of so-called publishing a web application. You may know this feature from VisualStudio as it is available from context menu on web projects. Basically, it removes all the files that are not necessary to run the application (like .cs, .csproj).</p>
<p>There are two central concepts in Web Deploy: operation and provider. Operation describes what to do. There are three (only!) possible operations:</p>
<ul>
<li>dump &#8211; displays information about an object</li>
<li>delete &#8211; deletes an object</li>
<li>sync &#8211; synchronizes two objects</li>
</ul>
<p>Web Deploy comes with a great variety of <a href="http://technet.microsoft.com/en-us/library/dd569040(WS.10).aspx">providers</a>. Providers implement specific deployment steps like changing the machine.config file or putting an assembly to GAC. The most important one for me is the <a href="http://technet.microsoft.com/en-us/library/dd569019(WS.10).aspx">package</a> provider. It allows to pack a specified web site in IIS into a zip file and clone it somewhere else. What you can&#8217;t read on the documentation page (but can find on the Internet, of course) is, you can build similar package via MSBuild. Do do so, just call</p>
<p><code class="syntaxhighlighter plain" style="display: inline;">MSBuild "ProjectName.csproj" /T:Package</code></p>
<p>After your main build process completes. The output is a nice zip file containing all the information necessary to deploy the web application.</p>
<h3>DRYing the build script</h3>
<p>For each application I deploy I need to call some packaging routing in the build script. This can quickly become a copy-pasted spaghetti. Fortunately I found out that MSBuild supports iteration. Here&#8217;s how you define the collection of elemenents</p>
<pre class="brush: xml;">
&lt;ItemGroup Label=&quot;WebPackages&quot;&gt;
&#160; &lt;WebPackages Include=&quot;ProjectA\ProjectA.csproj&quot; /&gt;
&#160; &lt;WebPackages Include=&quot;ProjectB\ProjectB.csproj&quot; /&gt;
&#160; &lt;WebPackages Include=&quot;ProjectC\ProjectC.csproj&quot; /&gt;
&lt;/ItemGroup&gt;</pre>
<p>And here is how you call a specific routine on all of them</p>
<pre class="brush: xml;">
&lt;Target Name=&quot;web-package-build&quot; Inputs=&quot;@WebPackages&quot; Outputs=&quot;%(WebPackages.Identity)&quot;&gt;
  &lt;Exec Command=&quot;$(MSBuild4) &amp;quot;$(SolutionRoot)\%(WebPackages.Identity)&amp;quot; /p:Configuration=$(BuildConfig) /p:DeployOnBuild=true /p:DeployTarget=Package /tv:4.0&quot; /&gt;
&lt;/Target&gt;</pre>
<p>Nice, isn&#8217;t it?</p>
<h3>One to rule them all</h3>
<p>Bare Web Deploy would probably be enough for three or four web applications. As you remember, in my case there is about a dozen of them and another dozen of console tools. That&#8217;s why I decided I need another layer. Later on it turned out to be a good idea also for another reason &#8212; security. During the audit process one of the auditors pointed out that we don&#8217;t have any mechanism to guarantee that the binaries deployed to production are not forged.</p>
<p>I thought it will be a trivial task to implement &#8212; just use a command-line tool to zip all the packages (and console applications, each in it&#8217;s own folder) and another command-line tool to sign the zip file digitally. Unfortunately it turned out that there are no built-in tools on the Windows platform for these simple tasks. I didn&#8217;t like the idea of installing applications like 7zip or similar on production servers so I decided to create a custom tool for the task. This is exactly how <a href="https://github.com/SzymonPobiega/PackMan">PackMan</a> was born.</p>
<p>PackMan is a quick and dirty tool for packaging a bunch of files together in a digitally signed zip file. Of course it also allows you to verify the signature and unpack the contents. PackMan is stream-based so it has no problem supporting quite large packages (mine has about 120 MB). It uses Windows PKI to retrieve the keys for signing and verifying.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=_ZXg5KpdXK0:epFUgoI6284:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=_ZXg5KpdXK0:epFUgoI6284:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/_ZXg5KpdXK0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2012/01/05/building-the-deployment-package/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2012/01/05/building-the-deployment-package/</feedburner:origLink></item>
		<item>
		<title>The automated deployment story</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/sRq02YbrOl4/</link>
		<comments>http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 05:45:44 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[build automation]]></category>
		<category><![CDATA[continuous delivery]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=906</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>Here&#8217;s the story of an automated .NET deployment. Story is strongly based on my current project. To give you some context, here are few facts about the project:

dozen web applications (half of which to be installed only on test environments)
more than dozen console applications doing various things (reporting, mailing, etc.)
four environments (DEV, TEST, DR and PROD), [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p>Here&#8217;s the story of an automated .NET deployment. Story is strongly based on my current project. To give you some context, here are few facts about the project:</p>
<ul>
<li>dozen web applications (half of which to be installed only on test environments)</li>
<li>more than dozen console applications doing various things (reporting, mailing, etc.)</li>
<li>four environments (DEV, TEST, DR and PROD), up to 4 machines each</li>
</ul>
<p>While it certainly is not the biggest .NET project, it for sure calls for automated deployment procedures. The previous tedious manual process was taking up to 8 hours to complete and, needless to say, was failing quite often due to deployment notes not being up to date.</p>
<p>I started automating the process a few months ago, but at first I was struggling with each and every step. The breakthrough came with reading the awesome <a href="http://www.amazon.com/gp/product/0321601912?tag=contindelive-20">Continuous Delivery</a> book by Jez Humble ad David Farley.</p>
<p>This is the first post in the (hopefully) long series. It is mean to give you an outline of the process we implemented. As time passes, it will fill with links to posts covering specific areas. So, here&#8217;s the sketch</p>
<ol>
<li>Compile the source code (nothing fancy here)</li>
<li>Run the commit stage tests (mainly unit tests)</li>
<li><a href="http://simon-says-architecture.com/2012/01/05/building-the-deployment-package">Build and digitally sign the deployment package</a></li>
<li>Put the package in the build drop folder (again, nothing fancy)</li>
<li><a href="http://simon-says-architecture.com/2012/01/19/the-release-candidate-repository">Create a new Release Candidate in the release repository</a></li>
<li>Get the latest Release Candidate which passed commit stage tests</li>
<li><a href="http://simon-says-architecture.com/2012/01/24/deploy-based-on-external-description-of-the-environment">Start the deployment based on description of the environment</a> (what to install where)</li>
<li>Upload the deployment package to target machine(s)</li>
<li><a href="http://simon-says-architecture.com/2012/02/03/automated-deployment-security/">Validate the authenticity of package</a> with public key of the publisher</li>
<li>Stop all running applications (both web and console hosted by Windows Scheduler)</li>
<li>(Re)create the applications and application pools on IIS</li>
<li>Update the binaries to new version</li>
<li>Start the web applications and schedule console applications</li>
<li>Verify the correctness of deployment</li>
<li>Run the integration and automated user acceptance tests</li>
<li>Update the status of Release Candidate reflecting the outcome of the tests</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=sRq02YbrOl4:H2Os1G9qjd8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=sRq02YbrOl4:H2Os1G9qjd8:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/sRq02YbrOl4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story/</feedburner:origLink></item>
		<item>
		<title>2011 in books</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/rub9W4JpXNM/</link>
		<comments>http://simon-says-architecture.com/2011/12/20/2011-in-books/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 19:39:41 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Notki po polsku]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=888</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/pl.png" width="17" height="17" alt="" title="Notki po polsku" /><br/>December is traditionally a time of retrospective posts. Forgive me please but I simply can&#8217;t resist following this trend. I&#8217;d like to share with you my thought about books I read this year. Hope you&#8217;ll find it useful when deciding what to read next.
REST in practice  
This was the first Kindle book I bought. [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/pl.png" width="17" height="17" alt="" title="Notki po polsku" /><br/><p>December is traditionally a time of retrospective posts. Forgive me please but I simply can&#8217;t resist following this trend. I&#8217;d like to share with you my thought about books I read this year. Hope you&#8217;ll find it useful when deciding what to read next.</p>
<h3>REST in practice <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </h3>
<p>This was the first Kindle book I bought. After reading it I could say I love both the book and the device. I learnt quite a lot about the principles of REST. The hardest part was understanding why these hypermedia are so important but then came the moment of enlightenment. I can for sure recommend reading it.</p>
<h3>CSS: The Missing Manual <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </h3>
<p>I must admit I had quite high expectations that I will learn how HTML layouts work and how to efficiently position elements. It turned out to be a book about CSS syntax and very basic stuff I already knew.</p>
<h3>Management 3.0 <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </h3>
<p>I wanted to learn a little bit about management for quite some time and suddenly this book came out. I simply love all the analogies (i.e. to bacteria) Jurgen uses in the book to explain how such complex systems as software developer teams work. Recommended to everybody, even if you don&#8217;t plan to become a manager.</p>
<h3>Event Processing in Action <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </h3>
<p>Another high expectation book and another disappointment. I expected a good book on event-driven architectures but actually EPiA is a book about taxonomy and nomenclature of event systems. Not much more than a bunch of definitions.</p>
<h3>Dependency Injection in .NET <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h3>
<p>I bought it via Manning early access program and it was for sure not a waste of money. Although because I had some experience with DI before and have been up-to-date with blogs and tweets of <a href="http://kozmic.pl/">Krzysztof Koźmic</a> and <a href="http://blog.ploeh.dk/">Mark Seeman</a>, there was not much new to me in the book. Still, I don&#8217;t regret the money and I can happily recommend the book, especially if you are new to DI.</p>
<h3>The Pragmatic Programmer <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_confused.gif' alt=':?' class='wp-smiley' /> </h3>
<p>A friend of mine recommended this book to me so I though I can give it a try. I had mixed feelings after reading it. I can&#8217;t recall a single thing that altered my thinking or opened my eyes to some new insight. For sure it is a solid book and at the time of writing it contained some cutting-edge stuff but after a few years these ideas have become mainstream and their understanding is expected even from novice developers.</p>
<h3>JavaScript: The Good Parts <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_confused.gif' alt=':?' class='wp-smiley' /> </h3>
<p>Another tentative one. I expected a lot more hardcore stuff in the book. It left me with a feeling that I know JavaScript (which is bullshit). If you happen to don&#8217;t know it at all (are there such people?) it may be a good book to start with.</p>
<h3>Streamlined Object Modeling <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </h3>
<p>After hearing so many good things about the book on Domain-Driven Design group I simply had to read it. To my surprise I dint&#8217;t like it. I could not get rid of a feeling that authors promote some catch-it-all model they developed and claim it solves all problems (even probably hunger in Africa). The only thing I really liked was the modeling heuristic that objects that are active in real world tend to work better if modeled as passive in the domain model and vice-versa.</p>
<h3>Working Effectively with Legacy Code <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h3>
<p>I bought this one because we started to rewrite some legacy code in my current project. I wanted to learn from the expert how to deal with such code. It turned out to be a good, solid book. I don&#8217;t remember any particular moments of enlightenment but for sure I learnt a lot.</p>
<h3>Continuous Delivery <img src='http://simon-says-architecture.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </h3>
<p>This is the last one. I&#8217;ve been reading it since Saturday and already read about 70%. Continuous Delivery is probably the best book I&#8217;ve read this year. Together with REST in Practice and Management 3.0, it totally changed the way I see software development as a process. Thanks Jez and Dave!</p>
<h3>Looking into the new year&#8230;</h3>
<p>There are several themes that dominate my <a href="http://www.amazon.com/registry/wishlist/20XDZB8O3I21T/ref=cm_sw_r_tw_ws_ajo8ob1WF0QY8">Amazon wishlist</a> for the next year:</p>
<ul>
<li>C# (need to refresh my knowledge)</li>
<li>Lean (having heard a lot about Kanban I finally need to read some &#8216;classic&#8217; books)</li>
<li>Architecture (Pattern Oriented series in particular)</li>
</ul>
<p>I would also like to read some &#8216;true classics&#8217; like Extreme Programming Explained by Kent Beck. Life will show if this is doable&#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=rub9W4JpXNM:RA3e0uo2jE8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=rub9W4JpXNM:RA3e0uo2jE8:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/rub9W4JpXNM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2011/12/20/2011-in-books/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2011/12/20/2011-in-books/</feedburner:origLink></item>
		<item>
		<title>.NET is not an enterprise application platform (yet)</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/nAeTJLerOI0/</link>
		<comments>http://simon-says-architecture.com/2011/12/12/net-is-not-an-enterprise-app-platformlication-platform-yet/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 17:52:29 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[architecture]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=881</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>&#8230;Windows is. If you have been convinced by Microsoft that .NET is an application platform for the enterprise, here is a list of arguments proving that it is not (yet).

IIS is not an application server. All it provides is serving dynamic web pages and hosting WCF web services.
AppFabric have not delivered on its promise. Nobody [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p>&#8230;Windows is. If you have been convinced by Microsoft that .NET is an application platform for the enterprise, here is a list of arguments proving that it is not (yet).</p>
<ul>
<li><strong>IIS is not an application server</strong>. All it provides is serving dynamic web pages and hosting WCF web services.</li>
<li><strong>AppFabric have not delivered on its promise</strong>. Nobody is using workflows so the only widely usable part of it is the distributed cache (which, I must admit, is nice).</li>
<li><strong>IIS does not allow to host scheduled tasks</strong>. For these you have to use Windows Scheduler which operates on OS level.</li>
<li><strong>IIS does not work well with custom threading models</strong> so things like NServiceBus have to be hosted as Windows Services.</li>
<li><strong>IIS does not have a decent monitoring &amp; management story</strong>. You have to use WMI which, again, is an OS level service that does not speak .NET language and is quite cumbersome do use.</li>
</ul>
<p>Convinced? So here&#8217;s a list of things which you, as a developer, can do to fix this problem</p>
<ul>
<li><strong>Extend IIS or create a complementary service</strong> that can use the same model as IIS (one core process per system + process per application) that would host scheduled tasks and could incorporate custom threading models thus allowing to run things like<a href="http://nservicebus.com/"> NServiceBus</a>.  <a href="http://topshelf-project.com/">TopShelf </a>would be a good starting point.</li>
<li>Assembly is not longer a good deployment unit &#8212; it is too small. <strong>Provide a packaging system</strong> that would allow to package several assemblies (a functional module) together. Such a module could be easily deployed (and undeployed) from the application server as a whole.</li>
<li><strong>Create a decent scheduling library</strong>. The only one there is, <a href="http://quartznet.sourceforge.net/">Quartz.NET</a>, is probably one of the oldest .NET open source projects still in use. It desperately needs a replacement that follows today&#8217;s design practices.</li>
<li>Think about how you could contribute to <a href="http://netmx.codeplex.com/">NetMX</a> or come up with a completely new,<strong> lightweight, monitoring &amp; management framework</strong>.</li>
</ul>
<p>Having all these things built, it would be quite easy to assemble an <strong>open source private cloud infrastructure</strong>. The goal would be to have a farm of servers running either Windows or Linux/Mono that can be treated as<strong> one logical machine</strong> to which I can easily deploy all kinds of components including (but not only)</p>
<ul>
<li>web applications (using various MVC frameworks)</li>
<li>scheduled services</li>
<li>message consumers (using various frameworks like <a href="http://nservicebus.com/">NServiceBus</a> or <a href="http://masstransit-project.com/">MassTransit</a>)</li>
<li>web services (using, again, variety of frameworks like WCF or <a href="http://openrasta.org/">OpenRasta</a>)</li>
</ul>
<p>delivered in easy to use packages.</p>
<ul></ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=nAeTJLerOI0:FwixQKoCgak:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=nAeTJLerOI0:FwixQKoCgak:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/nAeTJLerOI0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2011/12/12/net-is-not-an-enterprise-app-platformlication-platform-yet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2011/12/12/net-is-not-an-enterprise-app-platformlication-platform-yet/</feedburner:origLink></item>
		<item>
		<title>Global Day of Code Retreat</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/wYLzOyh7XmU/</link>
		<comments>http://simon-says-architecture.com/2011/12/07/global-day-of-code-retreat-2011/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 18:37:32 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[clean code]]></category>
		<category><![CDATA[code retreat]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=872</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>Last Saturday I attended the second Kraków Code Retreat which was a part of the Global Day of Code Retreat. The event was organized by Kraków Software Craftsmanship society, [sckrk].
The organizers did a great job preparing the meeting. There was even a coffee machine for those who, like myself, can&#8217;t start a proper coding day [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p>Last Saturday I attended the second <a href="http://coderetreat.sckrk.com/">Kraków Code Retreat</a> which was a part of the <a href="http://globalday.coderetreat.org/">Global Day of Code Retreat</a>. The event was organized by Kraków Software Craftsmanship society, <a href="http://sckrk.com/">[sckrk]</a>.</p>
<p>The organizers did a great job preparing the meeting. There was even a coffee machine for those who, like myself, can&#8217;t start a proper coding day without a cup of coffee (or two). Because the event started so early (between 8 and 9 AM), the organizers ensured that we have sandwiches for breakfast. It was a very nice surprise.</p>
<p>On the contrary, the form of the event was not a surprise for me. Partially because I attended the previous code retreat [sckrk] organized in April and partially because the form of these events is pretty much standardized. There are <strong>5-7 sessions</strong>, each about <strong>45 minutes long</strong>. During each session we try to solve exactly the same problem (the most popular one is <a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Conway&#8217;s Game of Life</a>) the best way we can. The assumption is that we <strong>work in pairs</strong> and we all employ <strong>TDD</strong>. The amount of time is calculated in such a way that it should be very difficult to finish the solution. The reason for this is, during a code retreat, you should not focus on getting things done but, instead, on writing <strong>the most beautiful code</strong> you can.</p>
<p>I was quite surprised by the fact that we (I paired with <a href="http://piotrleszczynski.com/">Piotr Leszczyński</a> for this session) managed to solve the problem within the provided time frame. Especially given that I did not manage to solve it during the event in April. The key to our &#8217;success&#8217; (remember, it&#8217;s not the completeness of the solution what matters here) was probably the fact that we both have had some experience in both pair programming and TDD. What is more, we did practice these disciplines together in some point in time. I really enjoyed these 40 or so minutes. It would be worth attending the event even for this one session. On the solution side, it was not particularly clever or beautiful. It was not purely object oriented and some abstractions were missing. But my feeling was it was a good SOLID code. The downside of having a complete solution in first try was that I was under it&#8217;s influence for the rest of the day. It was hard to think in a completely different way.</p>
<p>The effect was, I spent two sessions refining this solution. One of the improvements was making the coordinates a class on its own. It encapsulated the way neighbourhood (the key concept in Game of Life) is defined. We didn&#8217;t have enough time to make the last step and make our game board generic of T where T is an implementation of some Coordinates. It would make changing the coordinate system (for example to spherical or 3D) a trivial task.</p>
<p>The other improvement was made in the method that returned neighbouring coordinates for a given coordinate. In the first solution we just hard-coded it like this:</p>
<pre class="brush: csharp; title: ; notranslate">
yield return new Coordinates(x, y - 1);
yield return new Coordinates(x, y + 1);
...
yield return new Coordinates(x + 1, y);
</pre>
<p>The improved solution looked like this:</p>
<pre class="brush: csharp; title: ; notranslate">
return (from x in Enumerable.Range(-1, 3)
from y in Enumerable.Range(-1, 3)
select new Coordinate(x, y))
.Except(this);
</pre>
<p>It puts grater emphasis on the intent. It would be even better if Enumerable.Range method has min and max parameters instead of min and count.</p>
<p>Like I said before, one of the assumptions of core retreat is to test drive the design. The problem with this approach is, it is hard to force a completely different solution only be means of writing proper tests. I wanted to try something different so I convinced Piotr to leave TDD aside for one session. We agreed to use test-first approach but implement the design I proposed. Piotr suggested that we should also refrain from writing any conditional statements (if, switch). This sounded like a fair deal.</p>
<p>What we tried was an actor-based approach. Every cell was an actor which was able to respond to various events. The environment was responsible for routing these events so that cells get events generated by their neighbours. The solution was turn-based so that in the beginning of each turn every cell got events from other cells and at the end &#8212; a clock event from the environment. The response for this event could be either &#8216;alive&#8217; or &#8216;dead&#8217;.</p>
<p>The other interesting thing about this solution was, it allowed us to get rid of conditional statements in a quite elegant way. We used a state pattern to process the events:</p>
<pre class="brush: csharp; title: ; notranslate">
public interface IState
{
   IState ConsumeAliveEvent();
   IEvent GetResponse();
}
</pre>
<p>There can be four possible states in the game: base (cell will die in next round), after consuming one alive event (will also die), after two (will survive), after three (will survive) and more than three (will die).</p>
<p>Unfortunately we didn&#8217;t have enough time to finish the code, but it was quite promising. Especially the tests which were in form of statements like this</p>
<blockquote><p>given these (events) happened, the cell should generate these events</p></blockquote>
<p>In quick summary I would like to encourage you to take part in every code retreat event that is organized in you neighbourhood. It is really worth it, event if you have some experience in TDD and/or pair programming.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=wYLzOyh7XmU:o38EZjE5ccg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=wYLzOyh7XmU:o38EZjE5ccg:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/wYLzOyh7XmU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2011/12/07/global-day-of-code-retreat-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2011/12/07/global-day-of-code-retreat-2011/</feedburner:origLink></item>
		<item>
		<title>Events are not an implementation detail</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/dDytJXWZEtM/</link>
		<comments>http://simon-says-architecture.com/2011/11/29/events-are-not-implementation-detail/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 05:42:53 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Posts in English]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[event sourcing]]></category>
		<category><![CDATA[event-centric]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=867</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/>When listening to many discussion about Domain-Driven Design and Event Sourcing, subjects which I am recently very into, sometimes I have a feeling that events are considered merely a way of persisting aggregates. People tend to discuss benefits events have with regards to storing historical data, having possibility to generate any read model out of [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/gb.png" width="17" height="17" alt="" title="Posts in English" /><br/><p>When listening to many discussion about <em>Domain-Driven Design</em> and <em>Event Sourcing</em>, subjects which I am recently very into, sometimes I have a feeling that events are considered merely a way of persisting <em>aggregates</em>. People tend to discuss benefits events have with regards to storing historical data, having possibility to generate any read model out of events and so on. Reducing <em>event sourcing</em> to such &#8216;housekeeping&#8217; duties is castrating your architecture.</p>
<p>This point of view is expressed in a way people model their event-based solutions: thinking first about the <em>aggregates</em> and then, within each <em>aggregate</em>, about events they generate. Sometimes the process is even more event-<strong>UN</strong>centric when people first implement a command and then start thinking about what event types should be created.</p>
<p>Given the fact that most <em>Event Sourcing</em> practitioners have a background in <em>DDD</em>, we tend to bring our experience from working in data-centric environment to the event-centric world. There is, however, a fundamental difference between these two.</p>
<p>When building a behaviour-oriented <em>DDD</em> solution on top of a data-centric infrastructure (a database) <strong>you do your best to hide the database and its schema from the business layer</strong>. Over the years we learnt that it is better treated as implementation detail because it does not provide concepts useful to model behaviour. There concepts must be built on top of it. The underlying data layer must not be visible to the outside world because of it&#8217;s volatility &#8212; it has to change whenever the behaviour it supports needs to change.</p>
<p>On the other hand, when building a similar solution on top of event-centric infrastructure you can (and should) <strong>leverage events to model the behaviour</strong>. They (not <em>aggregates</em> or anything built on top of them) are the central concept here. Whenever business changes, new event types appear and some old are no longer generated but no event is ever lost. <em>Whatever happened, happened</em>.</p>
<p>Returning to my original thought, in an event-centric solution <em>aggregates</em> <strong>should not</strong> be treated as first-class citizens. Don&#8217;t get me wrong, they are very useful. In a healthy design probably a vast majority of events would be generated via <em>aggregates</em>, but some would not. <em>Aggregates</em> are priceless when it comes to <strong>modelling concurrency</strong> and to <strong>encapsulating business logic</strong>.</p>
<p>You may now want to ask a question when should you use <em>aggregates</em> and when not? The answer seems to be simple. Whenever your system needs to respond to some external activity, you just directly inject an event representing what have happened into your system. The idea is, again, <em>whatever happened, happened</em>. You can&#8217;t throw concurrency exception at The World saying it is wrong to raise this event right now. You have to humbly acknowledge the fact and record the information. On the other hand, when it is your system who conducted the activity to be communicated by an event, you should use an <em>aggregate</em> to have full control over how and when the event is published.</p>
<p>Have fun building event-centric solutions!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=dDytJXWZEtM:F7flH3jotX8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=dDytJXWZEtM:F7flH3jotX8:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/dDytJXWZEtM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2011/11/29/events-are-not-implementation-detail/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2011/11/29/events-are-not-implementation-detail/</feedburner:origLink></item>
		<item>
		<title>69. spotkanie KGD.NET</title>
		<link>http://feedproxy.google.com/~r/szymonpobiega/~3/M4jbby4BtZM/</link>
		<comments>http://simon-says-architecture.com/2011/11/22/69-spotkanie-kgd-net/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 11:51:14 +0000</pubDate>
		<dc:creator>Szymon Pobiega</dc:creator>
				<category><![CDATA[Notki po polsku]]></category>
		<category><![CDATA[KGD.NET]]></category>

		<guid isPermaLink="false">http://simon-says-architecture.com/?p=865</guid>
		<description><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/pl.png" width="17" height="17" alt="" title="Notki po polsku" /><br/>Chciałbym zaprosić wszystkich na 69. spotkanie Krakowskiej Grupy Developerów .NET. Spotkanie odbędzie się jak zwykle w siedzibie ABB, przy ulicy Starowiślnej 13. Będzie także dostępne on-line dzięki uprzejmości portalu VirtualStudy. Na spotkaniu, jak zwykle, dwie sesje. Tym razem będą to:
Kanban &#8211; Usprawnienia bez wysiłku, którą zaprezentuje Paweł Brodziński, oraz
Software as a Service &#8211; jedna baza danych, [...]]]></description>
			<content:encoded><![CDATA[<img src="http://simon-says-architecture.com//wp-content/uploads/pl.png" width="17" height="17" alt="" title="Notki po polsku" /><br/><p>Chciałbym zaprosić wszystkich na <strong>69. spotkanie Krakowskiej Grupy Developerów .NET</strong>. Spotkanie odbędzie się jak zwykle w siedzibie ABB, przy ulicy Starowiślnej 13. Będzie także <a href="http://virtualstudy.pl/pl/component/jevents/icalrepeat.detail/2011/11/23/319/-/transmisja-z-69-spotkania-kgdnet-kanban-i-saas">dostępne on-line</a> dzięki uprzejmości portalu <a href="http://virtualstudy.pl/pl/component/jevents/icalrepeat.detail/2011/11/23/319/-/transmisja-z-69-spotkania-kgdnet-kanban-i-saas">VirtualStudy</a>. Na spotkaniu, jak zwykle, dwie sesje. Tym razem będą to:</p>
<p><strong>Kanban &#8211; Usprawnienia bez wysiłku</strong>, którą zaprezentuje <strong>Paweł Brodziński</strong>, oraz</p>
<p><strong>Software as a Service &#8211; jedna baza danych, wielu użytkowników</strong>, którą przedstawi <strong>Maksymilian Majer</strong></p>
<p>Po spotkaniu zapraszamy wszystkich na wspólne piwo. Będzie to okazja, aby podyskutować z prelegentami na temat ich prezentacji w bardziej nieformalnych warunkach. Pierwsze dwie kolejki tym razem (to nie reguła) stawiają prelegenci!</p>
<p>Zapraszam do rejestracji na spotkanie <a href="http://www.kgdnet.pl/events/40514682/">tutaj</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=M4jbby4BtZM:quZPEi56FIY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/szymonpobiega?a=M4jbby4BtZM:quZPEi56FIY:0VBWazUhMmc"><img src="http://feeds.feedburner.com/~ff/szymonpobiega?d=0VBWazUhMmc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/szymonpobiega/~4/M4jbby4BtZM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simon-says-architecture.com/2011/11/22/69-spotkanie-kgd-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://simon-says-architecture.com/2011/11/22/69-spotkanie-kgd-net/</feedburner:origLink></item>
	</channel>
</rss>

