<?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>Elastic Grid Blog &#187; groovy</title>
	<atom:link href="http://blog.elastic-grid.com/category/groovy/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.elastic-grid.com</link>
	<description>Where Dynamicity Meets the Cloud</description>
	<lastBuildDate>Fri, 05 Feb 2010 13:15:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Slides of the Elastic Grid BoF at JavaZone 08</title>
		<link>http://blog.elastic-grid.com/2008/09/21/slides-of-the-elastic-grid-bof-at-javazone-08/</link>
		<comments>http://blog.elastic-grid.com/2008/09/21/slides-of-the-elastic-grid-bof-at-javazone-08/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 10:25:03 +0000</pubDate>
		<dc:creator>jeje</dc:creator>
				<category><![CDATA[amazon ec2]]></category>
		<category><![CDATA[amazon s3]]></category>
		<category><![CDATA[amazon sqs]]></category>
		<category><![CDATA[elastic grid]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[rio]]></category>
		<category><![CDATA[typica]]></category>

		<guid isPermaLink="false">http://blog.elastic-grid.com/?p=73</guid>
		<description><![CDATA[
The slides of the BoF on Elastic Grid and EC2 are finally available!
Thanks for all of you who could come. We had some interesting discussions and feedback after the talk.
This is the first time I had a chance to go to JavaZone and I must say it&#8217;s been quite interesting. A few friends and I [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><object width="425" height="348"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=javazone08bof-1222018393337662-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=javazone08bof-1222018393337662-8"  type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="348"></embed></object><!-- ysttest:Array
(
    [id] => 610165&amp;doc=javazone08bof-1222018393337662-8&amp;w=425
)
--></p>
<p><a href="https://elastic-grid-presentations.s3.amazonaws.com/JavaZone08-BoF.pdf">The slides of the BoF on Elastic Grid and EC2 are finally available</a>!</p>
<p>Thanks for all of you who could come. We had some interesting discussions and feedback after the talk.<br />
This is the first time I had a chance to go to <a href="http://www.javazone.no">JavaZone</a> and I must say it&#8217;s been quite interesting. A few friends and I had the opportunity to discuss with <a href="http://javazone.no/incogito/session/How+to+please+your+wife+-+The+leap+from+strategy+to+implementation+.html">Tom J. Bang</a> who gave us the opportunity to taste local stuff.</p>
<p>I also had the opportunity to discuss with a lot of people there: my friends from our local user group (<a href="http://glaforge.free.fr/weblog/">Guillaume Laforge</a>, <a href="http://blog.julienviet.com/">Julien Viet</a>, <a href="http://blogs.sun.com/alexismp">Alexis Moussine-Pouchkine</a>, <a href="http://www.coffeebreaks.org/blogs/">Jerome Lacoste</a>) but also <a href="http://www.davisworld.org">Scott Davis</a> and <a href="http://weblogs.java.net/blog/eitan/">Eitan Suez</a>. (Sorry for all the other ones I forgot to cite.)</p>
<p>For those of you who could not make it for <a href="http://blog.elastic-grid.com/2008/08/29/elastic-grid-talk-at-javazone-08/">our BoF session</a>, the organizers of the JavaZone event will provide a video. I&#8217;ll update the blog when the video is available.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.elastic-grid.com/2008/09/21/slides-of-the-elastic-grid-bof-at-javazone-08/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to write a Groovy DSL for Rio</title>
		<link>http://blog.elastic-grid.com/2008/07/08/how-to-write-a-groovy-dsl-for-rio/</link>
		<comments>http://blog.elastic-grid.com/2008/07/08/how-to-write-a-groovy-dsl-for-rio/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 15:14:08 +0000</pubDate>
		<dc:creator>jeje</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[rio]]></category>

		<guid isPermaLink="false">http://blog.elastic-grid.com/2008/07/08/how-to-write-a-groovy-dsl-for-rio/</guid>
		<description><![CDATA[Rio currently uses deployment descriptor files written in XML, which indicates the services you&#8217;d like to deploy, which cybernodes your service could run into, how you&#8217;d like to scale or relocate your services, etc.
That XML format, although quite extensible is also quite verbose, so a Domain Specific Language (DSL for short), means a lot of [...]]]></description>
			<content:encoded><![CDATA[<p>Rio currently uses deployment descriptor files written in XML, which indicates the services you&#8217;d like to deploy, which cybernodes your service could run into, how you&#8217;d like to scale or relocate your services, etc.</p>
<p>That XML format, although quite extensible is also quite verbose, so a Domain Specific Language (<acronym title="Domain Specific Language">DSL</acronym> for short), means a lot of sense in that context in order to reduce verbosity.</p>
<p>In order to ease the code for such a <acronym title="Domain Specific Language">DSL</acronym>, Rio deployment descriptors (called OpStrings) parsing was rewritten using Groovy. This is something which turned out to be quite easy actually and is mostly done. I spent about 4 or 5 days on this task, including writing some Groovy Tests in order to reduce the risk of regression. This work is interesting because I was able to at least cut the code to half its initial size and it is now more easy to read, hence maintain.</p>
<p>Armed with this test suite, I started to work on the <acronym title="Domain Specific Language">DSL</acronym>. The option I have taken is to transform the <acronym title="Domain Specific Language">DSL</acronym> syntax into the current XML file and then use the <em>usual</em> XML parser. The trade off is that it minimize the work needed to be done but of course it would be better to use the <acronym title="Domain Specific Language">DSL</acronym> in order to create the Java model already using when parsing the XML format (this is still being discussed).</p>
<p>So here is how it looks like. Below is the XML format taken from one of Rio examples:<br />
[sourcecode language='xml']<br />
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><br />
<!DOCTYPE opstring SYSTEM "java://org/jini/rio/dtd/rio_opstring.dtd"><br />
<opstring><br />
    <operationalString Name="Calculator"><br />
        <groups><br />
            <group>rio</group><br />
        </groups></p>
<p>        <resources id="impl.jars"><br />
            <jar>calculator/lib/calculator.jar</jar><br />
        </resources></p>
<p>        <resources id="client.jars"><br />
            <jar>calculator/lib/calculator-dl.jar</jar><br />
        </resources></p>
<p>        <serviceBean Name="Calculator"><br />
            <interfaces><br />
                <interface>calculator.Calculator</interface><br />
                <resources ref="client.jars"/><br />
            </interfaces><br />
            <implementationClass Name="calculator.service.CalculatorImpl"><br />
               <resources ref="impl.jars"/><br />
            </implementationClass></p>
<p>            <associations><br />
                <association Name="Add" Type="requires" Property="add"/><br />
                <association Name="Subtract" Type="requires" Property="subtract"/><br />
                <association Name="Multiply" Type="requires" Property="multiply"/><br />
                <association Name="Divide" Type="requires" Property="divide"/><br />
            </associations></p>
<p>            <maintain>1</maintain><br />
        </serviceBean></p>
<p>        <serviceBean Name="Add"><br />
            <interfaces><br />
                <interface>calculator.Add</interface><br />
                <resources ref="client.jars"/><br />
            </interfaces><br />
            <implementationClass Name="calculator.service.AddImpl"><br />
                <resources ref="impl.jars"/><br />
            </implementationClass><br />
            <maintain>1</maintain><br />
        </serviceBean></p>
<p>        <serviceBean Name="Subtract"><br />
            <interfaces><br />
                <interface>calculator.Subtract</interface><br />
                <resources ref="client.jars"/><br />
            </interfaces><br />
            <implementationClass Name="calculator.service.SubtractImpl"><br />
                <resources ref="impl.jars"/><br />
            </implementationClass><br />
            <maintain>1</maintain><br />
        </serviceBean></p>
<p>        <serviceBean Name="Multiply"><br />
            <interfaces><br />
                <interface>calculator.Multiply</interface><br />
                <resources ref="client.jars"/><br />
            </interfaces><br />
            <implementationClass Name="calculator.service.MultiplyImpl"><br />
                <resources ref="impl.jars"/><br />
            </implementationClass><br />
            <maintain>1</maintain><br />
        </serviceBean></p>
<p>        <serviceBean Name="Divide"><br />
            <interfaces><br />
                <interface>calculator.Divide</interface><br />
                <resources ref="client.jars"/><br />
            </interfaces><br />
            <implementationClass Name="calculator.service.DivideImpl"><br />
                <resources ref="impl.jars"/><br />
            </implementationClass><br />
            <maintain>1</maintain><br />
        </serviceBean></p>
<p>    </operationalString><br />
</opstring><br />
[/sourcecode]</p>
<p>Here is now the <acronym title="Domain Specific Language">DSL</acronym> in action for the same example:<br />
[sourcecode language='java']<br />
opstring(name:&#8217;Calculator&#8217;) {<br />
    groups(&#8216;rio&#8217;)</p>
<p>    resources(id: &#8216;impl.jars&#8217;, &#8216;calculator/lib/calculator.jar&#8217;)<br />
    resources(id: &#8216;client.jars&#8217;, &#8216;calculator/lib/calculator-dl.jar&#8217;)</p>
<p>    service(name: &#8216;Calculator&#8217;) {<br />
        interfaces {<br />
            classes(&#8216;calculator.Calculator&#8217;)<br />
            resources(ref: &#8216;client.jars&#8217;)<br />
        }<br />
        implementation(class: &#8216;calculator.service.CalculatorImpl&#8217;) {<br />
            resources(ref: &#8216;impl.jars&#8217;)<br />
        }<br />
        associations {<br />
            association(name: &#8216;Add&#8217;, type: &#8216;requires&#8217;, property: &#8216;add&#8217;)<br />
            association(name: &#8216;Subtract&#8217;, type: &#8216;requires&#8217;, property: &#8217;subtract&#8217;)<br />
            association(name: &#8216;Multiply&#8217;, type: &#8216;requires&#8217;, property: &#8216;multiply&#8217;)<br />
            association(name: &#8216;Divide&#8217;, type: &#8216;requires&#8217;, property: &#8216;divide&#8217;)<br />
        }<br />
        maintain 1<br />
    }</p>
<p>    service(name: &#8216;Add&#8217;) {<br />
        interfaces {<br />
            classes(&#8216;calculator.Add&#8217;)<br />
            resources(ref: &#8216;client.jars&#8217;)<br />
        }<br />
        implementation(class: &#8216;calculator.service.AddImpl&#8217;) {<br />
            resources(ref: &#8216;impl.jars&#8217;)<br />
        }<br />
        maintain 1<br />
    }</p>
<p>    service(name: &#8216;Subtract&#8217;) {<br />
        interfaces {<br />
            classes(&#8216;calculator.Subtract&#8217;)<br />
            resources(ref: &#8216;client.jars&#8217;)<br />
        }<br />
        implementation(class: &#8216;calculator.service.SubtractImpl&#8217;) {<br />
            resources(ref: &#8216;impl.jars&#8217;)<br />
        }<br />
        maintain 1<br />
    }</p>
<p>    service(name: &#8216;Multiply&#8217;) {<br />
        interfaces {<br />
            classes(&#8216;calculator.Multiply&#8217;)<br />
            resources(ref: &#8216;client.jars&#8217;)<br />
        }<br />
        implementation(class: &#8216;calculator.service.MultiplyImpl&#8217;) {<br />
            resources(ref: &#8216;impl.jars&#8217;)<br />
        }<br />
        maintain 1<br />
    }</p>
<p>    service(name: &#8216;Divide&#8217;) {<br />
        interfaces {<br />
            classes(&#8216;calculator.Divide&#8217;)<br />
            resources(ref: &#8216;client.jars&#8217;)<br />
        }<br />
        implementation(class: &#8216;calculator.service.DivideImpl&#8217;) {<br />
            resources(ref: &#8216;impl.jars&#8217;)<br />
        }<br />
        maintain 1<br />
    }<br />
}<br />
[/sourcecode]</p>
<p>What&#8217;s interesting is that if you have a close look at the above syntax, you will notice that the Add, Sutract, Divide and Multiply services are configured quite the same. Wouldn&#8217;t it be nicer to define the configuration once for all those services?</p>
<p>This is something which is accomplished for free because the <acronym title="Domain Specific Language">DSL</acronym> is a Groovy script, so any Groovy syntax is valid in it:<br />
[sourcecode language='java']<br />
opstring(name:&#8217;Calculator&#8217;) {<br />
    groups &#8216;rio&#8217;</p>
<p>    resources id:&#8217;impl.jars&#8217;, &#8216;calculator/lib/calculator.jar&#8217;<br />
    resources id:&#8217;client.jars&#8217;, &#8216;calculator/lib/calculator-dl.jar&#8217;</p>
<p>    service(name: &#8216;Calculator&#8217;) {<br />
        interfaces {<br />
            classes &#8216;calculator.Calculator&#8217;<br />
            resources ref:&#8217;client.jars&#8217;<br />
        }<br />
        implementation(class:&#8217;calculator.service.CalculatorImpl&#8217;) {<br />
            resources ref:&#8217;impl.jars&#8217;<br />
        }<br />
        associations {<br />
            association name:&#8217;Add&#8217;, type:&#8217;requires&#8217;, property:&#8217;add&#8217;<br />
            association name:&#8217;Subtract&#8217;, type:&#8217;requires&#8217;, property:&#8217;subtract&#8217;<br />
            association name:&#8217;Multiply&#8217;, type:&#8217;requires&#8217;, property:&#8217;multiply&#8217;<br />
            association name:&#8217;Divide&#8217;, type:&#8217;requires&#8217;, property:&#8217;divide&#8217;<br />
        }<br />
        maintain 1<br />
    }</p>
<p>    ['Add', 'Subtract', 'Multiply', 'Divide'].each { s -><br />
        println &#8220;Service is $s&#8221;<br />
        service(name: s) {<br />
            interfaces {<br />
                classes &#8220;calculator.$s&#8221;<br />
                resources ref:&#8217;client.jars&#8217;<br />
            }<br />
            implementation(class: &#8220;calculator.service.${s}Impl&#8221;) {<br />
                resources ref:&#8217;impl.jars&#8217;<br />
            }<br />
            maintain 1<br />
        }<br />
    }<br />
}<br />
[/sourcecode]</p>
<p>Our OpString file has now been reduced from 71 lines to 34 ones!</p>
<p>The only drawback in that case is that using the <acronym title="Domain Specific Language">DSL</acronym> you loose the autocompletion provided by any good XML editor.</p>
<p>So how does the code look like for that DSL:<br />
[sourcecode language='java']<br />
class GroovyDSLOpStringParser implements OpStringParser {<br />
    def OpStringParser xmlParser = new XmlOpStringParser()<br />
    def static final Logger logger = Logger.getLogger(GroovyDSLOpStringParser.class.name);</p>
<p>    public List<opString> parse(Object source, ClassLoader loader, boolean verify, String[] defaultExportJars,<br />
                                String codebaseOverride, String[] defaultGroups, boolean processingOverrides,<br />
                                Object loadPath) {<br />
        logger.info &#8220;Parsing source $source&#8221;<br />
        ExpandoMetaClass.enableGlobally()</p>
<p>        def tempFile = File.createTempFile(&#8216;rio-dsl&#8217;, &#8216;xml&#8217;)<br />
        def writer = new FileWriter(tempFile)<br />
        def builder = new groovy.xml.MarkupBuilder(writer)<br />
        Script dslScript = new GroovyShell().parse(source)</p>
<p>        dslScript.metaClass = createEMC(dslScript.class, {<br />
            ExpandoMetaClass emc -><br />
            emc.opstring = { Map attributes, Closure cl -><br />
                builder.printer.println(&#8216;<!DOCTYPE opstring SYSTEM "java://org/jini/rio/dtd/rio_opstring.dtd">&#8216;)<br />
                builder.opstring {<br />
                    OperationalString(Name: attributes.name) { cl() }<br />
                }<br />
                writer.close()<br />
                xmlParser.parse(tempFile, loader, verify, defaultExportJars, codebaseOverride, defaultGroups,<br />
                                processingOverrides, loadPath)<br />
            }<br />
            emc.groups = { String&#8230; groups -><br />
                builder.Groups {<br />
                    groups.each { Group(it) }<br />
                }<br />
            }<br />
            emc.cluster = { String&#8230; machines -><br />
                builder.Cluster {<br />
                    machines.each { Machine(it) }<br />
                }<br />
            }<br />
            emc.service = { Map attributes, Closure cl -><br />
                builder.ServiceBean(Name: attributes.name) { cl() }<br />
            }<br />
            emc.serviceExec = { Map attributes, Closure cl -><br />
                builder.ServiceExec(Name: attributes.name) { cl() }<br />
            }<br />
            emc.spring = { Map attributes, Closure cl -><br />
                builder.SpringBean(Name: attributes.name, config: attributes.config) { cl() }<br />
            }<br />
            emc.interfaces = { Closure cl -><br />
                builder.Interfaces { cl() }<br />
            }<br />
            emc.implementation = { Map attributes, Closure cl -><br />
                builder.ImplementationClass(Name: attributes.class) { cl() }<br />
            }<br />
            emc.execute = { Map attributes -><br />
                builder.Exec(nohup: attributes.nohup ? &#8216;yes&#8217; : &#8216;no&#8217;) {<br />
                    if (attributes.inDirectory)<br />
                        WorkingDirectory(attributes.inDirectory)<br />
                    def String[] cmd = attributes.command.split()<br />
                    CommandLine(cmd[0])<br />
                    if (cmd.size() &#8211; 1 > 0)<br />
                        cmd[1..cmd.size() - 1].each { InputArg(it) }<br />
                }<br />
            }<br />
            emc.classes = { String&#8230; interfaceClasses -><br />
                interfaceClasses.each { builder.Interface(it) }<br />
            }<br />
            emc.resources = { String&#8230; resources -><br />
                builder.Resources {<br />
                    resources.each { JAR(it) }<br />
                }<br />
            }<br />
            emc.resources = { Map attributes -><br />
                builder.Resources(attributes)<br />
            }<br />
            emc.resources = { Map attributes, String&#8230; resources -><br />
                builder.Resources(id: attributes.id) {<br />
                    resources.each { JAR(it) }<br />
                }<br />
            }<br />
            emc.configuration = { String configuration -><br />
                builder.Configuration(configuration)<br />
            }<br />
            emc.associations = { Closure cl -><br />
                builder.Associations { cl() }<br />
            }<br />
            emc.association = { Map attributes -><br />
                builder.Association(Name: attributes.name, Type: attributes.type,<br />
                                    Property: attributes.property, MatchOnName: attributes.matchOnName ? &#8216;yes&#8217; : &#8216;no&#8217;)<br />
            }<br />
            emc.maintain = { Integer maintain -><br />
                builder.Maintain(maintain)<br />
            }<br />
            emc.maxPerMachine = { Integer max -><br />
                builder.MaxPerMachine(max)<br />
            }<br />
            emc.maxPerMachine = { Map attributes, Integer max -><br />
                if (attributes.type)<br />
                    builder.MaxPerMachine(max, type: attributes.type)<br />
                else<br />
                    builder.MaxPerMachine(max)<br />
            }<br />
            emc.software = { Map attributes -><br />
                builder.SystemRequirements {<br />
                    SystemComponent(Name: &#8216;SoftwareSupport&#8217;) {<br />
                        Attribute(Name: &#8216;Name&#8217;, Value: attributes.name)<br />
                        Attribute(Name: &#8216;Version&#8217;, Value: attributes.version)<br />
                    }<br />
                }<br />
            }<br />
            emc.software = { Map attributes, Closure cl -><br />
                builder.SystemRequirements {<br />
                    SystemComponent(Name: &#8216;SoftwareSupport&#8217;) {<br />
                        Attribute(Name: &#8216;Name&#8217;, Value: attributes.name)<br />
                        Attribute(Name: &#8216;Version&#8217;, Value: attributes.version)<br />
                        builder.SoftwareLoad(removeOnDestroy: attributes.removeOnDestroy ? &#8216;yes&#8217; : &#8216;no&#8217;) { cl() }<br />
                    }<br />
                }<br />
            }<br />
            emc.download = { Map attributes -><br />
                builder.Download(InstallRoot: attributes.installRoot,<br />
                                 Unarchive: attributes.unarchive ? &#8216;yes&#8217; : &#8216;no&#8217;, Source: &#8221;) {<br />
                    Location(attributes.source)<br />
                }<br />
            }<br />
            emc.postInstall = { Map attributes, Closure cl -><br />
                builder.PostInstall(RemoveOnCompletion: attributes.removeOnCompletion ? &#8216;yes&#8217;: &#8216;no&#8217;) { cl() }<br />
            }<br />
            emc.serviceLevelAgreements = { Closure cl -><br />
                builder.ServiceLevelAgreements { cl() }<br />
            }<br />
            emc.sla = { Map attributes, Closure cl -><br />
                builder.SLA(ID: attributes.id, Low: attributes.low, High: attributes.high) { cl() }<br />
            }<br />
            emc.policy = { Map attributes -><br />
                builder.PolicyHandler(type: attributes.type, max: attributes.max,<br />
                                      lowerDampener: attributes.lowerDampener, upperDampener: attributes.upperDampener)<br />
            }<br />
            emc.logging = { Closure cl -><br />
                builder.Logging { cl() }<br />
            }<br />
            emc.logger = { String name, Level level = Level.INFO, Closure cl -><br />
                builder.Logger(Name: name, Level:level.toString()) { cl() }<br />
            }<br />
            emc.handler = { String name, Level level = Level.INFO -><br />
                builder.Handler(ClassName: name, Level:level.toString())<br />
            }<br />
        })<br />
        List<opString> opstrings = dslScript.run()<br />
        return opstrings<br />
    }</p>
<p>    public parseElement(Object element, GlobalAttrs global, ParsedService sDescriptor, OpString opString) {<br />
        throw new UnsupportedOperationException()<br />
    }</p>
<p>    static ExpandoMetaClass createEMC(Class clazz, Closure cl) {<br />
        ExpandoMetaClass emc = new ExpandoMetaClass(clazz, false)<br />
        cl(emc)<br />
        emc.initialize()<br />
        return emc<br />
    }</p>
<p>}<br />
[/sourcecode]</p>
<p>As you can see, the above code uses the XML MarkupBuilder which makes it very easy to generate the XML format. After that, it&#8217;s just a matter of delegating the real work to the XML parser!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.elastic-grid.com/2008/07/08/how-to-write-a-groovy-dsl-for-rio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
