You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2021/03/16 21:28:43 UTC

[camel] branch master updated: dsl: add support for Kotlin

This is an automated email from the ASF dual-hosted git repository.

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 9315e56  dsl: add support for Kotlin
9315e56 is described below

commit 9315e561b9cdaae9250dee5fa4a88b79af7cd1ab
Author: Luca Burgazzoli <lb...@gmail.com>
AuthorDate: Tue Mar 16 15:16:41 2021 +0100

    dsl: add support for Kotlin
---
 bom/camel-bom/pom.xml                              |   5 +
 dsl/camel-kotlin-dsl/pom.xml                       | 232 +++++++++++++++++++++
 .../services/org/apache/camel/routes-loader/kts    |   2 +
 dsl/camel-kotlin-dsl/src/main/docs/kotlin-dsl.adoc |  13 ++
 .../dsl/kotlin/KotlinCompilationConfiguration.kt   |  47 +++++
 .../org/apache/camel/dsl/kotlin/KotlinConstants.kt |  20 ++
 .../org/apache/camel/dsl/kotlin/KotlinDSL.kt       |  96 +++++++++
 .../camel/dsl/kotlin/KotlinRoutesBuilderLoader.kt  | 104 +++++++++
 .../camel/dsl/kotlin/model/BeansConfiguration.kt   |  46 ++++
 .../camel/dsl/kotlin/model/CamelConfiguration.kt   |  41 ++++
 .../dsl/kotlin/model/ComponentsConfiguration.kt    |  47 +++++
 .../dsl/kotlin/model/DataFormatsConfiguration.kt   |  40 ++++
 .../dsl/kotlin/model/LanguagesConfiguration.kt     |  40 ++++
 .../dsl/kotlin/model/RegistryConfiguration.kt      |  26 +++
 .../camel/dsl/kotlin/model/RestConfiguration.kt    |  33 +++
 .../dsl/kotlin/model/RestVerbConfiguration.kt      |  45 ++++
 ...org.apache.camel.dsl.kotlin.KotlinDSL.classname |   0
 .../dsl/kotlin/KotlinRoutesBuilderLoaderTest.kt    | 199 ++++++++++++++++++
 .../org/apache/camel/dsl/kotlin/support/MyBean.kt  |  21 ++
 .../src/test/resources/log4j2-test.properties      |  31 +++
 .../src/test/resources/routes/routes-new.kts       |  17 ++
 .../test/resources/routes/routes-with-beans.kts    |  33 +++
 .../routes-with-components-configuration-error.kts |  27 +++
 .../routes-with-components-configuration.kts       |  42 ++++
 .../routes-with-dataformats-configuration.kts      |  31 +++
 .../resources/routes/routes-with-endpoint-dsl.kts  |  21 ++
 .../resources/routes/routes-with-error-handler.kts |  25 +++
 .../routes/routes-with-languages-configuration.kts |  30 +++
 .../src/test/resources/routes/routes-with-rest.kts |  45 ++++
 .../src/test/resources/routes/routes.kts           |  21 ++
 dsl/pom.xml                                        |   1 +
 parent/pom.xml                                     |   6 +
 32 files changed, 1387 insertions(+)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index ac519b2..11d9b30 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1144,6 +1144,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
+        <artifactId>camel-kotlin-dsl</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
         <artifactId>camel-kudu</artifactId>
         <version>${project.version}</version>
       </dependency>
