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

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 49380ac1f0 NIFI-15121 Added validation timeout for ExecuteGroovyScript
49380ac1f0 is described below

commit 49380ac1f0e95a69c72fc5c8f0f9910bb3c5e37c
Author: exceptionfactory <[email protected]>
AuthorDate: Tue Oct 28 09:26:14 2025 -0500

    NIFI-15121 Added validation timeout for ExecuteGroovyScript
    
    Co-authored-by: Istvan Adamcsik 
<[email protected]>
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #10470.
---
 .../processors/groovyx/ExecuteGroovyScript.java    | 37 ++++++++++++++++------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git 
a/nifi-extension-bundles/nifi-groovyx-bundle/nifi-groovyx-processors/src/main/java/org/apache/nifi/processors/groovyx/ExecuteGroovyScript.java
 
b/nifi-extension-bundles/nifi-groovyx-bundle/nifi-groovyx-processors/src/main/java/org/apache/nifi/processors/groovyx/ExecuteGroovyScript.java
index 5859b6a411..227b5cf03b 100644
--- 
a/nifi-extension-bundles/nifi-groovyx-bundle/nifi-groovyx-processors/src/main/java/org/apache/nifi/processors/groovyx/ExecuteGroovyScript.java
+++ 
b/nifi-extension-bundles/nifi-groovyx-bundle/nifi-groovyx-processors/src/main/java/org/apache/nifi/processors/groovyx/ExecuteGroovyScript.java
@@ -22,9 +22,9 @@ import java.io.File;
 import java.lang.reflect.Method;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
+import java.time.Duration;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -68,10 +68,11 @@ import org.codehaus.groovy.runtime.StackTraceUtils;
 
 @InputRequirement(InputRequirement.Requirement.INPUT_ALLOWED)
 @Tags({"script", "groovy", "groovyx"})
-@CapabilityDescription(
-        "Experimental Extended Groovy script processor. The script is 
responsible for "
-        + "handling the incoming flow file (transfer to SUCCESS or remove, 
e.g.) as well as any flow files created by "
-        + "the script. If the handling is incomplete or incorrect, the session 
will be rolled back.")
+@CapabilityDescription("""
+        Execute custom Groovy script to handle input FlowFiles and route to 
standard relationships.
+        Script validation includes a timeout of 5 minutes to avoid potential 
issues with dynamic dependency resolution.
+        """
+)
 @Restricted(
         restrictions = {
                 @Restriction(
@@ -211,13 +212,29 @@ public class ExecuteGroovyScript extends 
AbstractProcessor {
         this.addClasspath = 
context.getProperty(ADD_CLASSPATH).evaluateAttributeExpressions().getValue(); 
//ADD_CLASSPATH
         this.groovyClasspath = 
context.newPropertyValue(GROOVY_CLASSPATH).evaluateAttributeExpressions().getValue();
 //evaluated from ${groovy.classes.path} global property
 
-        final Collection<ValidationResult> results = new HashSet<>();
+        final ValidationResult.Builder builder = new ValidationResult.Builder()
+                .subject("GroovyScript")
+                .input(scriptFile == null ? null : scriptFile.toString());
+
+        final Thread validationThread = Thread.startVirtualThread(() -> {
+            try {
+                getGroovyScript();
+                builder.valid(true);
+            } catch (final Throwable e) {
+                builder.explanation(e.toString());
+                builder.valid(false);
+            }
+        });
+
         try {
-            getGroovyScript();
-        } catch (Throwable t) {
-            results.add(new 
ValidationResult.Builder().subject("GroovyScript").input(this.scriptFile != 
null ? this.scriptFile.toString() : 
null).valid(false).explanation(t.toString()).build());
+            validationThread.join(Duration.ofMinutes(5));
+        } catch (final InterruptedException e) {
+            builder.valid(false);
+            builder.explanation("Groovy Script validation interrupted after 5 
minutes");
         }
-        return results;
+
+        final ValidationResult result = builder.build();
+        return List.of(result);
     }
 
     /**

Reply via email to