Odelia>Technologies

Exposer une Closure Groovy en tant que service HTTP

| |

L'outil GRAPE (GRoovy Adaptable/Advanced Packaging Engine) de Groovy constitue un excellent outil pour tester le framework d'intégration Apache Camel : dans cet article, nous allons définir une route Camel dans un script Groovy qui nous permettra d'exposer une Closure Groovy au travers d'un service HTTP, tandis que les dépendances de compilation et d'exécution seront résolues par GRAPE.
Plus précisément, la route étant prédéfinie, l'adresse du service, ainsi que le code Groovy à exécuter, seront placés dans un fichier externe et définis par un Domain Specific Language (DSL) Groovy simple que nous allons décrire.

Le DSL GroovyCamel

Ce DSL, que nous appellerons GroovyCamel, permet tout simplement de spécifier l'URL et le code Groovy (une Closure) qui sera exécuté lorsqu'une requête HTTP sera émise sur cette URL.
En voici tout de suite un exemple :

"http://localhost:8080/test" { ex ->
    println 'Salut !'
}

Simple, non ? Tout l'intérêt de ce DSL succinct est sa simplicité, et que l'on a qu'à se préoccuper du code à implémenter, la route Camel étant déduite de cette définition.

La route allant de Jetty à Processor

Le script GroovyCamel.groovy (fourni en fichier attaché à cet article) permet de définir et d'exécuter dans un contexte Camel, une route qui est construite après l'analyse du fichier DSL passé en argument de la méthode main du script.
Notez que les annotations GRAPE @Grab permettent de rechercher et de résoudre les dépendances nécessaires à l'exécution du script, à savoir les modules camel-groovy et camel-jetty de la version 2.3.0 d'Apache Camel.
C'est dans la méthode configure, héritée de la classe Camel GroovyRouteBuilder, que la route Camel est configurée, une fois que l'URL et la Closure Groovy ont été obtenues du fichier DSL : cette route part en fait d'un composant jetty qui sera à l'écoute sur l'URL analysée, et se poursuit vers un objet de type interface Processor, dont l'implémentation sera la Closure Groovy !
Car en effet, en Groovy, une Closure peut implémenter une interface.

Voici le code du script GroovyCamel.groovy :

package com.odelia.groovy.camel

import org.apache.camel.impl.DefaultCamelContext
import org.apache.camel.Processor
import org.apache.camel.language.groovy.GroovyRouteBuilder


@Grab(group='org.apache.camel', module='camel-groovy', version='2.3.0')
@Grab(group='org.apache.camel', module='camel-jetty', version='2.3.0')
class SimpleRouteBuilder extends GroovyRouteBuilder {

    def dslFilename
    def uri
    def processor
   
    void parse(filename) {
        def shell = new GroovyShell()
        def script = shell.parse(new File(filename))
        script.metaClass.methodMissing = { String name, args ->
            uri = name
            processor = args[0]
            processor.delegate = this
            processor.resolveStrategy = Closure.DELEGATE_ONLY
        }
        script.run()
    }

    void configure() {
        parse(dslFilename)   
        from("jetty:${uri}").process(processor as Processor)
    }
   
    static void main(String[] args) {
        if (args.size() != 1) {
            println 'Usage: groovy GroovyCamel.groovy <dsl_filename>'
            return
        }

        def camelCtx = new DefaultCamelContext()
        camelCtx.addRoutes(new SimpleRouteBuilder(dslFilename: args[0]))
        camelCtx.start()
    }
}

Dans un DSL GroovyCamel, la variable de la Closure représente un objet Camel de type Exchange qui permet de lire le message d'entrée et de définir le message de sortie ; renvoyer une réponse est ainsi très simple :

"http://localhost:8080/test" { ex ->
        ex.out.body = 'Salut !'
}

L'exécution du script GroovyCamel.groovy démarrera un contexte Camel, et la chaîne de caractères 'Salut !' pourra être renvoyée par un navigateur Internet, si vous naviguez vers l'URL http://localhost:8080/test.

Dans un contexte Web, le builder Groovy MarkupBuilder permet de construire une page web complète ; celui-ci est utilisé dans le fichier GroovyProcessor.groovy donné à titre de démonstration :

import groovy.xml.MarkupBuilder

"http://localhost:8080/test" { ex ->
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
       
    xml.html {
        head { title('GroovyCamel') }
        body {
            h1('GroovyCamel')
            p("Fichier DSL GroovyCamel : $dslFilename")
            p("Exposé sur l'URL : $uri")
            h1('Headers')
            table {
                ex.in.headers.each { h ->
                    tr {
                        td(h.key); td(h.value)
                    }
                }
            }
            h1('Body')
            p(ex.in.getBody(String)?: '(aucun)')                               
        }              
    }

    ex.out.body = writer.toString()
}

Utilisation du script GroovyCamel.groovy

Vous pouvez exécuter le script GroovyCamel.groovy avec la commande groovy :

groovy GroovyCamel.groovy <fichier_dsl_groovy>

Par exemple :

groovy GroovyCamel.groovy GroovyProcessor.groovy

Les fichiers GroovyCamel.groovy et GroovyProcessor.groovy étant fournis en pièces jointes à cet article.

Fichier attachéTaille
GroovyProcessor.groovy667 octets
GroovyCamel.groovy1.33 Ko

balises dans Langages et systèmes

AJAX cajo Camel DSL Grails GraphicsBuilder Groovy Java JBI prefuse RSS ServiceMix