Category Archives: grails

XML rendering in Grails

Notes taken when researching how to render efficiently a possibly large object tree resulting in complex XML.

Disclaimer: tested with Grails 1.3.7, but it should be valid in more recent framework versions

Convert object to XML string using XML converter

def ping = {
    def result = new Result(response: 'OK')
    def xml = new XML(result)
    render text: xml, contentType: 'text/xml', encoding: 'UTF-8'
}
  • adds explicit <class>…</class> element to the output
  • double transformation – object -> XML string -> ServletResponse output stream
  • relies on poorly documented Grails contracts – here be dragons

Variation – deep conversion

XML.use('deep') {
    def xml = new XML(result)
    render text: xml, contentType: 'text/xml', encoding: 'UTF-8'
}

Variation – customize conversion with a custom marshaller

class ResultMarshaller implements ObjectMarshaller {
    @Override
    boolean supports(object) {
        object instanceof Result
    }

    @Override
    void marshalObject(object, Converter converter) {
        // converter is an instance of XML
        converter.build {
            response object.response
        }
    }
}

class ResultRootElementCustomizingMarshaller extends ResultMarshaller implements NameAwareMarshaller {
    @Override
    String getElementName(o) {
        'wynik'
    }
}

Unit tests

def 'ping, no marshaller'() {
    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, """<result>
    <class>${Result.name}</class>
    <response>OK</response>
</result>"""
}

def 'ping, marshaller'() {
    given:
    XML.registerObjectMarshaller new ResultMarshaller()

    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<result><response>OK</response></result>'
}

def 'ping, marshaller customizing root element name'() {
    given:
    XML.registerObjectMarshaller new ResultRootElementCustomizingMarshaller()

    when:
    controller.ping()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<wynik><response>OK</response></wynik>'
}

Render object to the response using XML converter

def pingConverterRendersToResponse = {
    def xml = new XML(new Result(response: 'OK'))
    xml.render response
}

Unit tests

def 'ping, converter renders to response'() {
    when:
    controller.pingConverterRendersToResponse()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, """<result>
<class>${Result.name}</class>
<response>OK</response>
</result>"""
}

Convert object to XML string using StreamingMarkupBuilder

def pingViaBuilder = {
    def res = new Result(response: 'OK')
    render contentType: 'text/xml', encoding: 'UTF-8', {
        result {
            response res.response
        }
    }
}
  • feature provided by render method
  • direct write into ServletResponse writer
  • could lead to repeated rendering code

Unit tests

def 'ping, direct render'() {
    when:
    controller.pingViaBuilder()

    then:
    XmlAsserts.xmlsEqual controller.response.contentAsString, '<result><response>OK</response></result>'
}

Common objects/helper methods used in examples

class Result {
    String response
}

class XmlAsserts {
    static void xmlsEqual(String actual, String expected) {
        XMLUnit.ignoreWhitespace = true
        def diff = new Diff(actual, expected)
        assert diff.similar(), "${diff.toString()}\nActual XML: $actual\n\nExpected XML: $expected"
    }
}

cut + grep + awk + sed in action; prerequisite: Git repository:

git status -s | \
cut -c4- | \
grep "$test_type.*[Test|Spec]" | \
awk 'BEGIN { FS = "/" } ; { print ($(NF)) }' | \
sed 's/\.groovy//' | tr '\n' ' '

Find all dirty Grails tests

Asynchronous tests with GPars (Osoco test gallery, part 4)

If you wrote multithreaded code in Groovy/Grails, I’m sure you stumbled upon the GPars library. It simplifies parallel processing – sometimes it’s as easy as wrapping a code fragment with a GPars closure, changing the iteration method (in our example from each to eachParallel) and passing the closure to a GPars pool. The library implementation handles the executor pool creation and adds new methods to collections.

Whenever I deliberately add multithreading, I always separate responsibilities (processing logic and concurrency handling). I wrap the single-threaded class with a new one, handing the parallel execution (creating a pool, managing threads, handling cancellation, etc.):

class MultithreadedProcessorService {
    ProcessorService processorService
    def threadPoolSize = ConfigurationHolder.config.threadPool.size

    void processMultithreaded(batches) {
        GParsPool.withPool(threadPoolSize) {
            batches.eachParallel { batch ->
                processorService.process(batch)
            }
        }
    }
}

class ProcessorService {
    void process(batch) {
        // some processing
    }
}

