[[languages]]
= Languages

Camel K supports integration written in the following languages:name: value

[options="header"]
|=======================
| Language      | Description
| Java          | Both integrations in source `.java` files or compiled `.class` file can be run.
| XML           | Integrations written in plain XML DSL are supported (Spring XML or Blueprint not supported).
| Groovy        | Groovy `.groovy` files are supported (experimental).
| JavaScript    | JavaScript `.js` files are supported (experimental).
| Kotlin        | Kotlin Script `.kts` files are supported (experimental).
|=======================

[WARNING]
====
Work In Progress
====

=== Java

Using Java to write an integration to be deployed using camel-k is not different from defining your routing rules in Camel with the only difference that you do not need to build and package it as a jar.

[source,java]
.Example
----
import org.apache.camel.builder.RouteBuilder;

public class Sample extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("timer:tick")
            .setBody()
              .constant("Hello Camel K!")
            .to("log:info");
    }
}
----

=== XML

Camel K support the standard Camel Routes XML DSL:

[source,xml]
.Example
----
<routes xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="timer:tick"/>
        <setBody>
            <constant>Hello Camel K!</constant>
         </setBody>
        <to uri="log:info"/>
    </route>
</routes>
----

=== Groovy

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

[source,java]
----
from('timer:tick')
    .process { it.in.body = 'Hello Camel K!' }
    .to('log:info')
----

Camel K extends the Camel Java DSL making it easier to configure the context in which the integration runs using the top level _context_ block

[source,java]
----
context {
  // configure the context here
}
----

At the moment the enhanced DSL provides a way to bind items to the registry, to configure the components the context creates and some improvements over the REST DSL.

- *Registry*
+
The registry is accessible using the _registry_ block inside the _context_ one:
+
[source,java]
----
context {
    registry {
      bind "my-cache", Caffeine.newBuilder().build() // <1>
      bind "my-processor", processor { // <2>
         it.in.body = 'Hello Camel K!'
      }
      bind "my-predicate", predicate { // <3>
         it.in.body != null
      }
    }
}
----
<1> bind a bean to the context
<2> define a custom processor to be used later in the routes by ref
<2> define a custom predicate to be used later in the routes by ref


- *Components*
+
Components can be configured within the _components_ block inside the _context_ one:
+
[source,java]
----
context {
    components {
        'seda' { // <1>
            queueSize = 1234
            concurrentConsumers = 12
        }

        'log' { // <2>
            exchangeFormatter = {
                'body ==> ' + it.in.body
            } as org.apache.camel.spi.ExchangeFormatter
        }
    }
}
----
<1> configure the properties of the component whit name _seda_
<2> configure the properties of the component whit name _log_
+
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
+
[source,java]
----
context {
    components {
        ...

        'log' {
            formatter {
                'body ==> ' + it.in.body
            }
        }
    }
}
----
+
which is much better.
+
[TIP]
====
You can provide your custom extensions by packaging them in a dependency you declare for your integration.
====

- *Rest*
+
Integrations's REST endpoints can be configured using the top level _rest_ block:
+
[source,java]
----
rest {
    configuration { // <1>
        host = 'my-host'
        port '9192'
    }

    path('/my/path') { // <2>
        // standard Rest DSL
    }
}
----
<1> Configure the rest engine
<2> Configure the rest endpoint for the base path '/my/path'

=== Kotlin

An integration written in Kotlin looks very similar to a Java one except it can leverages Kotlin's language enhancements over Java:

[source,java]
----
from('timer:tick')
    .process { e -> e.getIn().body = 'Hello Camel K!' }
    .to('log:info');
----

Camel K extends the Camel Java DSL making it easier to configure the context in which the integration runs using the top level _context_ block

[source,java]
----
context {
  // configure the context here
}
----

At the moment the enhanced DSL provides a way to bind items to the registry, to configure the components the context creates and some improvements over the REST DSL.

- *Registry*
+
The registry is accessible using the _registry_ block inside the _context_ one:
+
[source,java]
----
context {
    registry {
        bind("my-cache", Caffeine.newBuilder().build()) // <1>
        bind("my-processor", processor { // <2>
            e -> e.getIn().body = "Hello"
        })
        bind("my-predicate", predicate { // <2>
            e -> e.getIn().body != null
        })
    }
}
----
<1> bind a simple bean to the context
<2> define a custom processor to be used later in the routes by ref
<2> define a custom predicate to be used later in the routes by ref


- *Components*
+
Components can be configured within the _components_ block inside the _context_ one:
+
[source,java]
----
context {
    components {
        component<SedaComponent>("seda") { //<1>
            queueSize = 1234
            concurrentConsumers = 12
        }

        component<SedaComponent>("mySeda") { // <2>
            queueSize = 4321
            concurrentConsumers = 21
        }

        component<LogComponent>("log") { // <3>
           setExchangeFormatter {
               e: Exchange -> "" + e.getIn().body
           }
       }
    }
}
----
<1> configure the properties of a component whit type _SedaComponent_ and name _seda_
<2> configure the properties of a component with type SedaComponent and name _mySeda_, note that as _mySeda_ does not represent a valid component scheme, a new component of the required type will be instantiated.
<3> configure the properties of the component whit name _log_
+
[NOTE]
====
As for Groovy, you can provide your custom extension to the DSL
====

- *Rest*
+
Integrations's REST endpoints can be configured using the top level _rest_ block:
+
[source,java]
----
rest {
    configuration {
        host = "my-host"
        port = "9192"
    }

    path("/my/path") { // <2>
        // standard Rest DSL
    }
}
----
<1> Configure the rest engine
<2> Configure the rest endpoint for the base path '/my/path'

=== JavaScript

The integration written in JavaScript looks very similar to a Java one:

[source,js]
----
function proc(e) {
    e.getIn().setBody('Hello Camel K!')
}

from('timer:tick')
    .process(proc)
    .to('log:info')
----

For JavaScript integrations, Camel K does not yet provide an enhanced DSL but you can access to some global bounded objects such as a writable registry and the camel context so to set the property _exchangeFormatter_ of the _LogComponent_ as done in previous example, you can do something like:

[source,js]
----

l = context.getComponent('log', true, false)
l.exchangeFormatter = function(e) {
    return "log - body=" + e.in.body + ", headers=" + e.in.headers
}
----
