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 64bd7d8db2 Groovy: extend test coverage
64bd7d8db2 is described below

commit 64bd7d8db280cd2caaa13d2714d452de26b7e8dc
Author: Jiri Ondrusek <ondrusek.j...@gmail.com>
AuthorDate: Wed Mar 12 08:25:52 2025 +0100

    Groovy: extend test coverage
---
 .../ROOT/pages/reference/extensions/groovy.adoc    |  6 ++
 .../groovy/runtime/src/main/doc/limitations.adoc   |  6 ++
 .../component/groovy/it/GroovyProducers.java       | 44 +++++++++++
 .../component/groovy/it/GroovyResource.java        | 39 ++++++----
 .../quarkus/component/groovy/it/GroovyRoutes.java  | 71 ++++++++++++++++++
 .../src/main/resources/application.properties      | 17 +++++
 .../groovy/src/main/resources/mygroovy.groovy      | 17 +++++
 .../quarkus/component/groovy/it/GroovyTest.java    | 86 +++++++++++++++++++++-
 8 files changed, 268 insertions(+), 18 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/groovy.adoc 
b/docs/modules/ROOT/pages/reference/extensions/groovy.adoc
index 49ec755be1..8a8fe60be2 100644
--- a/docs/modules/ROOT/pages/reference/extensions/groovy.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/groovy.adoc
@@ -52,3 +52,9 @@ Due to some limitations in GraalVM that prevent to execute 
even basic scripts in
 Groovy expressions is made with the static compilation enabled which means 
that the types used in your expression must
 be known at compile time. Please refer to the 
https://docs.groovy-lang.org/latest/html/documentation/core-semantics.html#static-type-checking[Groovy
 documentation for more details].
 
+This primarily impacts the customization of the Groovy Shell and the handling 
of exchange information.
+In native mode, customizing the Groovy Shell and accessing the following 
exchange variables will not function as expected.
+```
+header, variable, variables, exchangeProperty, exchangeProperties, log, 
attachment
+```
+
diff --git a/extensions/groovy/runtime/src/main/doc/limitations.adoc 
b/extensions/groovy/runtime/src/main/doc/limitations.adoc
index 5aa4300809..1681d0d654 100644
--- a/extensions/groovy/runtime/src/main/doc/limitations.adoc
+++ b/extensions/groovy/runtime/src/main/doc/limitations.adoc
@@ -1,3 +1,9 @@
 Due to some limitations in GraalVM that prevent to execute even basic scripts 
in native mode, the compilation of the
 Groovy expressions is made with the static compilation enabled which means 
that the types used in your expression must
 be known at compile time. Please refer to the 
https://docs.groovy-lang.org/latest/html/documentation/core-semantics.html#static-type-checking[Groovy
 documentation for more details].
+
+This primarily impacts the customization of the Groovy Shell and the handling 
of exchange information.
+In native mode, customizing the Groovy Shell and accessing the following 
exchange variables will not function as expected.
+```
+header, variable, variables, exchangeProperty, exchangeProperties, log, 
attachment
+```
\ No newline at end of file
diff --git 
a/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyProducers.java
 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyProducers.java
new file mode 100644
index 0000000000..f70ae2d167
--- /dev/null
+++ 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyProducers.java
@@ -0,0 +1,44 @@
+/*
+ * 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.component.groovy.it;
+
+import java.util.Collections;
+import java.util.Map;
+
+import groovy.lang.GroovyShell;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Named;
+import org.apache.camel.Exchange;
+import org.apache.camel.language.groovy.GroovyShellFactory;
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+@ApplicationScoped
+public class GroovyProducers {
+
+    @Named("customShell")
+    public GroovyShellFactory createCustomShell() {
+        return new GroovyShellFactory() {
+            public GroovyShell createGroovyShell(Exchange exchange) {
+                return new GroovyShell(new CompilerConfiguration());
+            }
+
+            public Map<String, Object> getVariables(Exchange exchange) {
+                return Collections.singletonMap("hello", (Object) "Ahoj");
+            }
+        };
+    }
+}
diff --git 
a/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyResource.java
 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyResource.java
index 2732e8ccc1..222bcc0b0b 100644
--- 
a/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyResource.java
+++ 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyResource.java
@@ -40,22 +40,6 @@ public class GroovyResource {
     @Inject
     ProducerTemplate producerTemplate;
 
-    @POST
-    @Path("/hello")
-    @Consumes(MediaType.TEXT_PLAIN)
-    @Produces(MediaType.TEXT_PLAIN)
-    public String hello(String message) {
-        return producerTemplate.requestBody("direct:groovyHello", message, 
String.class);
-    }
-
-    @POST
-    @Path("/hi")
-    @Consumes(MediaType.TEXT_PLAIN)
-    @Produces(MediaType.TEXT_PLAIN)
-    public String hi(String message) {
-        return producerTemplate.requestBody("direct:groovyHi", message, 
String.class);
-    }
-
     @POST
     @Path("/predicate")
     @Consumes(MediaType.TEXT_PLAIN)
@@ -75,4 +59,27 @@ public class GroovyResource {
         return producerTemplate.requestBodyAndHeaders("direct:" + route, 
statement, headers, String.class);
     }
 
+    @POST
+    @Path("/direct/{id}")
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String direct(@PathParam("id") String id, String message) {
+        return producerTemplate.requestBody("direct:" + id, message, 
String.class);
+    }
+
+    @Path("/contextValidation")
+    @POST
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String route() {
+        final Map<String, Object> headers = Map.of("header1", (Object) 
"value_of_header1");
+        return 
producerTemplate.requestBodyAndHeaders("direct:contextValidation", "body", 
headers, String.class);
+    }
+
+    @Path("results/validateExchangeProperties")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    public Object getMessagesOfWithoutSsl() throws InterruptedException {
+        return producerTemplate.requestBody("direct:validateExchangeProperty", 
"body", String.class);
+    }
 }
diff --git 
a/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyRoutes.java
 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyRoutes.java
index 4fd526812b..ad6edd6d3f 100644
--- 
a/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyRoutes.java
+++ 
b/integration-tests/groovy/src/main/java/org/apache/camel/quarkus/component/groovy/it/GroovyRoutes.java
@@ -16,13 +16,21 @@
  */
 package org.apache.camel.quarkus.component.groovy.it;
 
