Showing posts with label Groovy. Show all posts
Showing posts with label Groovy. Show all posts

Saturday, April 19, 2014

The Simplicity of Groovy and HTTP

Do you ever have the need to do some simple tasks in your IT environment? Maybe you need to run a few checks on some URL's and ensure that everything is copasetic (returning 200's). There are plenty of tools out there that can ping URL endpoints and give you feedback, but why put a tool in place when you can write a Groovy script in under 50 lines of code that is effective? My answer is a) I think writing Groovy is fun b) it can be simple enough that I would rather spend a little time and create something myself c) why bother with implementing a tool if it is not really needed?

The script is pretty straight forward and I first start with a few imports.
import java.net.HttpURLConnection
import groovy.transform.ToString

Then I define a simple class, Target, to hold some state for the URL endpoints we would like to query on. In the Target class exists the name property for identification purposes, the url property to hold our endpoint and finally the status property to hold the Target status. Pretty simple, right?
@ToString(includeNames=true)
class Target {
    def name
    def url
    def status
}

The ToString annotation is quite powerful as it makes the output of our class state nice and readable. It overrides the default String toString() {} method with a nice default. We could also override the method in the class and format the data however we would prefer. The next part of the script defines a list of new Target instances that we can iterate through and check the status of each URL.
def targetList = [
    new Target(name:"Google", url:"http://www.google.com"),
    new Target(name:"Amazon", url:"http://www.amazon.com"),
    new Target(name:"Oracle", url:"http://www.oracle.com"),
    new Target(name:"Axiomatic IT", url:"http://www.axiomaticit.com"),
    new Target(name:"Bad Endpoint", url:"http://www.asfakddddjh.com")
]

I put together some sample instances of Target with some good data and some bad data so we can make sure things are working as they are expected. The next block of Groovy iterates through the list of Target instances, attempts to connect to each URL, checks for the 200 response code, checks to ensure that data is returned when a 200 response code is returned, assigns the appropriate status to each Target instance, prints each Target using the toString() method provided by the @ToString annotation and finally disconnects the HttpURLConnection.
targetList.each { target ->

    def url = new URL(target.url)
    def huc
    
    try { 
        huc = url.openConnection()
        huc.requestMethod = "GET"
        huc.connect()

        if(huc.responseCode == 200) {
            def br = new BufferedReader(new InputStreamReader(huc.inputStream))
            if(br) {
                target.status = "Success"
            } else {
                target.status = "Failure"
            }
        }
    } catch (Exception e) {
        target.status = "Failure"
    }

    println target

    huc.disconnect()
}