To test the multithreaded class you can you use Spock interactions. As opposed to Groovy and Grails mocks, they are thread-safe and you won’t get any weird and unstable results:

class MultithreadedProcessorServiceSpec extends UnitSpec {
    private MultithreadedProcessorService multithreadedProcessorService
    // Using Spock mocks because they are thread-safe
    private ProcessorService processorService = Mock(ProcessorService)

    def setup() {
        mockConfig('threadPool.size=2')
        multithreadedProcessorService = new MultithreadedProcessorService(
            processorService: processorService
        )
    }

    def 'processes batches using multiple threads'() {
        given:
        def batches = [[0, 1], [2, 3, 4], [5]]
        def processedBatches = markedAsNotProcessed(batches)

        when:
        multithreadedProcessorService.processMultithreaded(batches)

        then:
        batches.size() * processorService.process({ batch ->
            processedBatches[batch] = true
            batch in batches
        })
        assertAllProcessed(processedBatches)

    }

    private markedAsNotProcessed(batches) {
        batches.inject([:]) { processed, batch ->
            processed[batch] = false
            processed
        }
    }

    private void assertAllProcessed(batches) {
        assert batches*.value == [true] * batches.size()
    }
}

This post series present the best of Osoco tests – tests that were tricky or we are just proud of. You can find a runnable source code for this test and more in the Grails Test Gallery project shared on GitHub.

Grails base persistence specification (Osoco test gallery, part 3)

In our projects we include at least one integration test per domain class. We want to assure us that the GORM mapping is correct and the class is persistable in the target database.

The test plan is simple:

  • create a valid persistable sample of the domain object
  • save it
  • clear Hibernate first level cache (i.e. flush and clear current session)
  • retrieve the object once again and compare it with the previously saved object. They must be equal as by equals() but be different object references

We put the steps above in a base abstract specification. In concrete specifications we implement merely the factory method spawning a persistable object instance.

abstract class PersistenceSpec extends IntegrationSpec {
    SessionFactory sessionFactory

    protected abstract createPersistableDomainObject()
    
    def 'persistable domain object should be able to be saved and retrieved'() {
        given:
        def persistableDomainObject = createPersistableDomainObject()

        when:
        def savedDomainObject = persistableDomainObject.save()

        then:
        savedDomainObject.id != null

        when:
        clearFirstLevelCache()

        def retrievedDomainObject = persistableDomainObject.class.get(savedDomainObject.id)

        then:
        savedDomainObject == retrievedDomainObject
        !savedDomainObject.is(retrievedDomainObject)
    }

    private clearFirstLevelCache() {
        sessionFactory.currentSession.flush()
        sessionFactory.currentSession.clear()
    }
}

This post series present the best of Osoco tests – tests that were tricky or we are just proud of. You can find a runnable source code for this test and more in the Grails Test Gallery project shared on GitHub.

Grails equals and hashCode testing (Osoco test gallery, part 2)

If you work with GORM and your objects are held in collections, you should implement equals and hashCode methods. As everything, they should be thouroughly tested if they obey equals-hashCode contract. At Osoco we created a equals-hashcode-test Grails plugin that provides a base Spock specification for that.

In your equals and hashCode tests you simply have to extend the EqualsHashCodeSpec and provide at least two methods:

  • a factory method createDomainObjectToCompare that will create a fresh object for the comparison
  • a map of modified properties included in equals and hashCode
  • optionally a map of modified properties ignored in both methods

Additionally in case of inheritance, we check whether the equals method complies with the symmetry rule. We do it in an extra feature method added to the spec:

def 'equals relation must be symmetric with inheritance'() {
    given:
    def content = new Content()

    and:
    def book = new Book()

    expect:
    (content == book) == (book == content)
}

You may say, in Grails 2.0 and Groovy 1.8 there are @Equals and @HashCode AST transformations and you don’t need to write tests of them. I agree to some point. I think you can trust Groovy developers and you don’t have to test the methods for reflexivity, symmetry, transivity, consistency, and ‘non-nullity’. Anyway, you have to test the annotation configuration if it includes the properties that actually account for the logical equality between objects.

In the future releases of the plugin we will surely simplify the base specification and remove some checks but we will surely continue testing both methods (with our plugin it’s dirt-cheap!)


This post series present the best of Osoco tests – tests that were tricky or we are just proud of. You can find a runnable source code for this test and more in the Grails Test Gallery project shared on GitHub.

Follow

Get every new post delivered to your Inbox.

Join 373 other followers