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

Thursday, October 23, 2008

Creating RESTful services with Jersey and Groovy

It's been a while since I have put anything of substance on here, so I thought I would get back to it. I've been doing a lot of development with Groovy as of late, which I absolutely love. I wanted to combine that with another API that I really like, Jersey. Jersey is the open source JAX-RS (JSR 311) Reference Implementation for building RESTful Web services. So, for a simple service to create I decided on an Announcements service. This service when invoked would look for a file located in the User Home directory and create some HTML to return that would get rendered in the browser. This example also shows why I might want to use Groovy and Jersey together, as I will leverage Groovy's MarkupBuilder to generate the HTML that gets returned. I won't get into the details of how to setup Jersey as they have lots of samples that you can find here, and instead I'll just jump right in to what the source code would look like for my announcement service.


import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces

@Path("/announcements")
class AnnouncementService {
def announcements = "announcements.txt"
def errorReadingFileText = " - Error reading Announcements, Announcement File may not exist."
def noAnnouncementsText = " - No Announcements for Today"

@GET
@Produces (value=["text/html"])
String getHtmlResponse() {
// Return some cliched textual content
return getAnnouncements()
}

String getAnnouncements() {
def announcement = new File(System.getProperty("user.home") + File.separator + announcements)
def writer = new StringWriter()
def result = new groovy.xml.MarkupBuilder(writer);
result.html {
body {
h1(align: "center", "As of ${date()}")
table(width: "100%", height: "100%") {
td {
if (!announcement.exists()) {
tr(errorReadingFileText)
} else if (announcement.text.length() <= 0) {
tr(noAnnouncementsText)
} else {
announcement?.eachLine {
tr(" - $it")
}
}
}
}
}
}
return writer.toString()
}
}

As you can see from the code above that we annotate our class with the @Path annotation. This basically defines your jersey resource. So if you wanted to invoke this resource you URL would be something like http://localhost:8080/sample/announcements where sample is the name of your war you deployed to your application server. In the code you can also see that our method getHtmlResponse() has been annotated with @GET which tells Jersey to call this method when the HTTP Request is a GET Request. So given the same URL noted above, you could type that into a browser and hit enter and it will invoke the announcement resource with a GET request and invoke our method. One other thing to note is the @Produces annotation. This annotation defines the mime type to return your result. In our case we want the result to render as html so we set the type to text/html. This annotation is one that I had to do a little diffrent with Groovy. In Java the annotation would look like @Produces("text/html"), whereas in Groovy I have to specifically call out the value property and enclose the value in brackets like this, @Produces (value=["text/html"]). If I didn't enclose the property in the proper way I got this error when compiling:

Annotation list attributes must use Groovy notation [el1, el2]

The good thing is my IDE (I was using Netbeans) caught this before compile time, and I refrenced this issue to figure out how to get around it.

So, as you can see from my source code that the bulk of the work is taking place in the getAnnouncements() method. This was the reason that I wanted to use Groovy, I could very easily read a file, and based on the content create some html markup that would be returned to the browser. Not much to discuss here, except that MarkupBuilder is very cool. Alright, I think that's it, Good Luck. One last thing is I used Jersey 1.0 and Groovy 1.5.6 to work this example.

Monday, February 25, 2008

Groovy Stub's

I've been getting the chance to use Groovy a lot more at work lately and it's allowed me to really dig deep into some of the features. One of those being the use of Stub's for Unit testing. This is a fantastic feature and really simple to use. Lets look at the following code below:



def Entries[] getFeed(feedUrl) {
def url = new URL(feedUrl)
def data = url.getText()

def xmlSlurper = new XmlSlurper()
def feed = xmlSlurper.parseText(data)

if (feedType.toLowerCase() == "rss") {
feed.channel.item.each { item ->
def rssItem = new Entries()
rssItem.title = item.title
rssItem.link = item.link
rssItem.description = item.description
rssItem.date = item.pubDate
println (rssItem)
entries.add (rssItem)
}
} else {
feed.entry.each { entry ->
def atomEntry = new Entries()

atomEntry.title = entry.title
atomEntry.link = entry.link[0].@href
atomEntry.description = entry.content
atomEntry.date = entry.published
entries.add (atomEntry)
}
}
return (Entries[]) entries.toArray()
}



This code is pretty straight forward in that we are taking a URL for an RSS feed and going to read the feed and create an Entries object for each entry in the feed (this is a great example of how to use Groovy to consume rss feeds). The problem with unit testing this is the following section:



def url = new URL(feedUrl)
def data = url.getText()


I needed a way to stub this out so I could isolate this code at the unit level. Using Groovy's StubFor was the perfect way, the following is what my unit test looked like:



def void testAtomFeed() {
def block = new RssDataBlock()
block.engineURL = "http://bob.com"
block.feedType = "atom"
def urlStub = new StubFor(URL)
urlStub.demand.getText {
return "my mock data"
}
urlStub.use {
def entries = block.getFeed("http://cnn.com")
assertEquals("", block.generateOutput(),
"Title:${title}\r\nDescription:${description}\r\nLink:${link}\r\nPublished Date: ${date}")
}
}



