torsdag 17 mars 2011

Grails script for running different environments

I have seen questions for how to do this, but it was really hard finding an answer, so I thought I might as well document it here.

As always, it´s really easy once you know how:


includeTargets << grailsScript("Init")

import org.codehaus.groovy.grails.cli.GrailsScriptRunner

target(main: "The description of the script goes here!") {
System.setProperty("grails.env", "wadl")
GrailsScriptRunner.main("test-app")
}

setDefaultTarget(main)

torsdag 24 februari 2011

Building a DSL with groovy

I am currently working an a small 2-d game, where there're supposed to be some organisms spread out over the "world". I soon realized that I will have to test different setups of the world with organisms spread out.
I wrote some tests for different locations of organisms, and added some comments to explain it visually.

The original test contained something like this:

/**
* This creates a world with two organisms, located:
* ---------------
* |______________|
* |_____1________|
* |__________2___|
* |______________|
*
*/
def world = new World(organisms: [new Organism(id:1, x:10,y:10), new Organism(id:2, x:20, y:20)])

This was an obvious candidate for a DSL; I beleive that any time you feel the need to explain your code (visually) with a comment, you should consider building a DSL instead.


This is my first draft:

class Organism {
def id, x, y, radius
}
class World {
def width, height
def organisms = []
}
class WorldBuilder {
def yIndex = 0
def organisms = []
def radius = 1
def xIndex = 0
def getProperty(String name) {
def metaProperty = metaClass.getMetaProperty(name)
if (!metaProperty) {
if(name.length() > xIndex){
xIndex = name.length()
}
name.eachWithIndex {character, index ->
if (character != '_') {
println "create an organism with: x:$index, y:${yIndex}, radius: 1"
organisms << new Organism(id:character, x:index, y:yIndex, radius: radius )
}
}
yIndex++
println "get the property with name: $name"
return this
}else{
return metaProperty.getProperty(this)
}
}

def build() {
new World(organisms: organisms, width: xIndex, height: yIndex)
}
}

class WorldBuilderTests extends GroovyTestCase {
void test_build() {
World world = new WorldBuilder().with {
_________1_____2
__3__4_____a___6
________________
}.build()
assertEquals(6, world.organisms.size())

def org1 = world?.organisms.find { it.id == "1" }
assertEquals(1, org1.radius)
assertEquals(9, org1.x)
assertEquals(0, org1.y)

assertEquals(16, world.width)
assertEquals(3, world.height)

}
}

onsdag 9 februari 2011

GroovyWS: setting endpoint and soap headers

I've seen questions on various forums regarding how to change the endpoint and add soap headers with GroovyWS.
Since GroovyWS is using CXF under its cover it is possible (albeit not intuitive) to do:


@Grab(
group='org.codehaus.groovy.modules',
module='groovyws',
version='0.5.2')
import groovyx.net.ws.WSClient
import org.apache.cxf.headers.Header
import javax.xml.soap.SOAPFactory
import javax.xml.namespace.QName
import org.apache.cxf.binding.soap.SoapHeader
import javax.xml.ws.BindingProvider
import org.apache.cxf.interceptor.LoggingOutInterceptor

proxy = new WSClient(
"http://www.w3schools.com/webservices/tempconvert.asmx?WSDL", this.class.classLoader)
proxy.initialize()

def cxfClient = proxy.client

def headers = []

// Add header
SOAPFactory sf = SOAPFactory.newInstance()
def authElement = sf.createElement(
new QName("a_namespace", "a_name"))

def productToken =
authElement.addChildElement("productToken")

def tokenHeader = new SoapHeader(
new QName("a_namespace", "a_name"), authElement);
headers.add(tokenHeader);

cxfClient.getRequestContext()
.put(Header.HEADER_LIST, headers)

// Set endpoint
cxfClient.getRequestContext()
.put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "another_url")

// Add a logging interceptor
cxfClient.outInterceptors.add(
new LoggingOutInterceptor())

result = proxy.CelsiusToFahrenheit(0)
println """You are probably freezing at
${result} degrees Farhenheit"""

torsdag 27 januari 2011

Grails functional testing json rest services

As stated here: there is no simple way to parse out json/xml responses when you´re testing a rest web service with the Grails functional testing plugin.
And it isn't really clear (to me at least) how you can post json data in the request.
Here is an example how I managed to do it. To parse the response I used dozer:

import grails.converters.JSON

@Grab(group='net.sf.dozer', module='dozer', version='5.0')
import org.dozer.DozerBeanMapper

class MyLittlePogo{
def name
def status
}

class TempFunctionalTests extends functionaltestplugin.FunctionalTestCase {

def dozerBeanMapper = new DozerBeanMapper()

public void testPostContactSettings() throws Exception {
post("/api/rest/currentuser/contactsettings") {
headers.put("Content-Type", "application/json;charset=UTF-8")
body {
"""${new JSON(
new MyLittlePogo(
name: "aname",
status: "INSTALLED"))}"""
}
}

// Convert the response to an instance of MyLittlePogo
def responseText = new String(response.responseData_.body_)
def jsonObj = JSON.parse(responseText)
MyLittlePogo myLittlePogo = dozerBeanMapper.map( jsonObj, MyLittlePogo )

assertStatus 200
assertNotNull myLittlePogo
}
}

fredag 7 januari 2011

Grails and nonProxyHosts

When you´re working with Grails behind a proxy you might not be able to download dependencies.
This can be solved if you run add-proxy followed by set-proxy. In my application I have some soap clients, which fails when run through a proxy.
I need my soap call to go to the server directly, not going through the proxy.
This can be acheived by editing BuildConfig.groovy:

System.properties.put("http.nonProxyHosts", "company.host1.se|company.host2.se")