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 <lburgazz...@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>