The import thing that is going on is we are creating a Stub for the URL class (new StubFor(URL)), and intercepting when the getText() method gets called we are going to return our sample data set. To use the stub you simply call urlStub.use and in the closure you execute your test. As you can see above, I call getFeed() with my bogus URL; and then I assert that the output I was expecting (generateOutput()pretty prints my output for me) is equal to what I actually got.

This is very powerful and makes my life a whole lot easier. The more I use Groovy, the more I'm impressed (I've even been able to convert some of my co-workers :) ). Stay tuned, I plan on posting about Groovlets next......

Monday, January 21, 2008

A Socket Client for Groovy

Groovy Rocks!! I needed a simple client that would write data to a socket to test this application I was working on so I wrote it in Java since I had done that before. My code looked like the following:


public static void main(String[] args) throws Exception {
String data = "test data";
InputStream is = new ByteArrayInputStream(data.getBytes());

Socket socket = new Socket("localhost", 8282);
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
BufferedReader bw = new BufferedReader(new InputStreamReader(
socket.getInputStream()));

BufferedReader br = new BufferedReader(new InputStreamReader(is));
String userInput;

if ((userInput = br.readLine()) != null) {
System.out.println("yeb");
pw.println(userInput);
pw.close();
bw.close();
br.close();
socket.close();
System.exit(200);
}
}


After I got done, I was curious how I could do this same sort of thing in Groovy. So, I spun up the Groovy Shell and away I went.....


s = new Socket("localhost", 8283)
s << "Groovy Rocks"
s.close()


... I type go in my groovy shell and I'm done. Seriously, 3 lines of code and a quick shell to test it out. Groovy is awesome.

Wednesday, October 10, 2007

Two Minute Drill for Groovy

I know I promised more on Groovy, and I will get some more examples up here. However, one of my co-workers, Joe Kueser, just posted a great blog about Groovy. Basically Joe's Blog, "What Makes Groovy So...Groovy?", is a two minute read that provides a great summary of a lot of the features in Groovy. Be sure to check out Joe's Two Minute Drill.

Saturday, October 6, 2007

Converting Dom to Groovy Code

I've been looking into and learning a little Groovy on the side. One of the things I'm most interested in is learning how to use the MarkupBuilder provided by Groovy. Essentially this, in my opinion, is a much better way to parse and construct XML. As a developer I use XML almost daily. First I'm looking at integrating this into my unit tests. Today I stumbled on the DomToGroovy class and found this pretty cool. I was trying to figure out how to construct XML using Groovy. I knew what the XML looked liked, so using the DomToGroovy class I could get a good idea what the Groovy code would look like that I needed to write. Below is a sample of how to do this, and I recommend the GroovyConsole to test with.


import javax.xml.parsers.DocumentBuilderFactory
import org.codehaus.groovy.tools.xml.DomToGroovy

def xmlExample = """
<jbi:message tns="http://j2ee.netbeans.org/wsdl/rssWsdl"
type="tns:rssWsdlOperationRequest" version="1.0"
jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper">
<jbi:part>
<entrylist xmlns="http://xml.netbeans.org/schema/1.0/extensions/rssbc">
<entry>
<title>Entry 1</title>
<link>http://localhost:8000/rss/feed/entry1<link>
<description>First Entry</description>
<publishdate>Dec 7, 1976</publishdate>
</entry>
<entry>
<title>Entry 2</title>
<link>http://localhost:8000/rss/feed/entry2<link>
<description>Second Entry</description>
<publishdate>Dec. 7, 1976</publishdate>
</entry>
</entrylist>
</jbi:part>
</jbi:message>
"""

def builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
def inputStream = new ByteArrayInputStream(xmlExample.bytes)
def document = builder.parse(inputStream)
def output = new StringWriter()
def converter = new DomToGroovy(new PrintWriter(output))

converter.print(document)
println output.toString()

The output essentially shows you what the Groovy code would look like to construct the XML that we provided.

jbi:message(type:'tns:rssWsdlOperationRequest', version:'1.0',
xmlns:jbi:'http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper',
xmlns:tns:'http://j2ee.netbeans.org/wsdl/rssWsdl') {
jbi:part) {
EntryList(xmlns:'http://xml.netbeans.org/schema/1.0/extensions/rssbc') {
Entry) {
title('Entry 1')
link('http://localhost:8000/rss/feed/entry1')
description('First Entry')
publishDate('Dec 7, 1976')
}
Entry) {
title('Entry 2')
link('http://localhost:8000/rss/feed/entry2')
description('Second Entry')
publishDate('Dec. 7, 1976')
}
}
}
}

I think this is a pretty slick way to quickly generate a code sample so that you can quickly get started. More to come on Groovy later......