diff --git a/dsl/camel-kotlin-dsl/pom.xml b/dsl/camel-kotlin-dsl/pom.xml
new file mode 100644
index 0000000..c445f48
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/pom.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>dsl</artifactId>
+        <version>3.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-kotlin-dsl</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: Kotlin DSL</name>
+    <description>Camel DSL with Kotlin</description>
+
+    <properties>
+        <firstVersion>3.9.0</firstVersion>
+        <sourcecheckExcludes>
+            **/resources/**/My*.java
+        </sourcecheckExcludes>
+        <sourcecheckExcludesComma>
+            ${sourcecheckExcludes},
+        </sourcecheckExcludesComma>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-endpointdsl</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-script-util</artifactId>
+            <version>${kotlin-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-scripting-jvm</artifactId>
+            <version>${kotlin-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-scripting-jvm-host</artifactId>
+            <version>${kotlin-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-main</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jackson</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-direct</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-rest</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-mock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-languages</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-bean</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-log</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-telegram</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-seda</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-jcl</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <version>${kotlin-version}</version>
+                <configuration>
+                    <jvmTarget>${jdk.version}</jvmTarget>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <jvmTarget>${jdk.version}</jvmTarget>
+                            <sourceDirs>
+                                <sourceDir>src/main/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>test-compile</id>
+                        <goals>
+                            <goal>test-compile</goal>
+                        </goals>
+                        <configuration>
+                            <jvmTarget>${jdk.version}</jvmTarget>
+                            <sourceDirs>
+                                <sourceDir>src/test/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <executions>
+                    <!-- Replacing default-compile as it is treated specially by maven -->
+                    <execution>
+                        <id>default-compile</id>
+                        <phase>none</phase>
+                    </execution>
+                    <!-- Replacing default-testCompile as it is treated specially by maven -->
+                    <execution>
+                        <id>default-testCompile</id>
+                        <phase>none</phase>
+                    </execution>
+                    <execution>
+                        <id>java-compile</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>java-test-compile</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkCount>1</forkCount>
+                    <reuseForks>false</reuseForks>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/kts b/dsl/camel-kotlin-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/kts
new file mode 100644
index 0000000..fa0fdbc
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/generated/resources/META-INF/services/org/apache/camel/routes-loader/kts
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.dsl.kotlin.KotlinRoutesBuilderLoader
diff --git a/dsl/camel-kotlin-dsl/src/main/docs/kotlin-dsl.adoc b/dsl/camel-kotlin-dsl/src/main/docs/kotlin-dsl.adoc
new file mode 100644
index 0000000..166f545
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/docs/kotlin-dsl.adoc
@@ -0,0 +1,13 @@
+[[kotlin-dsl-other]]
+= Kotlin DSL
+:docTitle: Kotlin Dsl
+:artifactId: camel-kotlin-dsl
+:description: Camel DSL with Kotlin
+:supportLevel: Experimental
+:since: 3.
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/others/kotlin-dsl.adoc[opts=optional]
+//Manually maintained attributes
+:group: DSL
+
+See https://camel.apache.org/manual/latest/dsl.html
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinCompilationConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinCompilationConfiguration.kt
new file mode 100644
index 0000000..805cd18
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinCompilationConfiguration.kt
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin
+
+import kotlin.script.experimental.api.*
+import kotlin.script.experimental.jvm.dependenciesFromClassloader
+import kotlin.script.experimental.jvm.jvm
+
+class KotlinCompilationConfiguration : ScriptCompilationConfiguration(
+{
+    defaultImports(
+        "org.apache.camel",
+        "org.apache.camel.spi"
+    )
+
+    jvm {
+        //
+        // The Kotlin script compiler does not inherit
+        // the classpath by default.
+        //
+        dependenciesFromClassloader(wholeClasspath = true)
+
+        //
+        // Scripts have to be compiled with the same
+        // jvm target level as the loader.
+        //
+        compilerOptions.append("-jvm-target")
+        compilerOptions.append(JVM_TARGET)
+    }
+    ide {
+        acceptedLocations(ScriptAcceptedLocation.Everywhere)
+    }
+})
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinConstants.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinConstants.kt
new file mode 100644
index 0000000..5c4050f
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinConstants.kt
@@ -0,0 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin
+
+const val EXTENSION = "kts"
+const val JVM_TARGET = "1.8"
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinDSL.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinDSL.kt
new file mode 100644
index 0000000..0054999
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinDSL.kt
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin
+
+import org.apache.camel.Exchange
+import org.apache.camel.Predicate
+import org.apache.camel.Processor
+import org.apache.camel.builder.BuilderSupport
+import org.apache.camel.builder.EndpointConsumerBuilder
+import org.apache.camel.builder.ErrorHandlerBuilder
+import org.apache.camel.builder.endpoint.EndpointBuilderFactory
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder
+import org.apache.camel.dsl.kotlin.model.BeansConfiguration
+import org.apache.camel.dsl.kotlin.model.CamelConfiguration
+import org.apache.camel.dsl.kotlin.model.RestConfiguration
+import org.apache.camel.model.*
+import org.apache.camel.model.rest.RestDefinition
+import kotlin.script.experimental.annotations.KotlinScript
+
+@KotlinScript(fileExtension = EXTENSION, compilationConfiguration = KotlinCompilationConfiguration::class)
+abstract class KotlinDSL(
+        private val builder : EndpointRouteBuilder) : BuilderSupport(builder.context), EndpointBuilderFactory {
+
+    fun rest(): RestDefinition {
+        return builder.rest()
+    }
+
+    fun rest(block: RestConfiguration.() -> Unit) {
+        RestConfiguration(builder).block()
+    }
+
+    fun beans(block: BeansConfiguration.() -> Unit) {
+        BeansConfiguration(context).block()
+    }
+
+    fun camel(block: CamelConfiguration.() -> Unit) {
+        CamelConfiguration(context).block()
+    }
+
+    fun from(uri: String): RouteDefinition {
+        return builder.from(uri)
+    }
+
+    fun from(endpoint: EndpointConsumerBuilder): RouteDefinition {
+        return builder.from(endpoint)
+    }
+
+    fun intercept() : InterceptDefinition {
+        return builder.intercept()
+    }
+
+    fun onException(exception: Class<out Throwable>) : OnExceptionDefinition {
+        return builder.onException(exception)
+    }
+
+    fun onCompletion() : OnCompletionDefinition {
+        return builder.onCompletion()
+    }
+
+    fun interceptFrom() : InterceptFromDefinition {
+        return builder.interceptFrom()
+    }
+
+    fun interceptFrom(uri: String) : InterceptFromDefinition{
+        return builder.interceptFrom(uri)
+    }
+
+    fun interceptSendToEndpoint(uri: String) : InterceptSendToEndpointDefinition {
+        return builder.interceptSendToEndpoint(uri)
+    }
+
+    fun errorHandler(handler: ErrorHandlerBuilder) {
+        builder.errorHandler(handler)
+    }
+
+    fun processor(fn: (Exchange) -> Unit) : Processor {
+        return Processor { exchange -> fn(exchange) }
+    }
+    fun predicate(fn: (Exchange) -> Boolean) : Predicate {
+        return Predicate { exchange -> fn(exchange) }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoader.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoader.kt
new file mode 100644
index 0000000..e916b18
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoader.kt
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin
+
+import org.apache.camel.Experimental
+import org.apache.camel.ExtendedCamelContext
+import org.apache.camel.RoutesBuilder
+import org.apache.camel.RuntimeCamelException
+import org.apache.camel.api.management.ManagedAttribute
+import org.apache.camel.api.management.ManagedResource
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder
+import org.apache.camel.spi.Resource
+import org.apache.camel.spi.StartupStepRecorder
+import org.apache.camel.spi.annotations.RoutesLoader
+import org.apache.camel.support.RoutesBuilderLoaderSupport
+import org.slf4j.LoggerFactory
+import java.io.Reader
+import java.lang.Exception
+import kotlin.script.experimental.api.*
+import kotlin.script.experimental.host.toScriptSource
+import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
+import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
+
+@Experimental
+@ManagedResource(description = "Managed KotlinRoutesBuilderLoader")
+@RoutesLoader(EXTENSION)
+class KotlinRoutesBuilderLoader : RoutesBuilderLoaderSupport() {
+    var recorder: StartupStepRecorder? = null
+
+    @Throws(Exception::class)
+    override fun doBuild() {
+        super.doBuild()
+
+        if (camelContext != null) {
+            this.recorder = camelContext.adapt(ExtendedCamelContext::class.java).startupStepRecorder
+        }
+    }
+
+    @ManagedAttribute(description = "Supported file extension")
+    override fun getSupportedExtension(): String {
+        return EXTENSION
+    }
+
+    @Throws(Exception::class)
+    override fun loadRoutesBuilder(resource: Resource): RoutesBuilder? {
+        val step = if (recorder != null) recorder!!.beginStep(KotlinRoutesBuilderLoader::class.java, resource.location, "Compiling RouteBuilder") else null
+
+        try {
+            return EndpointRouteBuilder.loadEndpointRoutesBuilder(resource) {
+                reader, builder -> load(reader, builder)
+            }
+        } finally {
+            recorder?.endStep(step)
+        }
+    }
+
+    private fun load(reader: Reader, builder: EndpointRouteBuilder) {
+        val host = BasicJvmScriptingHost()
+        val config = createJvmCompilationConfigurationFromTemplate<KotlinDSL>()
+
+        val result = host.eval(
+                reader.readText().toScriptSource(),
+                config,
+                ScriptEvaluationConfiguration {
+                    //
+                    // Arguments used to initialize the script base class (IntegrationConfiguration)
+                    //
+                    constructorArgs(builder)
+                }
+        )
+
+        // ensure evaluation errors propagation
+        when(val rv = result.valueOrNull()?.returnValue) {
+            is ResultValue.Error -> throw RuntimeCamelException(rv.error)
+        }
+
+        if (result.reports.isNotEmpty()) {
+            val logger = LoggerFactory.getLogger(KotlinRoutesBuilderLoader::class.java)
+            for (report in result.reports) {
+                when (report.severity) {
+                    ScriptDiagnostic.Severity.FATAL -> logger.error(report.message, report.exception)
+                    ScriptDiagnostic.Severity.ERROR -> logger.error(report.message, report.exception)
+                    ScriptDiagnostic.Severity.WARNING -> logger.warn(report.message, report.exception)
+                    ScriptDiagnostic.Severity.INFO -> logger.info(report.message)
+                    ScriptDiagnostic.Severity.DEBUG -> logger.debug(report.message)
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/BeansConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/BeansConfiguration.kt
new file mode 100644
index 0000000..0edc573
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/BeansConfiguration.kt
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.CamelContext
+import org.apache.camel.Exchange
+import org.apache.camel.Predicate
+import org.apache.camel.Processor
+import org.apache.camel.builder.endpoint.EndpointBuilderFactory
+
+class BeansConfiguration(
+        val context: CamelContext) : EndpointBuilderFactory {
+
+    inline fun <reified T : Any> bean(name: String, block: T.() -> Unit) {
+        val bean = context.injector.newInstance(T::class.java)
+        bean.block()
+
+        context.registry.bind(name, T::class.java, bean)
+    }
+
+    inline fun bean(name: String, crossinline function: () -> Any ) {
+        context.registry.bind(name, function())
+    }
+
+    fun processor(name: String, fn: (Exchange) -> Unit) {
+        context.registry.bind(name, Processor { exchange -> fn(exchange) } )
+    }
+
+    fun predicate(name: String, fn: (Exchange) -> Boolean) {
+        context.registry.bind(name, Predicate { exchange -> fn(exchange) } )
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/CamelConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/CamelConfiguration.kt
new file mode 100644
index 0000000..6e65fdf
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/CamelConfiguration.kt
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.CamelContext
+
+class CamelConfiguration (
+        private val context: CamelContext) {
+
+    fun components(block: ComponentsConfiguration.() -> Unit): ComponentsConfiguration {
+        val delegate = ComponentsConfiguration(context)
+        delegate.block()
+        return delegate
+    }
+
+    fun languages(block: LanguagesConfiguration.() -> Unit): LanguagesConfiguration {
+        val delegate = LanguagesConfiguration(context)
+        delegate.block()
+        return delegate
+    }
+
+    fun dataFormats(block: DataFormatsConfiguration.() -> Unit): DataFormatsConfiguration {
+        val delegate = DataFormatsConfiguration(context)
+        delegate.block()
+        return delegate
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/ComponentsConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/ComponentsConfiguration.kt
new file mode 100644
index 0000000..ad47723
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/ComponentsConfiguration.kt
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.CamelContext
+import org.apache.camel.Component
+
+class ComponentsConfiguration(val context: CamelContext) {
+    inline fun <reified T : Component> component(name: String, block: T.() -> Unit) : T {
+        var target = context.getComponent(name, true, false)
+        var bind = false
+
+        if (target != null && !T::class.java.isInstance(target)) {
+            throw IllegalArgumentException("Type mismatch, expected: ${T::class.java}, got: ${target.javaClass}")
+        }
+
+        // if the component is not found, let's create a new one. This is
+        // equivalent to create a new named component, useful to create
+        // multiple instances of the same component but with different setup
+        if (target == null) {
+            target = context.injector.newInstance(T::class.java)
+            bind = true
+        }
+
+        block.invoke(target as T)
+
+        if (bind) {
+            context.registry.bind(name, T::class.java, target)
+        }
+
+        return target
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/DataFormatsConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/DataFormatsConfiguration.kt
new file mode 100644
index 0000000..a5f8d0d
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/DataFormatsConfiguration.kt
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.CamelContext
+import org.apache.camel.spi.DataFormat
+
+class DataFormatsConfiguration(val context: CamelContext) {
+    inline fun <reified T : DataFormat> dataFormat(name: String, block: T.() -> Unit) : T {
+        var target = context.registry.lookupByNameAndType(name, T::class.java)
+        var bind = false
+
+        if (target == null) {
+            target = context.injector.newInstance(T::class.java)
+            bind = true
+        }
+
+        block.invoke(target)
+
+        if (bind) {
+            context.registry.bind(name, T::class.java, target)
+        }
+
+        return target
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/LanguagesConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/LanguagesConfiguration.kt
new file mode 100644
index 0000000..b26046d
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/LanguagesConfiguration.kt
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.CamelContext
+import org.apache.camel.spi.Language
+
+class LanguagesConfiguration(val context: CamelContext) {
+    inline fun <reified T : Language> language(name: String, block: T.() -> Unit) : T {
+        var target = context.registry.lookupByNameAndType(name, T::class.java)
+        var bind = false
+
+        if (target == null) {
+            target = context.injector.newInstance(T::class.java)
+            bind = true
+        }
+
+        block.invoke(target)
+
+        if (bind) {
+            context.registry.bind(name, T::class.java, target)
+        }
+
+        return target
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RegistryConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RegistryConfiguration.kt
new file mode 100644
index 0000000..ca394de
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RegistryConfiguration.kt
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.spi.Registry
+
+
+class RegistryConfiguration(val registry: Registry) {
+    fun bind(name: String, value: Any) {
+        registry.bind(name, value)
+    }
+}
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestConfiguration.kt
new file mode 100644
index 0000000..ee734aa
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestConfiguration.kt
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.builder.RouteBuilder
+import org.apache.camel.model.rest.RestConfigurationDefinition
+
+class RestConfiguration(
+        private val builder: RouteBuilder) : RestVerbConfiguration(builder, builder.rest()) {
+
+    fun configuration(block: RestConfigurationDefinition.() -> Unit) {
+        val delegate = builder.restConfiguration()
+        delegate.block()
+    }
+
+    fun path(path: String, block: RestVerbConfiguration.() -> Unit) {
+        RestVerbConfiguration(builder, path).block()
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestVerbConfiguration.kt b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestVerbConfiguration.kt
new file mode 100644
index 0000000..57d50ba
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/model/RestVerbConfiguration.kt
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.model
+
+import org.apache.camel.builder.RouteBuilder
+import org.apache.camel.model.rest.RestDefinition
+
+open class RestVerbConfiguration(
+        private val builder: RouteBuilder,
+        private val definition: RestDefinition) {
+
+    constructor(builder: RouteBuilder, path: String): this(builder, builder.rest(path))
+
+    fun get(path: String, block: RestDefinition.() -> Unit) = definition.get(path).block()
+    fun get(block: RestDefinition.() -> Unit) = definition.get().block()
+
+    fun post(path: String, block: RestDefinition.() -> Unit) = definition.post(path).block()
+    fun post(block: RestDefinition.() -> Unit) = definition.post().block()
+
+    fun delete(path: String, block: RestDefinition.() -> Unit) = definition.delete(path).block()
+    fun delete(block: RestDefinition.() -> Unit) = definition.delete().block()
+
+    fun head(path: String, block: RestDefinition.() -> Unit) = definition.head(path).block()
+    fun head(block: RestDefinition.() -> Unit) = definition.head().block()
+
+    fun put(path: String, block: RestDefinition.() -> Unit) = definition.put(path).block()
+    fun put(block: RestDefinition.() -> Unit) = definition.put().block()
+
+    fun patch(path: String, block: RestDefinition.() -> Unit) = definition.patch(path).block()
+    fun patch(block: RestDefinition.() -> Unit) = definition.patch().block()
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/main/resources/META-INF/kotlin/script/templates/org.apache.camel.dsl.kotlin.KotlinDSL.classname b/dsl/camel-kotlin-dsl/src/main/resources/META-INF/kotlin/script/templates/org.apache.camel.dsl.kotlin.KotlinDSL.classname
new file mode 100644
index 0000000..e69de29
diff --git a/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoaderTest.kt b/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoaderTest.kt
new file mode 100644
index 0000000..d3b7819
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/KotlinRoutesBuilderLoaderTest.kt
@@ -0,0 +1,199 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin
+
+import org.apache.camel.Predicate
+import org.apache.camel.Processor
+import org.apache.camel.RuntimeCamelException
+import org.apache.camel.component.jackson.JacksonDataFormat
+import org.apache.camel.component.log.LogComponent
+import org.apache.camel.component.seda.SedaComponent
+import org.apache.camel.dsl.kotlin.support.MyBean
+import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.language.bean.BeanLanguage
+import org.apache.camel.model.ProcessDefinition
+import org.apache.camel.model.ToDefinition
+import org.apache.camel.model.rest.GetVerbDefinition
+import org.apache.camel.model.rest.PostVerbDefinition
+import org.apache.camel.processor.FatalFallbackErrorHandler
+import org.apache.camel.support.DefaultHeaderFilterStrategy
+import org.assertj.core.api.Assertions.assertThat
+import org.assertj.core.api.Assertions.assertThatExceptionOfType
+import org.junit.jupiter.api.Test
+
+class KotlinRoutesBuilderLoaderTest {
+
+    @Test
+    fun `load routes`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        val routes = ctx.routeDefinitions
+
+        assertThat(routes).hasSize(1)
+        assertThat(routes[0].input.endpointUri).isEqualTo("timer:tick")
+        assertThat(routes[0].outputs[0]).isInstanceOf(ProcessDefinition::class.java)
+        assertThat(routes[0].outputs[1]).isInstanceOf(ToDefinition::class.java)
+    }
+
+    @Test
+    fun `load routes with endpoint dsl`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-endpoint-dsl.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        val routes = ctx.routeDefinitions
+
+        assertThat(routes).hasSize(1)
+        assertThat(routes[0].input.endpointUri).isEqualTo("timer://tick?period=1s")
+        assertThat(routes[0].outputs[0]).isInstanceOfSatisfying(ToDefinition::class.java) {
+            assertThat(it.endpointUri).isEqualTo("log://info")
+        }
+    }
+
+
+    @Test
+    fun `load integration with rest`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-rest.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        assertThat(ctx.restConfiguration.host).isEqualTo("my-host")
+        assertThat(ctx.restConfiguration.port).isEqualTo(9192)
+        assertThat(ctx.restDefinitions.size).isEqualTo(2)
+
+        with(ctx.restDefinitions.find { it.path == "/my/path" }) {
+            assertThat(this?.verbs).hasSize(1)
+
+            with(this?.verbs?.get(0) as GetVerbDefinition) {
+                assertThat(uri).isEqualTo("/get")
+                assertThat(consumes).isEqualTo("application/json")
+                assertThat(produces).isEqualTo("application/json")
+                assertThat(to).hasFieldOrPropertyWithValue("endpointUri", "direct:get")
+            }
+        }
+
+        with(ctx.restDefinitions.find { it.path == "/post" }) {
+            assertThat(this?.verbs).hasSize(1)
+
+            with(this?.verbs?.get(0) as PostVerbDefinition) {
+                assertThat(uri).isNull()
+                assertThat(consumes).isEqualTo("application/json")
+                assertThat(produces).isEqualTo("application/json")
+                assertThat(to).hasFieldOrPropertyWithValue("endpointUri", "direct:post")
+            }
+        }
+    }
+
+    @Test
+    fun `load integration with beans`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-beans.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        assertThat(ctx.registry.findByType(MyBean::class.java)).hasSize(1)
+        assertThat(ctx.registry.lookupByName("myBean")).isInstanceOf(MyBean::class.java)
+        assertThat(ctx.registry.findByType(DefaultHeaderFilterStrategy::class.java)).hasSize(1)
+        assertThat(ctx.registry.lookupByName("filterStrategy")).isInstanceOf(DefaultHeaderFilterStrategy::class.java)
+        assertThat(ctx.registry.lookupByName("myProcessor")).isInstanceOf(Processor::class.java)
+        assertThat(ctx.registry.lookupByName("myPredicate")).isInstanceOf(Predicate::class.java)
+    }
+
+    @Test
+    fun `load integration with components configuration`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-components-configuration.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        val seda = ctx.getComponent("seda", SedaComponent::class.java)
+        val mySeda = ctx.getComponent("mySeda", SedaComponent::class.java)
+        val log = ctx.getComponent("log", LogComponent::class.java)
+
+        assertThat(seda.queueSize).isEqualTo(1234)
+        assertThat(seda.concurrentConsumers).isEqualTo(12)
+        assertThat(mySeda.queueSize).isEqualTo(4321)
+        assertThat(mySeda.concurrentConsumers).isEqualTo(21)
+        assertThat(log.exchangeFormatter).isNotNull
+    }
+
+    @Test
+    fun `load integration with components configuration error`() {
+        assertThatExceptionOfType(RuntimeCamelException::class.java)
+                .isThrownBy {
+                    val ctx = DefaultCamelContext()
+                    val res = ctx.resourceLoader.resolveResource("/routes/routes-with-components-configuration-error.kts")
+
+                    ctx.routesLoader.loadRoutes(res)
+                }
+                .withCauseInstanceOf(IllegalArgumentException::class.java)
+                .withMessageContaining("Type mismatch, expected: class org.apache.camel.component.log.LogComponent, got: class org.apache.camel.component.seda.SedaComponent");
+    }
+
+    @Test
+    fun `load integration with languages configuration`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-languages-configuration.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        val bean = ctx.resolveLanguage("bean") as BeanLanguage
+        assertThat(bean.beanType).isEqualTo(String::class.java)
+        assertThat(bean.method).isEqualTo("toUpperCase")
+
+        val mybean = ctx.resolveLanguage("my-bean") as BeanLanguage
+        assertThat(mybean.beanType).isEqualTo(String::class.java)
+        assertThat(mybean.method).isEqualTo("toLowerCase")
+    }
+
+    @Test
+    fun `load integration with dataformats configuration`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-dataformats-configuration.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+
+        val jackson = ctx.resolveDataFormat("json-jackson") as JacksonDataFormat
+        assertThat(jackson.unmarshalType).isEqualTo(Map::class.java)
+        assertThat(jackson.isPrettyPrint).isTrue()
+
+        val myjackson = ctx.resolveDataFormat("my-jackson") as JacksonDataFormat
+        assertThat(myjackson.unmarshalType).isEqualTo(String::class.java)
+        assertThat(myjackson.isPrettyPrint).isFalse()
+    }
+
+    @Test
+    fun `load integration with error handler`() {
+        val ctx = DefaultCamelContext()
+        val res = ctx.resourceLoader.resolveResource("/routes/routes-with-error-handler.kts")
+
+        ctx.routesLoader.loadRoutes(res)
+        ctx.start()
+
+        try {
+            assertThat(ctx.routes).hasSize(1)
+            assertThat(ctx.routes[0].getOnException("my-on-exception")).isInstanceOf(FatalFallbackErrorHandler::class.java)
+        } finally {
+            ctx.stop()
+        }
+    }
+}
diff --git a/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/support/MyBean.kt b/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/support/MyBean.kt
new file mode 100644
index 0000000..4748458
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/kotlin/org/apache/camel/dsl/kotlin/support/MyBean.kt
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.kotlin.support
+
+class MyBean {
+    var name: String = ""
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/log4j2-test.properties b/dsl/camel-kotlin-dsl/src/test/resources/log4j2-test.properties
new file mode 100644
index 0000000..163f7f8
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/log4j2-test.properties
@@ -0,0 +1,31 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-kotlin-dsl-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n
+
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
+#rootLogger.appenderRef.out.ref = out
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-new.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-new.kts
new file mode 100644
index 0000000..7f8b923
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-new.kts
@@ -0,0 +1,17 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+println("test")
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-beans.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-beans.kts
new file mode 100644
index 0000000..7063f51
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-beans.kts
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+beans {
+    bean<org.apache.camel.dsl.kotlin.support.MyBean>("myBean") {
+        name = "test"
+    }
+
+    bean("filterStrategy") {
+        org.apache.camel.support.DefaultHeaderFilterStrategy()
+    }
+
+    processor("myProcessor") {
+        it.getIn().body = "Hello"
+    }
+
+    predicate("myPredicate") {
+        false
+    }
+}
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration-error.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration-error.kts
new file mode 100644
index 0000000..3c209b5
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration-error.kts
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.camel.Exchange
+
+camel {
+    components {
+        component<org.apache.camel.component.log.LogComponent>("seda") {
+            setExchangeFormatter {
+                e: Exchange -> "" + e.getIn().body
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration.kts
new file mode 100644
index 0000000..3fdf39c
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-components-configuration.kts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.camel.Exchange
+import org.apache.camel.component.log.LogComponent
+import org.apache.camel.component.seda.SedaComponent
+
+camel {
+    components {
+        component<LogComponent>("log") {
+            setExchangeFormatter {
+                e: Exchange -> "" + e.getIn().body
+            }
+        }
+
+        component<SedaComponent>("seda") {
+            queueSize = 1234
+            concurrentConsumers = 12
+        }
+
+        component<SedaComponent>("mySeda") {
+            queueSize = 4321
+            concurrentConsumers = 21
+        }
+    }
+}
+
+from("timer:tick")
+    .to("log:info")
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-dataformats-configuration.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-dataformats-configuration.kts
new file mode 100644
index 0000000..b5cc267
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-dataformats-configuration.kts
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.camel.component.jackson.JacksonDataFormat
+
+camel {
+    dataFormats {
+        dataFormat<JacksonDataFormat>("json-jackson") {
+            unmarshalType = Map::class.java
+            isPrettyPrint = true
+        }
+
+        dataFormat<JacksonDataFormat>("my-jackson") {
+            unmarshalType = String::class.java
+            isPrettyPrint = false
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-endpoint-dsl.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-endpoint-dsl.kts
new file mode 100644
index 0000000..fc04af9
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-endpoint-dsl.kts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var f = timer("tick").period("1s")
+var t = log("info")
+
+from(f)
+    .to(t)
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-error-handler.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-error-handler.kts
new file mode 100644
index 0000000..ed55f49
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-error-handler.kts
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+onException(IllegalArgumentException::class.java)
+    .id("my-on-exception")
+    .to("log:exception")
+
+from("timer:tick")
+    .process().message {
+        m -> m.headers["MyHeader"] = "MyHeaderValue"
+    }
+    .to("log:info")
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-languages-configuration.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-languages-configuration.kts
new file mode 100644
index 0000000..065497a
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-languages-configuration.kts
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.camel.language.bean.BeanLanguage
+
+camel {
+    languages {
+        language<BeanLanguage>("bean") {
+            beanType = String::class.java
+            method = "toUpperCase"
+        }
+        language<BeanLanguage>("my-bean") {
+            beanType = String::class.java
+            method = "toLowerCase"
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-rest.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-rest.kts
new file mode 100644
index 0000000..d9dd70b
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes-with-rest.kts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+rest {
+    configuration {
+        host = "my-host"
+        port = "9192"
+    }
+
+    path("/my/path") {
+        get("/get") {
+            consumes("application/json")
+            produces("application/json")
+            to("direct:get")
+        }
+    }
+
+    post {
+        path("/post")
+        consumes("application/json")
+        produces("application/json")
+        to("direct:post")
+    }
+}
+
+
+
+from("timer:tick")
+    .process().message {
+        m -> m.headers["MyHeader"] = "MyHeaderValue"
+    }
+    .to("log:info")
diff --git a/dsl/camel-kotlin-dsl/src/test/resources/routes/routes.kts b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes.kts
new file mode 100644
index 0000000..7d28bb5
--- /dev/null
+++ b/dsl/camel-kotlin-dsl/src/test/resources/routes/routes.kts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+from("timer:tick")
+    .process().message {
+        m -> m.headers["MyHeader"] = "MyHeaderValue"
+    }
+    .to("log:info")
\ No newline at end of file
diff --git a/dsl/pom.xml b/dsl/pom.xml
index 00e9a80..310cb36 100644
--- a/dsl/pom.xml
+++ b/dsl/pom.xml
@@ -40,6 +40,7 @@
         <module>camel-xml-jaxb-dsl-test</module>
         <module>camel-yaml-dsl</module>
         <module>camel-js-dsl</module>
+        <module>camel-kotlin-dsl</module>
     </modules>
 
     <properties>
diff --git a/parent/pom.xml b/parent/pom.xml
index 97e2727..24aaa04 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -360,6 +360,7 @@
         <jython-standalone-version>2.5.3</jython-standalone-version>
         <jzlib-version>1.1.3</jzlib-version>
         <kafka-version>2.7.0</kafka-version>
+        <kotlin-version>1.4.20</kotlin-version>
         <kubernetes-client-version>5.1.1</kubernetes-client-version>
         <kubernetes-model-version>5.1.1</kubernetes-model-version>
         <kudu-version>1.14.0</kudu-version>
@@ -2708,6 +2709,11 @@
 				<artifactId>camel-js-dsl</artifactId>
 				<version>${project.version}</version>
 			</dependency>
+			<dependency>
+				<groupId>org.apache.camel</groupId>
+				<artifactId>camel-kotlin-dsl</artifactId>
+				<version>${project.version}</version>
+			</dependency>
 
             <!-- camel catalog -->
             <dependency>