+import java.util.Optional;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.FileDataSource;
+import org.apache.camel.attachment.AttachmentMessage;
 import org.apache.camel.builder.RouteBuilder;
+import org.eclipse.microprofile.config.ConfigProvider;
 
 public class GroovyRoutes extends RouteBuilder {
 
     @Override
     public void configure() {
 
+        Optional<Boolean> inNative = 
ConfigProvider.getConfig().getOptionalValue("quarkus.native.enabled", 
Boolean.class);
+
         routeTemplate("whereTo")
                 .templateParameter("bar")
                 .templateBean("myBar", "groovy", "resource:classpath:bean.txt")
@@ -34,6 +42,11 @@ public class GroovyRoutes extends RouteBuilder {
 
         from("direct:groovyHello")
                 .transform().groovy("\"Hello \" + body + \" from Groovy!\"");
+
+        from("direct:filter")
+                .filter().groovy("!(request.body as String).contains('Hi')")
+                .transform().groovy("\"Received unknown request: \" + body");
+
         from("direct:predicate")
                 .choice()
                 .when().groovy("((int) body) / 2 > 10")
@@ -45,5 +58,63 @@ public class GroovyRoutes extends RouteBuilder {
                 .script()
                 .groovy("exchange.getMessage().setBody('Hello ' + 
exchange.getMessage().getBody(String.class) + ' from Groovy!')");
 
+        from("direct:multiStatement")
+                .transform().groovy("""
+                        def a = "Hello A"
+                        def b = "Hello B"
+                        //other statements
+                        def result = "Hello C"
+                        """);
+
+        from("direct:scriptFromResource")
+                
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")
+                .setBody(simple("${header.myHeader}"));
+
+        from("direct:validateContext")
+                .setHeader("myHeader", constant("myHeaderValue"))
+                .setVariable("myVariable", constant("myVariableValue"))
+                .setProperty("myProperty", constant("myPropertyValue"))
+                .process(exchange -> {
+                    AttachmentMessage attMsg = 
exchange.getIn(AttachmentMessage.class);
+                    attMsg.addAttachment("mygroovy.groovy", new 
DataHandler(new FileDataSource("mygroovy.groovy")));
+                })
+                .transform().groovy("return " + getContextVariables(false))
+                .log("${body}");
+
+        //routes only for jvm
+        if (inNative.isEmpty() || !inNative.get()) {
+            from("direct:customizedHi")
+                    .transform().groovy("hello + \" \" + body + \" from 
Groovy!\"");
+
+            from("direct:validateContextInJvm")
+                    .setHeader("myHeader", constant("myHeaderValue"))
+                    .setVariable("myVariable", constant("myVariableValue"))
+                    .setProperty("myProperty", constant("myPropertyValue"))
+                    .process(exchange -> {
+                        AttachmentMessage attMsg = 
exchange.getIn(AttachmentMessage.class);
+                        attMsg.addAttachment("mygroovy.groovy", new 
DataHandler(new FileDataSource("mygroovy.groovy")));
+                    })
+                    .transform().groovy("return " + getContextVariables(true))
+                    .log("${body}");
+        }
+    }
+
+    private static String getContextVariables(boolean jvm) {
+        String contextVariables = "\"headers: \" + headers + " +
+                "\", exchange: \" + exchange + " +
+                "\", camelContext: \" + camelContext + " +
+                "\", request: \" + request";
+
+        if (jvm) {
+            // following properties are not working in the native mode
+            contextVariables += " + \", exchangeProperties: \" + 
exchangeProperties + " +
+                    "\", exchangeProperty: \" + exchangeProperty + " +
+                    "\", variable: \" + variable + " +
+                    "\", variables: \" + variables + " +
+                    "\", header: \" + header + " +
+                    "\", attachments: \" + attachments + " +
+                    "\", log: \" + log";
+        }
+        return contextVariables;
     }
 }
diff --git a/integration-tests/groovy/src/main/resources/application.properties 
b/integration-tests/groovy/src/main/resources/application.properties
new file mode 100644
index 0000000000..14d5d5f7bf
--- /dev/null
+++ b/integration-tests/groovy/src/main/resources/application.properties
@@ -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.
+## ---------------------------------------------------------------------------
+quarkus.native.resources.includes=*.groovy
diff --git a/integration-tests/groovy/src/main/resources/mygroovy.groovy 
b/integration-tests/groovy/src/main/resources/mygroovy.groovy
new file mode 100644
index 0000000000..8baf968ea4
--- /dev/null
+++ b/integration-tests/groovy/src/main/resources/mygroovy.groovy
@@ -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.
+ */
+return "Hello " + body + " from resources!"
\ No newline at end of file
diff --git 
a/integration-tests/groovy/src/test/java/org/apache/camel/quarkus/component/groovy/it/GroovyTest.java
 
b/integration-tests/groovy/src/test/java/org/apache/camel/quarkus/component/groovy/it/GroovyTest.java
index 1a4dc1a3a1..defd9f688f 100644
--- 
a/integration-tests/groovy/src/test/java/org/apache/camel/quarkus/component/groovy/it/GroovyTest.java
+++ 
b/integration-tests/groovy/src/test/java/org/apache/camel/quarkus/component/groovy/it/GroovyTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.quarkus.component.groovy.it;
 
+import io.quarkus.test.junit.DisabledOnIntegrationTest;
 import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
@@ -30,7 +31,7 @@ class GroovyTest {
     void groovyHello() {
         RestAssured.given()
                 .body("Will Smith")
-                .post("/groovy/hello")
+                .post("/groovy/direct/groovyHello")
                 .then()
                 .statusCode(200)
                 .body(CoreMatchers.is("Hello Will Smith from Groovy!"));
@@ -40,7 +41,7 @@ class GroovyTest {
     void groovyHi() {
         RestAssured.given()
                 .body("Jack")
-                .post("/groovy/hi")
+                .post("/groovy/direct/groovyHi")
                 .then()
                 .statusCode(200)
                 .body(CoreMatchers.is("Hi Jack we are going to Shamrock"));
@@ -77,4 +78,85 @@ class GroovyTest {
                 .body(Matchers.is("Hello world from Groovy!"));
     }
 
+    @Test
+    void groovyFilter() {
+        //hi is not changed
+        RestAssured.given()
+                .body("Hi")
+                .post("/groovy/direct/filter")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Hi"));
+        //hello is changed
+        RestAssured.given()
+                .body("Hello")
+                .post("/groovy/direct/filter")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Received unknown request: Hello"));
+    }
+
+    @Test
+    void groovyMultiStatement() {
+        //hi is not changed
+        RestAssured.given()
+                .body("Hi")
+                .post("/groovy/direct/multiStatement")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Hello C"));
+    }
+
+    @Test
+    void groovyScriptFromResource() {
+        RestAssured.given()
+                .body("Sheldon")
+                .post("/groovy/direct/scriptFromResource")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Hello Sheldon from resources!"));
+    }
+
+    @Test
+    void contextValidation() {
+        RestAssured.given()
+                .body("")
+                .post("/groovy/direct/validateContext")
+                .then()
+                .statusCode(200)
+                .body(Matchers.containsString("camelContext: CamelContext("))
+                .body(Matchers.containsString("request: Message"))
+                .body(Matchers.containsString("headers: 
[myHeader:myHeaderValue"));
+    }
+
+    //following tests don't work in the native mode (see extension doc)
+
+    @DisabledOnIntegrationTest
+    @Test
+    void contextValidationInJVMMode() {
+        //JVM mode allows to use more variables
+        RestAssured.given()
+                .body("")
+                .post("/groovy/direct/validateContextInJvm")
+                .then()
+                .statusCode(200)
+                .body(Matchers.containsString("exchangeProperties: 
[myProperty:myPropertyValue"))
+                .body(Matchers.containsString("exchangeProperty: 
[myProperty:myPropertyValue"))
+                .body(Matchers.containsString("variable: 
[myVariable:myVariableValue]"))
+                .body(Matchers.containsString("variable: 
[myVariable:myVariableValue]"))
+                .body(Matchers.containsString("header: 
[myHeader:myHeaderValue]"))
+                .body(Matchers.containsString("attachments: [mygroovy.groovy"))
+                .body(Matchers.containsString("log: org.slf4j.impl"));
+    }
+
+    @DisabledOnIntegrationTest
+    @Test
+    void groovyCustomizedShellHi() {
+        RestAssured.given()
+                .body("Jack")
+                .post("/groovy/direct/customizedHi")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Ahoj Jack from Groovy!"));
+    }
 }

Reply via email to