<?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>ALTERthought Blogs &#187; General</title>
	<atom:link href="http://alterlabs.com/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://alterlabs.com</link>
	<description>Results through imagination</description>
	<lastBuildDate>Tue, 13 Apr 2010 19:19:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Speaking @ PMI Fairview Park Forum</title>
		<link>http://alterlabs.com/uncategorized/speaking-pmi-fairview-park-forum/</link>
		<comments>http://alterlabs.com/uncategorized/speaking-pmi-fairview-park-forum/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 19:09:28 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile project management]]></category>
		<category><![CDATA[rapid planning]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=602</guid>
		<description><![CDATA[On Wednesday, April 21st, Sunjay Pandey will be speaking at the Project Management Institute’s Fairview Park Forum .  Sunjay will be presenting a topic entitled Project Plan Ninja which discusses how to manage Rapid Business Requirements generation on a Rapid Application Development project.
Sunjay will be presenting proven techniques that can take your team from [...]]]></description>
			<content:encoded><![CDATA[<p>On Wednesday, April 21st, Sunjay Pandey will be speaking at the <a href="http://www.pmiwdc.org/Fairview" target="_blank" title="Fairview">Project Management Institute’s Fairview Park Forum</a> .  Sunjay will be presenting a topic entitled <a href="http://at.alterthought.com/project-plan-ninja" title="Project Plan Ninja">Project Plan Ninja</a> which discusses how to manage Rapid Business Requirements generation on a Rapid Application Development project.</p>
<p>Sunjay will be presenting proven techniques that can take your team from vision to requirements in hours, not weeks. </p>
<p><strong>Presentation Abstract</strong></p>
<p>Markets, customers, and industries are moving quickly. Rapid application development is a strategic necessity. But, rapid application development techniques require rapid estimation and planning techniques. Business demands for improved time-to-market means your teams must estimate, plan, and budget application development projects with greater speed and accuracy.</p>
<p>Project Plan Ninja provides modern cues, clues, and tools for turning application development requirements into actionable budgets &#038; work plans.</p>
<ul>
<li>Estimate application development projects in hours, not weeks</li>
<li>Quickly and confidently enter feature negotiation with customers</li>
<li>Envision a consistent estimation and budgeting process for your teams</li>
<li>Bridge the gap between Agile-oriented and plan-driven estimation</li>
<li>Understand how to build practical, repeatable work plans</li>
</ul>
<p>There is no charge for attending this event, but preregistration is required.   Please visit <a href="http://www.pmiwdc.org/Fairview" target="_blank" title="Fairview">www.pmiwdc.org/Fairview</a> and click on “Register Online” on the April 21 event.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/uncategorized/speaking-pmi-fairview-park-forum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking @ Norfolk Area PMI Dinner Group</title>
		<link>http://alterlabs.com/uncategorized/speaking-norfolk-area-pmi-dinner-group/</link>
		<comments>http://alterlabs.com/uncategorized/speaking-norfolk-area-pmi-dinner-group/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 15:37:26 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=588</guid>
		<description><![CDATA[On Wed Oct 7th, Sunjay Pandey will be speaking at the Project Management Institute’s Norfolk Dinner Meeting.  Sunjay will be presenting the topic: The Switching Gears Factor which describes portions of ALTERthought’s IT Governance approaches &#8211; particularly estimation and budgeting.  In this session, Sunjay will discuss how the multi-tasking arising from multi-project assignments [...]]]></description>
			<content:encoded><![CDATA[<p>On Wed Oct 7th, Sunjay Pandey will be speaking at the <a href="http://pmihr.org/index.php?option=com_events&#038;task=view_detail&#038;agid=185&#038;year=2009&#038;month=10&#038;day=07&#038;Itemid=26" title="Norfolk PMI">Project Management Institute’s Norfolk Dinner Meeting</a>.  Sunjay will be presenting the topic: <a href="http://alterlabs.com/general/articles/the-switching-gears-factor/">The Switching Gears Factor</a> which describes portions of ALTERthought’s IT Governance approaches &#8211; particularly estimation and budgeting.  In this session, Sunjay will discuss how the multi-tasking arising from multi-project assignments can impact IT projects. He will also discuss how it can  be accounted for and how to manage this impact. Registration is available <a href="http://guest.cvent.com/i.aspx?4W,M3,10e1917e-3612-4277-a506-672c2611faa6">online</a>. We look forward to seeing you there.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/uncategorized/speaking-norfolk-area-pmi-dinner-group/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails and Cloud Computing: Part 1 &#8211; Amazon EC2</title>
		<link>http://alterlabs.com/uncategorized/grails-and-cloud-computing-part-1-amazon-ec/</link>
		<comments>http://alterlabs.com/uncategorized/grails-and-cloud-computing-part-1-amazon-ec/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 15:24:27 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Groovy/Grails]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=135</guid>
		<description><![CDATA[Progress to Date
This entry is a part of the &#8216;What can you build in 40hrs&#8216; series&#8211; which, in a nutshell, involved an experiment to see what we could build in about typical weeks worth of work.  In the last post we effectively completed the basic functional requirements of the application, and now have a [...]]]></description>
			<content:encoded><![CDATA[<h3>Progress to Date</h3>
<p>This entry is a part of the &#8216;<em>What can you build in 40hrs</em>&#8216; series&#8211; which, in a nutshell, involved an experiment to see what we could build in about typical weeks worth of work.  In the <a href="http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-5/">last post</a> we effectively completed the basic functional requirements of the application, and now have a working system that can be used to manage two sets of to-do lists as part of a task management application.</p>
<h3>Cloud Computing</h3>
<p>As part of this effort, we wanted to try something &#8216;new&#8217; as part of the application initiative. We decided to make one of the system requirements of the application involve its deployment into a Cloud Computing infrastructure&#8211; the leading candidates at time of construction being <a href="http://aws.amazon.com/ec2/">Amazon&#8217;s Elastic Cloud Computing (EC2</a>) and Google&#8217;s App Engine.  </p>
<p>While both Amazon and Google offer similar infrastructure platforms, as it shall be seen, the level of effort necessary to deploy a stock Grails application into these infrastructures varies greatly.<br />
<span id="more-135"></span><br />
This entry concerns itself with the deployment of the <em>TwoDo</em> application into Amazon&#8217;s EC2 infrastructure.  A subsequent entry will detail the efforts necessary to get the same application running on Google&#8217;s AppEngine platform. (At the time I started this effort Google&#8217;s AppEngine had only recently released its Java API, and was dribbling out access to its infrastructure in a controlled fashion (FIFO?) As such, I did not initially have the rights to deploy an application to AppEngine&#8211; hence the decision to go with EC2 first.)</p>
<h3>Cloud Tools Plugin</h3>
<p>We are going to leverage the <a href="http://code.google.com/p/cloudtools/">CloudTools Plugin</a> for all the heavy lifting aspects of getting our application deployed into Amazon.  Cloud Tools was developed by the founder of <a href="http://www.cloudfoundry.com/">CloudFoundry</a>&#8211; a service designed to deploy Java/Grails apps to Amazon&#8217;s EC2.  I suppose I could have gone with the CloudFoundry as part of my deployment efforts (and indeed, will probably try it out) but for whatever reason chose to start at a lower level by using the plugin.</p>
<div class="strongpoint">
<strong>Footnote:</strong> In the elapse time since I started the project and the authoring of this post, <a href="http://chris-richardson.blog-city.com/cloud_foundry_is_now_part_of_springsource.htm">SpringSource has acquired CloudFoundry</a> as part of its Cloud Computing push. Exciting stuff!
</div>
<h3>Getting Started</h3>
<p>A prerequisite for using the <em>CloudTools Plugin</em> is to have an existing Amazon AWS account. The setup of which is easy, and well documented outside of this blog&#8230; so we aren&#8217;t going to concern ourselves with much of it here. If nothing else simply go to the <a href="http://aws.amazon.com/ec2/">main site</a> and click the &#8216;Sign Up for Amazon EC2&#8242; button</p>
<div class="strongpoint">
It should be stressed that the use of Amazon&#8217;s EC2 infrastructure is not free. Registration and setup on Amazon&#8217;s site requires a form of payment to be associated with your account.
</div>
<p>The first basic step was to install the plugin. I downloaded the plugin from the main <em>CloudTools</em> site and installed it from my local drive:</p>
<blockquote><p><em>grails install-plugin /path/to/downloads/grails-cloud-tools-0.6.zip </em>
</p></blockquote>
<p>The installation process creates a<code> conf/CloudTools.groovy</code> file which, in theory, could be simply added to the list of configuration files that Grails should slurp during boot time via an explicit specification in the <code>conf/Config.groovy</code> file like so:</p>

<div class="wp_syntax"><div class="code"><pre class="1" style="font-family:monospace;">...
grails.config.locations = [&quot;classpath:CloudTools.groovy&quot;]
..</pre></div></div>

<p>However, I could never get this file to be located during the deployment process, so I eventually punted and copied the contents of the <code>conf/CloudTools.groovy</code> file directly into <code>conf/Config.groovy</code></p>
<p>Once the contents of the <code>conf/CloudTools.groovy</code> file are pasted into the standard <code>conf/Config.groovy</code> file it needs to be edited with the specifics of our application. </p>
<h4>Database Setup</h4>
<p>The <em>CloudTools plugin</em> will create a MySql schema for us, as well as a user account used to access the DB as part of the deployment process. All we need to to is edit the parameters passed to the schema() method of the ClusterSpec() object that we pasted into our Config.groovy file:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;">cloudTools <span style="color: #66cc66;">&#123;</span>
...
  <span style="color: #006600;">clusterSpec</span> <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ClusterSpec<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
      .<span style="color: #006600;">tomcats</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
      .<span style="color: #006600;">topology</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;SingleInstanceTopology&quot;</span><span style="color: #66cc66;">&#41;</span>
       .<span style="color: #006600;">instanceType</span><span style="color: #66cc66;">&#40;</span>EC2InstanceType.<span style="color: #006600;">SMALL</span><span style="color: #66cc66;">&#41;</span>
       .<span style="color: #006600;">slaves</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
       .<span style="color: #006600;">bucketPrefix</span><span style="color: #66cc66;">&#40;</span><span style="color: #aaaadd; font-weight: bold;">System</span>.<span style="color: #006600;">getProperty</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;grails.env&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
       .<span style="color: #006600;">catalinaOptsBuilder</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;&quot;&quot;{builder, databasePrivateDnsName, slaves -&gt;</span>
<span style="color: #ff0000;">            builder.arg(&quot;-Xmx500m&quot;)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;com.sun.management.jmxremote&quot;)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;com.sun.management.jmxremote.port&quot;, 8091)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;com.sun.management.jmxremote.authenticate&quot;, false)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;com.sun.management.jmxremote.ssl&quot;, false)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;ptrack.application.environment&quot;, &quot;ec2&quot;)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;log4j.configuration&quot;, &quot;log4j-minimal.properties&quot;)</span>
<span style="color: #ff0000;">	    builder.prop(&quot;jdbc.db.server&quot;, databasePrivateDnsName)}&quot;&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="display:block;background-color: #ffc;">        .<span style="color: #006600;">schema</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;blogtwodo&quot;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;twodouser&quot;</span>: <span style="color: #ff0000;">&quot;password&quot;</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></span></pre></td></tr></table></div>

<p>On <strong>line 18</strong> above we configure the <code>ClusterSpec</code> to create the &#8216;<em>blogtwo</em>&#8216; database and the &#8216;<em>twodouser</em>&#8216;, the specifications of which should match the contents of the <code>conf/DataSource.groovy</code> file.</p>
<h4>CloudTools AWS Properties File</h4>
<p> We need to indicate the location of our Amazon Web Service <a href="http://code.google.com/p/cloudtools/wiki/AwsPropertiesFile">property file</a>, which is set by editing the value for the <code>awsPropertiesFile</code> property within the <code>conf/Config.groovy</code> file.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">...
<span style="color: #006600;">cloudTools</span> <span style="color: #66cc66;">&#123;</span>
<span style="display:block;background-color: #ffc;">  awsPropertiesFile <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;etc/ec2.properties&quot;</span></span>  ...
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>As you can see we have created a new <code>grails-app/etc</code> directory to hold this new file.  The properties file is a <em>CloudTools</em> specific artifact that  contains the relevant configuration information required by Amazon to host our application. In order to deploy into Amazon&#8217;s platform we are going to need provide several bits of information by way of this properties file.  Let&#8217;s take a look at the contents of ours and dissect it line-by-line:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="robots" style="font-family:monospace;">imageId.m1.small=ami-6f2cc906
imageId.m1.large=ami-0129cc68
imageId.m1.xlarge=ami-0129cc68
accountId=XXXX-XXXX-XXXX
accessKey=XXXXXXXXXXXXXXXXXXX
secretKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
keyName=blogtwodo
keyPairFile=/Users/don/DevelopmentWork/blogtwodo/etc/blogtwodo.pem
sshDir=/usr/bin</pre></td></tr></table></div>

<p><strong>AMI Identification</strong><br />
An application deployed into the EC2 will reside in <strong>Amazon Machine Image (AMI)</strong>. Think of this as a identifier for the base OS image/VPS.  In our case (<strong>lines 1-3</strong>) we will simply use the ones specified by the plugin <a href="http://code.google.com/p/cloudtools/wiki/AwsPropertiesFile">documentation</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="robots" style="font-family:monospace;">imageId.m1.small=ami-6f2cc906
imageId.m1.large=ami-0129cc68
imageId.m1.xlarge=ami-0129cc68</pre></td></tr></table></div>

<p><strong>Security Credentials</strong><br />
The next few lines contain part of the security credentials we need to provide to Amazon.  From within the Amazon Web Services Console, we navigate to &#8216;<em>Your Account -> Security Credentials</em>&#8216;.  The <code>accountId</code> (<strong>line 4)</strong> is your 12-digit account displayed on this page under the &#8216;<em>Your AWS Account ID, E-mail Address and Password</em>&#8216; section.</p>
<p>While within the &#8216;<em>Access Keys</em>&#8216; tab, I clicked &#8216;<em>Create a New access Key</em>&#8216; and used the resulting generated information to fill in the <code>accessKey</code> (<strong>line 5</strong>) and secretKey (<strong>line 6</strong>) properties.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>4
5
6
</pre></td><td class="code"><pre class="robots" style="font-family:monospace;">accountId=XXXX-XXXX-XXXX
accessKey=XXXXXXXXXXXXXXXXXXX
secretKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</pre></td></tr></table></div>

<p>Amazon&#8217;s site does a good job describing the purpose of the above access credentials:</p>
<blockquote><p>
<em><strong>Access Key ID</strong><br />
Your Access Key ID identifies you as the party responsible for service requests. Use your Access Key ID as the value of the AWSAccessKeyId parameter in requests you send to Amazon Web Services (when required).</em></p>
<p><em><strong>Secret Access Key</strong><br />
Each Access Key ID has a Secret Access Key associated with it. Use your Secret Access Key to calculate a signature to include in requests to web services that require authenticated requests. Your Secret Access Key is a secret, and should be known only by you and AWS. You should never include your Secret Access Key in your requests to AWS. You should never e-mail your Secret Access Key to anyone. It is important to keep your Secret Access Key confidential to protect your account. </em>
</p></blockquote>
<p><strong>Key Pair</strong><br />
 In addition to the above credentials we need to provide a public/private key pair in the form of an PEM file. Keys are created from within the EC2 dashboard and I created a new keypair with the application name of &#8216;blogtwodo&#8217; by logging into the &#8216;<em>Amazon EC2 dashboard -> Key Pairs</em>&#8216; and clicking the &#8216;<em>Create Key Pair</em>&#8216; link. The resulting <em>blogtwodo.pem</em> file was saved locally and moved into the <code>grails-app/etc</code> directory, where its configured by <strong>lines 7 and 8</strong> below:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>7
8
</pre></td><td class="code"><pre class="robots" style="font-family:monospace;">keyName=blogtwodo
keyPairFile=/Users/don/DevelopmentWork/blogtwodo/etc/blogtwodo.pem</pre></td></tr></table></div>

<p>Finally we need to indicate the path to an ssh client (<strong>line 9</strong>) to be used to securely upload our application to Amazon. I am using OSX on a Mac which includes this natively in the <code>/usr/bin</code> directory:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>9
</pre></td><td class="code"><pre class="robots" style="font-family:monospace;">sshDir=/usr/bin</pre></td></tr></table></div>

<h3>Deployment</h3>
<p>OK. With our configuration out of the way lets try and deploy this thing. From the command line we invoke the gant deployment target added by the <em>CloudTools</em> plugin:</p>
<blockquote><p><em>grails cloud-tools-deploy</em>
</p></blockquote>
<p>&#8230; which promptly reports the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">Error executing script CloudToolsDeploy<span style="color: #66cc66;">:</span> No such property<span style="color: #66cc66;">:</span> DEFAULT_J5_DEPS for class<span style="color: #66cc66;">:</span> ExplodedWar_groovy</pre></div></div>

<p>Whats the deal? Well, the <em>CloudTools</em> plugin was developed pre Grails v1.1.1, as it turns out there  are a few incompatibilities that need to be addressed in order to get our application deployed.</p>
<p>This error is addressed by adding the following highlighted code (<strong>line 10</strong>) to the <code>$GRAILS_HOME/scripts/_GrailsWar.groovy</code></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;">...
<span style="color: #006600;">DEFAULT_DEPS</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>
    <span style="color: #ff0000;">&quot;ant-*.jar&quot;</span>,
     ...
     ...
<span style="color: #66cc66;">&#93;</span>
&nbsp;
DEFAULT_J5_DEPS <span style="color: #66cc66;">=</span> DEFAULT_DEPS</pre></td></tr></table></div>

<p>OK. Lets try to deploy again&#8230;.. this time, although we get farther, we eventually fail with the error:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">ssh<span style="color: #66cc66;">:</span> connect to host ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com port <span style="color: #cc66cc;">22</span><span style="color: #66cc66;">:</span> Operation timed out</pre></div></div>

<p>Drat. Now what? After a little digging it&#8217;s determined that the problem is that we have not allowed the SSH protocol through the built in firewall associated with our application. This is fixed by navigating from within the EC Dashboard to &#8216;Security Groups -> default group&#8217; and adding the SSH protocol  to the table of connection methods.  Let&#8217;s try our deployment again.</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING<span style="color: #66cc66;">:</span> UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/don/DevelopmentWork/blogtwodo/etc/blogtwodo.pem' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.</pre></div></div>

<p>Sigh. OK. Trying again after <em>chmod</em>&#8216;ing the PEM file to 400 (<em>chmod 400 blogtwodo.pem</em>). </p>
<p>After <em><strong>several</strong></em> minutes (and I do mean several.. deployment took close to 10 minutes) this time we get:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">...
...
Location<span style="color: #66cc66;">:</span> http<span style="color: #66cc66;">:</span>//localhost/blogtwodo/ <span style="color: #66cc66;">&#91;</span>following<span style="color: #66cc66;">&#93;</span>
--<span style="color: #cc66cc;">10</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">34</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">55</span>--  http<span style="color: #66cc66;">:</span>//localhost/blogtwodo/
Connecting to localhost|127.0.0.1|<span style="color: #66cc66;">:</span>80... connected.
HTTP request sent, awaiting response... <span style="color: #cc66cc;">404</span> /blogtwodo/
<span style="color: #cc66cc;">10</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">34</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">55</span> ERROR <span style="color: #cc66cc;">404</span><span style="color: #66cc66;">:</span> /blogtwodo/.
&nbsp;
Finished deploying cluster</pre></div></div>

<p>Hmm. The ERROR 404 does not look good, but it does look like the application <em>technically</em> deployed.  A check on the EC2 console confirms that we have a single running instance, and clicking on it drills down to a panel that shows us the public DNS address we can use to test it out with a browser (running <em>grails cloud-tools-describe</em> gets us the same information from the command line.) When I visit the base address I get a generic Apache test page, which is encouraging:<br />
<a href="http://alterlabs.com/wp-content/uploads/2009/09/screen-capture.png"><img src="http://alterlabs.com/wp-content/uploads/2009/09/screen-capture-300x265.png" alt="apache2 testpage" title="apache2 testpage" width="300" height="265" class="alignnone size-medium wp-image-548" /></a></p>
<p>But, sure enough, I am greeted with a 404 error when I try to hit our applications URL with a browser.</p>
<p>So now what?  Well, when in doubt, go for the log files.  We can ssh directly into our running instance using our PEM file for authentication:</p>
<blockquote><p><em>ssh -i etc/blogtwodo.pem root@ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com</em></p></blockquote>
<p>A bit of poking around/exploring our VPS leads me to a promising log file: <code>/var/log/tomcat5/catalina.out</code> with a suspicious stacktrace:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">...
java.lang.NoClassDefFoundError<span style="color: #66cc66;">:</span> net.chrisrichardson.ec2deployer.cluster.ClusterSpec
        at Config$_run_closure3.class$<span style="color: #66cc66;">&#40;</span>Config.groovy<span style="color: #66cc66;">&#41;</span>
        at Config$_run_closure3.$get$$class$net$chrisrichardson$ec2deployer$cluster$ClusterSpec<span style="color: #66cc66;">&#40;</span>Config.groovy<span style="color: #66cc66;">&#41;</span>
        at Config$_run_closure3.doCall<span style="color: #66cc66;">&#40;</span>Config.groovy<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">87</span><span style="color: #66cc66;">&#41;</span>
        at Config$_run_closure3.doCall<span style="color: #66cc66;">&#40;</span>Config.groovy<span style="color: #66cc66;">&#41;</span>
        at Config.run<span style="color: #66cc66;">&#40;</span>Config.groovy<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">76</span><span style="color: #66cc66;">&#41;</span>
...</pre></div></div>

<p>It would seem that the <em>CloudTools</em> jars don&#8217;t appear to be packaged into our deployment war file. After a bit of investigation, this problem turns out to be another issue caused by behavior changes to Grails v1.1.1&#8211; notably in the management of plugins. The <em>CloudTools</em> plugin expects to find stuff located local to the grails project directory and the new Grails v1.1.1 paradigm moves all that stuff to centralized ~/.grails (on a Mac anyway) location.  My hack to get things working involved creating a symbolic link so that <em>CloudTools</em> would deploy all the necessary bits (for all our other plugins as well):</p>
<blockquote><p>
<em>ln -s ~/.grails/1.1.1/projects/blogtwodo/plugins  ./plugins</em>
</p></blockquote>
<div class="strongpoint">
<strong>&iexcl;IMPORTANTE!</strong> It&#8217;s important to note that often times a failed deployment will still manage to start a new AMI instance on your behalf, which means you will billed $0.10 per/hour for this instances uptime, even if you never do anything with it. After every deployment attempt (successful or unsuccessful) I recommend checking the number of running instances in the EC2 console and terminating any that were accidents.
</div>
<p>OK. Surely that must be the last step.  After deploying once again, we again get the 404 error. Now what?  Well checking the logfile again reveals this:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">org.springframework.jdbc.CannotGetJdbcConnectionException<span style="color: #66cc66;">:</span> Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException<span style="color: #66cc66;">:</span> Cannot create PoolableConnectionFactory <span style="color: #66cc66;">&#40;</span>Access denied for user 'twodouser'@'localhost' <span style="color: #66cc66;">&#40;</span>using password<span style="color: #66cc66;">:</span> YES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>I don&#8217;t doubt that there are better solutuions, but simply I punted and simply forcibly granted our &#8216;twoduser&#8217; access to the database via the <em>mysql</em> command line:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is <span style="color: #cc66cc;">6</span> to server version<span style="color: #66cc66;">:</span> 5.0.22-log
&nbsp;
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
&nbsp;
mysql&gt; use blogtwodo
Database changed
mysql&gt; GRANT USAGE ON *.* TO 'twodouser'@'localhost' IDENTIFIED BY 'password';
Query OK, <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
mysql&gt; GRANT ALL PRIVILEGES ON `blogtwodo`.* TO 'blogtwodo'@'localhost' WITH GRANT OPTION;
Query OK, <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This time we want to make sure that we redeploy the application to the <strong>same</strong> AMI where we just made our database changes, so we deploy the app using the <em>cloud-tools-redeploy</em> gant target:</p>
<blockquote><p><em>grails cloud-tools-redeploy</em></p></blockquote>
<p>At last we get something that appears to be a clean deployment:</p>

<div class="wp_syntax"><div class="code"><pre class="robots" style="font-family:monospace;">Connecting to localhost|127.0.0.1|<span style="color: #66cc66;">:</span>8080... connected.
HTTP request sent, awaiting response... <span style="color: #cc66cc;">302</span> Moved Temporarily
Location<span style="color: #66cc66;">:</span> http<span style="color: #66cc66;">:</span>//localhost<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">8080</span>/blogtwodo/ <span style="color: #66cc66;">&#91;</span>following<span style="color: #66cc66;">&#93;</span>
--<span style="color: #cc66cc;">10</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">48</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">48</span>--  http<span style="color: #66cc66;">:</span>//localhost<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">8080</span>/blogtwodo/
Connecting to localhost|127.0.0.1|<span style="color: #66cc66;">:</span>8080... connected.
HTTP request sent, awaiting response... <span style="color: #cc66cc;">302</span> Moved Temporarily
Location<span style="color: #66cc66;">:</span> http<span style="color: #66cc66;">:</span>//localhost<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">8080</span>/blogtwodo/public <span style="color: #66cc66;">&#91;</span>following<span style="color: #66cc66;">&#93;</span>
--<span style="color: #cc66cc;">10</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">48</span><span style="color: #66cc66;">:</span><span style="color: #cc66cc;">49</span>--  http<span style="color: #66cc66;">:</span>//localhost<span style="color: #66cc66;">:</span><span style="color: #cc66cc;">8080</span>/blogtwodo/public
Connecting to localhost|127.0.0.1|<span style="color: #66cc66;">:</span>8080... connected.
HTTP request sent, awaiting response... <span style="color: #cc66cc;">200</span> OK
Length<span style="color: #66cc66;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#91;</span>text/html<span style="color: #66cc66;">&#93;</span>
<span style="color: #cc66cc;">200</span> OK
&nbsp;
Finished redeploying cluster</pre></div></div>

<p>Pointing the browser at the site confirms it as working:<br />
<div id="attachment_569" class="wp-caption alignnone" style="width: 310px"><a href="http://alterlabs.com/wp-content/uploads/2009/09/screen-capture-11.png"><img src="http://alterlabs.com/wp-content/uploads/2009/09/screen-capture-11-300x183.png" alt="click to enlarge" title="ec2-working" width="300" height="183" class="size-medium wp-image-569" /></a><p class="wp-caption-text">click to enlarge</p></div></p>
<p><strong>Awesome</strong>.</p>
<h3>Conclusion and Wrapup</h3>
<p> All told the above took about 2 days (16 hours) to get working. Our total number of hours spent prior to this was about 30 hours, which brings our total to ~46 hours&#8230; just over our 40 hour goal. Still not too bad IMO. Let&#8217;s survey the pros and cons about the approach we used today:</p>
<h3>Pros:</h3>
<ul>
<li>Integration with EC2 is largely transparent to your underlying Grails application&#8211; once you get everything configured correctly that is&#8230; after which deployment is a snap</li>
<li>This transparency is <strong>huge</strong>. I did <em>nothing</em>, repeat <strong>nothing</strong>, to alter the underlying application for suitability with EC2. This is <strong>NOT</strong> the case with Google&#8217;s AppEngine, as will be shown in the next post in this series.</li>
<li>I don&#8217;t doubt that using the CloudFoundry management console makes deployment that much easier, without the need of a plugin. I plan to play with this more later, so expect a blog post on this as well.
</li>
</ul>
<h3>Cons:</h3>
<ul>
<li>It&#8217;s not free. We deployed the twodo application in an absolutely bare bones configuration&#8211; A single AMI which costs US$0.10 per/hour &#8211;> US$2.40 per/day &#8211;> ~US$72 per/month. While not catastrophically expensive, if you don&#8217;t need the ability to infinitely scale on a moments notice, you can certainly find cheaper hosting options.</li>
<li>We currently have no persistent storage configured. Yes, we have a MySql instance running, but for all practical purposes it might as well be an in memory database. If the AMI ever goes away, our DB is slicked as well. A &#8216;real&#8217; Cloud Computing solution would require the use of something like <a href="http://aws.amazon.com/ebs/">Amazon&#8217;s Elastic Block Storage Service (EBS)</a> ( which is also not free)</li>
<li>While it was not a _ton_ of work, it did take some sleuthing to get things finally working. I am assuming that this plugin is likely to no longer be actively supported, as (presumably) the CloudFoundry system effectively replaces it. Not a con exactly, but I think I would investigate what CloudFoundry has to offer before choosing this plugin as my definitive approach to getting an app into the Cloud.</li>
</ul>
<p>That&#8217;s it for now. The next post in the series will document the deploying our application to Google&#8217;s AppEngine, so check back often/subscribe!</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/amazon+ec2" rel="tag"> amazon ec2</a>, <a href="http://technorati.com/tag/cloud+computing" rel="tag"> cloud computing</a>, <a href="http://technorati.com/tag/grails" rel="tag"> grails</a>, <a href="http://technorati.com/tag/groovy" rel="tag"> groovy</a>, <a href="http://technorati.com/tag/java" rel="tag"> java</a>, <a href="http://technorati.com/tag/software+development" rel="tag"> software development</a></p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/uncategorized/grails-and-cloud-computing-part-1-amazon-ec/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Grails App in ~40 hrs (part 5)</title>
		<link>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-5/</link>
		<comments>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-5/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 17:13:43 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Groovy/Grails]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[agile software]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[grailsui plugin]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=281</guid>
		<description><![CDATA[Welcome back to our effort to build a Grails app in less than a week. This post will cover the final functional aspects of the application, after which we can move on to trying to deploy the app into a Cloud Computing platform. 
To recap briefly our progress to date:

Part 1: We introduce the basic [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome back to our effort to build a <a href="http://grails.org">Grails</a> app in less than a week. This post will cover the final functional aspects of the application, after which we can move on to trying to deploy the app into a Cloud Computing platform. </p>
<p>To recap briefly our progress to date:</p>
<ul>
<li><a href="http://alterlabs.com/general/articles/what-can-you-build-in-40-hours/">Part 1</a>: We introduce the basic challenge: Build a non-trivial app in about 40hours.</li>
<li><a href="http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/">Part 2</a>: We talk about the basic app concept.. a todo list manager called (cleverly) twodo. We have decided on the general technical framework (Grails, etc)</li>
<li><a href="http://alterlabs.com/technologies/java/grails-task-management-app-part-3/">Part 3</a>: The first &#8216;technical&#8217; post. JSecurity setup, initial Domain object created.</li>
<li><a href="http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-4/">Part 4</a>: The UI is refined, and we start using the GrailsUI plugin to populate a YUI DataTable via AJAX.</li>
</ul>
<p>So, although this post it titled #5, its really only the third technical post. In the last post we made our UI a bit more pleasing (or at least more intentional), and introduced the <a href="http://grails.org/plugin/grails-ui">GrailsUI plugin</a> into the mix for purposes of using AJAX to dynamically update a <a href="http://developer.yahoo.com/yui/datatable/">YUI DataTable</a>. In this post we will put the finishing touches on the core application, which primarily involves getting the GrailsUI <em>DataTable</em> to work the way we want to.<br />
<span id="more-281"></span><br />
This post will be a bit on the long side, because I want to finish up the core application so the next couple of posts can deal with deploying the <em>twodo</em> application into a Computing Cloud like Google&#8217;s <em>AppEngine</em> or <em>Amazon&#8217;s EC2</em>.</p>
<h3>DataTable and Cell Editing</h3>
<p>In the last post we populated a single simple YUI data table with test data using the <em>GrailsUI</em>, and it did exactly what we asked of it. However, our current implementation produced a simple <em>read-only</em> table. I envisioned using a DataTable construct to not only display the data, but to allow the user to dynamically update it via AJAX&#8211; sorta like an online spread sheet type application (in a similar fashion to the YUI example provided <a href="http://developer.yahoo.com/yui/examples/datatable/dt_cellediting_clean.html">here</a>.)</p>
<p>To this end, I initially installed the latest (v1.0.4) version of the plugin as per standard instructions, and it worked fine for our initial tests&#8211; however, it <strong>did not</strong> allow for the editing of the table cells. As it turns out this is a known limitation of the current stable version of the plugin. So now what? Well, <a href="http://www.entertonement.com/clips/cvdcmysyvq--Internet-machineWill-Ferrell-Blades-of-Glory-Chazz-Michael-Michaels-">working The Google On The Internet Machine</a> revealed that the 1.1-SNAPSHOT has <a href="http://weblog.dangertree.net/2009/01/29/upcoming-grails-ui-11-new-features-datatable-inline-cell-editing/">inline cell editing capabilities</a> so I downloaded the 1.1-SNAPSHOT version from the plugin <a href="http://plugins.grails.org/grails-grails-ui/branches/RELEASE-1.1-SNAPSHOT/">site</a> and installed it from my local drive (<em>grails install-plugin /path/to/download/grails-grails-ui-1.1-SNAPSHOT.zip</em>)</p>
<p>Recall that in the last post we used the<code> gui:datatable</code> tag to construct a simple DataTable like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>gui:dataTable id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dt_1&quot;</span>
    columnDefs<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[
        [id:'ID', formatter:'text', hidden:true],
        [status:'Status', formatter:'text'],
        [description:'Description', formatter:'text'],
        [est:'Est', formatter:'text'],
    ]&quot;</span>
...
/<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>The snapshot version of the tag supports additional <code>editor</code> configuration parameter to be passed along as part of the <code>columnDefs</code>, that allow for the specification of an AJAX target to be called when the cell is edited. Lets take a few baby steps and modify the <em>&#8217;subscription&#8217;</em> column to allow for editing:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>gui:dataTable id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dt_1&quot;</span>
    columnDefs<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[</span>
<span style="color: #ff0000;">      [id:'ID', formatter:'text', hidden:true],</span>
<span style="color: #ff0000;">      [status:'Status', formatter:'text'],</span>
<span style="color: #ff0000;">      [description:'Description', formatter:'text',</span>
<span style="display:block;background-color: #ffc;"><span style="color: #ff0000;">        editor:[controller:'home', action:'tableChange']],</span></span><span style="color: #ff0000;">      [est:'Est', formatter:'text'],</span>
<span style="color: #ff0000;">    ]&quot;</span>
...
/<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>Note the additional code on <strong>line 6</strong> where we indicate that changes to a cell in the &#8216;<em>description</em>&#8216; column are to be handled by making an AJAX call to the &#8216;<em>tableChange</em>&#8216; action in the &#8216;<em>home</em>&#8216; controller.  Let&#8217;s point our browser at the page (<em>http://localhost:8080/blogtwodo/home/datatable</em>), and see what happens when we try to edit a cell in the <em>description</em> column.</p>
<div id="attachment_355" class="wp-caption alignnone" style="width: 310px"><br />
<a href="http://alterlabs.com/wp-content/uploads/2009/08/Picture-22.png"><img class="alignnone size-medium wp-image-355" title="Cell Editing" src="http://alterlabs.com/wp-content/uploads/2009/08/Picture-22-300x164.png" alt="Cell Editing" width="300" height="164" /></a><p class="wp-caption-text">click to enlarge</p></div>
<p>OK. As the screen shot above indicates, when we click the cell to edit it, some JavaScript automagically renders a little dialog box for us with some basic editing options. Perfect.</p>
<p>But when we continue and try to actually change the value of the cell and save it by clicking on the &#8216;Save&#8217; button, we get the following ugly error message: </p>
<div id="attachment_356" class="wp-caption alignnone" style="width: 310px"><br />
<a href="http://alterlabs.com/wp-content/uploads/2009/08/Error.png"><img class="alignnone size-medium wp-image-359" title="Error" src="http://alterlabs.com/wp-content/uploads/2009/08/Error-300x269.png" alt="Error" width="300" height="269" /></a><p class="wp-caption-text">click to enlarge</p></div>
<p>Hey! Whats with the error?  Well, the <em>DataTable</em> is attempting to make an AJAX call to the <code>tableChange</code> action&#8211; which does not exist yet. So let&#8217;s remedy that right now:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
<span style="color: #000000; font-weight: bold;">class</span> HomeController <span style="color: #66cc66;">&#123;</span>
  ...
  <span style="color: #808080; font-style: italic;">/**
    * AJAX Call
    */</span>
  <span style="color: #000000; font-weight: bold;">def</span> tableChange <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">// TODO: Verify that this task belong to the current user!</span>
    <span style="color: #000000; font-weight: bold;">def</span> task <span style="color: #66cc66;">=</span> Task.<span style="color: #663399;">get</span><span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">id</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span> params.<span style="color: #006600;">field</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">'description'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      task.<span style="color: #006600;">description</span> <span style="color: #66cc66;">=</span> params.<span style="color: #006600;">newValue</span>
      task.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span>
    render <span style="color: #ff0000;">&quot;table changed&quot;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Our initial cut at the <code>tableChange</code> method is about as straight forward as it gets.  We load the <em>Task</em> by <em>id</em> (without even checking to see if it belongs to our user! Yikes) and save the new value.  Simply reloading our home page after saving verifies that our changes to the description field were indeed saved.  </p>
<div class="strongpoint">
As can be seen by examining our controller logic above, the <em>DataTable</em> control passes us useful information as part of the request parameters back to the action.  The <code>params.id</code>, <code>params.newValue</code> and the <code>params.field</code> parameters are send along as part of the request.  These parameters are &#8216;hardcoded&#8217; by the GrailsUI Plugin.  I don&#8217;t recall finding this anywhere in the documentation, but viewing the source of the rendered page reveals it obviously enough.  It&#8217;s also mentioned in <a href="http://jira.codehaus.org/browse/GRAILSPLUGINS-583">this JIRA entry</a>.
</div>
<p>Now that we have the basic approach down, we can use what we have learned as a basis for constructing the real code that will be used to manipulate the two task lists in the application.<br />
We can now add the additional configuration to provide editing for the other columns in the <em>DataTable</em>, as well as corresponding logic in the controller to handle the updates, like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>gui:dataTable id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dt_1&quot;</span>
  columnDefs<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[</span>
<span style="color: #ff0000;">    [id:'ID', formatter:'text', hidden:true],</span>
<span style="color: #ff0000;">    [status:'Status', formatter:'text',</span>
<span style="color: #ff0000;">      editor:[controller:'home', action:'tableChange', </span>
<span style="display:block;background-color: #ffc;"><span style="color: #ff0000;">        type:'dropdown', config:[dropdownOptions:['open','complete','delete'],disableBtns:true]]],</span></span><span style="color: #ff0000;">    [description:'Description', formatter:'text',</span>
<span style="color: #ff0000;">      editor:[controller:'home', action:'tableChange']],</span>
<span style="color: #ff0000;">    [est:'Est', formatter:'text',</span>
<span style="color: #ff0000;">      editor:[controller:'home', action:'tableChange']],</span>
<span style="color: #ff0000;">  ]&quot;</span>
...
/<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>Notice that in addition to the basic cell editing, we also specify a bunch of other nifty options to the to the <code>g:datatable</code> control that help customize the behavior of the editor.  On <strong>line 6</strong> we indicate that the <em>status</em> column is to use a dropdown list for editing (with the list values of &#8216;<em>open</em>&#8216;, &#8216;<em>closed</em>&#8216; and &#8216;<em>delete</em>&#8216;&#8211; we will use the &#8216;delete&#8217; option later), and that the default save/cancel buttons are to be hidden. In the <code>tableChange</code> action we make the obvious/appropriate corresponding changes to handle the edits to the additional fields.</p>
<p>Up and until now we have been fooling around with the <em>DataTable</em> in a test page. We want the contents of our two task lists to be rendered as the users home page after they successfully log in, so its about time we reincorporate what we have learned back into the main application (<code>views/home/index.gsp</code>) Taking the sample code above and embellishing it a bit with CSS gets us something like this:</p>
<div id="attachment_357" class="wp-caption alignnone" style="width: 310px"><br />
<a href="http://alterlabs.com/wp-content/uploads/2009/09/both.png"><img src="http://alterlabs.com/wp-content/uploads/2009/09/both-300x210.png" alt="both" title="both" width="300" height="210" class="alignnone size-medium wp-image-398" /></a><p class="wp-caption-text">click to enlarge</p></div>
<p>So we have basic editing, but its still lacking a few fundamentals&#8211; notably callback notification on success/failure of the edit.  We will address that in a bit below&#8230;</p>
<h3>Adding Rows</h3>
<p>So far all of the data we have been manipulating had been manually added as fixture data in the last post. Obviously a task management application needs a way to add new tasks so lets tackle that now.</p>
<p>Normally adding a new Task in a conventional non-AJAX fashion is trivial. (Actually, come to think of it, the standard Grails taglibs make using AJAX pretty trivial as well.)</p>
<p>However, accomplishing the same thing using AJAX <strong>and</strong> our DataTable, however, proves to be a tad bit trickier.  Lets start again with baby steps and (reasonably) add a <code>g:remoteForm</code> at the bottom of our Work tasks list that submits via AJAX to an action in the home controller (once we figure it out for the Work tasks, we can replicate it for the Personal)</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>g:formRemote name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;worktask_form&quot;</span> onSuccess<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;alert('Success!')&quot;</span> 
        url<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[action:'addRow',params: [ taskType:'work']]&quot;</span><span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>input type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;newTask&quot;</span> id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;newTask&quot;</span>/<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>button type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span><span style="color: #66cc66;">&gt;</span>Add<span style="color: #66cc66;">&lt;</span>/button<span style="color: #66cc66;">&gt;</span>  
<span style="color: #66cc66;">&lt;</span>/g:formRemote<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>We put a simple <code>alert()</code> in the <code>onSuccess</code> event to prove things are working. Exercising our code thru the browser gives us the alert message we expect, but our <em>DataTable</em> is not yet updated to show the new row. If we refresh the page, we see the new row, but that&#8217;s hardly sufficient.</p>
<p>The obvious solution is to register a callback function that in turn forcibly refreshes the <em>DataTable</em>. Surprisingly, (at least according to the hours I spent trying to get this aspect of the system to work,) the <em>YUI DataTable </em>possesses no such straightforward function.  The <em>GrailsUI DataTable Object</em> <em>does</em>, however, include a <code>requery()</code> function, which gets us 99% of the way there, so as a final resort I coded my own <code>refresh()</code> function based on this and extended the <em>YUI DataTable Object</em> by adding it to the javascript prototype:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Used to refesh our contents after a row change. </span>
<span style="color: #006600; font-style: italic;">// Basically a copy of requery() with a new Callback</span>
GRAILSUI.<span style="color: #660066;">DataTable</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">refresh</span> <span style="color: #339933;">=</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
  <span style="color: #006600; font-style: italic;">// NOTICE: This is what has changed from the requery() function</span>
  <span style="color: #003366; font-weight: bold;">var</span> oCallback <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
<span style="display:block;background-color: #ffc;">    success<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onDataReturnReplaceRows</span><span style="color: #339933;">,</span>  <span style="color: #006600; font-style: italic;">//&lt;&lt;- this line</span></span>    failure<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onDataReturnSetRows</span><span style="color: #339933;">,</span>        
    scope<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span>
    argument<span style="color: #339933;">:</span> newState 
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
...
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>We can then make our <code>onSuccess</code> callback invoke this new function, and test it out:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"> <span style="color: #66cc66;">&lt;</span>g:formRemote name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;worktask_form&quot;</span> onSuccess<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;GRAILSUI.dt_1.refresh();&quot;</span> 
         url<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[action:'addRow',params: [ taskType:'work']]&quot;</span><span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>This time, adding a new row refreshed our DataTable and the new row shows up in our list&#8211; which is awesome. </p>
<h3>Deleting Rows</h3>
<p>Now that we can add Tasks to our list, we need to also provide a mechanism for removing them.  Recall that we configured our dropdown list for the &#8216;<em>status</em>&#8216; column to allow the for three values: &#8216;<em>open</em>&#8216;, &#8216;<em>closed</em>&#8216; and &#8216;<em>delete</em>&#8216;.  The plan is to use a cell edit on the status column to trigger the deletion of the Task.  With that in mind I added the following code to the<code> tableChange</code> action (which is the action to be called during our cell edits):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
<span style="color: #000000; font-weight: bold;">class</span> HomeController <span style="color: #66cc66;">&#123;</span>
  ...
&nbsp;
 <span style="color: #000000; font-weight: bold;">def</span> tableChange <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">def</span> profileInstance <span style="color: #66cc66;">=</span> Profile.<span style="color: #006600;">current</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #000000; font-weight: bold;">def</span> task <span style="color: #66cc66;">=</span> Task.<span style="color: #663399;">get</span><span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">id</span><span style="color: #66cc66;">&#41;</span>
   ...
   <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span> params.<span style="color: #006600;">field</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">'status'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
     <span style="color: #b1b100;">switch</span> <span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">newValue</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
       <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'open'</span>: 
         task.<span style="color: #006600;">completionDate</span> <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">null</span>
         task.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #000000; font-weight: bold;">break</span>
       <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'closed'</span>: 
         task.<span style="color: #006600;">completionDate</span> <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #aaaadd; font-weight: bold;">Date</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
         task.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #000000; font-weight: bold;">break</span>
       <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'delete'</span>:
         <span style="color: #808080; font-style: italic;">// no easy way to tell what list it was from so remove from both</span>
         profileInstance.<span style="color: #006600;">removeFromWorkTasks</span><span style="color: #66cc66;">&#40;</span>task<span style="color: #66cc66;">&#41;</span>
         profileInstance.<span style="color: #006600;">removeFromPersonalTasks</span><span style="color: #66cc66;">&#40;</span>task<span style="color: #66cc66;">&#41;</span>
         profileInstance.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #993399;">println</span> <span style="color: #ff0000;">&quot;*** Deleted task ${task}&quot;</span>
         <span style="color: #000000; font-weight: bold;">break</span>
     <span style="color: #66cc66;">&#125;</span> 
   <span style="color: #66cc66;">&#125;</span>
...
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<div class="strongpoint">
Why do we call both <code>removeFromWorkTasks()</code> <strong>AND</strong> <code>removeFromPersonalTask()</code> (<strong>lines 19</strong> and <strong>20</strong>)? Currently there is no simple way to tell which list our Task belonged to, so we swing a heavy hammer and delete from both Task lists to cover our bases.
</div>
<p>When we change our status column to &#8216;<em>delete</em>&#8216;  we see a rewarding message in the console, but our <em>DataTable</em> does not update to show any change. We have to refresh the page for the <em>DataTable</em> to show an updated list.  Why? For that we move to the next section&#8230;.</p>
<h3>Custom GrailsUI DataTable Changes</h3>
<p>One thing that became quickly obvious was that as great as the GrailsUI plugin is, it still lacking in a few areas. Notably there is no mechanism for notifying the UI of a successful cell edit. This is not a big deal when we are simply editing the contents of an existing row (because our browser screen is naturally kept in sync)&#8230; but it becomes a definite issue when removing a row from the DataTable.</p>
<p>What we need is the ability to register a callback with underlying YUI structures of a function to be called after a DataTable cell edit. If we view the browser page source and look at the underlying javascript that the <code>g:dataTable</code> tag generates for us we can see what is up:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">... 
<span style="color: #003366; font-weight: bold;">var</span> registerEditorListener <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>editor<span style="color: #339933;">,</span> field<span style="color: #339933;">,</span> url<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  GRAILSUI.<span style="color: #660066;">dt_1</span>.<span style="color: #660066;">loadingDialog</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> editorCallback <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
<span style="display:block;background-color: #ffc;">    failure<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></span>      <span style="color: #006600; font-style: italic;">// revert the cell value</span>
      GRAILSUI.<span style="color: #660066;">dt_1</span>.<span style="color: #660066;">updateCell</span><span style="color: #009900;">&#40;</span>oArgs.<span style="color: #660066;">editor</span>.<span style="color: #660066;">getRecord</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> field<span style="color: #339933;">,</span> oArgs.<span style="color: #660066;">oldData</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #006600; font-style: italic;">// alert user</span>
      <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Recieved an error during edit: '</span> <span style="color: #339933;">+</span> o.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
   YAHOO.<span style="color: #660066;">util</span>.<span style="color: #660066;">Connect</span>.<span style="color: #660066;">asyncRequest</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> editorCallback<span style="color: #339933;">,</span> <span style="color: #3366CC;">'id='</span> <span style="color: #339933;">+</span> oArgs.<span style="color: #660066;">editor</span>.<span style="color: #660066;">getRecord</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&amp;field='</span> <span style="color: #339933;">+</span> field <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&amp;newValue='</span> <span style="color: #339933;">+</span> oArgs.<span style="color: #660066;">newData</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>From the code above we can see that the taglib creates a <code>registerEditorListener</code> function, and does indeed define a callback to be registered with the AJAX call. <strong>BUT</strong> it only defines what to do in case of a failure (<strong>line 5</strong>) and <strong>not</strong> what to do in cases of success. Knowing this, its easy enough to tweak the <code>grails-app/taglib/DataTableTagLib.groovy</code> file included in the GrailsUI plugin project to allow for us to pass in as part of the <code>g:dataTable</code> configuration a callback to use for cell editing.  After tweaking, our augmented taglib generates something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">...
<span style="color: #003366; font-weight: bold;">var</span> editorCallback <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#123;</span>editorSuccessCallback<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
  failure<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    ... 
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#8230;and we simply add the <code>editorSuccessCallback</code> parameter to our g:dataTable configuration data:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>gui:dataTable id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dt_1&quot;</span>
  ...  
  <span style="color: #006600;">editorSuccessCallback</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;GRAILSUI.dt_1.refresh();&quot;</span>
  ..
<span style="color: #66cc66;">&#93;</span><span style="color: #ff0000;">&quot;/&gt;</span></pre></td></tr></table></div>

<p>Now anytime we perform any successful cell edit (including deletes) , the <code>DataTable.refresh()</code> function is invoked and our table is rendered accurately.  Killer.</p>
<h3>Conclusion and Next Steps</h3>
<p>Fundamentally the application is now functionally complete. There was plenty of mundane polishing and such that was not documented in this series, but all of  the big stuff was touched upon.</p>
<p>The work accomplished in todays posts took a little over 20 hours to complete&#8230; the majority of the time split evenly between exploring the GrailsUI TagLib code trying to make the refresh work and tweaking CSS (which <em>always</em> seems to take more time than expected.)  That brings our total time spent todate to about 30 hours.</p>
<p>The next post will (finally!) talk about deploying the twodo application into Amazon&#8217;s Elastic Compute Cloud (EC2).  See you soon&#8230;</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/agile" rel="tag"> agile</a>, <a href="http://technorati.com/tag/grails" rel="tag"> grails</a>, <a href="http://technorati.com/tag/groovy" rel="tag"> groovy</a>, <a href="http://technorati.com/tag/grailsui" rel="tag"> grailsui</a>, <a href="http://technorati.com/tag/java" rel="tag"> java</a>, <a href="http://technorati.com/tag/software+development" rel="tag"> software development</a></p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-5/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Grails App in ~40 hrs (part 4)</title>
		<link>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-4/</link>
		<comments>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-4/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 15:03:56 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Groovy/Grails]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[grailsui plugin]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=222</guid>
		<description><![CDATA[The last post covered the kickoff to the &#8216;twodo&#8216; application&#8211; where we created our Grails application, wired in JSecurity via plugin, and created a few of the core Domain objects the system will need.
In this post we will refine the general look and feel of the User Interface, as well as start building the core [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://alterlabs.com/technologies/java/grails-task-management-app-part-3/">last post</a> covered the kickoff to the &#8216;<em>twodo</em>&#8216; application&#8211; where we created our <em>Grails</em> application, wired in <em>JSecurity</em> via plugin, and created a few of the core <em>Domain</em> objects the system will need.</p>
<p>In this post we will refine the general look and feel of the User Interface, as well as start building the core list management functionality via a UI Plugin.<br />
<span id="more-222"></span></p>
<h3>Look and Feel</h3>
<p>To this point we have done almost no UI creation, and have not customized the default out-of-the-box look and feel of the application.  I knew from talking to the stakeholder (in this case my business partner) that he envisioned a simple/clean interface with little clutter. The general site template was envisioned to look something like this:</p>
<p><img src="http://alterlabs.com/wp-content/uploads/2009/08/layout-300x204.jpg" alt="layout" title="layout" width="300" height="204" class="alignnone size-medium wp-image-322" /></p>
<p>Under the assumption that the look and feel, would (like all other aspects of the app) continue to evolve over the course of the development iterations, I did not want to spend <em>too</em> much time on polishing the initial cut at the UI template.  I started with a simple raw HTML/CSS template, a bit of time in <a href="http://www.gimp.org/">The Gimp</a> and some CSS tweaking via <a href="http://getfirebug.com/">Firebug</a> until I got something that seemed initially acceptable. I added in some greeting text and voila&#8211; comparing the original/old login screen:</p>
<p><img src="http://alterlabs.com/wp-content/uploads/2009/08/Picture-1-300x216.png" alt="Crude Login Screen" title="Crude Login Screen" width="300" height="216" class="size-medium wp-image-189" /></p>
<p>&#8230;and the new one:<br />
<img src="http://alterlabs.com/wp-content/uploads/2009/08/Picture-11-300x205.png" alt="Picture 1" title="Picture 1" width="300" height="205" class="alignright size-medium wp-image-257" /></p>
<p>OK. Still not award winning perhaps, but at least it looks intentional. </p>
<div class="strongpoint">Its worth noting that the fancy rounded borders around the login/register boxes were <strong>quickly</strong> done using <a href="http://www.css3.info/preview/rounded-border/">CSS3 tags</a>. If the stakeholder likes the look, we can make something more permanent/portable. If they dont like it, we have not spent a load of time on something that gets thrown away</div>
<p>I don&#8217;t profess to be much an artist when it comes to web pages, and don&#8217;t intend to turn this post into a treatise on web design, but I think its worth peeking at the main <code>views/layout/main.gsp</code> layout file used for this project:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
   <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>title<span style="color: #66cc66;">&gt;&lt;</span>g:layoutTitle <span style="color: #000000; font-weight: bold;">default</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;TwoDo&quot;</span> /<span style="color: #66cc66;">&gt;&lt;</span>/title<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>link rel<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${createLinkTo(dir:'css',file:'template_css.css')}&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>/<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>link rel<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${createLinkTo(dir:'css',file:'main.css')}&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>/<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>link rel<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;shortcut icon&quot;</span> href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${resource(dir:'images',file:'favicon.ico')}&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;image/x-icon&quot;</span> /<span style="color: #66cc66;">&gt;</span>
&nbsp;
        <span style="color: #66cc66;">&lt;</span>g:javascript library<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;application&quot;</span> /<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>g:layoutHead /<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>/head<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>body<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>g:render template<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/layouts/includes/logo&quot;</span>/<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;page&quot;</span><span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;page-bg&quot;</span><span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>g:render template<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/layouts/includes/messages&quot;</span>/<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;</span>g:render template<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/layouts/includes/errors&quot;</span>/<span style="color: #66cc66;">&gt;</span>
&nbsp;
        <span style="color: #66cc66;">&lt;!--</span> <span style="color: #993399;">start</span> content <span style="color: #66cc66;">--&gt;</span>
        <span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #66cc66;">&gt;</span>
          <span style="color: #66cc66;">&lt;</span>g:layoutBody/<span style="color: #66cc66;">&gt;</span> 
        <span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
        <span style="color: #66cc66;">&lt;!--</span> end content <span style="color: #66cc66;">--&gt;</span>
        <span style="color: #66cc66;">&lt;</span>div style<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;clear:both;&quot;</span><span style="color: #66cc66;">&gt;&amp;</span>nbsp<span style="color: #66cc66;">;&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>g:render template<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/layouts/includes/footer&quot;</span>/<span style="color: #66cc66;">&gt;</span>
 <span style="color: #66cc66;">&lt;</span>/body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/html<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>The main thing that is worth noting is that for every major rectangular region of the main template (as indicated on the napkin) we have further subdivided the layout into smaller templates which are then rendered from within main layout via the  <a href="http://grails.org/doc/latest/ref/Tags/render.html">g:render</a> taglib.  As an example, we examine a few of the templates below.</p>
<p>Here is the <code>layouts/includes/_logo.gsp</code> template, which has been configured to:</p>
<ul>
<li>Show a simple text logo. We will eventually replace this with a graphic</li>
<li>Display a greeting for the logged in user.</li>
<li>Provide a logout link</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;logo&quot;</span><span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;&lt;</span>a href<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${resource(dir:'')}&quot;</span><span style="color: #66cc66;">&gt;</span>TwoDo<span style="color: #66cc66;">!&lt;</span>/a<span style="color: #66cc66;">&gt;&lt;</span>/h1<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>jsec:isLoggedIn<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;greeting&quot;</span> <span style="color: #66cc66;">&gt;</span>
    Hello,<span style="color: #66cc66;">&lt;</span>jsec:principal/<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&lt;</span>g:link controller<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;auth&quot;</span> action<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;signOut&quot;</span><span style="color: #66cc66;">&gt;</span>logout<span style="color: #66cc66;">&lt;</span>/g:link<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&lt;</span>/span<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/jsec:isLoggedIn<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>And finally, a look at the <code>layouts/includes/_messages.gsp</code> which includes logic for the rendering of flash messages in a consistent manner:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;message_wrapper&quot;</span> <span style="color: #66cc66;">&lt;</span>g:<span style="color: #b1b100;">if</span> test<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${!flash.message}&quot;</span><span style="color: #66cc66;">&gt;</span> style<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none;&quot;</span><span style="color: #66cc66;">&lt;</span>/g:if<span style="color: #66cc66;">&gt;&gt;</span>
  <span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;messageBar&quot;</span> <span style="color: #66cc66;">&lt;</span>g:<span style="color: #b1b100;">if</span> test<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${!flash.message}&quot;</span><span style="color: #66cc66;">&gt;</span>style<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none;&quot;</span><span style="color: #66cc66;">&lt;</span>/g:if<span style="color: #66cc66;">&gt;&gt;</span>$<span style="color: #66cc66;">&#123;</span>flash.<span style="color: #006600;">message</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>This divide-and-conquer strategy makes sense in many things software related, and the case of layout templates is no exception.</p>
<h3>Security and Profile Management</h3>
<p>It quickly becomes apparent that we require a mechanism for retrieving the current users <code>Profile</code> after a successful login. <em>JSecurity</em> provides a <code>SecurityUtil</code> class with a method that allows us to get the currently logged in <a href="http://www.jsecurity.org/api/org/jsecurity/subject/Subject.html">Subject</a>. From there we can get the <a href="http://www.jsecurity.org/api/org/jsecurity/subject/Subject.html#getPrincipal%28%29">Principle</a>, and from the <code>Principle</code> we can get the <code>Profile</code>.  I found it convenient to implement this logic in a pseudo-GORM like fashion by simply adding a static method to the existing <code>Profile</code> class:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;">...
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.jsecurity.SecurityUtils</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Profile <span style="color: #000000; font-weight: bold;">extends</span> Base <span style="color: #66cc66;">&#123;</span>
  ...
  <span style="color: #808080; font-style: italic;">/**
    * Return the profile associated with the currently logged in user
    */</span>
  <span style="color: #000000; font-weight: bold;">static</span> Profile current<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">def</span> principle <span style="color: #66cc66;">=</span> SecurityUtils.<span style="color: #006600;">getSubject</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">getPrincipal</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">return</span> Profile.<span style="color: #006600;">findByUsername</span><span style="color: #66cc66;">&#40;</span> principle <span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>Our controllers/whatever now simply need to call <code>Profile.current()</code> to get the currently logged in user.</p>
<h3>GrailsUI Plugin</h3>
<p>As per our <a href="http://alterlabs.com/technologies/java/grails-task-management-app-part-3#sitemap">sitemap</a> in the last post, we only have a handful of pages in the entire application. Once a user logs in, they will be at their home (<code>views/home/index.gsp</code>) page, which will display their current list of tasks side by side. The manipulations of these lists seemed a prime candidate for some fancy UI and AJAXy goodness. In particular I envisioned a dynamic table that would use AJAX to manipulate the contents of the task lists.  Rather than roll it all from scratch we will enlist the help of a the <a href="http://developer.yahoo.com/yui/">Yahoo UI libraries</a> by way of the <a href="http://grails.org/plugin/grails-ui">GrailsUI plugin</a>.  I had used the YUI library on prior projects and, wanting  to maximize my productivity, so chose it over other competing frameworks (jQuery, etc.)</p>
<p>The GrailsUI plugin basically provides us with a wrapper taglib that encapsulates the underlying YUI javascript.  In particular we are interested in the <code>gui:dataTable</code> tag, which wraps a <a href="http://developer.yahoo.com/yui/datatable/">YUI DataTable Control.</a> Installing the GrailsUI Plugin automagically installs its YUI dependencies.</p>
<p>Before we tackle using the taglib/control however, lets look ahead, and address our data testing needs.</p>
<p>From reading the associated documentation, I knew that our GrailsUI DataTable was eventually going be populated by an AJAX call that will return its data in <a href="http://www.json.org/">JSON</a> format&#8211; which is all well and good.  So the first order of business was to create some fixture data with which to test. To this end I added a simple action to the default <em>Task</em> controller we generated in the last post to create a few tasks for purposes of testing:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> TaskController <span style="color: #66cc66;">&#123;</span>
...
  <span style="color: #000000; font-weight: bold;">def</span> data <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">def</span> p <span style="color: #66cc66;">=</span> Profile.<span style="color: #006600;">current</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span> i <span style="color: #b1b100;">in</span> 0..5 <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      p.<span style="color: #006600;">addToWorkTasks</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Task<span style="color: #66cc66;">&#40;</span>description:<span style="color: #ff0000;">&quot;Work Task #${i}&quot;</span>, estimate:<span style="color: #cc66cc;">60</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      p.<span style="color: #006600;">addToPersonalTasks</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Task<span style="color: #66cc66;">&#40;</span>description:<span style="color: #ff0000;">&quot;Personal Task #${i}&quot;</span>, estimate:<span style="color: #cc66cc;">60</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span> 
    flash.<span style="color: #006600;">message</span> <span style="color: #66cc66;">=</span> p.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">?</span><span style="color: #ff0000;">&quot;Added fake tasks to profile&quot;</span>:<span style="color: #ff0000;">&quot;Failed to add fake tasks&quot;</span>
    redirect<span style="color: #66cc66;">&#40;</span>action:list<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
...
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>The code above grabs the <code>Profile</code> of the current user then creates and associates some dummy <code>Tasks</code> with it.  Pointing our browser at <em>http://localhost:8080/blogtwodo/task/data</em> invokes the action and allows us to visually verify the data by listing all the Tasks in the system.</p>
<p>OK. Now that we have some data, lets work on making a <em>DataTable</em> retrieve it via AJAX. The plugin <a href="http://grails.org/plugin/grails-ui">home page</a> has some helpful information about using the <em>DataTable</em>, as does the authors <a href="http://weblog.dangertree.net/2008/11/02/using-grailsui-datatable-tag/">blog</a>. As per usual I started with a crude test to work the kinks out, with the assumption that it could be suitably refined later.  By following the examples provided in the plugin documentation I quickly put together a simple test page that looked like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>gui:resources components<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;['dataTable']&quot;</span> /<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>meta http<span style="color: #66cc66;">-</span>equiv<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> content<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> /<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>meta name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;layout&quot;</span> content<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;main&quot;</span> /<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>title<span style="color: #66cc66;">&gt;</span>DataTable Test<span style="color: #66cc66;">&lt;</span>/title<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>/head<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>body<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>div<span style="color: #66cc66;">&gt;</span>  
      <span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;</span>Work DataTable:<span style="color: #66cc66;">&lt;</span>/h1<span style="color: #66cc66;">&gt;</span> 
      <span style="color: #66cc66;">&lt;</span>gui:dataTable id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dt_1&quot;</span>
         columnDefs<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[
            [id:'ID', formatter:'text', hidden:true],
            [status:'Status', formatter:'text'],
            [description:'Description', formatter:'text'],
            [est:'Est', formatter:'text'],
         ]&quot;</span>
         sortedBy<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;id&quot;</span>
         allowExclusiveSort<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'true'</span>
         draggableColumns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;false&quot;</span>
         controller<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;home&quot;</span> action<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tasks&quot;</span> params<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[taskType:'work']&quot;</span>
         rowsPerPage<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;10&quot;</span> 
         paginatorConfig<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;[
             template:'{PreviousPageLink} {NextPageLink} {CurrentPageReport}',
             pageReportTemplate:'{totalRecords} total records'
         ]&quot;</span>/<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>/body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/html<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>In a nutshell, the above code:</p>
<ol>
<li>Includes the resources for the <em>GrailsUI DataTable</em> (line:3)</li>
<li>Makes a <em>DataTable</em> with 4 columns (&#8216;id&#8217;, &#8217;status&#8217;, &#8216;description&#8217; and &#8216;est&#8217;). (lines:11-17)</li>
<li><strong>Note</strong>: The &#8216;id&#8217; column is strictly for sorting purposes and we don&#8217;t want it shown on the screen, so we mark it as &#8216;hidden&#8217;. (line:13)</li>
<li>Wires the <em>DataTable</em> to populate itself from the action &#8216;<em>tasks</em>&#8216; on the &#8216;<em>home</em>&#8216; controller and also passes the parameter <em>taskType</em> set to &#8216;<em>work</em>&#8216; (line:21)</li>
</ol>
<p>The other configuration attributes are reasonably self explanatory, or will get additional treatment in later posts. The <em>g:dataTable</em> tag does all the (considerable) heavy lifting for us and imports all the UI javascript files, configures the underlying <a href="http://developer.yahoo.com/yui/datasource/">YUI DataSource</a> and associated <a href="http://developer.yahoo.com/yui/datasource/#schemas">response schema</a>, as well as setting up various AJAX callbacks on our behalf.<strong> Great stuff.</strong></p>
<p>We have configured our datatable tag to point at a &#8216;<em>tasks</em>&#8216; action, so lets take a look at that now. Its pretty basic:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">grails.converters.JSON</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> HomeController <span style="color: #66cc66;">&#123;</span>
 ... 
  <span style="color: #000000; font-weight: bold;">def</span> tasks <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">def</span> list <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #808080; font-style: italic;">//</span>
    <span style="color: #808080; font-style: italic;">// Get the current user profile</span>
    <span style="color: #808080; font-style: italic;">// </span>
    <span style="color: #000000; font-weight: bold;">def</span> profileInstance <span style="color: #66cc66;">=</span> Profile.<span style="color: #006600;">current</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">def</span> tasks <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>params<span style="color: #66cc66;">?</span>.<span style="color: #006600;">taskType</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">'work'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">?</span>profileInstance.<span style="color: #006600;">workTasks</span>:profileInstance.<span style="color: #006600;">personalTasks</span>
&nbsp;
    tasks.<span style="color: #663399;">each</span> <span style="color: #66cc66;">&#123;</span>
       list <span style="color: #66cc66;">&lt;&lt;</span> <span style="color: #66cc66;">&#91;</span>
           id: it.<span style="color: #006600;">id</span>,
           status: it.<span style="color: #006600;">completionDate</span><span style="color: #66cc66;">?</span><span style="color: #ff0000;">&quot;done&quot;</span>:<span style="color: #ff0000;">&quot;front burner&quot;</span>,
           est: it.<span style="color: #006600;">estimate</span>,
           description: it.<span style="color: #006600;">description</span>,
       <span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">def</span> data <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>
      totalRecords: list.<span style="color: #663399;">size</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>,
      results: list
    <span style="color: #66cc66;">&#93;</span>
    render data <span style="color: #000000; font-weight: bold;">as</span> JSON
  <span style="color: #66cc66;">&#125;</span>
  ...
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>The GrailsUI DataTable expects its response schema to be fed to it in JSON format.  Our tasks action basically:</p>
<ol>
<li>Gets the current Profile the logged in user (line:11 )</li>
<li>Looks at the params to see which list of tasks to work on (line:12 )</li>
<li>Iterates over the task list, adding a map of the Task attributes to a list (lines:14-20</li>
<li>Create a Map that holds the new list, as well as the total number of records. This is required by the response schema (lines:22-25)</li>
<li>Render the Map as JSON back to our view (line:26)</li>
</ol>
<p>Pointing our browser to <em>http://localhost:8080/blogtwodo/home/datatable</em> should get us the following:<br />
<img src="http://alterlabs.com/wp-content/uploads/2009/08/Picture-12-300x167.png" alt="DataTable" title="DataTable" width="300" height="167" class="alignnone size-medium wp-image-307" /></p>
<p>OK, it may not look like much now, but it proves out the underpinnings. We will use it as a starting point, and continue to refine it in later posts.</p>
<div class="strongpoint">
<strong>ONE OTHER NOTE:</strong> Its mentioned in the GrailsUI documentation, but its worth mentioning again. If you want to make use of the default YUI CSS formatting (which we do) one needs to make sure that the HTML <code><body></code> tag belongs to the CSS class <code>yui-skin-sam</code>.  In our case this was added to the master layout file <code>views/layouts/main.gsp</code>
</div>
<h3>Next Steps</h3>
<p>Alright. That&#8217;s about it for this post. To recap we have:</p>
<ul>
<li>Established a candidate look and feel for our application, and have broken out layout in to modular templates</li>
<li>Provided a means to conveniently get the Profile of the currently logged in user.</li>
<li>Installed the GrailsUI plugin and used it to populate a crude DataTable via AJAX</li>
</ul>
<p>The above took about 1/2 a day, or 5 hours or so to make happen (most of which was spent wrangling with HTML &#038; CSS,) which puts our running total of ~7 hours spent so far with ~33 remaining in the kitty.</p>
<p>In the next post we will continue to refine the overall UI and get our <em>DataTable</em> control to allow cell editing of our tasks. See you then!</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/agile" rel="tag"> agile</a>, <a href="http://technorati.com/tag/grails" rel="tag"> grails</a>, <a href="http://technorati.com/tag/groovy" rel="tag"> groovy</a>, <a href="http://technorati.com/tag/grailsui" rel="tag"> grailsui</a>, <a href="http://technorati.com/tag/java" rel="tag"> java</a>, <a href="http://technorati.com/tag/software+development" rel="tag"> software development</a></p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/technologies/java/grails-app-in-40-hrs-part-4/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Building a Grails App in ~40 hrs (part 3)</title>
		<link>http://alterlabs.com/technologies/java/grails-task-management-app-part-3/</link>
		<comments>http://alterlabs.com/technologies/java/grails-task-management-app-part-3/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 15:06:47 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Groovy/Grails]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[agile software]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jsecurity]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=139</guid>
		<description><![CDATA[In part 1 and part 2 of this series we introduced a challenge to build a reasonably non-trivial application in just  a week.  We have decided on Grails as the primary technology framework, and once we have a prototype working, we hope to deploy it to a cloud computing platform like Google&#8217;s AppEngine [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://alterlabs.com/general/articles/what-can-you-build-in-40-hours/">part 1</a> and<a href="http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/"> part 2</a> of this series we introduced a challenge to build a reasonably non-trivial application in just  a week.  We have decided on <a href="http://grails.org">Grails</a> as the primary technology framework, and once we have a prototype working, we hope to deploy it to a cloud computing platform like Google&#8217;s <a href="http://code.google.com/appengine/">AppEngine</a> or Amazon&#8217;s <a href="http://aws.amazon.com/ec2/">Elastic Compute Cloud (EC2)</a>.</p>
<p>This longish post will primarily concern itself with some initial setup and design and the inclusion and integration of <a href="http://www.jsecurity.org/">JSecurity</a> into our application.<br />
<span id="more-139"></span></p>
<h3>The Vision</h3>
<p>We know that our application is going to be a simple task management system called &#8216;<em>twodo</em>&#8216;&#8211; the intent of which is to allow the user to balance their work to-do&#8217;s with their personal to-do&#8217;s.</p>
<p>When my partner (aka Stakeholder) and I were discussing the application, he drew a simple diagram on a napkin that showed two lists presented side-by-side, the leftmost list for work tasks and the rightmost list for personal tasks.  This seemed as good of a place to start with regard to general design, and this simple vision drove much of the basic site layout and internal constructs.</p>
<p>After a few minutes of noodling, the following simple high-level <a name="sitemap">sitemap</a> emerged and seemed reasonable:<br />
<img class="alignnone size-medium wp-image-208" title="map" src="http://alterlabs.com/wp-content/uploads/2009/08/map-300x143.jpg" alt="map" width="300" height="143" /></p>
<h3>Basic Setup</h3>
<p>I created a new project (<em>grails create-app blogtwodo</em>) and configured my <code>conf/DataSource.groovy</code> to point at a locally running MySql instance with a newly created/empty &#8216;twodo&#8217; database.</p>
<h3>Basic Domain Model</h3>
<p>As stated above, the basic function of the app is to manage two sets of task lists&#8211; one list for work, and one list for personal tasks.  To this end I created a <code>Profile</code> domain class and a <code>Task</code> domain class.</p>
<p>The <code>Profile</code> will represent a registered user within the system, and will contain the account information and some basic configuration settings. The <code>Profile</code> will also hold a reference to the lists of <code>Tasks</code>, one list for each task type.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Profile <span style="color: #000000; font-weight: bold;">extends</span> Base <span style="color: #66cc66;">&#123;</span>
  <span style="color: #aaaadd; font-weight: bold;">String</span> username
  <span style="color: #aaaadd; font-weight: bold;">String</span> email
  <span style="color: #aaaadd; font-weight: bold;">String</span> firstName
  <span style="color: #aaaadd; font-weight: bold;">String</span> lastName
&nbsp;
  <span style="color: #993333;">int</span>  hoursInWorkWeek <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">40</span>
  <span style="color: #993333;">int</span>  hoursInPersonalWeek <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">10</span>  
&nbsp;
  <span style="color: #000000; font-weight: bold;">static</span> hasMany <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>workTasks:Task, personalTasks:Task<span style="color: #66cc66;">&#93;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">static</span> constraints <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
    username<span style="color: #66cc66;">&#40;</span>unique:<span style="color: #000000; font-weight: bold;">true</span>, <span style="color: #663399;">size</span>:5..15<span style="color: #66cc66;">&#41;</span>
    email<span style="color: #66cc66;">&#40;</span>email:<span style="color: #000000; font-weight: bold;">true</span>,nullable:<span style="color: #000000; font-weight: bold;">false</span>,blank:<span style="color: #000000; font-weight: bold;">false</span>,unique:<span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>
    firstName<span style="color: #66cc66;">&#40;</span>nullable:<span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>
    lastName<span style="color: #66cc66;">&#40;</span>nullable:<span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Similarly the <code>Task</code> class holds the task details, as well as a reference back to its parent <code>Profile</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Task <span style="color: #000000; font-weight: bold;">extends</span> Base <span style="color: #66cc66;">&#123;</span>
  <span style="color: #aaaadd; font-weight: bold;">String</span> description
  <span style="color: #aaaadd; font-weight: bold;">Date</span> completionDate
  <span style="color: #993333;">int</span>  estimate <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>  <span style="color: #808080; font-style: italic;">// minutes to complete task</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">static</span> belongsTo <span style="color: #66cc66;">=</span> Profile
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>You may have noticed that the Task and Profile Domain classes inherit from a Base class. From past experience I have found it handy to have a simple Abstract Base Class from which all Domain classes inherit. For now we will use this Base class to enable <a href="http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html#5.5.1%20Events%20and%20Auto%20Timestamping">auto-timestamping</a> for our Domain classes:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> Base <span style="color: #66cc66;">&#123;</span>
  <span style="color: #aaaadd; font-weight: bold;">Date</span> dateCreated  <span style="color: #808080; font-style: italic;">// grails will auto timestamp</span>
  <span style="color: #aaaadd; font-weight: bold;">Date</span> lastUpdated  <span style="color: #808080; font-style: italic;">// grails will auto timestamp</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">static</span> constraints <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
     dateCreated<span style="color: #66cc66;">&#40;</span>editable:<span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>
     lastUpdated<span style="color: #66cc66;">&#40;</span>editable:<span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>I figured the above Domain objects were good enough to start with, and I could worry about constraints, etc. as the design progressed.  I used Grails to generate the controllers and scaffolding (<em>grails generate-all</em>), fired up the dev server and verified my efforts via the browser. Navigating to <em>http://localhost:8080/blogtwodo</em> presented me the expected default Grails welcome screen and listed the Controllers for my <code>Task</code> and <code>Profile</code> classes. (These generated CRUD interfaces are handy for initial testing and once the app progresses in functionality we can remove them.)</p>
<p>So far so good.</p>
<h3>Security Setup</h3>
<p>Our application does not have any exceptional security requirements&#8211; we want users to be able to able to start using the system with a minimum of fuss immediately after a simple registration process.  We won&#8217;t need any roles for this application&#8211; users are either anonymous, or registered. I have used the Grails <a href="http://grails.org/plugin/jsecurity">JSecurity Plugin</a> on past projects and knew it would be more than sufficient for our needs.</p>
<p>To get the ball rolling I followed the steps listed in the JSecurity <a href="http://www.grails.org/JSecurity+Plugin+-+Quick+Start">Quick Start Guide </a> to install the plugin and autogenerate some basic underlying constructs.</p>
<p>The quick start procedure creates a bunch of Jsec-prefixed Domain classes and an <code>AuthController</code> into the default package. I like things a bit more organized so I moved both the Domain classes and the Controller into a <code>com.alterlabs.sec</code> package.  As a result of moving these classes we also need to add an import statement to the generated <code>grails-app/realms/JsecDbRealm.groovy</code> file (<code>import com.alterlabs.sec.*</code>) so that it can find the various needed <em>JSecurity</em> objects at runtime.</p>
<p>As per the quick start guide I created a simple <code>conf/SecurityFilters.groovy</code> file. The following code requires authorization to access anything other than the (yet to be created) public controller:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">com.at.sec.*</span>
<span style="color: #000000; font-weight: bold;">class</span> SecurityFilters <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">def</span> filters <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #808080; font-style: italic;">// Ensure that all controllers and actions require an authenticated user,</span>
  <span style="color: #808080; font-style: italic;">// except for the &quot;public&quot; controller</span>
&nbsp;
    auth<span style="color: #66cc66;">&#40;</span>controller: <span style="color: #ff0000;">&quot;*&quot;</span>, action: <span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      before <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #808080; font-style: italic;">// Exclude the &quot;public&quot; controller.</span>
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>controllerName <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;public&quot;</span> <span style="color: #66cc66;">||</span> controllerName <span style="color: #66cc66;">==</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">// This just means that the user must be authenticated. He does</span>
        <span style="color: #808080; font-style: italic;">// not need any particular role or permission</span>
        accessControl <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">true</span> <span style="color: #66cc66;">&#125;</span>
      <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>For purposes of initial testing, I also added some temporary code to the <code>BootStrap.groovy</code> file that creates a hardcoded user (user &#8216;don&#8217;, password &#8216;twodo&#8217;). We will remove this code later as the application progresses.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.jsecurity.crypto.hash.Sha1Hash</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">com.alterlabs.sec.*</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> BootStrap <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">def</span> init <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> servletContext <span style="color: #66cc66;">-&amp;</span>gt<span style="color: #66cc66;">;</span>
     <span style="color: #808080; font-style: italic;">// TODO: Remove this stuff later</span>
    <span style="color: #000000; font-weight: bold;">def</span> role <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsecRole<span style="color: #66cc66;">&#40;</span>name: <span style="color: #ff0000;">&quot;User&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">def</span> user <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsecUser<span style="color: #66cc66;">&#40;</span>username: <span style="color: #ff0000;">&quot;don&quot;</span>,
            passwordHash: <span style="color: #000000; font-weight: bold;">new</span> Sha1Hash<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;twodo&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">toHex</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">new</span> JsecUserRoleRel<span style="color: #66cc66;">&#40;</span>user: user, role: role<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">def</span> destroy <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
   <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>To test it I fired up the app and was presented the generated list of Controllers, including an additional entry for the newly added <code>com.alterlabs.sec.AuthController</code>. Clicking on the Profile controller presents the Quick Start generated login page, and I can successfully login with the &#8216;don&#8217; account created during the BootStrapping.  <strong>Awesome</strong>.</p>
<h3>Login and Registration UI</h3>
<p>Recall that we want to allow for a simple registration process. Once a user has registered he/she should be able to login and start using the application. Right or wrong, I find that many agile based development efforts derive requirements from the imagined user interface, and that is the direction we will take here.  I envisioned another napkin with as screen that presents the user with two basic panels, one for new user registration, one for existing users to login:</p>
<p><img class="alignnone size-medium wp-image-215" title="login" src="http://alterlabs.com/wp-content/uploads/2009/08/login-300x209.gif" alt="login" width="300" height="209" /></p>
<p>Anonymous users will only have access to the public space, and once authenticated they will be sent to a home controller, where we eventually hope to add the meat of our application logic and content.  With that in mind I next created both a <code>public</code> and <code>home</code> controller (<em>grails create-controller</em>)</p>
<p>I replaced the default <code>view/index.gsp</code> page that Grails provides with a few simple lines that uses the JSecurity taglibs to redirect to either the <code>home</code> controller or the <code>public</code> controller depending on whether the user is authenticted.</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">$<span style="color: #66cc66;">&#123;</span> response.<span style="color: #006600;">sendRedirect</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/blogtwodo/home&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
$<span style="color: #66cc66;">&#123;</span> response.<span style="color: #006600;">sendRedirect</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/blogtwodo/public&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Lets create a crude page, as per our napkin above that will allow the user to either register or login.  We want this page to be publicly accessible so this was created in <code>views/public/index.gsp</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;">&nbsp;
<span style="color: #66cc66;">&lt;!--</span>
<span style="color: #808080; font-style: italic;">#login_or_register {margin:10px;width:500px;}</span>
<span style="color: #808080; font-style: italic;">#login_box {border:#006DBA 1px solid;float:left;width:220px;padding: 10px;}</span>
<span style="color: #808080; font-style: italic;">#register_box {border:#006DBA 1px solid;float:right;width:220px;padding:10px;}</span>
<span style="color: #66cc66;">--&gt;</span>
<span style="color: #66cc66;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;errors&quot;</span><span style="color: #66cc66;">&gt;&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>h1<span style="color: #66cc66;">&gt;</span>Welcome to TwoDo<span style="color: #66cc66;">!&lt;</span>/h1<span style="color: #66cc66;">&gt;</span>
Register now to <span style="color: #663399;">get</span> started, or login <span style="color: #b1b100;">if</span> you have an account
<span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;login_or_register&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;login_box&quot;</span><span style="color: #66cc66;">&gt;</span>
&nbsp;
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span><span style="color: #66cc66;">&gt;</span>Username:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span><span style="color: #66cc66;">&gt;</span>Password:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>button<span style="color: #66cc66;">&gt;</span>Login<span style="color: #66cc66;">&lt;</span>/button<span style="color: #66cc66;">&gt;&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>div id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;register_box&quot;</span><span style="color: #66cc66;">&gt;</span>
&nbsp;
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span><span style="color: #66cc66;">&gt;</span>Username:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;value ${hasErrors(bean:profileInstance,field:'username','errors')}&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> value<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${fieldValue(bean:profileInstance,field:'username')}&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>/span<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;email&quot;</span><span style="color: #66cc66;">&gt;</span>Email:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>span <span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;value ${hasErrors(bean:profileInstance,field:'email','errors')}&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input id<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;email&quot;</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;email&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> value<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;${fieldValue(bean:profileInstance,field:'email')}&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>/span<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span><span style="color: #66cc66;">&gt;</span>Password:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>label <span style="color: #b1b100;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;vpassword&quot;</span><span style="color: #66cc66;">&gt;</span>Confirm:<span style="color: #66cc66;">&lt;</span>/label<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>input name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;vpassword&quot;</span> <span style="color: #663399;">size</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;20&quot;</span> type<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> /<span style="color: #66cc66;">&gt;</span>
      <span style="color: #66cc66;">&lt;</span>button<span style="color: #66cc66;">&gt;</span>Register<span style="color: #66cc66;">&lt;</span>/button<span style="color: #66cc66;">&gt;&lt;</span>/div<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/div<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>Pointing our browser to<em>http://localhost:8080/blogtwodo</em> renders the above (thanks to our redirect) as shown below:<br />
<img class="size-medium wp-image-189" title="Crude Login Screen" src="http://alterlabs.com/wp-content/uploads/2009/08/Picture-1-300x216.png" alt="Crude Login Screen" width="300" height="216" /></p>
<p>OK, so we won&#8217;t win any design awards. It&#8217;s ugly but it will serve for now&#8211; we will worry about the aesthetics later. Basically we have a page with two forms that submit to actions within two different controllers.</p>
<p>The login form is trivial&#8211; it&#8217;s simply configured to submit to the existing <code>signIn</code> action within the <code>AuthController</code> that was created as part of the JSecurity Quick Start. Once again easily tested via the browser.</p>
<p>The first thing we need to do is provide the association between the <em>JSecurity</em> constructs and our own <code>Profile</code> object.  To do this we simply add an association to the <code>JsecUserRoleRel</code> object to our <code>Profile</code>. The <code>JsecUserRoleRel</code> holds the relationship between a <code>JsecUser</code> and a <code>JsecRole</code> and has references to both&#8211; which in turn gives our <code>Profile</code> object access to both. (Note: Yeah I know I said we had no need of formal roles in our application, but it seems silly to paint ourselves into a corner.)</p>
<p>After adding this association to the <code>Profile</code> class now looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">com.alterlabs.sec.JsecUserRoleRel</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Profile <span style="color: #000000; font-weight: bold;">extends</span> Base <span style="color: #66cc66;">&#123;</span>
  ...
  <span style="color: #006600;">JsecUserRoleRel</span>  principle
  ...
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>The second form in the above GSP submits to the <code>save</code> action of the <code>public</code> controller for registration. The registration process needs to take care of the following:</p>
<ol>
<li>Create and persist a new JSecurity <code>JsecUser</code> object</li>
<li>Create  a new <code>Profile</code> object</li>
<li>Associate the <code>JSecUser</code> with the <code>Profile</code> and persist</li>
<li>Log the new user in</li>
<li>Send the authenticated user on to the home page</li>
</ol>
<p>Our <code>public</code> controller now looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #a1a100;">com.alterlabs.twodo</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">com.alterlabs.sec.*</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #a1a100;">org.jsecurity.crypto.hash.Sha1Hash</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> PublicController <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">def</span> securityService
&nbsp;
  <span style="color: #000000; font-weight: bold;">def</span> index <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #66cc66;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">def</span> save <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">def</span> profileInstance <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Profile<span style="color: #66cc66;">&#40;</span>params<span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">def</span> role <span style="color: #66cc66;">=</span> JsecRole.<span style="color: #006600;">findByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;User&quot;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">def</span> ju <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsecUser<span style="color: #66cc66;">&#40;</span>username: profileInstance.<span style="color: #006600;">username</span>, passwordHash: <span style="color: #000000; font-weight: bold;">new</span> Sha1Hash<span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">password</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">toHex</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    profileInstance.<span style="color: #006600;">principle</span> <span style="color: #66cc66;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsecUserRoleRel<span style="color: #66cc66;">&#40;</span>user: ju, role: role<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
    <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>profileInstance.<span style="color: #006600;">hasErrors</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&amp;</span>amp<span style="color: #66cc66;">;&amp;</span>amp<span style="color: #66cc66;">;</span> profileInstance.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      flash.<span style="color: #006600;">message</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Profile ${profileInstance.id} created&quot;</span>
      <span style="color: #808080; font-style: italic;">// OK, lets log them in and take them to their home page...</span>
      <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #66cc66;">&#123;</span>
        securityService.<span style="color: #006600;">authenticate</span><span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">username</span>, params.<span style="color: #006600;">password</span><span style="color: #66cc66;">&#41;</span>
        redirect<span style="color: #66cc66;">&#40;</span>controller:<span style="color: #ff0000;">'home'</span>,action:<span style="color: #ff0000;">'index'</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#125;</span>
      <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #66cc66;">&#40;</span><span style="color: #aaaadd; font-weight: bold;">Exception</span> ex<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        <span style="color: #808080; font-style: italic;">// Authentication failed</span>
        flash.<span style="color: #006600;">message</span> <span style="color: #66cc66;">=</span> message<span style="color: #66cc66;">&#40;</span>code: <span style="color: #ff0000;">&quot;login.failed&quot;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">def</span> m <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span> username: params.<span style="color: #006600;">username</span> <span style="color: #66cc66;">&#93;</span>
        redirect<span style="color: #66cc66;">&#40;</span>action: <span style="color: #ff0000;">'index'</span>, params: m<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">else</span> <span style="color: #66cc66;">&#123;</span>
      render<span style="color: #66cc66;">&#40;</span>view:<span style="color: #ff0000;">'index'</span>,model:<span style="color: #66cc66;">&#91;</span>profileInstance:profileInstance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#125;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><strong>NOTE</strong>: I have encapsulated the authentication logic from the<em> JSecurity Quick Start</em> <code>AuthController</code> into a <code>SecurityService</code>, which is called on line 21 above.  (This is left as an exercise to the reader :) )</p>
<p>Once again we can verify our progress by using a browser to explicitly try out the registration process (and in this case I also created a few unit tests.)</p>
<h3>Next Steps</h3>
<p>OK, not a bad start. At this stage I had spent perhaps 1-2 hours on the effort, with a decent amount to show for it. We have created our core Domain objects, wired in security and have created the self registration process.  The next post we will look at designing the View layouts, refining the User Interface, and adding some of the core functionality into the mix.</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/agile" rel="tag"> agile</a>, <a href="http://technorati.com/tag/grails" rel="tag"> grails</a>, <a href="http://technorati.com/tag/groovy" rel="tag"> groovy</a>, <a href="http://technorati.com/tag/jsecurity" rel="tag"> jsecurity</a>, <a href="http://technorati.com/tag/software+development" rel="tag"> software development</a></p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/technologies/java/grails-task-management-app-part-3/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Talk @ UVa MSMIT</title>
		<link>http://alterlabs.com/general/news/talk-uva-msmit/</link>
		<comments>http://alterlabs.com/general/news/talk-uva-msmit/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 01:50:31 +0000</pubDate>
		<dc:creator>sunjay</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Estimation]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[agile project management]]></category>
		<category><![CDATA[rapid planning]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://alterlabs.com/?p=185</guid>
		<description><![CDATA[I gave a talk today at my alma mater for the Executive Masters in Management Information Technology Northern Virginia section. Professor Ryan Nelson was kind enough to invite me to present a combination of topics pertaining to both Agile Project Management and Rapid Planning. All-in-all, I had a great time &#8212; even if it is [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a talk today at my <a title="UVa" href="http://www.virginia.edu/" target="_blank">alma mater </a>for the <a href="http://www.commerce.virginia.edu/grad/msmit/">Executive Masters in Management Information Technology</a> Northern Virginia section. Professor Ryan Nelson was kind enough to invite me to present a combination of topics pertaining to both <a href="http://at.alterthought.com/agile-by-numbers">Agile Project Management</a> and<a href="http://at.alterthought.com/project-plan-ninja"> Rapid Planning</a>. All-in-all, I had a great time &#8212; even if it is a Saturday. The current crop of Executive graduate students &#8212; as I was informed &#8212; was highly engaged and astute. There were terrific questions and comments all around. Clearly, I&#8217;m biased but anyone considering a strategic techonlogy management program would be well-served by selecting this one.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/general/news/talk-uva-msmit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building A Grails App in 40 hrs</title>
		<link>http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/</link>
		<comments>http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 16:51:31 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Groovy/Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/</guid>
		<description><![CDATA[In a prior post, I talked about an experiment &#8212; to build a working task management application in about 40 hours.
The high-level constraints governing the experiment were as follows:

The application should be web-based and ‘modern’ (AJAX, friendly URL’s, etc)
It should be reasonably non-trivial.
It should be developed as it were going to someday become a Software [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://alterlabs.com/general/articles/what-can-you-build-in-40-hours/">prior post</a>, I talked about an experiment &#8212; to build a working task management application in about 40 hours.</p>
<p>The high-level constraints governing the experiment were as follows:</p>
<ul>
<li>The application should be web-based and ‘modern’ (AJAX, friendly URL’s, etc)</li>
<li>It should be reasonably non-trivial.</li>
<li>It should be developed as it were going to someday become a <a href="http://en.wikipedia.org/wiki/Software_as_a_service">Software As A Service</a> type of application.</li>
<li>It should involve some new/untried/unfamiliar technology– just to make things more realistic/interesting</li>
<li>Where possible, we’d explore some geeky ‘bells and whistles’</li>
</ul>
<p>My biggest concern was the time constraint.  40 hours is not a heck of a lot of time, and given the other requirement of having to deal with some other unfamiliar technology I needed something that would allow for <a href="http://en.wikipedia.org/wiki/Rapid_application_development">RAD</a>. The resulting architecture for the application ended up looking something like this:</p>
<p><span id="more-137"></span></p>
<ul>
<li>The application was designed as a <a href="http://grails.org/">Grails</a> (v1.1.1) application. No surprises here. I have used Grails on a number of prior efforts, and its my framework of choice.</li>
<li>The more sophisticated/AJAXy UI components were provided courtesy of the excellent <a href="http://grails.org/plugin/grails-ui">GrailsUI Plugin</a>- which in turn is based on the excellent <a href="http://developer.yahoo.com/yui/">Yahoo UI</a> JavaScript library.</li>
<li>We decided to play around with deploying the application into a <a href="http://en.wikipedia.org/wiki/Cloud_computing">Cloud Computing</a> infrastructure like Google&#8217;s <a href="http://code.google.com/appengine/">AppEngine</a> or Amazon&#8217;s <a href="http://aws.amazon.com/ec2/">Elastic Compute Cloud (EC2)</a> platform. I had no experience with either prior to this effort.</li>
</ul>
<p>The Cloud Computing aspect was the real twist &#8212; In one fell swoop, we attempted to meet the requirements for SaaS, &#8216;new or unfamiliar technology&#8217; and high geek factor.  As a bonus it could provide an online presence so that readers could visit and play with the app.</p>
<p>This post and a series of subsequent ones to follow, attempt to document in reasonable chronological order, the details associated with realizing this challenge. That is, the information is presented in the blog posts in the approximate order it was experienced in &#8216;real-life&#8217;&#8211; with a couple of notable exceptions.</p>
<p>In broad brushstrokes the application development cycle looked something like this:</p>
<ol>
<li>Build a standard Grails application locally that meets the basic functional requirements.</li>
<li>Take the prototype from Step#1 and port it to Amazon&#8217;s EC2</li>
<li>Take the prototype from Step#1 and port it to Google&#8217;s AppEngine</li>
</ol>
<p>The above approach seemed reasonable, and at the time I started this endeavor, I had signed up for Google&#8217;s AppEngine <a href="http://code.google.com/appengine/docs/java/overview.html">Java SDK</a> access, but had not yet been granted it&#8211; so implementing an EC2 version of the application first seemed only reasonable. More on this in later posts.</p>
<p>OK! this is the last of the non-technical intro posts. The next post in the series will talk about the design and construction of the basic/local application.</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/agile" rel="tag"> agile</a>, <a href="http://technorati.com/tag/grails" rel="tag"> grails</a>, <a href="http://technorati.com/tag/cloud+computing" rel="tag"> cloud computing</a>, <a href="http://technorati.com/tag/appengine" rel="tag"> appengine</a>, <a href="http://technorati.com/tag/ec2" rel="tag"> ec2</a>, <a href="http://technorati.com/tag/software+development" rel="tag"> software development</a></p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/technologies/java/building-a-grails-app-in-40-hrs/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Speaking @ DC Area PMI Luncheon Group</title>
		<link>http://alterlabs.com/uncategorized/speaking-dc-area-pmi-luncheon-group/</link>
		<comments>http://alterlabs.com/uncategorized/speaking-dc-area-pmi-luncheon-group/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 21:17:30 +0000</pubDate>
		<dc:creator>don</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://alterlabs.com/uncategorized/speaking-dc-area-pmi-luncheon-group/</guid>
		<description><![CDATA[On Monday August 17th, Sunjay Pandey will be speaking at the Project Management Institute’s DC Area Luncheon Group .  Sunjay will be presenting a topic entitled Project Plan Ninja which discusses how to manage Rapid Business Requirements generation on a Rapid Application Development project. Sunjay will be presenting proven techniques that can take your [...]]]></description>
			<content:encoded><![CDATA[<p>On Monday August 17th, Sunjay Pandey will be speaking at the <a href="http://www.pmiwdc.org/2009-08-M2D2" target="_blank" title="DC Luncheon Group">Project Management Institute’s DC Area Luncheon Group</a> .  Sunjay will be presenting a topic entitled <a href="http://at.alterthought.com/project-plan-ninja" title="Project Plan Ninja">Project Plan Ninja</a> which discusses how to manage Rapid Business Requirements generation on a Rapid Application Development project. Sunjay will be presenting proven techniques that can take your team from vision to requirements in hours, not weeks. This event is free of charge, however advanced <a href="http://www.pmi-ssc.org/m2d2/registration.shtml">registration</a> is required. We look forward to seeing you there!</p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/uncategorized/speaking-dc-area-pmi-luncheon-group/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beyond velocity: issue metrics</title>
		<link>http://alterlabs.com/technologies/howtos/beyond-velocity-issue-metrics/</link>
		<comments>http://alterlabs.com/technologies/howtos/beyond-velocity-issue-metrics/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 23:30:26 +0000</pubDate>
		<dc:creator>sunjay</dc:creator>
				<category><![CDATA[Agile Development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[How-Tos]]></category>
		<category><![CDATA[Technology/Technical Approaches]]></category>

		<guid isPermaLink="false">http://alterlabs.com/uncategorized/beyond-velocity-issue-metrics/</guid>
		<description><![CDATA[Continuing our series on beefing up the Agile dashboard with &#8216;leading indicator&#8217; type metrics, let&#8217;s discuss project issues. First, let&#8217;s get on the same page on the definition. A good way to understand the definition of an issue is to compare to that of a risk. So, what&#8217;s the difference between and issue and a [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing <a title="Beefing up the Agile dashboard" href="http://alterlabs.com/general/articles/velocity-plus-plus-beefing-up-the-agile-dashboard/">our series</a> on beefing up the Agile dashboard with &#8216;leading indicator&#8217; type metrics, let&#8217;s discuss project issues. First, let&#8217;s get on the same page on the definition. A good way to understand the definition of an issue is to compare to that of a risk. So, what&#8217;s the difference between and issue and a risk? An issue is something that is currently impacting or will certainly impact your project.  A risk is something that has yet to materialize, but has a probability of materializing in the future and impacting your project. Further, what is the significance of analyzing issue metrics in an Agile setting? Well, issue management is a prime indicator of how mature an organization and its processes are. This category (and others we&#8217;ll cover) gives insight into the mechanics of how well projects are managed in a shop. In our experience, it is the most significant indicator of whether a project is going to experience overruns. It is the &#8220;organization&#8217;s project environment.&#8221;<br />
<span id="more-134"></span> As we&#8217;ve discussed before, understanding what&#8217;s happening with issues on your project could serve as a forewarning of impending hiccups in project velocity. But, before we discuss the handful of things to quantify and track, a couple of housekeeping notes.</p>
<p><strong>An Act of Congress to get this info?<br />
</strong></p>
<p>Most organizations we&#8217;ve worked with have some tool they track issues with: jira, bugzilla, trak, good-old-excel. You name it.  So, in general, the mechanism for collecting issues should not be a big stretch.</p>
<p>On the other hand, the process of being diligent enough to log issues is another matter. From our experience in the Agile setting, those issues which get &#8216;parked&#8217;  by project members during a stand-up/scrum for further discussion are obviously clear candidates for further analysis and tacking. Clearly, during the scrum is not the only time that issues arise. The key point here is to be diligent about tracking issues. That being said, one of the key roadblocks to being diligent is insisting on excessive details about the &#8216;attributes&#8217; of an issue. Now, there is always the respectable goal of having super fine-grained data that you can report and track progress against, but we all  know this fine-grained reporting rarely happens. Which leads us to &#8230;<br />
<strong>Issue &#8220;Priority&#8221;</strong></p>
<p>Many teams  go overboard on trying to assign priority to an issue. &#8216;Low, Medium, Medium-High, High, Super Duper High, Nuclear&#8217; and variants are not uncommon to see in a priority field. At the end of the day, these designations tell us little-to-nothing about the significance of the issue. In our opinion its more fruitful to use a few meaningful priorities that convey the impact of an issue. For instance: full stop (all work being blocked), progress slowed (work continues, but decisions are needed fast), work continues, impedes/complicates some other function outside of development. Again, from the Agile lens, we care about things that are going to affect progress (i.e. velocity). There&#8217;s no need to split hairs by having umpteen variants of &#8220;work is being impacted.&#8221;  If its in the sprint plan, its important; period.<br />
<strong></strong></p>
<p><strong>Issue &#8220;Statuses&#8221;</strong></p>
<p>Status is another area where teams tend to get lost in trying to convey information that is &#8212; well &#8212;  better left for a status <em>report</em>. From an Agile perspective, an issue is either: impacting this sprint, will impact the next sprint, will impact some other future sprint, is resolved, is reopened. So if an issue has priority of &#8216;full stop&#8217; with a status of &#8216;impacting this sprint,&#8217; its logical that it should get a lot of attention because you can be guaranteed that velocity is being affected as you speak.</p>
<p>So, when its all said an done, the attributes associated with an issue should basically boil down to: who&#8217;s responsible, which sprint, the open date, the close date, the priority, the status, and description. Anything else that is made a requirement for entry is either &#8216;nice-to-have&#8217; or is getting in the way of effective issue management.<br />
<strong></strong></p>
<p><strong><strong>So, what to measure?</strong></strong></p>
<p>Okay, &#8220;step down from the sopabox, Sunjay.&#8221; So, what is it that we&#8217;re analyzing. Well, there are fancy names (in bold) for these things, and there are common sens<em>e </em>(<em>in italics</em>) descriptions that help understand why its important to track. We&#8217;ll give you both.</p>
<ul>
<li>Issue Resolution Velocity &#8211; <em>how fast issues are being closed</em>: what&#8217;s the sprint/project average, mean, moving average? What is the open count of high priority issues versus all logged to date?</li>
<li>Issue Leakage &#8211; <em>are issues like zombies &#8212; being re-opened</em>?: what&#8217;s the sprint/project average, mean, moving average?</li>
<li>Issue Growth Rate &#8211; <em>how is the log growing/shrinking</em>?: how many new? how many outstanding, what&#8217;s the ratio of new to open?</li>
</ul>
<p>So at the end of the day, the &#8216;issue&#8217; category and the data that comes from analyzing it provide important fodder for the agile retrospective. Its a leading indicator that can be used to assess why velocity is slipping or what might happen with velocity in the future.  If you can, its probably a good idea to add it to your toolkit.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://alterlabs.com/technologies/howtos/beyond-velocity-issue-metrics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
