You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2023/01/10 07:37:11 UTC
[camel-quarkus] branch main updated: Ref #4379: Groovy DSL native support
This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 9ec7bc8625 Ref #4379: Groovy DSL native support
9ec7bc8625 is described below
commit 9ec7bc8625f68df39b32f6925678282dcbac0e33
Author: Nicolas Filotto <nf...@talend.com>
AuthorDate: Thu Jan 5 18:45:54 2023 +0100
Ref #4379: Groovy DSL native support
---
docs/modules/ROOT/examples/others/groovy-dsl.yml | 6 +-
.../pages/reference/extensions/groovy-dsl.adoc | 37 +++-
extensions-jvm/pom.xml | 1 -
.../groovy-dsl/deployment/pom.xml | 0
.../dsl/groovy/deployment/GroovyDslProcessor.java | 178 +++++++++++++++++
.../deployment/GroovyGeneratedClassBuildItem.java | 27 +--
{extensions-jvm => extensions}/groovy-dsl/pom.xml | 2 +-
.../groovy-dsl/runtime/pom.xml | 1 +
.../runtime/src/main/doc/limitations.adoc | 18 ++
.../quarkus/dsl/groovy/runtime/Configurer.java | 17 +-
.../dsl/groovy/runtime/GroovyDslRecorder.java | 49 +++++
.../groovy/runtime/graal/GroovySubstitutions.java | 83 ++++++++
.../graal/SubstituteGroovyRoutesBuilderLoader.java | 21 +-
.../main/resources/META-INF/quarkus-extension.yaml | 3 +-
extensions/pom.xml | 1 +
integration-tests-jvm/groovy-dsl/pom.xml | 105 ----------
.../camel/quarkus/dsl/groovy/GroovyDslTest.java | 49 -----
integration-tests-jvm/pom.xml | 1 -
integration-tests/groovy-dsl/pom.xml | 217 +++++++++++++++++++++
.../quarkus/dsl/groovy/GroovyDslResource.java | 58 ++++--
.../src/main/resources/application.properties | 2 +-
.../src/main/resources/routes/my-routes.groovy | 8 +-
.../routes-with-components-configuration.groovy | 20 +-
.../routes-with-dataformats-configuration.groovy | 23 ++-
.../routes/routes-with-endpoint-dsl.groovy | 9 +-
.../routes/routes-with-error-handler.groovy | 11 +-
.../routes-with-languages-configuration.groovy | 17 +-
.../camel/quarkus/dsl/groovy/GroovyDslIT.java | 11 +-
.../camel/quarkus/dsl/groovy/GroovyDslTest.java | 59 ++++++
integration-tests/pom.xml | 1 +
tooling/scripts/test-categories.yaml | 1 +
31 files changed, 810 insertions(+), 226 deletions(-)
diff --git a/docs/modules/ROOT/examples/others/groovy-dsl.yml b/docs/modules/ROOT/examples/others/groovy-dsl.yml
index 062e598158..606db51927 100644
--- a/docs/modules/ROOT/examples/others/groovy-dsl.yml
+++ b/docs/modules/ROOT/examples/others/groovy-dsl.yml
@@ -2,11 +2,11 @@
# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
cqArtifactId: camel-quarkus-groovy-dsl
cqArtifactIdBase: groovy-dsl
-cqNativeSupported: false
-cqStatus: Preview
+cqNativeSupported: true
+cqStatus: Stable
cqDeprecated: false
cqJvmSince: 1.8.0
-cqNativeSince: n/a
+cqNativeSince: 2.16.0
cqCamelPartName: groovy-dsl
cqCamelPartTitle: Groovy Dsl
cqCamelPartDescription: Camel DSL with Groovy
diff --git a/docs/modules/ROOT/pages/reference/extensions/groovy-dsl.adoc b/docs/modules/ROOT/pages/reference/extensions/groovy-dsl.adoc
index 43af62e00f..b5b1d0c9e4 100644
--- a/docs/modules/ROOT/pages/reference/extensions/groovy-dsl.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/groovy-dsl.adoc
@@ -4,17 +4,17 @@
= Groovy DSL
:linkattrs:
:cq-artifact-id: camel-quarkus-groovy-dsl
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
:cq-description: Support for parsing Groovy route definitions at runtime
:cq-deprecated: false
:cq-jvm-since: 1.8.0
-:cq-native-since: n/a
+:cq-native-since: 2.16.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.8.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.8.0## [.badge-key]##Native since##[.badge-supported]##2.16.0##
endif::[]
Support for parsing Groovy route definitions at runtime
@@ -29,6 +29,10 @@ Please refer to the above link for usage and configuration details.
[id="extensions-groovy-dsl-maven-coordinates"]
== Maven coordinates
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-groovy-dsl[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
+
+Or add the coordinates to your existing project:
+
[source,xml]
----
<dependency>
@@ -39,3 +43,26 @@ Please refer to the above link for usage and configuration details.
ifeval::[{doc-show-user-guide-link} == true]
Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
endif::[]
+
+[id="extensions-groovy-dsl-camel-quarkus-limitations"]
+== Camel Quarkus limitations
+
+The Groovy extensions are not supported which means that the extensions defined in the Camel project are ignored, more details in https://github.com/apache/camel-quarkus/issues/4384[Groovy DSL - Add support of Groovy extensions issue #4384].
+
+In case of native compilation, for some specific use cases like the following one, it could be needed to add the flag `--report-unsupported-elements-at-runtime` to prevent compilation error of type `DeletedElementException: Unsupported method java.lang.Class.registerNatives() is reachable`.
+
+[source,groovy]
+----
+import org.apache.camel.component.seda.SedaComponent
+
+camel {
+ components {
+ mySeda(SedaComponent) { // <1>
+ // rest of the closure here
+ }
+ }
+}
+// rest of the Groovy script
+----
+<1> Requires the flag `--report-unsupported-elements-at-runtime` to be added to the build command for native compilation.
+
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 2902ad693e..01ff26c757 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -67,7 +67,6 @@
<module>google-functions</module>
<module>google-secret-manager</module>
<module>groovy</module>
- <module>groovy-dsl</module>
<module>guava-eventbus</module>
<module>hashicorp-vault</module>
<module>hbase</module>
diff --git a/extensions-jvm/groovy-dsl/deployment/pom.xml b/extensions/groovy-dsl/deployment/pom.xml
similarity index 100%
rename from extensions-jvm/groovy-dsl/deployment/pom.xml
rename to extensions/groovy-dsl/deployment/pom.xml
diff --git a/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
new file mode 100644
index 0000000000..c97336d80e
--- /dev/null
+++ b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
@@ -0,0 +1,178 @@
+/*
+ * 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.quarkus.dsl.groovy.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
+import io.quarkus.deployment.pkg.steps.NativeBuild;
+import io.quarkus.maven.dependency.ResolvedDependency;
+import io.quarkus.paths.PathCollection;
+import io.quarkus.runtime.RuntimeValue;
+import org.apache.camel.CamelContext;
+import org.apache.camel.quarkus.core.deployment.main.CamelMainHelper;
+import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.dsl.groovy.runtime.Configurer;
+import org.apache.camel.quarkus.dsl.groovy.runtime.GroovyDslRecorder;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.Phases;
+import org.codehaus.groovy.tools.GroovyClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroovyDslProcessor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GroovyDslProcessor.class);
+ private static final String PACKAGE_NAME = "org.apache.camel.quarkus.dsl.groovy.generated";
+ private static final Pattern IMPORT_PATTERN = Pattern.compile("import .*");
+ private static final String FILE_FORMAT = "package %s\n" +
+ "%s\n" +
+ "@groovy.transform.InheritConstructors \n" +
+ "class %s extends %s {\n" +
+ " void configure(){ \n" +
+ " %s\n" +
+ " }\n" +
+ "}";
+ private static final String FEATURE = "camel-groovy-dsl";
+
+ @BuildStep
+ FeatureBuildItem feature() {
+ return new FeatureBuildItem(FEATURE);
+ }
+
+ @BuildStep(onlyIf = NativeBuild.class)
+ void compileScriptsAOT(BuildProducer<GeneratedClassBuildItem> generatedClass,
+ BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+ BuildProducer<GroovyGeneratedClassBuildItem> generatedGroovyClass,
+ CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
+ LOG.debug("Loading .groovy resources");
+ Map<String, Resource> nameToResource = new HashMap<>();
+ CompilationUnit unit = new CompilationUnit();
+ CamelMainHelper.forEachMatchingResource(
+ resource -> {
+ if (!resource.getLocation().endsWith(".groovy")) {
+ return;
+ }
+ try (InputStream is = resource.getInputStream()) {
+ String name = determineName(resource);
+ String fqn = String.format("%s.%s", PACKAGE_NAME, name);
+ unit.addSource(fqn, toGroovyClass(name, IOHelper.loadText(is)));
+ nameToResource.put(fqn, resource);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ if (nameToResource.isEmpty()) {
+ return;
+ }
+ CompilerConfiguration cc = new CompilerConfiguration();
+ cc.setClasspathList(
+ curateOutcomeBuildItem.getApplicationModel().getDependencies().stream()
+ .map(ResolvedDependency::getResolvedPaths)
+ .flatMap(PathCollection::stream)
+ .map(Objects::toString)
+ .collect(Collectors.toList()));
+ unit.configure(cc);
+ unit.compile(Phases.CLASS_GENERATION);
+ for (GroovyClass clazz : unit.getClasses()) {
+ String className = clazz.getName();
+ generatedClass.produce(new GeneratedClassBuildItem(true, className, clazz.getBytes()));
+ if (nameToResource.containsKey(className)) {
+ reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, className));
+ generatedGroovyClass
+ .produce(new GroovyGeneratedClassBuildItem(className, nameToResource.get(className).getLocation()));
+ }
+ }
+ }
+
+ @BuildStep(onlyIf = NativeBuild.class)
+ @Record(value = ExecutionTime.STATIC_INIT)
+ void registerRoutesBuilder(List<GroovyGeneratedClassBuildItem> classes,
+ CamelContextBuildItem context,
+ GroovyDslRecorder recorder) throws Exception {
+ RuntimeValue<CamelContext> camelContext = context.getCamelContext();
+ for (GroovyGeneratedClassBuildItem clazz : classes) {
+ recorder.registerRoutesBuilder(camelContext, clazz.getName(), clazz.getLocation());
+ }
+ }
+
+ // To put it back once the Groovy extensions will be supported (https://github.com/apache/camel-quarkus/issues/4384)
+ // @BuildStep
+ // void registerNativeImageResources(BuildProducer<ServiceProviderBuildItem> serviceProvider) {
+ // serviceProvider
+ // .produce(ServiceProviderBuildItem.allProvidersFromClassPath("org.codehaus.groovy.runtime.ExtensionModule"));
+ // }
+
+ private static String determineName(Resource resource) {
+ String str = FileUtil.onlyName(resource.getLocation(), true);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0, length = str.length(); i < length; i++) {
+ char c = str.charAt(i);
+ if ((i == 0 && Character.isJavaIdentifierStart(c)) || (i > 0 && Character.isJavaIdentifierPart(c))) {
+ sb.append(c);
+ } else {
+ sb.append((int) c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert a Groovy script into a Groovy class to be able to compile it.
+ *
+ * @param name the name of the Groovy class
+ * @param contentResource the content of the Groovy script
+ * @return the content of the corresponding Groovy class.
+ */
+ private static String toGroovyClass(String name, String contentResource) {
+ List<String> imports = new ArrayList<>();
+ imports.add("import org.apache.camel.*");
+ imports.add("import org.apache.camel.spi.*");
+ Matcher m = IMPORT_PATTERN.matcher(contentResource);
+ int beginIndex = 0;
+ while (m.find()) {
+ imports.add(m.group());
+ beginIndex = m.end();
+ }
+ if (beginIndex > 0) {
+ contentResource = contentResource.substring(beginIndex);
+ }
+ return String.format(
+ FILE_FORMAT, PACKAGE_NAME, String.join("\n", imports), name, Configurer.class.getName(), contentResource);
+ }
+}
diff --git a/extensions-jvm/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java
similarity index 59%
rename from extensions-jvm/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
rename to extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java
index de170e888d..2dbe334a7f 100644
--- a/extensions-jvm/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
+++ b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java
@@ -14,24 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.camel.quarkus.dsl.groovy.deployment;
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeBuild;
+import io.quarkus.builder.item.MultiBuildItem;
+
+public final class GroovyGeneratedClassBuildItem extends MultiBuildItem {
-public class GroovyDslProcessor {
- private static final String FEATURE = "camel-groovy-dsl";
+ final String name;
+ final String location;
+
+ public GroovyGeneratedClassBuildItem(String name, String location) {
+ this.name = name;
+ this.location = location;
+ }
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
+ public String getName() {
+ return this.name;
}
- @BuildStep(onlyIf = NativeBuild.class)
- void nativeUnsupported() {
- throw new RuntimeException("The " + FEATURE + " extension is not supported in native mode "
- + "as loading Groovy code at runtime is not supported on GraalVM");
+ public String getLocation() {
+ return location;
}
}
diff --git a/extensions-jvm/groovy-dsl/pom.xml b/extensions/groovy-dsl/pom.xml
similarity index 96%
rename from extensions-jvm/groovy-dsl/pom.xml
rename to extensions/groovy-dsl/pom.xml
index 5c5dcc990f..1c8867f8a4 100644
--- a/extensions-jvm/groovy-dsl/pom.xml
+++ b/extensions/groovy-dsl/pom.xml
@@ -21,7 +21,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
+ <artifactId>camel-quarkus-extensions</artifactId>
<version>2.16.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
diff --git a/extensions-jvm/groovy-dsl/runtime/pom.xml b/extensions/groovy-dsl/runtime/pom.xml
similarity index 98%
rename from extensions-jvm/groovy-dsl/runtime/pom.xml
rename to extensions/groovy-dsl/runtime/pom.xml
index fe38581b00..d41a33af8e 100644
--- a/extensions-jvm/groovy-dsl/runtime/pom.xml
+++ b/extensions/groovy-dsl/runtime/pom.xml
@@ -32,6 +32,7 @@
<properties>
<camel.quarkus.jvmSince>1.8.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>2.16.0</camel.quarkus.nativeSince>
</properties>
<dependencies>
diff --git a/extensions/groovy-dsl/runtime/src/main/doc/limitations.adoc b/extensions/groovy-dsl/runtime/src/main/doc/limitations.adoc
new file mode 100644
index 0000000000..b1a77c234a
--- /dev/null
+++ b/extensions/groovy-dsl/runtime/src/main/doc/limitations.adoc
@@ -0,0 +1,18 @@
+The Groovy extensions are not supported which means that the extensions defined in the Camel project are ignored, more details in https://github.com/apache/camel-quarkus/issues/4384[Groovy DSL - Add support of Groovy extensions issue #4384].
+
+In case of native compilation, for some specific use cases like the following one, it could be needed to add the flag `--report-unsupported-elements-at-runtime` to prevent compilation error of type `DeletedElementException: Unsupported method java.lang.Class.registerNatives() is reachable`.
+
+[source,groovy]
+----
+import org.apache.camel.component.seda.SedaComponent
+
+camel {
+ components {
+ mySeda(SedaComponent) { // <1>
+ // rest of the closure here
+ }
+ }
+}
+// rest of the Groovy script
+----
+<1> Requires the flag `--report-unsupported-elements-at-runtime` to be added to the build command for native compilation.
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
similarity index 64%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
index f0136d044a..c892ef1a42 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
@@ -14,6 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+package org.apache.camel.quarkus.dsl.groovy.runtime;
+
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
+import org.apache.camel.dsl.groovy.common.GroovyDSL;
+
+public abstract class Configurer extends GroovyDSL {
+
+ // The constructor needs to remain public to be accessible from a Groovy Script
+ public Configurer(EndpointRouteBuilder builder) {
+ super(builder);
+ }
+
+ public abstract void configure();
+}
diff --git a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java
new file mode 100644
index 0000000000..95d9904a41
--- /dev/null
+++ b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java
@@ -0,0 +1,49 @@
+/*
+ * 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.quarkus.dsl.groovy.runtime;
+
+import java.lang.reflect.Constructor;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.CamelContext;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
+import org.apache.camel.support.ResourceHelper;
+
+@Recorder
+public class GroovyDslRecorder {
+ public void registerRoutesBuilder(RuntimeValue<CamelContext> camelContext, String className, String location)
+ throws Exception {
+ Constructor<? extends Configurer> constructor = (Constructor<? extends Configurer>) Class.forName(className)
+ .getDeclaredConstructor(EndpointRouteBuilder.class);
+ camelContext.getValue().addRoutes(
+ new EndpointRouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ setCamelContext(camelContext.getValue());
+ setResource(ResourceHelper.fromString(location, ""));
+ try {
+ constructor.newInstance(this).configure();
+ } catch (Exception e) {
+ throw new RuntimeCamelException("Cannot create instance of class: " + className, e);
+ }
+ }
+ });
+ }
+}
diff --git a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/GroovySubstitutions.java b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/GroovySubstitutions.java
new file mode 100644
index 0000000000..3ddba6d540
--- /dev/null
+++ b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/GroovySubstitutions.java
@@ -0,0 +1,83 @@
+/*
+ * 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.quarkus.dsl.groovy.runtime.graal;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MutableCallSite;
+import java.lang.reflect.Constructor;
+
+import com.oracle.svm.core.annotate.Delete;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import org.codehaus.groovy.control.ParserPluginFactory;
+
+final class GroovySubstitutions {
+}
+
+@TargetClass(className = "org.codehaus.groovy.vmplugin.v8.IndyInterface")
+final class SubstituteIndyInterface {
+
+ @Substitute
+ protected static void invalidateSwitchPoints() {
+ throw new UnsupportedOperationException("invalidateSwitchPoints is not supported");
+ }
+
+ @Substitute
+ public static Object fromCache(MutableCallSite callSite, Class<?> sender, String methodName, int callID,
+ Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) {
+ throw new UnsupportedOperationException("fromCache is not supported");
+ }
+}
+
+@TargetClass(className = "org.codehaus.groovy.control.SourceUnit")
+final class SubstituteSourceUnit {
+
+ @Substitute
+ public void convert() {
+ throw new UnsupportedOperationException("convert is not supported");
+ }
+}
+
+@TargetClass(className = "org.codehaus.groovy.vmplugin.v8.Java8")
+final class SubstituteJava8 {
+
+ @Substitute
+ private static Constructor<MethodHandles.Lookup> getLookupConstructor() {
+ throw new UnsupportedOperationException("getLookupConstructor is not supported");
+ }
+}
+
+@TargetClass(className = "org.codehaus.groovy.antlr.AntlrParserPlugin")
+@Delete
+final class SubstituteAntlrParserPlugin {
+
+}
+
+@TargetClass(className = "org.codehaus.groovy.antlr.AntlrParserPluginFactory")
+@Delete
+final class SubstituteAntlrParserPluginFactory {
+
+}
+
+@TargetClass(className = "org.codehaus.groovy.control.ParserPluginFactory")
+final class SubstituteParserPluginFactory {
+
+ @Substitute
+ public static ParserPluginFactory antlr2() {
+ throw new UnsupportedOperationException("antlr2 is not supported");
+ }
+}
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/SubstituteGroovyRoutesBuilderLoader.java
similarity index 59%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/SubstituteGroovyRoutesBuilderLoader.java
index f0136d044a..d2880aaa95 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/graal/SubstituteGroovyRoutesBuilderLoader.java
@@ -14,6 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+package org.apache.camel.quarkus.dsl.groovy.runtime.graal;
+
+import java.io.Reader;
+
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
+import org.apache.camel.dsl.groovy.GroovyRoutesBuilderLoader;
+
+@TargetClass(GroovyRoutesBuilderLoader.class)
+final class SubstituteGroovyRoutesBuilderLoader {
+
+ @Substitute
+ protected void doLoadEndpointRouteBuilder(Reader reader, EndpointRouteBuilder builder) {
+ // Do nothing
+ }
+
+}
diff --git a/extensions-jvm/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from extensions-jvm/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 0635a7e050..3310fa3906 100644
--- a/extensions-jvm/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/groovy-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -24,9 +24,8 @@
name: "Camel Groovy DSL"
description: "Support for parsing Groovy route definitions at runtime"
metadata:
- unlisted: true
guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/groovy-dsl.html"
categories:
- "integration"
status:
- - "preview"
+ - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 98e2d02638..f548467277 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -117,6 +117,7 @@
<module>google-storage</module>
<module>graphql</module>
<module>grok</module>
+ <module>groovy-dsl</module>
<module>grpc</module>
<module>gson</module>
<module>hazelcast</module>
diff --git a/integration-tests-jvm/groovy-dsl/pom.xml b/integration-tests-jvm/groovy-dsl/pom.xml
deleted file mode 100644
index 6baeb851b9..0000000000
--- a/integration-tests-jvm/groovy-dsl/pom.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?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/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>2.16.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-groovy-dsl</artifactId>
- <name>Camel Quarkus :: Integration Tests :: Groovy DSL</name>
- <description>Integration tests for Camel Groovy DSL extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-groovy-dsl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy-jsonb</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit5</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.assertj</groupId>
- <artifactId>assertj-core</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-groovy-dsl-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/integration-tests-jvm/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java b/integration-tests-jvm/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java
deleted file mode 100644
index 67fca5acb0..0000000000
--- a/integration-tests-jvm/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.quarkus.dsl.groovy;
-
-import javax.ws.rs.core.MediaType;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.path.json.JsonPath;
-import org.apache.camel.dsl.groovy.GroovyRoutesBuilderLoader;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@QuarkusTest
-public class GroovyDslTest {
- @Test
- public void testMainInstanceWithJavaRoutes() {
- JsonPath p = RestAssured.given()
- .accept(MediaType.APPLICATION_JSON)
- .get("/test/main/describe")
- .then()
- .statusCode(200)
- .extract()
- .body()
- .jsonPath();
-
- assertThat(p.getString("routes-builder-loader"))
- .isEqualTo(GroovyRoutesBuilderLoader.class.getName());
- assertThat(p.getList("routeBuilders", String.class))
- .isEmpty();
- assertThat(p.getList("routes", String.class))
- .contains("my-groovy-route");
- }
-}
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index 119130ec32..b6fdee38d3 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -66,7 +66,6 @@
<module>google-functions</module>
<module>google-secret-manager</module>
<module>groovy</module>
- <module>groovy-dsl</module>
<module>guava-eventbus</module>
<module>hashicorp-vault</module>
<module>hbase</module>
diff --git a/integration-tests/groovy-dsl/pom.xml b/integration-tests/groovy-dsl/pom.xml
new file mode 100644
index 0000000000..693767cf44
--- /dev/null
+++ b/integration-tests/groovy-dsl/pom.xml
@@ -0,0 +1,217 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-build-parent-it</artifactId>
+ <version>2.16.0-SNAPSHOT</version>
+ <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-integration-test-groovy-dsl</artifactId>
+ <name>Camel Quarkus :: Integration Tests :: Groovy DSL</name>
+ <description>Integration tests for Camel Groovy DSL extension</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-groovy-dsl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-seda</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-timer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-log</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy-jsonb</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>virtualDependencies</id>
+ <activation>
+ <property>
+ <name>!noVirtualDependencies</name>
+ </property>
+ </activation>
+ <dependencies>
+ <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-groovy-dsl-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-jackson-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-log-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-seda-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-timer-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.package.type>native</quarkus.package.type>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/integration-tests-jvm/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java b/integration-tests/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java
similarity index 51%
rename from integration-tests-jvm/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java
rename to integration-tests/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java
index 6ccb0cb719..863953b844 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java
+++ b/integration-tests/groovy-dsl/src/main/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslResource.java
@@ -16,45 +16,67 @@
*/
package org.apache.camel.quarkus.dsl.groovy;
+import java.util.stream.Collectors;
+
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.Route;
import org.apache.camel.dsl.groovy.GroovyRoutesBuilderLoader;
import org.apache.camel.quarkus.main.CamelMain;
import org.apache.camel.spi.RoutesBuilderLoader;
-@Path("/test")
+@Path("/groovy-dsl")
@ApplicationScoped
public class GroovyDslResource {
@Inject
CamelMain main;
- @Path("/main/describe")
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @Path("/main/groovyRoutesBuilderLoader")
@GET
- @Produces(MediaType.APPLICATION_JSON)
- public JsonObject describeMain() {
+ @Produces(MediaType.TEXT_PLAIN)
+ public String groovyRoutesBuilder() {
final ExtendedCamelContext camelContext = main.getCamelContext().adapt(ExtendedCamelContext.class);
+ return camelContext.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH)
+ .findClass(GroovyRoutesBuilderLoader.EXTENSION).get().getName();
+ }
- JsonArrayBuilder routeBuilders = Json.createArrayBuilder();
- main.configure().getRoutesBuilders().forEach(builder -> routeBuilders.add(builder.getClass().getName()));
+ @Path("/main/routeBuilders")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String routeBuilders() {
+ return main.configure().getRoutesBuilders().stream()
+ .map(rb -> rb.getClass().getSimpleName())
+ .sorted()
+ .collect(Collectors.joining(","));
+ }
- JsonArrayBuilder routes = Json.createArrayBuilder();
- main.getCamelContext().getRoutes().forEach(route -> routes.add(route.getId()));
+ @Path("/main/routes")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String routes() {
+ return main.getCamelContext().getRoutes().stream()
+ .map(Route::getId)
+ .sorted()
+ .collect(Collectors.joining(","));
+ }
- return Json.createObjectBuilder()
- .add("routes-builder-loader",
- camelContext.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH)
- .findClass(GroovyRoutesBuilderLoader.EXTENSION).get().getName())
- .add("routeBuilders", routeBuilders)
- .add("routes", routes)
- .build();
+ @POST
+ @Path("/hello")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.TEXT_PLAIN)
+ public String hello(String message) {
+ return producerTemplate.requestBody("direct:groovyHello", message, String.class);
}
}
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/application.properties b/integration-tests/groovy-dsl/src/main/resources/application.properties
similarity index 93%
rename from integration-tests-jvm/groovy-dsl/src/main/resources/application.properties
rename to integration-tests/groovy-dsl/src/main/resources/application.properties
index 2d233c8360..7ab2bf28e3 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/application.properties
+++ b/integration-tests/groovy-dsl/src/main/resources/application.properties
@@ -18,4 +18,4 @@
#
# Main
#
-camel.main.routes-include-pattern = classpath:routes/my-routes.groovy
+camel.main.routes-include-pattern = classpath:routes/*.groovy
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/my-routes.groovy
similarity index 74%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/my-routes.groovy
index f0136d044a..e1e7cb2972 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/my-routes.groovy
@@ -14,6 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+from('direct:groovyHello')
+ .id('my-groovy-route')
+ .setBody().simple('Hello ${body} from Groovy!')
+ // Extensions are not supported due to https://github.com/apache/camel-quarkus/issues/4384
+ // .setBody { e -> "Hello " + e.in.body + " from Groovy!" }
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-components-configuration.groovy
similarity index 73%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/routes-with-components-configuration.groovy
index f0136d044a..c32538db86 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-components-configuration.groovy
@@ -14,6 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+
+camel {
+ components {
+ seda {
+ // set value as method
+ queueSize 1234
+
+ // set value as property
+ concurrentConsumers = 12
+ }
+ }
+}
+
+
+from('timer:tick')
+ .id('routes-with-components-configuration')
+ .to('log:info')
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-dataformats-configuration.groovy
similarity index 64%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/routes-with-dataformats-configuration.groovy
index f0136d044a..127dba3550 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-dataformats-configuration.groovy
@@ -14,6 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+
+import org.apache.camel.component.jackson.JacksonDataFormat
+
+camel {
+ dataFormats {
+ dataFormat("jackson") {
+ unmarshalType = Map.class
+ prettyPrint = true
+ }
+ dataFormat("my-jackson", JacksonDataFormat) {
+ unmarshalType = String.class
+ prettyPrint = false
+ }
+ }
+}
+
+
+from('timer:tick')
+ .id('routes-with-dataformats-configuration')
+ .to('log:info')
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-endpoint-dsl.groovy
similarity index 87%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/routes-with-endpoint-dsl.groovy
index f0136d044a..18f2b7b9ce 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-endpoint-dsl.groovy
@@ -14,6 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+def f = timer('tick').period('1s')
+def t = log('info')
+
+from(f)
+ .id('routes-with-endpoint-dsl')
+ .to(t)
\ No newline at end of file
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-error-handler.groovy
similarity index 82%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/routes-with-error-handler.groovy
index f0136d044a..406269a016 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-error-handler.groovy
@@ -14,6 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+
+onException(IllegalArgumentException.class)
+ .id('my-on-exception')
+ .to('log:exception')
+
+from('timer:tick')
+ .id('routes-with-error-handler')
+ .to('log:info')
\ No newline at end of file
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-languages-configuration.groovy
similarity index 78%
copy from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
copy to integration-tests/groovy-dsl/src/main/resources/routes/routes-with-languages-configuration.groovy
index f0136d044a..144249b8ae 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/main/resources/routes/routes-with-languages-configuration.groovy
@@ -14,6 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+
+camel {
+ languages {
+ bean {
+ beanType = String.class
+ method = "toUpperCase"
+ }
+ }
+}
+
+
+from('timer:tick')
+ .id('routes-with-languages-configuration')
+ .to('log:info')
\ No newline at end of file
diff --git a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy b/integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslIT.java
similarity index 82%
rename from integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
rename to integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslIT.java
index f0136d044a..50fb8bd47d 100644
--- a/integration-tests-jvm/groovy-dsl/src/main/resources/routes/my-routes.groovy
+++ b/integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslIT.java
@@ -14,6 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-from('direct:start')
- .id('my-groovy-route')
- .log('Hello Groovy !!!')
\ No newline at end of file
+package org.apache.camel.quarkus.dsl.groovy;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class GroovyDslIT extends GroovyDslTest {
+
+}
diff --git a/integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java b/integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java
new file mode 100644
index 0000000000..87e065f256
--- /dev/null
+++ b/integration-tests/groovy-dsl/src/test/java/org/apache/camel/quarkus/dsl/groovy/GroovyDslTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.quarkus.dsl.groovy;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import org.apache.camel.dsl.groovy.GroovyRoutesBuilderLoader;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+class GroovyDslTest {
+
+ @Test
+ void groovyHello() {
+ RestAssured.given()
+ .body("John Smith")
+ .post("/groovy-dsl/hello")
+ .then()
+ .statusCode(200)
+ .body(CoreMatchers.is("Hello John Smith from Groovy!"));
+ }
+
+ @Test
+ void testMainInstanceWithJavaRoutes() {
+ RestAssured.given()
+ .get("/groovy-dsl/main/groovyRoutesBuilderLoader")
+ .then()
+ .statusCode(200)
+ .body(CoreMatchers.is(GroovyRoutesBuilderLoader.class.getName()));
+
+ RestAssured.given()
+ .get("/groovy-dsl/main/routeBuilders")
+ .then()
+ .statusCode(200)
+ .body(CoreMatchers.is(""));
+
+ RestAssured.given()
+ .get("/groovy-dsl/main/routes")
+ .then()
+ .statusCode(200)
+ .body(CoreMatchers.is(
+ "my-groovy-route,routes-with-components-configuration,routes-with-dataformats-configuration,routes-with-endpoint-dsl,routes-with-error-handler,routes-with-languages-configuration"));
+ }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 6cec5ae466..061f0adea1 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -104,6 +104,7 @@
<module>google-storage</module>
<module>graphql</module>
<module>grok</module>
+ <module>groovy-dsl</module>
<module>grpc</module>
<module>hazelcast</module>
<module>headersmap</module>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index e81a8e5052..c0c776976d 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -204,6 +204,7 @@ group-13:
- fhir
- github
- google
+ - groovy-dsl
- jira
- java-joor-dsl
- js-dsl