Writing Integrations in Groovy

An integration written in Groovy looks very similar to a Java one except it can leverages Groovy’s language enhancements over Java such as closures:

from('timer:tick')
    .process { it.in.body = 'Hello Camel K!' }
    .to('log:info')

Configuring the Application

Camel K extends the Camel Java DSL making it easier to configure Camel’s behavior using the top level camel block

camel {
  // configure camel here
}

The camel block allows to configure the following Camel features:

  • Components

    camel {
        components {
            seda { (1)
                queueSize = 1234
                concurrentConsumers = 12
            }
    
            log { (2)
                exchangeFormatter = {
                    'body ==> ' + it.in.body
                } as org.apache.camel.spi.ExchangeFormatter
            }
    
            mySeda(SedaComponent) { (3)
                queueSize = 4321
                concurrentConsumers = 21
            }
        }
    }
    1 configure the properties of the component whit name seda
    2 configure the properties of the component whit name log
    3 creates and configure a component of type SedaComponent whose name is mySeda

    Setting the property exchangeFormatter looks a little ugly as you have to declare the type of your closure. For demonstration purpose we have created a Groovy extension module that simplify configuring the exchangeFormatter so you can rewrite your DSL as

    camel {
        components {
            log {
                formatter {
                    'body ==> ' + it.in.body
                }
            }
        }
    }

    which is much better.

    You can provide your custom extensions by packaging them in a dependency you declare for your integration.

  • Languages

    camel {
        languages {
            language("bean") { (1)
                beanType = String.class
                method = "toUpperCase"
            }
            myBean(BeanLanguage) { (2)
                beanType = String.class
                method = "toLowerCase"
            }
            simple { (3)
            }
        }
    }
    1 configure the properties of the language whit name bean
    2 creates and configure a language of type BeanLanguage whose name is myBean
    3 configure the properties of the language whit name simple
  • DataFormats

    camel {
        dataFormats {
            dataFormat("json-jackson") { (1)
                unmarshalType = Map.class
                prettyPrint = true
            }
            myJackson(JacksonDataFormat) { (2)
                unmarshalType = String.class
                prettyPrint = false
            }
            csv { (3)
            }
        }
    }
    1 configure the properties of the data format whit name json-jackson
    2 creates and configure a data format of type JacksonDataFormat whose name is myJackson
    3 configure the properties of the data format whit name csv

Beans

Beans can be bound to the registry using a dedicated bean DSL :

beans {
    myCache = Caffeine.newBuilder().build() (1)

    myProcessor = processor { (2)
        it.in.body = 'Hello Camel K!'
    }

    myPredicate = predicate { (3)
        it.in.body != null
    }

    dataSource(org.apache.commons.dbcp2.BasicDataSource) { (4)
        driverClassName = "org.h2.Driver"
        url = "jdbc:h2:mem:camel"
        username = "sa"
        password = ""
    }
}
1 define a bean
2 define a custom processor
3 define a custom predicate
4 define a custom bean with name dataSource and type org.apache.commons.dbcp2.BasicDataSource

Rest Support

Integrations’s REST endpoints can be configured using the top level rest block:

rest {
    configuration { (1)
        host = 'my-host'
        port '9192'
    }

    path('/my/path') {
        get('/get') { (2)
            consumes 'application/json'
            produces 'application/json'
            to 'direct:get'
        }
    }

    post { (3)
        path '/post'
        consumes 'application/json'
        produces 'application/json'
        to 'direct:post'
    }
}
1 Configure the rest engine
2 Configure the behavior of the method GET for the path '/my/path/get' and invoke the endpoint 'direct:get'
3 Configure the behavior of the method POST for the path '/post' and invoke the endpoint 'direct:post'