<?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>Dan Lynn&#187; Grails Archives  &#8211; Dan Lynn</title>
	<atom:link href="http://danlynn.com/category/grails/feed/" rel="self" type="application/rss+xml" />
	<link>http://danlynn.com</link>
	<description>Finding adventure in just about everything</description>
	<lastBuildDate>Thu, 17 Jun 2010 16:47:18 +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>Serving Grails static content with UI-Performance and Cloud Foundry</title>
		<link>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/</link>
		<comments>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 23:54:18 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[cloud foundry]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ebs]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[j2ee]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[static content]]></category>
		<category><![CDATA[ui performance]]></category>

		<guid isPermaLink="false">http://danlynn.com/?p=98</guid>
		<description><![CDATA[I am excited about Cloud Foundry. It promises to greatly simplify java application deployment to Amazon&#8217;s Elastic Compute Cloud (EC2). With a few clicks, you can deploy an J2EE application (e.g. Grails) to the container of your choice (Tomcat 5.5, tc Server, and more) on a fresh EC2 Linux instance backed by a MySQL database on Amazon&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I am excited about <a href="http://www.cloudfoundry.com/" target="_blank">Cloud Foundry</a>. It promises to greatly simplify java application deployment to<a href="http://aws.amazon.com/ec2/" target="_blank"> Amazon&#8217;s Elastic Compute Cloud</a> (EC2). With a few clicks, you can deploy an J2EE application (e.g. <a href="http://grails.org/" target="_blank">Grails</a>) to the container of your choice (<a href="http://tomcat.apache.org/" target="_blank">Tomcat 5.5</a>, <a href="http://www.springsource.com/products/tcserver" target="_blank">tc Server</a>, and more) on a fresh EC2 Linux instance backed by a MySQL database on <a href="http://aws.amazon.com/ebs/" target="_blank">Amazon&#8217;s Elastic Block Store</a> (EBS). It doesn&#8217;t get much easier than this. The instance configuration automatically configures your container behind an Apache instance, which gives you some great options for hosting static content or configuring side-by-side application platforms.</p>
<p>I&#8217;ve been using <a href="http://burtbeckwith.com/blog/" target="_blank">Burt Beckwith</a>&#8217;s <a href="http://www.grails.org/plugin/ui-performance" target="_blank">UI Performance</a> plugin for Grails to bundle and compress my static content (images, js, css) during the build, so I can save on outbound bandwith and improve the response time of my application. In order to take advantage of this build-time optimization, <strong>we need to modify the Apache configuration to serve static content instead of proxying those requests to the container.</strong></p>
<ol>
<li><span style="font-family: Courier, monospace">$ grails install-plugin ui-performance</span></li>
<li>Configure your app to use the plugin&#8217;s taglibs and to bundle resources if necessary. (See <a href="http://www.grails.org/plugin/ui-performance" target="_blank">http://www.grails.org/plugin/ui-performance</a>)</li>
<li>Add a handler for the <span style="font-family: Courier, monospace">CreateWarEnd</span> event in your <span style="font-family: Courier, monospace">scripts/Events.groovy</span> file (make one if you don&#8217;t have one). This handler will package all the bundled and gzipped resources into a static zip file that you can upload to Cloud Foundry:
<pre class="brush: groovy;">
eventCreateWarEnd = {warName, stagingDir -&gt;
    def directory = new File(warName).parent

    ant.zip(destfile:&quot;${directory}/static.zip&quot;) {
        fileset(dir:&quot;${stagingDir}&quot;) {
            include name: &quot;images/**&quot;
            include name: &quot;css/**&quot;
            include name: &quot;js/**&quot;
        }
    }
}
</pre>
</li>
<li>Create a &#8220;container initialization script&#8221; for Cloud Foundry to execute when your instance starts up. This script will tell Apache to directly serve the following directories and to add the appropriate Content-Encoding header for content that is already gzipped. The name doesn&#8217;t really matter at this point, but I called mine <span style="font-family: Courier, monospace">proxyexcludes.sh</span>.
<pre class="brush: groovy;">
cat &gt; /etc/httpd/conf.d/_proxyexcludes.conf &lt;&lt;END
ProxyPass /images !
ProxyPass /css !
ProxyPass /js !

SetEnvIf Request_URI &quot;\\.gz\\.(css|js|jpg|gif|png|ico)\$&quot; already_compressed=true
Header set Content-Encoding gzip env=already_compressed
END
</pre>
<p>I found that keeping this file up to date was easier if I just let grails rebuild it every time after the WAR is created. I modified my <span style="font-family: Courier, monospace">eventCreateWarEnd</span> handler to take care of this for me:</p>
<pre class="brush: groovy; highlight: [13,14,15,16,17,18,19,20,21];">
eventCreateWarEnd = {warName, stagingDir -&gt;
    def directory = new File(warName).parent

    ant.zip(destfile:&quot;${directory}/static.zip&quot;) {
        fileset(dir:&quot;${stagingDir}&quot;) {
            include name: &quot;images/**&quot;
            include name: &quot;css/**&quot;
            include name: &quot;js/**&quot;
        }
    }

    ant.echo &quot;Creating Proxy exclusion list: ${directory}/proxyexcludes.sh&quot;
    new File(&quot;${directory}/proxyexcludes.sh&quot;) &lt;&lt; &quot;&quot;&quot;cat &gt; /etc/httpd/conf.d/_proxyexcludes.conf &lt;&lt;END
ProxyPass /images !
ProxyPass /css !
ProxyPass /js !

SetEnvIf Request_URI &quot;\\.gz\\.(css|js|jpg|gif|png|ico)\$&quot; already_compressed=true
Header set Content-Encoding gzip env=already_compressed
END
&quot;&quot;&quot;

}
</pre>
</li>
<li><span style="font-family: Courier, monospace">$ grails war</span></li>
<li>Upload the static.zip file produced during the build as &#8220;static content&#8221; when you upload your app to Cloud Foundry:
<p><div id="attachment_117" class="wp-caption alignnone" style="width: 310px"><a href="http://danlynn.com/wp-content/cloud_foundry_static_content.jpg"><img class="size-medium wp-image-117" title="Cloud Foundry Upload Static Content" src="http://danlynn.com/wp-content/cloud_foundry_static_content-300x58.jpg" alt="" width="300" height="58" /></a><p class="wp-caption-text">Cloud Foundry Upload Static Content</p></div></li>
<li>When creating a deployment, upload your &#8220;proxyexcludes.sh&#8221; container initialization script:
<p><div id="attachment_114" class="wp-caption alignnone" style="width: 310px"><a href="http://danlynn.com/wp-content/cloud_foundry_init_script.jpg"><img class="size-medium wp-image-114" title="Cloud Foundry Deployment" src="http://danlynn.com/wp-content/cloud_foundry_init_script-300x89.jpg" alt="" width="300" height="89" /></a><p class="wp-caption-text">Cloud Foundry Deployment</p></div></li>
<li>Fire up your instance and check out the performance gains!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails GORM and UUIDs</title>
		<link>http://danlynn.com/grails/grails-gorm-and-uuids/</link>
		<comments>http://danlynn.com/grails/grails-gorm-and-uuids/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 18:53:47 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Grails]]></category>

		<guid isPermaLink="false">http://danlynn.com/?p=39</guid>
		<description><![CDATA[Let&#8217;s say that you&#8217;ve decided you want to add a globally-unique identifier (GUID/UUID) to one of your domain classes. You might want to do this for portability to other systems or for a variety of reasons. Given that some people in the Grails community don&#8217;t recommend using a UUID or string as a primary key, [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say that you&#8217;ve decided you want to add a globally-unique identifier (GUID/UUID) to one of your domain classes. You might want to do this for portability to other systems or for a variety of reasons. Given that <a href="http://www.nabble.com/String-as-PK-td25030884.html">some people in the Grails community</a> don&#8217;t recommend using a UUID or string as a primary key, you might find that you want to add a UUID as a separate <a href="http://en.wikipedia.org/wiki/Natural_key">natural key</a> to your class and set it using GORM&#8217;s <a href="http://docs.codehaus.org/display/GRAILS/GORM+-+Events">beforeInsert</a> event hook:</p>
<pre class="brush: groovy; light: true;">
class Person {
    String name
    String uniqueIdentifier

    transient beforeInsert = {
        uniqueIdentifier = java.util.UUID.randomUUID().toString()
    }
}
</pre>
<p>This works great, but if you&#8217;re like me, in that you like to work with test data while developing, you probably have some code in your BootStrap.groovy file that no longer works. The problem is that GORM&#8217;s validate() method does not call event hooks, and that property we just added is not nullable. One small change and we&#8217;re back in business:</p>
<pre class="brush: groovy; highlight: [6]; light: true;">
class Person {
    String name
    String uniqueIdentifier

    stating constraints = {
        uniqueIdentifier(nullable:true)
    }

    transient beforeInsert = {
        uniqueIdentifier = java.util.UUID.randomUUID().toString()
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://danlynn.com/grails/grails-gorm-and-uuids/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