Below, you can see an example of what the output looks like when I ran the script. The @ToString annotation is producing the format below by default for each Target instance. It just makes things pretty when we call println or log the value of a Target instance.
Target(name:Google, url:http://www.google.com, status:Success)
Target(name:Amazon, url:http://www.amazon.com, status:Success)
Target(name:Oracle, url:http://www.oracle.com, status:Success)
Target(name:Axiomatic IT, url:http://www.axiomaticit.com, status:Success)
Target(name:Bad Endpoint, url:http://www.asfakddddjh.com, status:Failure)

Groovy makes things pretty simple and in under 50 lines of code I have a simple script I can run to check the status of some Web site URL's. I can make things a bit fancier and have the list of Target instances populated from some external data source like a file or database. I could also check the data to ensure that the response is returning valid HTML or some other valid type of data format. The possibilities are there but for now, I have what I need without too much overhead.

Having Fun with Groovy and the Ternary Operator

Groovy is a great language to compliment your Java skills and to increase your productivity on the JVM. From time to time I work on some code and enjoy sharing its likeness here so I can ensure that a) I don't forget what I have done and b) encourage other developers who are interested in the technologies I find interesting. In this script, I have a model object, Policy, that would normally be fetched from a database or some flavor of Web service.
class Policy {
    def number
    def type
    def value
}

Next, I define a closure the expects a policy number as input. Using the ternary operator, we verify that a valid policy number has been provided. If a policy number is provided, the closure returns a new Policy with some default values. In a normal situation the second part of the ternary operator would make a call to access a database or call a Web service to return meaningful data rather than just return some static Policy object.
// static fetch method returns a default Policy or an empty Policy
def fetchPolicy = { policyNumber ->
    policyNumber ? new Policy(number:policyNumber, type:"Life", value:10000) : new Policy()
}

It is pretty straight forward. When the policy number is not null or not empty we get the static Policy object. If the policy number is null or an empty string we just return an empty Policy object. Here is the rest of script that does a few assertions on a null policy number, a valid policy number and a policy number which is an empty string.
def policyNumber

// policyNumber is a null value
policyNumber = null
def policy1 = fetchPolicy(policyNumber)

assert policy1.number == null
assert policy1.type == null
assert policy1.value == null

// policyNumber is a valid value
policyNumber = "123456"
def policy2 = fetchPolicy(policyNumber)

assert policy2.number == "123456"
assert policy2.type == "Life"
assert policy2.value == 10000

// policyNumber is an empty value
policyNumber = ""
def policy3 = fetchPolicy(policyNumber)

assert policy3.number == null
assert policy3.type == null
assert policy3.value == null

There is nothing too fancy with this script but you may have noticed that there are no null checks or empty string checks within the fetchPolicy closure. It may not be a big winner for every developer, but I think that these little nuances are what make Groovy a language all Java developers should have in their toolbox.

Wednesday, December 21, 2011

A Message Routing Groovy DSL

The other day I was discussing system integration with a friend and he mentioned something about creating a DSL (Domain Specific Language) for the many aspects of enterprise integration. I have limited experience with writing DSL's but I figured I would give it a shot. Inspired by this post on the Canoo blog and my friend's idea, I started hacking on GroovyConsole. Groovy is a great language for writing DSL's because of the language's features like closures and map based interface implementation. Plus, Groovy has the benefit of being fully compatible with Java and other Java based tools. What I want to do is create a DSL for writing rules for a hypothetical message routing engine. Here is my Message domain class and System enum:
import groovy.transform.TupleConstructor

enum System {
    bus, db2, iSeries, mySQL, oracle, postgre
}

@TupleConstructor
class Message {
    String payload
    System origination
    System destination
    
    String toString() {
        "${payload} from:${origination} to:${destination}"
    }
}

Here is what I think the DSL might look like:
route message to oracle, mySQL when origination eq db2

What I am saying is, route a message to oracle and mySQL systems when the message's origination is db2. I guess I really didn't need to explain that because the DSL is pretty self explanatory, right? Let's move on to see what else the DSL might look like:
route message to iSeries, oracle, mySQL when payload contains 'Hello'

Is there a need to explain what the previous statement is stating? If you have not caught on yet, it is saying route a message to the iSeries, oracle and mySQL systems when the message's payload contains the word 'Hello'. In each case, I would imagine creating a new Message for each system that will be put on a queue or sent to an endpoint to be processed. Here is the meat of the code that will implement the DSL I designed above:
import static System.*

messages = []

Above, we have the initialization of the list of messages that will be the result of our DSL statement. If the proper conditions are met, we are returned a list of new messages to send to other systems.
def payload = { Message message ->
    message.payload
}

def destination = { Message message ->
    message.destination
}

def origination = { Message message ->
    message.origination
}

The code above handles referencing each message property. The code below handles the keywords route, to, when, eq, neq and contains. It also handles each message instance and the array of System destinations, for example: iSeries, oracle, mySQL.
def route(Message message) {
    [to: { System[] destinations ->
        [when: { Closure clos ->
            [eq: { System system ->
                if(clos(message) == system)
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            },
            neq: { System system ->
                if(clos(message) != system)
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            },
            contains: { String string ->
                if(clos(message).contains(string))
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            }]
        }]
    }]
}

Below, is an example Message instance for testing the DSL.
message = new Message("Hello there!", db2, bus)

When I run my DSL statements from above, I see the list of messages created to be sent on to the other systems.
route message to oracle, mySQL when origination eq db2

Result: [Hello there! from:db2 to:oracle, Hello there! from:db2 to:mySQL]

The second example:
route message to iSeries, oracle, mySQL when payload contains 'Hello'

Result: [Hello there! from:db2 to:iSeries, Hello there! from:db2 to:oracle, Hello there! from:db2 to:mySQL]

I think this is very cool for my first attempt at a DSL with Groovy. I am sure I can clean up the code a bit (feedback is welcome) and this is really just scratching the surface of what we can do with Groovy and DSL's!

Wednesday, October 26, 2011

Something Else I Need to Remember About Groovy

This is something else I need to remember when writing a Groovy script.
def c = "closure"
m = "method"

def myClosure = {
    println c
}

def myMethod() {
    println m
}

myClosure()
myMethod()

The above works as I expect it to. As soon as I change line 2 to this...
def m = "method"

...I get an error. Just something that I need to keep in my head on the Groovy Console.

Tuesday, October 25, 2011

A Quick Reminder About Using a Language

Let's say I decided to do all this work...
def boolean isNumber(String s) {
    try {
        int i = Integer.parseInt(s)
        return true
    } catch (Exception e) {
        return false
    }
}
In order to do this...
println isNumber("4")
println isNumber("-4")
println isNumber("t")

To get this result...
true
true
false

When all I needed to do is use the language features...
println "4".isNumber()
println "-4".isNumber()
println "t".isNumber()​​​​​​​​​​​​​​

To get the same result with a lot less coding...
true
true
false

Sunday, August 21, 2011

A Quick Intro to Gradle

I have been spending some time learning and working with Gradle. Gradle is a Groovy based build and dependency tool that supports declarative builds and build-by-convention. Gradle is an open source project and it is used by many companies and other open source Java and Groovy projects.

First, make sure you have Java 1.5+ installed and download Gradle from gradle.org. Create a GRADLE_HOME variable in your environment referencing where you have unpacked your download. Next, add GRADLE_HOME/bin to your PATH variable. To confirm Gradle is installed and working, enter gradle --version at a command prompt.

Once you know Gradle is installed properly, you can now setup your project. To put together a simple project, all you need is a /src/main/java directory with your packages and Java source and a build.gradle file. I highly recommend adding a /src/test/java directory with your test packages and Java unit testing source because everyone needs to write tests.

I have been using Gradle with a Java project that I have been working on. I mostly have been depending on Gradle to handle my dependency resolution, running tests and packaging my project. So, what kind of work goes into using Gradle for my needs? It is quite simple, it is a build file, build.gradle, with a few lines of Groovy.

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'commons-logging', name: 'commons-logging', version: '1.+'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}


The above entries let Gradle know to use the Java plugin, add Maven Central to the repositories and add commons-logging as a dependency for compilation and JUnit as a dependency of the test compilation. Within the project directory enter gradle build at a command prompt. The source will be compiled, the tests will be run with reports and you will have a packaged Jar file. It is ridiculously simple to get started. The Gradle team has done a great job. Have fun writing code.

Friday, December 17, 2010

A Mock Service with Groovy and Jetty

I recently needed to do some testing on a project that integrated with a Web service supported by another team of developers. After I completed my development work, I wanted to do some quick integration testing but I was forced to wait on the completion of the Web services. I was pretty confident that my code changes would work, but I really needed that "live" interactivity to know for sure.

In order to not be caught in this predicament again, I decided to create a simple mock service using Groovy, Jetty and some static XML files. Here is the result using an example domain model and sample data:

I put together a Groovy script to create an instance of a Jetty server. This is very similar to the example that can be found on the Groovy Web site (wink, wink).

import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.*
import groovy.servlet.*

@Grab(group = 'org.mortbay.jetty', module = 'jetty-embedded', version = '6.1.0')
def runServer = {
    def server = new Server(8181)
    def context = new Context(server, "/", Context.SESSIONS);
    
    context.resourceBase = "."
    context.addServlet(new ServletHolder(new TemplateServlet()), "*.html")
    context.addServlet(new ServletHolder(new DefaultServlet()), "*.xml")

    server.start()
}

runServer()

First, we import what we need from Jetty and here I am using @Grab to resolve our Jetty dependency.

Next, runServer is defined to do all of our work. Within runServer, we define a new Jetty Server and use it to create a new Jetty Context. I then set the context's resourceBase to "." which is the directory where the above Groovy file, mockService.groovy, is located.

Now, we need to handle requests to our server. Instead of using a standard Web descriptor, web.xml, file we can write a few line of code to add a new Groovy TemplateServlet mapped to handle the *.html request pattern and a new Jetty DefaultServlet mapped to handle the *.xml request pattern.

The Jetty DefaultServlet will handle resolving our static, test XML files.

The TemplateServlet will handle resolving and running our HTML files and it will allow us to be able to create dynamic Groovy templates like the following:

<html>
    <body>
        

File List

<% def f = new File(".") if(f.isDirectory()) { f.listFiles([accept:{file->file ==~ /.*?\.xml/}] as FileFilter).toList()*.name.each { %> ${it} <% } } %> </body> </html>


What is great about the TemplateServlet is that the above, fileList.html, contains Groovy that will be executed when the file is requested. This executed code will find all .xml files located in the current directory and display HTML links to each test XML file. For example, I have these two static, test files:

12345.xml

<?xml version="1.0" encoding="UTF-8"?>
<account>
    <id>12345</id>
    <name>Acount 12345</name>
    <address>
        <street1>123 Test St</street1>
        <city>City</city>
        <state>State</state>
        <postalcode>33333</postalcode>
    </address>
</account>

54321.xml

<?xml version="1.0" encoding="UTF-8"?>
<account>
    <id>54321</id>
    <name>Acount 54321</name>
    <address>
        <street1>123 Test St</street1>
        <city>City</city>
        <state>State</state>
    <postalcode>33333</postalcode>
    </address>
</account>


The fileList.html request will render something like:

File List


12345.xml
54321.xml

All we need to do to get started is open a command prompt, navigate to my development directory where the mockService.groovy file is located and run:

> groovy mockService.groovy

Now, my application can be configured to point to this local service. In this example, when I want to do a GET request for 'Account 12345', the application can make a call to http://localhost:8181/12345.xml. We can follow that pattern and request 'Account 54321' by calling http://localhost:8181/54321.xml or any other xxxxx.xml file I place in my development directory. I am now able to run simple integration tests with my application while the other team works to complete the final service.

To really understand the simplicity that is involved, here is a quick view of my development directory:

/mockService
- 12345.xml
- 54321.xml
- fileList.html
- mockService.groovy

Nothing too magical going on here but for me it is just another way to bring Groovy into the work environment to get things done.

Wednesday, December 01, 2010

Google App Engine, Gaelyk and Twilio

Having fun in the evenings playing with Google App Engine, Gaelyk and Twilio. Using Gaelyk (Groovy) and the Google App Engine platform, I have been able to play around with my trial account at Twilio to create a simple IVR application. What is really nice is that Gaelyk is great for Groovy developers looking for a simple way to get something done on GAE and Twilio is a full-featured IVR platform that is much more flexible and less expensive than the enterprise IVR platform I work with on a daily basis. SMS, recording and robust call handling are some features I plan to explore in more detail in the upcoming nights. Working these past ~2 years with IVR applications I have found that IVR and Web development share many cross-cutting concerns like availability, redundancy, reliability and scalability. With GAE providing the platform and Twilio managing the telephony portion of the application, businesses can deploy a simple IVR with less upfront investment and less maintenance costs.

Tuesday, October 05, 2010

Gaelyk: Routes + Parameters + Binding = Simple Controller

If you haven't heard it from me yet or anyone else, Groovy is an incredible dynamic language for the JVM that brings you(the Java developer) productivity like Parliament Funkadelic brings the funk. When you leverage the power of Grails and the underlying technologies(Spring, Hibernate, GORM...), Java Web development takes a monumental step in the direction of productivity. When you want to run a simple Java Web application on Google App Engine, Groovy/Grails is definitely a great option. Ah, but we do have another option for Groovy on Google App Engine, Gaelyk. It is definitely not Grails, but for simple Web applications, Gaelyk is another technology that helps at getting things done.

If you are familiar with Groovy and/or Grails and/or Groovlets, you can build a 0.1 version Web app in a few hours. One thing that I stumbled upon was utilizing WEB-INF/routes.groovy, parameters(params) and the binding property in the .groovy files to build a simple, easy to read controller. Let's take a look at an example WEB-INF/routes.groovy file first:
// routes
get  "/failure",    forward: "failure.gtpl"

get  "/",           forward: "controller.groovy"
get  "/@a",         forward: "controller.groovy?a=@a"

Above, we map the HTTP method(GET, POST...) and URL patterns to views(.gtpl files) or .groovy files(WEB-INF/groovy/). A GET request of http://myserver.com/failure would forward to and render the failure.gtpl view. Likewise, a GET request of http://myserver.com/ or http://myserver.com/anything(other than failure) would be forwarded to the WEB-INF/groovy/controller.groovy file below:
def index = {
    // do something
    forward "index.gtpl"
}

def list = {
    // do something
    forward "list.gtpl"
}

def view = {
    // do something
    forward "view.gtpl"
}

binding.setProperty("index", index)
binding.setProperty("list", list)
binding.setProperty("view", view)

if(params.a) {
    try {
        def var = binding.getVariable("${params.a}")
        var.call()
    } catch(Exception e) {
        redirect "/failure"
    }
} else
    index.call()

In the WEB-INF/groovy/controller.groovy file above, I have created Closures for each http://myserver.com/anything that I would like to support. Using the script's binding property, I have added each Closure as a variable. When each request that contains a parameter we expect, in this case parameter a(params.a), I try to get that variable and execute the call() method on it. Here, the application supports http://myserver.com/index, http://myserver.com/list and http://myserver.com/view.  If params.a does not exist, we execute the default index Closure. If params.a is not supported(or not bound to the script), the binding.getVariable("${params.a}") call fails and the controller redirects to http://myserver.com/failure.

The nice thing is that we can keep better track of our .groovy files we have and tie them into our model(if needed). Here is a possible future WEB-INF/routes.groovy file:
// routes
get  "/failure",  forward: "failure.gtpl"

get  "/",            forward: "indexController.groovy"
get  "/book/@a",  forward: "bookController.groovy?a=@a"
get  "/author/@a",  forward: "authorController.groovy?a=@a"

Nothing too exciting, it is just something I found to be helpful when working with Gaelyk and I thought I would it share it. Gaelyk is pretty fun to work with. I suggest starting with downloading the Google App Engine Java SDK and the Gaelyk template project if you are new to Groovy. Gaelyk also makes working with Google App Engine super simple because of the Groovy-er access to GAE's API(check out the Gaelyk tutorial). Realistically, most Web developers should be able to get a nice application running in the Google App Engine cloud in a few hours and that is very Groovy!

Tuesday, September 07, 2010

Groovy Set or List

Below is a script that might be helpful to new Groovy developers. We sometimes have to be careful when we are working so closely with Java and Groovy at the same time. In this first block, I create a HashSet (java.util.HashSet) with a Collection as an argument to the Constructor:

def mySet = new HashSet(["test", "tester"])

assert mySet.size() == 2

mySet << "test"
mySet << "tester"

assert mySet.size() == 2


I then try to add duplicate entries ("test" and "tester"), using the << operator, into mySet which does not work and I verify this by asserting that mySet's size is still 2, as when it was instantiated.

Next, I instantiate an empty HashSet (java.util.HashSet) and then assign a collection of values to mySet. Again, I try to add (<<) duplicate entries ("test" and "tester") into mySet.

def mySet = new HashSet()

mySet = ["test", "tester"]

assert mySet.size() == 2

mySet << "test"
mySet << "tester"

assert mySet.size() == 2


In the above snippet, the second assertion fails. What? mySet is an instance of HashSet (java.util.HashSet)! How did this happen? Maybe, I should open a defect? Not so fast. We have to think about the dynamic (not static) nature semantics of Groovy. If we examine the line

mySet = ["test", "tester"]


and focus on the collection

["test", "tester"]

we should know that in Groovy

["test", "tester"].class

is an ArrayList (java.util.ArrayList) and thereafter so is the variable mySet. Now this might seem like a disappointment to Java developers who are starting to learn Groovy, but if we really want a unique collection of entries we can always utilize

mySet.unique()


to take care of this task for us or we can just instantiate HashSet and use the add method or << operator to add values to mySet.

def mySet = new HashSet()

mySet.add("test")
mySet << "tester"

assert mySet.size() == 2

Wednesday, September 01, 2010

VXML and Groovy's MarkupBuilder

For the last ~1.5 years I have been working with IVR applications. The framework we use is Java based and we use an Eclipse based IDE with a nice drag and drop editor to create the application's call flow. The IVR application is packaged into a .war or .ear file by the IDE and we deploy the application to a Web container like Tomcat. The IVR is then pointed at the application's entry point URL. The core flow is mapped into Servlets and each request into the application generates VXML (Voice XML) that is interpreted by the actual IVR which is responsible for handling call control and communicating with the other telephony technologies.

I think there could/should be a way to use Groovy's MarkupBuilder and most likely Gaelyk to create IVR applications with less ceremony than using the drag and drop editor. We can create static VXML very simply with Groovy's MarkupBuilder:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()
def vxml = new MarkupBuilder()

vxml.vxml {
    field (name:"color") {
        grammar ("red | green | blue")
        prompt (count: 1, "Say red, green or blue.")
        prompt (count: 2, "Please say red, green or blue.")
        noinput (count: 1) {
            prompt ("I didn't hear you." )
            reprompt ()
        }
        noinput (count: 2) {
            prompt ("Sorry, I still didn't hear you.")
            reprompt ()
        }
        nomatch (count: 1) {
            prompt ("I didn't understand you." )
            reprompt ()
        }
        nomatch (count: 2) {
            prompt ("Sorry, I still didn't understand you.")
            reprompt ()
        }
    }
}

writer.toString()

Here is the output of the above:

<vxml>
    <field name='color'>
        <grammar>red | green | blue</grammar>
        <prompt count='1'>Say red, green or blue.</prompt>
        <prompt count='2'>Please say red, green or blue.</prompt>
        <noinput count='1'>
            <prompt>I didn't hear you.</prompt>
            <reprompt />
        </noinput>
        <noinput count='2'>
            <prompt>Sorry, I still didn't hear you.</prompt>
            <reprompt />
        </noinput>
        <nomatch count='1'>
            <prompt>I didn't understand you.</prompt>
            <reprompt />
        </nomatch>
        <nomatch count='2'>
            <prompt>Sorry, I still didn't understand you.</prompt>
            <reprompt />
        </nomatch>
    </field>
</vxml>


Then, if a nice, simple DSL (Domain Specific Language) is designed for building IVR applications with Groovy, we can then simplify the craft of creating IVR applications. Plus, we would gain the productivity of using Groovy when calling Web services and databases to provide dynamic data for the application. Just a crazy thought.

Monday, August 23, 2010

Having Fun with Groovy

I love browsing over to Groovy Console from time to time to check out scripts that have been recently published. It is a great place to learn Groovy or just have fun with Groovy without having to install anything. In the script below, I wanted to multiply two lists of Strings together so while playing around at the Groovy Console site I wrote:
java.util.ArrayList.metaClass.multiply = { e ->
    def list = new ArrayList()
    delegate.each { a ->
        e.each {
            list.add(a + it)
        }
    }
    list
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y

Now, there may be a better way of handling this in Groovy, but I get the result I am expecting by implementing the multiply method for the ArrayList MetaClass in the top part of the script.

Then I create my lists, x and y, and multiply (*) them together. Nothing too crazy going on here but this demonstrates the power that Groovy can provide programmers with very little effort. Here is the result:
[k1v1, k1v2, k1v3, k2v1, k2v2, k2v3, k3v1, k3v2, k3v3]


Update:

A few more elegant solutions posted at the Groovy Console site.

Shorter version.*
java.util.ArrayList.metaClass.multiply = { e ->
    delegate.collect { a -> e.collect { a + it } } .flatten()
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y


Another version.*
java.util.ArrayList.metaClass.multiply = {
    [delegate, it].combinations().collect { a -> a[0] + a[1] }
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y


No MOP version.**
x = ["k1", "k2", "k3"] 
y = ["v1", "v2", "v3"] 
[x, y].combinations()*.join()


*Courtesy of Paul Holt.
**Courtesy of paulk_asert.

Sunday, April 11, 2010

Groovy Metaprogramming: propertyMissing

The other day, while working on a Java project, I realized that I could implement an application requirement quite quickly by extending a current domain object and adding an attribute. This is an enterprise wide, industry standard domain object model so I couldn't just add the attribute to the domain object without cutting through some red tape. Plus, it was an attribute that I needed for my application and it would most likely have no use in other projects. So, I had something like this:
public class Policy {

    private String policyNumber;
    private Double value;
    private Double interestRate;

    /* getters and setters */
    ....
}

Then to get things done, I went ahead and created:
public class MyPolicy extends Policy {

    private String myNewProperty;
    private Policy p;

    public MyPolicy(Policy policy) {
        this.p = policy;
    }

    /* getters and setters */
    ....
}

Now, I could fulfill the requirement with ease because I now had a Policy object with the extra attribute I needed, myNewProperty, all in the MyPolicy object. I could now handle the Policy returned from the Web service call and pass it into the MyPolicy constructor, do some work to create an instance of MyPolicy with a Policy object, derive the value of myNewProperty and then send it on to a view for example. Nice, I think that will work for my application.

Later, I thought about how nice it would have been if the Policy object was implemented with Groovy. Then I could take advantage of Groovy's metaprogramming features like propertyMissing. When I have propertyMissing in my language arsenal, I can create the Policy object like so:

class Policy {

    def properties = Collections.synchronizedMap([:])

    String policyNumber
    Double value
    Double interestRate

    def propertyMissing(String name, value)  { properties[name] = value }

    def propertyMissing(String name) { properties[name] }
}

In the implementation above, the propertyMissing(String name, value) method is called when trying to set a value, myNewProperty, that doesn't exist in the Policy object. The propertyMissing(String name) method is called when trying to get a property, myNewProperty, that doesn't exist in the Policy object. By default, the propertyMissing(String name) will return null if the value was never initialized or never dynamically created. Yeah, it is an incredible feature. What is really nice is that I didn't have to create the MyPolicy object at all! In the Groovy world I could write the following:

def p = new Policy()

p.policyNumber = "12345678"
p.value = 12000.00
p.interestRate = 2.3

println p.policyNumber
println p.value
println p.interestRate

/* new property */
p.myNewProperty = "Active"

println p.myNewProperty


Later on I could even write:

/* another new property */
p.myOtherNewProperty = "Wow"

println p.myOtherNewProperty

This would save me some time and now because the Policy object is expandable, other applications that need to extend the Policy object, for application purposes, will be able to utilize these features. I am convinced, Groovy IS productivity for Java.

Thursday, December 10, 2009

Hazelcast Groovyness

Data distribution is a pretty cool topic. Recently, I have been working with Hazelcast, which is an open source clustering and data distribution platform for Java. Well, I really like what I have seen so far and I figured why not have some fun with Hazelcast and Groovy.

I started by adding the Hazelcast 1.7.1 jar to $GROOVY_HOME/lib. Hazelcast, at an introductory level, provides distributed implementations of java.util { Queue, List, Set, Map }. I can run a Groovy script on multiple JVM's and I can share a Map of customers on each instance. For example:

    def customersMap = Hazelcast.getMap("customers")

Now, I have an instance of Map and I can add values using Hazelcast's distributed id generator:

def idGen = Hazelcast.getIdGenerator("customer-ids")
def id = idGen.newId()
customersMap.put(id, "Customer $id")

So, that was pretty simple, right? Here is the entire Groovy script HazelcastGroovynessAdd.groovy:

import com.hazelcast.core.Hazelcast
import com.hazelcast.core.IdGenerator

def customersMap = Hazelcast.getMap("customers")
def idGen = Hazelcast.getIdGenerator("customer-ids")
def id = idGen.newId()
customersMap.put(id, "Customer $id")


I can open up a few different command prompts and enter:

> groovy HazelcastGroovynessAdd.groovy

Now, the customers Map has a few customers in it and our Groovy scripts are still running. Let's add an com.hazelcast.core.EntryListener to the customers Map so we can detect a com.hazelcast.core.EntryEvent. Here is HazelcastGroovyness.groovy:

import com.hazelcast.core.Hazelcast
import com.hazelcast.core.EntryListener
import com.hazelcast.core.EntryEvent

def listener = [
    entryAdded: { EntryEvent ev ->
        println "key $ev.key was added with value $ev.value to $ev.name"
        Hazelcast.getMap("customers").values().each {
            println it
        }
    },
    entryUpdated: { EntryEvent ev -> },
    entryRemoved: { EntryEvent ev -> },
    entryEvicted: { EntryEvent ev -> }
] as EntryListener

def customersMap = Hazelcast.getMap("customers")
customersMap.addEntryListener(listener, true)

In the above code, we define listener which implements com.hazelcast.core.EntryListener. I now start up HazelcastGroovyness.groovy at a new command prompt(s):

> groovy HazelcastGroovyness.groovy

We can go back to our original HazelcastGroovynessAdd.groovy script and open (re-open) a few more command prompts and run the script that adds customers to the Map. Now in each running instance of HazelcastGroovyness.groovy we see something like:

key 2000001 was added with value Customer 2000001 to c:customers
Customer 2000001
Customer 1000001
Customer 1

Hazelcast is very cool, easy to use technology that provides distributed data with a few lines of code, especially with Groovy. More information can be found at Hazelcast's website and at the project site at Google Code.

Monday, May 11, 2009

Groovy Prime Numbers

The other day I wanted to prove the power of Groovy to a few more core Java developers. I sat down and played with a little script that I think proves the power, or ease of use, of Groovy while having fun with number theory. My goal was to have a Collection that contains Prime Numbers calculated from a given range of numbers x to y, or in Groovy syntax x..y. I am taking a few things for granted with this script. For example, I know that 2 is the lowest Prime Number (it helps simplify the algorithm) and that 1 is not a Prime Number. So here's the script:

def t = 1..100
def v = []

t.each { n ->
    (2..n).each { d ->
        if(n % d == 0 && n != d)
        v.add(n)
    }
}

println t - v - 1

We have our range of numbers t and we are capturing the non-Prime numbers and adding them to our Collection v. The final line of the script is doing a lot of groovy work for us that would take a few more lines of code with plain Java syntax. What is it doing for us? It is taking our range of numbers t and subtracting (removing) our non-Prime numbers collected in v. This line is also removing the number 1 because we know that 1 is not a Prime Number. Finally, it is printing the result like so:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

Very cool stuff. Now, I know that many of us are rarely building a Collection of Prime Numbers and I know this script does not do things in a timely manner with a range like 1..10000 (it took a couple of minutes), but I am sure this feature of Collections in Groovy can be utilized in many ways in my development.

Monday, February 09, 2009

Groovy Closure Currying

So I have been diving into Groovy a bit heavier lately and I was just checking out Closure currying. So let's say I have a Closure, like myClosure below, that takes in 2 parameters, var1 and var2. Let's look at the code:

...
def myClosure = { var1, var2 ->
    var1.call()
    var2.call()
}

def walk = { println "I am walking..." }
def run = { println "I am running..." }
def fly = { println "I am flying..." }

myClosure(walk, run)
myClosure(walk, fly)

def walkFirst = myClosure.curry(walk)
walkFirst(run)
walkFirst(fly)
...

When I call myClosure(walk, run) and myClosure(walk, fly) I get:

...
I am walking...
I am running...
I am walking...
I am flying...
...


Well what curry() does for us is take out some of the duplication that we may find when passing in parameters to our Closure. I notice that the Closure walk is passed in both times because we want to walk before we can run or fly. If we take advantage of curry() we can create another Closure called walkFirst. The Closure, walkFirst, is created here:

...
def walkFirst = myClosure.curry(walk)
...


This now gives us a simpler Closure we can send run and fly into without worrying about having to pass in walk first. This is a very useful utility of Groovy and Closures and we get exactly what we were expecting:

...
I am walking...
I am running...
I am walking...
I am flying...
...


Very cool stuff. Do yourself a favor, read more about Groovy.

Sunday, October 19, 2008

Editable Flex Datagrid and Grails

I have been really digging into Flex lately and I have been complimenting Flex's incredibly nice UI capabilities with services written on Grails. I am extremely impressed with Flex and Grails really helps me get things up and running very quickly (you already know this if you are using Grails). Let's look at a quick example of where I am using one domain class and a few simple Grails actions in a controller in order to provide search and editing capabilities to a simple Flex application based on a datagrid.

The Grails domain class, Item.groovy:

...
class Item {

    String name
    String brand
    String line
}
...

The Grails controller class ItemController.groovy:

...
class ItemController {

    def search = {
        if(!params.max) {
            params.max = 100
        }
        if(!params.name) {
            params.name = ""
        }

        def itemList = Item.findAllByNameLike("$params.name%",[max:params.max])

        render(contentType:"text/xml") {
            items {
                for(i in itemList) {
                    item {
                        id(i.id)
                        name(i.name)
                        brand(i.brand)
                        line(i.line)
                    }
                }
            }
        }
    }

    def save = {
        if(params.id) {
            def item = Item.get(params.id)

            if(item) {
                item.properties = params
                if(!item.hasErrors() && item.save()) {
                    render ""
                }
                else {
                    render ""
                }
            }
        }
    }
}
...


I also added this to the conf/BootStrap.groovy so I would have some data to work with once I started up the Grails applicaiton. The code below creates 1,000 items during start-up:

...
def init = { servletContext ->

    (1..1000).each {
        new Item(name: "Item $it", brand: "My Brand", line: "My Line").save()
    }
}
...

I mostly worked with only 1,000 items, but I increased this up to 100,000 items to put it through some tests and it worked very nicely.

Now let's dive right into the MXML. Here is the entire itemlist.mxml file:

...
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
<![CDATA[

import mx.controls.Alert;
import mx.events.DataGridEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

[Bindable]
private var itemId:String;

[Bindable]
private var itemName:String;

[Bindable]
private var itemBrand:String;

[Bindable]
private var itemLine:String;

private function sendItemData(event:DataGridEvent):void
{
var myEditor:TextInput = TextInput(event.currentTarget.itemEditorInstance);
itemName = myEditor.text;

itemId = event.currentTarget.editedItemRenderer.data["id"];
itemBrand = event.currentTarget.editedItemRenderer.data["brand"];
itemLine = event.currentTarget.editedItemRenderer.data["line"];

itemSaveService.send();
}

protected function filterList():void
{
itemSearchService.send();
}

private function fault_Handler(event:FaultEvent):void
{
Alert.show(event.fault.message, "Could not load items.");
}
]]>
</mx:Script>

<mx:HTTPService
id="itemSaveService"
method="POST"
url="http://localhost:8080/itemlist/item/save"
resultFormat="e4x"
fault="fault_Handler(event);"
showBusyCursor="true">
<mx:request xmlns="">
<id>{itemId}</id>
<name>{itemName}</name>
<brand>{itemBrand}</brand>
<line>{itemLine}</line>
</mx:request>
</mx:HTTPService>

<mx:HTTPService
id="itemSearchService"
method="GET"
url="http://localhost:8080/itemlist/item/search"
resultFormat="e4x"
fault="fault_Handler(event);"
showBusyCursor="true">
<mx:request xmlns="">
<name>{searchBox.text}</name>
</mx:request>
</mx:HTTPService>

<mx:Panel title="Item List" height="100%" width="100%" paddingTop="10" paddingLeft="10" paddingRight="10">

<mx:Label text="Search:"/><mx:TextInput id="searchBox" enter="filterList();"/>

<mx:DataGrid id="dg" width="100%" height="50%" rowCount="5"
dataProvider="{itemSearchService.lastResult.item}"
editable="true"
itemEditEnd="sendItemData(event);">
<mx:columns>
<mx:DataGridColumn dataField="id" headerText="Id" editable="false"/>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="brand" headerText="Brand" editable="false"/>
<mx:DataGridColumn dataField="line" headerText="Line" editable="false"/>
</mx:columns>
</mx:DataGrid>

</mx:Panel>
</mx:Application>
...

Now that all of the code is out on the table, we can start to dissect what is happening with the Flex UI.

When the application starts up:




Once we type in "Item " and press enter:




When we click on a value under the "Name" column in our datagrid:




We have 2 HTTPService's setup to send requests back to our Grails controller at http://localhost:8080/itemlist/item/save and http://localhost:8080/itemlist/item/search. The first service call will send all the item data to the ItemController's save action and the second one will send our search box's text to the ItemController's search action. We have ActionScript functions that handle the "Enter" key press event on the search box and we also have a function that will be called after the datagrid field has been edited.

Most of the code is pretty self explanatory but if you have any questions, feel free to contact me. Also, Marcel Overdijk has some great posts on Grails and Flex that can really help out when you get stuck.

Saturday, March 15, 2008

Create Bugs with Bugzilla's XMLRPC Web Service and Groovy

The other day I was looking into moving development bugs from one bug system over to Bugzilla. Someone in my group pointed out that Bugzilla had an XMLRPC Web service exposed at:
http://bugzilla-address/xmlrpc.cgi.

The current bug system had a feature that would export the bugs into XML data. I exported the bug data, moved the XML file to my local machine, and opened the Groovy Console. Let's check out how simple things can be.

Here is sort of what the XML looks like:

...
<issues>
<issue>
<product>Product Name</product>
<component>Component Name</component>
<summary>Summary</summary>
<version>1.0</version>
<description>Description</description>
<opsys>Operating System</opsys>
<platform>Platform</platform>
<priority>High</priority>
<severity>Low</severity>
<status>Open</status>
</issue>
</issues>
...


Here is what we need to import into our Groovy script:

...
import groovy.util.XmlSlurper

import java.util.Map
import java.util.HashMap
import java.net.ServerSocket

import org.apache.commons.httpclient.*
import org.apache.xmlrpc.client.*
...


Here is our class, main method, dependencies, and setup of the XMLRPCClient (I needed the HTTPClient and XMLRpcCommonsTransportFactory because Bugzilla likes to deal with Cookies after logged in):

...
public class BugzillaCreateFromXML {

// get the xml data of our issues in the .xml file
def xmlData = new XmlSlurper().parse(new File("C:/issues.xml"))

def httpClient = new HttpClient()
def rpcClient = new XmlRpcClient()
def factory = new XmlRpcCommonsTransportFactory(rpcClient)
def config = new XmlRpcClientConfigImpl()factory.setHttpClient(httpClient)

rpcClient.setTransportFactory(factory)
config.setServerURL(new URL("http://bugzilla-addres/xmlrpc.cgi"))
rpcClient.setConfig(config)

public static void main(String[] args) {
    // here is where the work getting done
    // map of the login data
    Map loginMap = new HashMap()
    loginMap.put("login", "admin")
    loginMap.put("password", "admin")
    loginMap.put("rememberlogin", "Bugzilla_remember")

    // login to bugzilla
    def loginResult = rpcClient.execute("User.login", loginMap)
    println loginResult

    // map of the bug data
    Map bugMap = new HashMap()

    // iterate through each issue
    xmlData.issue.each {
        bugMap.put("product", it.product.text())
        bugMap.put("component", it.component.text())
        bugMap.put("summary", it.summary.text())
        bugMap.put("version", it.version.text())
        bugMap.put("description", it.description.text())
        bugMap.put("op_sys", it.opsys.text())
        bugMap.put("platform", it.platform.text())
        bugMap.put("priority", it.priority.text())
        bugMap.put("severity", it.severity.text())
        bugMap.put("status", it.status.text())

        // create bug
        def createResult = rpcClient.execute("Bug.create", bugMap)
            println createResult

            // clear bugMap so we can re-populate it with the next issue
            bugMap.clear()
        }
    }
}
...

That is it. It took me about 30 minutes to parse the XML file and loop through each node with Groovy. I spent about an hour finding out that HTTPClient was also needed, I originally started working with Groovy's XMLRPC library. You need to have the appropriate Apache XMLRPC Client libraries in place in your Groovy lib directory. I ran this from the Groovy Console and it did exactly what I needed it to do. The Groovy file is available for download .