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

josedee pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-kogito-apps.git


The following commit(s) were added to refs/heads/main by this push:
     new c31279ebe [incubator-kie-isues#2321] Adding validations for REST WIH 
parameters. (#2327)
c31279ebe is described below

commit c31279ebe533e5219fb965a3f8696b9c60e46aab
Author: Christine-Jose <[email protected]>
AuthorDate: Wed May 20 17:23:58 2026 +0530

    [incubator-kie-isues#2321] Adding validations for REST WIH parameters. 
(#2327)
    
    * t Adding validations for REST WIH
    
    * Review Comments
    
    * Review Comments
    
    * Review comments
---
 .rat-excludes                                      |   5 +
 .../jitexecutor/bpmn/JITBPMNServiceImpl.java       | 471 +++++++++++++++++++++
 .../jitexecutor/bpmn/JITBPMNServiceImplTest.java   |  65 +++
 .../kie/kogito/jitexecutor/bpmn/TestingUtils.java  |  10 +
 .../resources/RestWIH_AllValid_Scenarios.bpmn2     | 289 +++++++++++++
 .../src/test/resources/RestWIH_Invalid.bpmn2       | 195 +++++++++
 .../src/test/resources/RestWIH_Valid.bpmn2         | 101 +++++
 .../src/test/resources/RestWIH_Valid_Proper.bpmn2  | 112 +++++
 .../src/test/resources/RestWIH_Valid_Simple.bpmn2  |  47 ++
 9 files changed, 1295 insertions(+)

diff --git a/.rat-excludes b/.rat-excludes
index 08797b29e..f9371bde5 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -52,6 +52,11 @@ 
jitexecutor/jitexecutor-bpmn/src/test/resources/SingleProcess.bpmn2
 jitexecutor/jitexecutor-bpmn/src/test/resources/SingleUnparsableModel.bpmn2
 jitexecutor/jitexecutor-bpmn/src/test/resources/UnparsableModel.bpmn2
 jitexecutor/jitexecutor-bpmn/src/test/resources/ValidModel.bpmn
+jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_AllValid_Scenarios.bpmn2
+jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Invalid.bpmn2
+jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid.bpmn2
+jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Proper.bpmn2
+jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Simple.bpmn2
 jitexecutor/jitexecutor-dmn/src/main/resources/META-INF/resources/bundle.js
 
jobs/kogito-addons-springboot-embedded-jobs/src/test/resources/application.properties
 
jobs-service/kogito-addons-jobs-service/kogito-addons-quarkus-jobs/src/test/resources/application.properties
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/main/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImpl.java
 
b/jitexecutor/jitexecutor-bpmn/src/main/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImpl.java
index 601c3c6ea..abefebd90 100644
--- 
a/jitexecutor/jitexecutor-bpmn/src/main/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImpl.java
+++ 
b/jitexecutor/jitexecutor-bpmn/src/main/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImpl.java
@@ -21,9 +21,19 @@ package org.kie.kogito.jitexecutor.bpmn;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.Reader;
+import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.drools.io.InputStreamResource;
 import org.jbpm.bpmn2.xml.BPMNDISemanticModule;
@@ -31,8 +41,10 @@ import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule;
 import org.jbpm.bpmn2.xml.BPMNSemanticModule;
 import org.jbpm.compiler.xml.XmlProcessReader;
 import org.jbpm.compiler.xml.core.SemanticModules;
+import org.jbpm.process.core.Work;
 import org.jbpm.process.core.validation.ProcessValidationError;
 import org.jbpm.ruleflow.core.validation.RuleFlowProcessValidator;
+import org.jbpm.workflow.core.node.WorkItemNode;
 import org.kie.api.definition.process.Process;
 import org.kie.api.io.Resource;
 import org.kie.kogito.jitexecutor.bpmn.responses.JITBPMNValidationResult;
@@ -55,6 +67,35 @@ public class JITBPMNServiceImpl implements JITBPMNService {
 
     private static String ERROR_TEMPLATE = "Uri: %s - Process id: %s - name : 
%s - error : %s";
 
+    private static final String NODE_ERROR_TEMPLATE = "Uri: %s - Process id: 
%s - name: %s - Node: %s [%s] - error: %s";
+
+    // REST Work Item Handler validation constants
+    private static final String REST_TASK_TYPE = "Rest";
+    private static final String ACCESS_TOKEN_STRATEGY_PARAM = 
"AccessTokenAcquisitionStrategy";
+    private static final String REST_SERVICE_CALL_TASK_ID_PARAM = 
"RestServiceCallTaskId";
+    private static final String URL_PARAM = "Url";
+    private static final String METHOD_PARAM = "Method";
+    private static final String PROTOCOL_PARAM = "Protocol";
+    private static final String HOST_PARAM = "Host";
+    private static final String PORT_PARAM = "Port";
+    private static final String CONTENT_DATA_PARAM = "ContentData";
+    private static final String REQUEST_TIMEOUT_PARAM = "RequestTimeout";
+
+    private static final Set<String> VALID_STRATEGIES = new HashSet<>(
+            Arrays.asList("propagated", "configured", "none"));
+    private static final Set<String> VALID_HTTP_METHODS = new HashSet<>(
+            Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE"));
+    private static final Set<String> METHODS_WITH_BODY = new HashSet<>(
+            Arrays.asList("POST", "PUT", "PATCH"));
+    private static final Set<String> VALID_PROTOCOLS = new HashSet<>(
+            Arrays.asList("http", "https"));
+
+    private static final Pattern VALID_TASK_ID_PATTERN = 
Pattern.compile("^[A-Za-z0-9_]+$");
+    private static final Pattern EXPRESSION_PATTERN = 
Pattern.compile("^#\\{.+\\}$");
+    private static final Pattern URL_PLACEHOLDER_PATTERN = 
Pattern.compile("\\{[^}]+\\}");
+    private static final Pattern QUERY_PARAM_PATTERN = 
Pattern.compile("^QUERY_(.+)$");
+    private static final Pattern HEADER_PARAM_PATTERN = 
Pattern.compile("^HEADER_(.+)$");
+
     static {
         BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNSemanticModule());
         BPMN_SEMANTIC_MODULES.addSemanticModule(new 
BPMNExtensionsSemanticModule());
@@ -95,6 +136,11 @@ public class JITBPMNServiceImpl implements JITBPMNService {
                 for (ProcessValidationError processValidationError : 
processValidationErrors) {
                     toReturn.add(getErrorString(processValidationError, 
resourceUri));
                 }
+                // REST Work Item Handler validation - parse XML to get 
parameter values
+                Map<String, Map<String, String>> nodeParameters = 
parseNodeParametersFromXml(modelXML);
+                for (Process process : processes) {
+                    toReturn.addAll(validateRestWorkItems(process, 
resourceUri, nodeParameters));
+                }
             }
         } catch (Throwable e) {
             String error = e.getMessage() != null && !e.getMessage().isEmpty() 
? e.getMessage() : e.toString();
@@ -137,4 +183,429 @@ public class JITBPMNServiceImpl implements JITBPMNService 
{
         String uri = resourceUri != null ? resourceUri : "(unknown)";
         return String.format(ERROR_TEMPLATE, uri, failed.getId(), 
failed.getName(), processValidationError.getMessage());
     }
+
+    private static Collection<String> validateRestWorkItems(Process process, 
String resourceUri, Map<String, Map<String, String>> nodeParameters) {
+        Collection<String> errors = new ArrayList<>();
+
+        if (process == null) {
+            return errors;
+        }
+
+        org.kie.api.definition.process.Node[] nodes = 
((org.jbpm.workflow.core.WorkflowProcess) process).getNodes();
+        if (nodes == null) {
+            return errors;
+        }
+
+        for (org.kie.api.definition.process.Node node : nodes) {
+            if (node instanceof WorkItemNode) {
+                WorkItemNode workItemNode = (WorkItemNode) node;
+                Work work = workItemNode.getWork();
+
+                if (work != null && REST_TASK_TYPE.equals(work.getName())) {
+                    // Try to get parameters using the node's UUID from 
metadata
+                    String nodeUuid = (String) 
workItemNode.getMetaData().get("UniqueId");
+                    Map<String, String> params = null;
+
+                    if (nodeUuid != null) {
+                        params = nodeParameters.get(nodeUuid);
+                    }
+
+                    if (params == null) {
+                        params = 
nodeParameters.get(String.valueOf(workItemNode.getId()));
+                    }
+
+                    errors.addAll(validateRestWorkItem(workItemNode, process, 
resourceUri, params));
+                }
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateRestWorkItem(WorkItemNode node, 
Process process, String resourceUri, Map<String, String> nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        Work work = node.getWork();
+
+        errors.addAll(validateMethod(work, node, process, resourceUri, 
nodeParams));
+
+        errors.addAll(validateUrl(work, node, process, resourceUri, 
nodeParams));
+
+        errors.addAll(validateProtocolHostPort(work, node, process, 
resourceUri, nodeParams));
+
+        errors.addAll(validateContentData(work, node, process, resourceUri, 
nodeParams));
+
+        errors.addAll(validateQueryAndHeaderParams(work, node, process, 
resourceUri, nodeParams));
+
+        errors.addAll(validateRequestTimeout(work, node, process, resourceUri, 
nodeParams));
+
+        errors.addAll(validateAccessTokenStrategy(work, node, process, 
resourceUri, nodeParams));
+
+        errors.addAll(validateRestServiceCallTaskId(work, node, process, 
resourceUri, nodeParams));
+
+        return errors;
+    }
+
+    private static Collection<String> validateMethod(Work work, WorkItemNode 
node, Process process, String resourceUri, Map<String, String> nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String method = getParameterValue(work, nodeParams, METHOD_PARAM);
+
+        if (method != null && !method.trim().isEmpty()) {
+
+            if (isExpression(method)) {
+                return errors;
+            }
+
+            String upperMethod = method.toUpperCase();
+            if (!VALID_HTTP_METHODS.contains(upperMethod)) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("Method must be one of: GET, POST, PUT, 
PATCH, DELETE, or an expression like #{expr}. Found: '%s'", method)));
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateUrl(Work work, WorkItemNode 
node, Process process, String resourceUri, Map<String, String> nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String url = getParameterValue(work, nodeParams, URL_PARAM);
+
+        if (url == null || url.trim().isEmpty()) {
+            errors.add(formatNodeError(resourceUri, process, node,
+                    "Url is required for REST service call tasks"));
+        } else if (!isExpression(url)) {
+
+            if (!isValidUrlFormat(url)) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("Url must be a valid URL format. Found: 
'%s'", url)));
+            } else {
+                boolean isRelativeUrl = url.startsWith("/") && 
!url.startsWith("//");
+                if (isRelativeUrl) {
+                    String protocol = getParameterValue(work, nodeParams, 
PROTOCOL_PARAM);
+                    String host = getParameterValue(work, nodeParams, 
HOST_PARAM);
+
+                    if ((protocol == null || protocol.trim().isEmpty()) && 
(host == null || host.trim().isEmpty())) {
+                        errors.add(formatNodeError(resourceUri, process, node,
+                                String.format("Url is a relative path '%s'. 
Either provide a complete URL (e.g., 'https://example.com/users') or specify 
Protocol and Host parameters", url)));
+                    }
+                }
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateProtocolHostPort(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String url = getParameterValue(work, nodeParams, URL_PARAM);
+        String protocol = getParameterValue(work, nodeParams, PROTOCOL_PARAM);
+        String host = getParameterValue(work, nodeParams, HOST_PARAM);
+        String port = getParameterValue(work, nodeParams, PORT_PARAM);
+
+        if (protocol != null && !protocol.trim().isEmpty() && 
!isExpression(protocol)) {
+            String lowerProtocol = protocol.toLowerCase();
+            if (!VALID_PROTOCOLS.contains(lowerProtocol)) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("Protocol must be 'http' or 'https'. 
Found: '%s'", protocol)));
+            }
+
+            if (url != null && !url.trim().isEmpty() && !isExpression(url)) {
+                if (url.startsWith("http://";) || url.startsWith("https://";)) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            "Protocol should not be specified when Url already 
contains the protocol"));
+                }
+            }
+        }
+
+        if (host != null && !host.trim().isEmpty()) {
+            if (url != null && !url.trim().isEmpty() && !isExpression(url)) {
+                if (url.startsWith("http://";) || url.startsWith("https://";)) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            "Host should not be specified when Url already 
contains the host"));
+                }
+            }
+        }
+
+        if (port != null && !port.trim().isEmpty() && !isExpression(port)) {
+            try {
+                int portNum = Integer.parseInt(port);
+                if (portNum < 1 || portNum > 65535) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("Port must be between 1 and 65535. 
Found: %d", portNum)));
+                }
+            } catch (NumberFormatException e) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("Port must be a valid integer. Found: 
'%s'", port)));
+            }
+
+            if (url != null && !url.trim().isEmpty() && !isExpression(url)) {
+                if (url.matches(".*:\\d+.*")) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            "Port should not be specified when Url already 
contains the port"));
+                }
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateContentData(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String contentData = getParameterValue(work, nodeParams, 
CONTENT_DATA_PARAM);
+        String method = getParameterValue(work, nodeParams, METHOD_PARAM);
+
+        if (contentData != null && !contentData.trim().isEmpty()) {
+
+            String effectiveMethod = (method != null && 
!method.trim().isEmpty()) ? method.toUpperCase() : "GET";
+
+            if (!isExpression(effectiveMethod) && 
!METHODS_WITH_BODY.contains(effectiveMethod)) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("ContentData should only be used with 
methods that support request bodies (POST, PUT, PATCH). Current method: '%s'", 
effectiveMethod)));
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateQueryAndHeaderParams(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+
+        Set<String> allParamNames = new 
HashSet<>(work.getParameters().keySet());
+        if (nodeParams != null) {
+            allParamNames.addAll(nodeParams.keySet());
+        }
+
+        for (String paramName : allParamNames) {
+
+            if (QUERY_PARAM_PATTERN.matcher(paramName).matches()) {
+                String value = getParameterValue(work, nodeParams, paramName);
+                if (value == null || value.trim().isEmpty()) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("Query parameter '%s' has an empty 
value", paramName)));
+                }
+            }
+
+            if (HEADER_PARAM_PATTERN.matcher(paramName).matches()) {
+                String value = getParameterValue(work, nodeParams, paramName);
+                if (value == null || value.trim().isEmpty()) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("Header parameter '%s' has an empty 
value", paramName)));
+                }
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateRequestTimeout(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String timeout = getParameterValue(work, nodeParams, 
REQUEST_TIMEOUT_PARAM);
+
+        if (timeout != null && !timeout.trim().isEmpty() && 
!isExpression(timeout)) {
+            try {
+                long timeoutValue = Long.parseLong(timeout);
+                if (timeoutValue < 0) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("RequestTimeout must be a 
non-negative number. Found: %d", timeoutValue)));
+                }
+            } catch (NumberFormatException e) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("RequestTimeout must be a valid number. 
Found: '%s'", timeout)));
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateAccessTokenStrategy(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String strategy = getParameterValue(work, nodeParams, 
ACCESS_TOKEN_STRATEGY_PARAM);
+
+        if (strategy == null || strategy.trim().isEmpty()) {
+            errors.add(formatNodeError(resourceUri, process, node,
+                    "AccessTokenAcquisitionStrategy is required for REST 
service call tasks"));
+        } else {
+            // Expressions are not allowed for this parameter
+            if (isExpression(strategy)) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("AccessTokenAcquisitionStrategy cannot 
be an expression. Must be one of: propagated, configured, none. Found: '%s'", 
strategy)));
+            } else if (!VALID_STRATEGIES.contains(strategy.toLowerCase())) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        String.format("AccessTokenAcquisitionStrategy must be 
one of: propagated, configured, none. Found: '%s'", strategy)));
+            }
+        }
+
+        return errors;
+    }
+
+    private static Collection<String> validateRestServiceCallTaskId(Work work, 
WorkItemNode node, Process process, String resourceUri, Map<String, String> 
nodeParams) {
+        Collection<String> errors = new ArrayList<>();
+        String strategy = getParameterValue(work, nodeParams, 
ACCESS_TOKEN_STRATEGY_PARAM);
+        String taskId = getParameterValue(work, nodeParams, 
REST_SERVICE_CALL_TASK_ID_PARAM);
+
+        // RestServiceCallTaskId is required when strategy is "configured"
+        if (strategy != null && 
"configured".equalsIgnoreCase(strategy.trim())) {
+            if (taskId == null || taskId.trim().isEmpty()) {
+                errors.add(formatNodeError(resourceUri, process, node,
+                        "RestServiceCallTaskId is required when 
AccessTokenAcquisitionStrategy is 'configured'"));
+            } else {
+                // Expressions are not allowed for this parameter
+                if (isExpression(taskId)) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("RestServiceCallTaskId cannot be an 
expression. Found: '%s'", taskId)));
+                } else if (!VALID_TASK_ID_PATTERN.matcher(taskId).matches()) {
+                    errors.add(formatNodeError(resourceUri, process, node,
+                            String.format("RestServiceCallTaskId must contain 
only alphanumeric characters and underscores. Found: '%s'", taskId)));
+                }
+            }
+        }
+
+        return errors;
+    }
+
+    private static String getParameterValue(Work work, Map<String, String> 
nodeParams, String paramName) {
+        Object value = work.getParameter(paramName);
+        if (value != null) {
+            return value.toString();
+        }
+
+        if (nodeParams != null && nodeParams.containsKey(paramName)) {
+            return nodeParams.get(paramName);
+        }
+
+        return null;
+    }
+
+    private static Map<String, Map<String, String>> 
parseNodeParametersFromXml(String modelXML) {
+        Map<String, Map<String, String>> result = new HashMap<>();
+
+        try {
+            DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            org.w3c.dom.Document doc = builder.parse(new 
org.xml.sax.InputSource(new StringReader(modelXML)));
+
+            org.w3c.dom.NodeList tasks = doc.getElementsByTagNameNS("*", 
"task");
+            if (tasks.getLength() == 0) {
+                tasks = doc.getElementsByTagName("task");
+            }
+
+            for (int i = 0; i < tasks.getLength(); i++) {
+                org.w3c.dom.Element task = (org.w3c.dom.Element) tasks.item(i);
+                String taskId = task.getAttribute("id");
+
+                if (taskId != null && !taskId.isEmpty()) {
+                    Map<String, String> params = new HashMap<>();
+
+                    // Find dataInputAssociation elements
+                    org.w3c.dom.NodeList associations = 
task.getElementsByTagNameNS("*", "dataInputAssociation");
+                    if (associations.getLength() == 0) {
+                        associations = 
task.getElementsByTagName("dataInputAssociation");
+                    }
+
+                    for (int j = 0; j < associations.getLength(); j++) {
+                        org.w3c.dom.Element association = 
(org.w3c.dom.Element) associations.item(j);
+
+                        // Get targetRef (parameter name)
+                        org.w3c.dom.NodeList targetRefs = 
association.getElementsByTagNameNS("*", "targetRef");
+                        if (targetRefs.getLength() == 0) {
+                            targetRefs = 
association.getElementsByTagName("targetRef");
+                        }
+
+                        if (targetRefs.getLength() > 0) {
+                            String targetRef = 
targetRefs.item(0).getTextContent().trim();
+
+                            // Extract parameter name from targetRef
+                            String paramName = 
getParameterNameFromDataInputId(task, targetRef);
+
+                            // Get the value from assignment/from element
+                            org.w3c.dom.NodeList assignments = 
association.getElementsByTagNameNS("*", "assignment");
+                            if (assignments.getLength() == 0) {
+                                assignments = 
association.getElementsByTagName("assignment");
+                            }
+
+                            if (assignments.getLength() > 0) {
+                                org.w3c.dom.Element assignment = 
(org.w3c.dom.Element) assignments.item(0);
+                                org.w3c.dom.NodeList froms = 
assignment.getElementsByTagNameNS("*", "from");
+                                if (froms.getLength() == 0) {
+                                    froms = 
assignment.getElementsByTagName("from");
+                                }
+
+                                if (froms.getLength() > 0) {
+                                    String value = 
froms.item(0).getTextContent().trim();
+                                    if (paramName != null && value != null && 
!value.isEmpty()) {
+                                        params.put(paramName, value);
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    if (!params.isEmpty()) {
+                        result.put(taskId, params);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.warn("Failed to parse BPMN XML for parameter extraction", 
e);
+        }
+
+        return result;
+    }
+
+    private static String getParameterNameFromDataInputId(org.w3c.dom.Element 
task, String dataInputId) {
+        try {
+
+            org.w3c.dom.NodeList ioSpecs = task.getElementsByTagNameNS("*", 
"ioSpecification");
+            if (ioSpecs.getLength() == 0) {
+                ioSpecs = task.getElementsByTagName("ioSpecification");
+            }
+
+            if (ioSpecs.getLength() > 0) {
+                org.w3c.dom.Element ioSpec = (org.w3c.dom.Element) 
ioSpecs.item(0);
+
+                org.w3c.dom.NodeList dataInputs = 
ioSpec.getElementsByTagNameNS("*", "dataInput");
+                if (dataInputs.getLength() == 0) {
+                    dataInputs = ioSpec.getElementsByTagName("dataInput");
+                }
+
+                for (int i = 0; i < dataInputs.getLength(); i++) {
+                    org.w3c.dom.Element dataInput = (org.w3c.dom.Element) 
dataInputs.item(i);
+                    String id = dataInput.getAttribute("id");
+                    String name = dataInput.getAttribute("name");
+
+                    if (dataInputId.equals(id) && name != null && 
!name.isEmpty()) {
+                        return name;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.warn("Failed to map dataInput id to parameter name", e);
+        }
+        return null;
+    }
+
+    private static boolean isExpression(String value) {
+        return value != null && 
EXPRESSION_PATTERN.matcher(value.trim()).matches();
+    }
+
+    private static boolean isValidUrlFormat(String url) {
+        if (url == null || url.trim().isEmpty()) {
+            return false;
+        }
+
+        if (URL_PLACEHOLDER_PATTERN.matcher(url).find()) {
+            return true;
+        }
+
+        return url.startsWith("http://";) || url.startsWith("https://";) || 
url.startsWith("/");
+    }
+
+    private static String formatNodeError(String resourceUri, Process process, 
WorkItemNode node, String errorMessage) {
+        String uri = resourceUri != null ? resourceUri : "(unknown)";
+        String processId = process != null ? process.getId() : "(unknown)";
+        String processName = process != null ? process.getName() : "(unknown)";
+        String nodeName = node.getName() != null ? node.getName() : 
"(unnamed)";
+        String nodeId = String.valueOf(node.getId());
+        return String.format(NODE_ERROR_TEMPLATE, uri, processId, processName, 
nodeName, nodeId, errorMessage);
+    }
 }
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImplTest.java
 
b/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImplTest.java
index 454051070..b1d3eb52f 100644
--- 
a/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImplTest.java
+++ 
b/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/JITBPMNServiceImplTest.java
@@ -38,6 +38,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.kie.kogito.jitexecutor.bpmn.TestingUtils.MULTIPLE_BPMN2_FILE;
 import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.MULTIPLE_INVALID_BPMN2_FILE;
+import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.REST_WIH_ALL_VALID_SCENARIOS_BPMN2_FILE;
+import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.REST_WIH_INVALID_BPMN2_FILE;
+import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.REST_WIH_VALID_BPMN2_FILE;
+import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.REST_WIH_VALID_PROPER_BPMN2_FILE;
+import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.REST_WIH_VALID_SIMPLE_BPMN2_FILE;
 import static org.kie.kogito.jitexecutor.bpmn.TestingUtils.SINGLE_BPMN2_FILE;
 import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.SINGLE_INVALID_BPMN2_FILE;
 import static 
org.kie.kogito.jitexecutor.bpmn.TestingUtils.SINGLE_UNPARSABLE_BPMN2_FILE;
@@ -160,4 +165,64 @@ class JITBPMNServiceImplTest {
         assertThat(retrieved).isEqualTo(expected);
     }
 
+    @Test
+    void validateModel_RestWIHValid_ParsesSuccessfully() throws IOException {
+        String toValidate = new 
String(IoUtils.readBytesFromInputStream(Objects.requireNonNull(JITBPMNService.class.getResourceAsStream(REST_WIH_VALID_BPMN2_FILE))));
+        JITBPMNValidationResult retrieved = 
jitBpmnService.validateModel(toValidate);
+
+        assertThat(retrieved).isNotNull();
+        assertThat(retrieved.getErrors()).isNotNull();
+
+        assertThat(retrieved.getErrors()).allMatch(error -> 
error.contains("Url is required") || 
error.contains("AccessTokenAcquisitionStrategy is required"));
+    }
+
+    @Test
+    void validateModel_RestWIHValidProper_ParsesSuccessfully() throws 
IOException {
+        String toValidate = new 
String(IoUtils.readBytesFromInputStream(Objects.requireNonNull(JITBPMNService.class.getResourceAsStream(REST_WIH_VALID_PROPER_BPMN2_FILE))));
+        JITBPMNValidationResult retrieved = 
jitBpmnService.validateModel(toValidate);
+
+        assertThat(retrieved).isNotNull();
+        assertThat(retrieved.getErrors()).isNotNull();
+
+        assertThat(retrieved.getErrors()).allMatch(error -> 
error.contains("Url is required") || 
error.contains("AccessTokenAcquisitionStrategy is required"));
+    }
+
+    @Test
+    void validateModel_RestWIHValidSimple_ParsesSuccessfully() throws 
IOException {
+        String toValidate = new 
String(IoUtils.readBytesFromInputStream(Objects.requireNonNull(JITBPMNService.class.getResourceAsStream(REST_WIH_VALID_SIMPLE_BPMN2_FILE))));
+        JITBPMNValidationResult retrieved = 
jitBpmnService.validateModel(toValidate);
+
+        assertThat(retrieved).isNotNull();
+        assertThat(retrieved.getErrors()).isNotNull();
+
+        assertThat(retrieved.getErrors()).allMatch(error -> 
error.contains("Url is required") || 
error.contains("AccessTokenAcquisitionStrategy is required"));
+    }
+
+    @Test
+    void validateModel_RestWIHInvalid_HasValidationErrors() throws IOException 
{
+        String toValidate = new 
String(IoUtils.readBytesFromInputStream(Objects.requireNonNull(JITBPMNService.class.getResourceAsStream(REST_WIH_INVALID_BPMN2_FILE))));
+        JITBPMNValidationResult retrieved = 
jitBpmnService.validateModel(toValidate);
+
+        assertThat(retrieved).isNotNull();
+        assertThat(retrieved.getErrors()).isNotNull().isNotEmpty();
+
+        assertThat(retrieved.getErrors()).anyMatch(error -> 
error.contains("Missing Strategy") && 
error.contains("AccessTokenAcquisitionStrategy is required"));
+        assertThat(retrieved.getErrors()).anyMatch(error -> 
error.contains("Invalid Strategy") && 
error.contains("AccessTokenAcquisitionStrategy must be one of"));
+        assertThat(retrieved.getErrors()).anyMatch(error -> 
error.contains("Missing TaskId") && error.contains("RestServiceCallTaskId is 
required"));
+        assertThat(retrieved.getErrors()).anyMatch(error -> 
error.contains("Invalid TaskId Format") && 
error.contains("RestServiceCallTaskId must contain only alphanumeric"));
+        assertThat(retrieved.getErrors()).anyMatch(error -> 
error.contains("Missing URL") && error.contains("Url is required"));
+    }
+
+    @Test
+    void validateModel_AllValidScenarios_ParsesSuccessfully() throws 
IOException {
+        String toValidate = new 
String(IoUtils.readBytesFromInputStream(Objects.requireNonNull(JITBPMNService.class.getResourceAsStream(REST_WIH_ALL_VALID_SCENARIOS_BPMN2_FILE))));
+        JITBPMNValidationResult retrieved = 
jitBpmnService.validateModel(toValidate);
+
+        assertThat(retrieved).isNotNull();
+        assertThat(retrieved.getErrors()).isNotNull();
+
+        // The BPMN file should parse successfully
+        // Similar to above, validation errors for required fields will be 
present
+    }
+
 }
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/TestingUtils.java
 
b/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/TestingUtils.java
index 6364c090f..440ddeedb 100644
--- 
a/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/TestingUtils.java
+++ 
b/jitexecutor/jitexecutor-bpmn/src/test/java/org/kie/kogito/jitexecutor/bpmn/TestingUtils.java
@@ -36,6 +36,16 @@ public class TestingUtils {
 
     public static final String UNPARSABLE_BPMN2_FILE = 
"/UnparsableModel.bpmn2";
 
+    public static final String REST_WIH_VALID_BPMN2_FILE = 
"/RestWIH_Valid.bpmn2";
+
+    public static final String REST_WIH_VALID_PROPER_BPMN2_FILE = 
"/RestWIH_Valid_Proper.bpmn2";
+
+    public static final String REST_WIH_VALID_SIMPLE_BPMN2_FILE = 
"/RestWIH_Valid_Simple.bpmn2";
+
+    public static final String REST_WIH_INVALID_BPMN2_FILE = 
"/RestWIH_Invalid.bpmn2";
+
+    public static final String REST_WIH_ALL_VALID_SCENARIOS_BPMN2_FILE = 
"/RestWIH_AllValid_Scenarios.bpmn2";
+
     public static String getFilePath(String fileName) {
         return "src/test/resources" + fileName;
     }
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_AllValid_Scenarios.bpmn2
 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_AllValid_Scenarios.bpmn2
new file mode 100644
index 000000000..43905adb0
--- /dev/null
+++ 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_AllValid_Scenarios.bpmn2
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
+                   xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"; 
+                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"; 
+                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"; 
+                   xmlns:di="http://www.omg.org/spec/DD/20100524/DI"; 
+                   xmlns:drools="http://www.jboss.org/drools"; 
+                   id="_RestWIHAllValidScenarios" 
+                   targetNamespace="http://www.omg.org/bpmn20";>
+  <bpmn2:itemDefinition id="_StringItem" structureRef="String"/>
+  <bpmn2:process id="RestWIHAllValidScenarios" 
drools:packageName="com.example" drools:version="1.0" drools:adHoc="false" 
name="rest-wih-all-valid-scenarios" isExecutable="true" processType="Public">
+    <bpmn2:startEvent id="_1" name="Start">
+      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    
+    <!-- Valid: POST with ContentData -->
+    <bpmn2:task id="_2" name="Valid POST with Body" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Valid POST with Body]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_1-_2</bpmn2:incoming>
+      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_2_MethodInput" itemSubjectRef="_StringItem" 
name="Method"/>
+        <bpmn2:dataInput id="_2_ContentDataInput" itemSubjectRef="_StringItem" 
name="ContentData"/>
+        <bpmn2:dataInput id="_2_UrlInput" itemSubjectRef="_StringItem" 
name="Url"/>
+        <bpmn2:dataInput id="_2_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_StringItem" name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_2_HEADER_Content_TypeInput" 
itemSubjectRef="_StringItem" name="HEADER_Content-Type"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_2_MethodInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_2_ContentDataInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_2_UrlInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_2_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_2_HEADER_Content_TypeInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_MethodInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[POST]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_MethodInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_ContentDataInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from xsi:type="bpmn2:tFormalExpression"><![CDATA[{"name": 
"John", "age": 30}]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_ContentDataInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/users]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_2_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[propagated]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_HEADER_Content_TypeInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[application/json]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_HEADER_Content_TypeInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    
+    <!-- Valid: Method with expression -->
+    <bpmn2:task id="_3" name="Valid Method Expression" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Valid Method 
Expression]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_2-_3</bpmn2:incoming>
+      <bpmn2:outgoing>_3-_4</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_3_MethodInput" itemSubjectRef="_StringItem" 
name="Method"/>
+        <bpmn2:dataInput id="_3_UrlInput" itemSubjectRef="_StringItem" 
name="Url"/>
+        <bpmn2:dataInput id="_3_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_StringItem" name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_3_MethodInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_3_UrlInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_3_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_MethodInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[#{httpMethod}]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_MethodInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/data]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_3_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[none]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    
+    <!-- Valid: URL with placeholders -->
+    <bpmn2:task id="_4" name="Valid URL Placeholders" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Valid URL 
Placeholders]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_3-_4</bpmn2:incoming>
+      <bpmn2:outgoing>_4-_5</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_4_UrlInput" itemSubjectRef="_StringItem" 
name="Url"/>
+        <bpmn2:dataInput id="_4_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_StringItem" name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_4_UrlInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_4_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_4_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/users/{userId}/profile]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_4_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_4_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[none]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_4_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    
+    <!-- Valid: Query and Header parameters -->
+    <bpmn2:task id="_5" name="Valid Query and Headers" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Valid Query and 
Headers]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_4-_5</bpmn2:incoming>
+      <bpmn2:outgoing>_5-_6</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_5_UrlInput" itemSubjectRef="_StringItem" 
name="Url"/>
+        <bpmn2:dataInput id="_5_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_StringItem" name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_5_QUERY_pageInput" itemSubjectRef="_StringItem" 
name="QUERY_page"/>
+        <bpmn2:dataInput id="_5_QUERY_limitInput" itemSubjectRef="_StringItem" 
name="QUERY_limit"/>
+        <bpmn2:dataInput id="_5_HEADER_AcceptInput" 
itemSubjectRef="_StringItem" name="HEADER_Accept"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_5_UrlInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_5_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_5_QUERY_pageInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_5_QUERY_limitInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_5_HEADER_AcceptInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/users]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_5_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_5_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[none]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_5_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_QUERY_pageInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[1]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_5_QUERY_pageInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_QUERY_limitInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[10]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_5_QUERY_limitInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_HEADER_AcceptInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[application/json]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_5_HEADER_AcceptInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    
+    <!-- Valid: Valid RequestTimeout -->
+    <bpmn2:task id="_6" name="Valid Timeout" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Valid Timeout]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_5-_6</bpmn2:incoming>
+      <bpmn2:outgoing>_6-_7</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_6_RequestTimeoutInput" 
itemSubjectRef="_StringItem" name="RequestTimeout"/>
+        <bpmn2:dataInput id="_6_UrlInput" itemSubjectRef="_StringItem" 
name="Url"/>
+        <bpmn2:dataInput id="_6_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_StringItem" name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_6_RequestTimeoutInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_6_UrlInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_6_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_6_RequestTimeoutInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[30000]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_6_RequestTimeoutInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_6_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/data]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_6_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_6_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[none]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_6_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    
+    <bpmn2:endEvent id="_7" name="End">
+      <bpmn2:incoming>_6-_7</bpmn2:incoming>
+    </bpmn2:endEvent>
+    
+    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
+    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
+    <bpmn2:sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4"/>
+    <bpmn2:sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5"/>
+    <bpmn2:sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6"/>
+    <bpmn2:sequenceFlow id="_6-_7" sourceRef="_6" targetRef="_7"/>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="RestWIHAllValidScenarios">
+      <bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
+        <dc:Bounds height="56" width="56" x="100" y="100"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
+        <dc:Bounds height="102" width="154" x="236" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
+        <dc:Bounds height="102" width="154" x="470" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__4" bpmnElement="_4">
+        <dc:Bounds height="102" width="154" x="704" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__5" bpmnElement="_5">
+        <dc:Bounds height="102" width="154" x="938" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__6" bpmnElement="_6">
+        <dc:Bounds height="102" width="154" x="1172" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__7" bpmnElement="_7">
+        <dc:Bounds height="56" width="56" x="1406" y="100"/>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Invalid.bpmn2 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Invalid.bpmn2
new file mode 100644
index 000000000..6c0c263c2
--- /dev/null
+++ b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Invalid.bpmn2
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
+                   xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"; 
+                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"; 
+                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"; 
+                   xmlns:di="http://www.omg.org/spec/DD/20100524/DI"; 
+                   xmlns:drools="http://www.jboss.org/drools"; 
+                   id="_RestWIHInvalidTest" 
+                   targetNamespace="http://www.omg.org/bpmn20";>
+  <bpmn2:process id="RestWIHInvalid" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="rest-wih-invalid-process" 
isExecutable="true" processType="Public">
+    <bpmn2:startEvent id="_1" name="Start">
+      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:task id="_2" name="Missing Strategy" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Missing Strategy]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_1-_2</bpmn2:incoming>
+      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_2_UrlInput" name="Url"/>
+        <bpmn2:inputSet>
+          <bpmn2:dataInputRefs>_2_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/data</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_2_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_3" name="Invalid Strategy" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Invalid Strategy]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_2-_3</bpmn2:incoming>
+      <bpmn2:outgoing>_3-_4</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_3_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_3_UrlInput" name="Url"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_3_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_3_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_3_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">invalid_strategy</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_3_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/data</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_3_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_4" name="Missing TaskId" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Missing TaskId]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_3-_4</bpmn2:incoming>
+      <bpmn2:outgoing>_4-_5</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_4_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_4_UrlInput" name="Url"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_4_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_4_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_4_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">configured</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_4_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_4_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/secure</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_4_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_5" name="Invalid TaskId Format" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Invalid TaskId 
Format]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_4-_5</bpmn2:incoming>
+      <bpmn2:outgoing>_5-_6</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_5_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_5_RestServiceCallTaskIdInput" 
name="RestServiceCallTaskId"/>
+        <bpmn2:dataInput id="_5_UrlInput" name="Url"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_5_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_5_RestServiceCallTaskIdInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_5_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_5_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">configured</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_5_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_RestServiceCallTaskIdInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">Invalid-Task-ID!</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_5_RestServiceCallTaskIdInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_5_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/secure</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_5_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_6" name="Missing URL" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Missing URL]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_5-_6</bpmn2:incoming>
+      <bpmn2:outgoing>_6-_7</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_6_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_6_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_6_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from xsi:type="bpmn2:tFormalExpression">none</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_6_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:endEvent id="_7" name="End">
+      <bpmn2:incoming>_6-_7</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
+    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
+    <bpmn2:sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4"/>
+    <bpmn2:sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5"/>
+    <bpmn2:sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6"/>
+    <bpmn2:sequenceFlow id="_6-_7" sourceRef="_6" targetRef="_7"/>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="RestWIHInvalid">
+      <bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
+        <dc:Bounds height="56" width="56" x="100" y="100"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
+        <dc:Bounds height="102" width="154" x="236" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
+        <dc:Bounds height="102" width="154" x="470" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__4" bpmnElement="_4">
+        <dc:Bounds height="102" width="154" x="704" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__5" bpmnElement="_5">
+        <dc:Bounds height="102" width="154" x="938" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__6" bpmnElement="_6">
+        <dc:Bounds height="102" width="154" x="1172" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__7" bpmnElement="_7">
+        <dc:Bounds height="56" width="56" x="1406" y="100"/>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid.bpmn2 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid.bpmn2
new file mode 100644
index 000000000..f714fe23f
--- /dev/null
+++ b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid.bpmn2
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"; 
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"; 
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"; 
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"; 
xmlns:drools="http://www.jboss.org/drools"; id="_RestWIHValidTest" 
targetNamespace="http://www.omg.org/bpmn20";>
+  <bpmn2:process id="RestWIHValid" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="rest-wih-valid-process" 
isExecutable="true" processType="Public">
+    <bpmn2:endEvent id="_4" name="End">
+      <bpmn2:incoming>_3-_4</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
+    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
+    <bpmn2:sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4" />
+    <bpmn2:startEvent id="_1" name="Start">
+      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:task id="_2" name="REST Call with Propagated" 
drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue>REST Call with Propagated</drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_1-_2</bpmn2:incoming>
+      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_2_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy" />
+        <bpmn2:dataInput id="_2_UrlInput" name="Url" />
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_2_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_2_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_2_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">propagated</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_2_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/data</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_2_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_3" name="REST Call with Configured" 
drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue>REST Call with Configured</drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_2-_3</bpmn2:incoming>
+      <bpmn2:outgoing>_3-_4</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_3_AccessTokenAcquisitionStrategyInput" 
name="AccessTokenAcquisitionStrategy" />
+        <bpmn2:dataInput id="_3_RestServiceCallTaskIdInput" 
name="RestServiceCallTaskId" />
+        <bpmn2:dataInput id="_3_UrlInput" name="Url" />
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_3_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_3_RestServiceCallTaskIdInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_3_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_3_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">configured</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_3_AccessTokenAcquisitionStrategyInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_RestServiceCallTaskIdInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">Valid_Task_ID_123</bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression">_3_RestServiceCallTaskIdInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression">https://api.example.com/secure</bpmn2:from>
+          <bpmn2:to xsi:type="bpmn2:tFormalExpression">_3_UrlInput</bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="_4167B2C8-5737-464B-9678-2B1449184FF8">
+    <bpmndi:BPMNPlane bpmnElement="RestWIHValid" 
id="_5CFD32BB-E1FD-4F50-B91C-F891F001E44C">
+      <bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
+        <dc:Bounds height="56" width="56" x="100" y="100" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
+        <dc:Bounds height="102" width="154" x="236" y="77" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
+        <dc:Bounds height="102" width="154" x="470" y="77" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__4" bpmnElement="_4">
+        <dc:Bounds height="56" width="56" x="704" y="100" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Proper.bpmn2 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Proper.bpmn2
new file mode 100644
index 000000000..9dd7d53d6
--- /dev/null
+++ b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Proper.bpmn2
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
+                   xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"; 
+                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"; 
+                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"; 
+                   xmlns:di="http://www.omg.org/spec/DD/20100524/DI"; 
+                   xmlns:drools="http://www.jboss.org/drools"; 
+                   xmlns:tns="http://www.jboss.org/drools";
+                   id="_RestWIHValidProperTest" 
+                   targetNamespace="http://www.omg.org/bpmn20";>
+  <bpmn2:itemDefinition id="_AccessTokenAcquisitionStrategyItem" 
structureRef="String"/>
+  <bpmn2:itemDefinition id="_RestServiceCallTaskIdItem" structureRef="String"/>
+  <bpmn2:itemDefinition id="_UrlItem" structureRef="String"/>
+  <bpmn2:process id="RestWIHValidProper" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="rest-wih-valid-proper" 
isExecutable="true" processType="Public">
+    <bpmn2:startEvent id="_1" name="Start">
+      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:task id="_2" name="REST Call Propagated" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[REST Call Propagated]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_1-_2</bpmn2:incoming>
+      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_2_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_AccessTokenAcquisitionStrategyItem" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_2_UrlInput" itemSubjectRef="_UrlItem" 
name="Url"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_2_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_2_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_2_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[propagated]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_2_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/data]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_2_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:task id="_3" name="REST Call Configured" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[REST Call Configured]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_2-_3</bpmn2:incoming>
+      <bpmn2:outgoing>_3-_4</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput id="_3_AccessTokenAcquisitionStrategyInput" 
itemSubjectRef="_AccessTokenAcquisitionStrategyItem" 
name="AccessTokenAcquisitionStrategy"/>
+        <bpmn2:dataInput id="_3_RestServiceCallTaskIdInput" 
itemSubjectRef="_RestServiceCallTaskIdItem" name="RestServiceCallTaskId"/>
+        <bpmn2:dataInput id="_3_UrlInput" itemSubjectRef="_UrlItem" 
name="Url"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_3_AccessTokenAcquisitionStrategyInput</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_3_RestServiceCallTaskIdInput</bpmn2:dataInputRefs>
+          <bpmn2:dataInputRefs>_3_UrlInput</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_3_AccessTokenAcquisitionStrategyInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[configured]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_AccessTokenAcquisitionStrategyInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_RestServiceCallTaskIdInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[Valid_Task_ID_123]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_RestServiceCallTaskIdInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        <bpmn2:targetRef>_3_UrlInput</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[https://api.example.com/secure]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_3_UrlInput]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+    </bpmn2:task>
+    <bpmn2:endEvent id="_4" name="End">
+      <bpmn2:incoming>_3-_4</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
+    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
+    <bpmn2:sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4"/>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="RestWIHValidProper">
+      <bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
+        <dc:Bounds height="56" width="56" x="100" y="100"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
+        <dc:Bounds height="102" width="154" x="236" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
+        <dc:Bounds height="102" width="154" x="470" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__4" bpmnElement="_4">
+        <dc:Bounds height="56" width="56" x="704" y="100"/>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git 
a/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Simple.bpmn2 
b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Simple.bpmn2
new file mode 100644
index 000000000..9066e0a45
--- /dev/null
+++ b/jitexecutor/jitexecutor-bpmn/src/test/resources/RestWIH_Valid_Simple.bpmn2
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
+                   xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"; 
+                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"; 
+                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"; 
+                   xmlns:di="http://www.omg.org/spec/DD/20100524/DI"; 
+                   xmlns:drools="http://www.jboss.org/drools"; 
+                   xmlns:tns="http://www.jboss.org/drools";
+                   id="_RestWIHValidSimpleTest" 
+                   targetNamespace="http://www.omg.org/bpmn20";>
+  <bpmn2:process id="RestWIHValidSimple" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="rest-wih-valid-simple" 
isExecutable="true" processType="Public">
+    <bpmn2:startEvent id="_1" name="Start">
+      <bpmn2:outgoing>_1-_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:task id="_2" name="REST Call" drools:taskName="Rest">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[REST Call]]></drools:metaValue>
+        </drools:metaData>
+        <drools:onEntry-script scriptFormat="http://www.java.com/java";>
+          
<drools:script><![CDATA[kcontext.setVariable("AccessTokenAcquisitionStrategy", 
"propagated");
+kcontext.setVariable("Url", "https://api.example.com/data";);]]></drools:script>
+        </drools:onEntry-script>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_1-_2</bpmn2:incoming>
+      <bpmn2:outgoing>_2-_3</bpmn2:outgoing>
+    </bpmn2:task>
+    <bpmn2:endEvent id="_3" name="End">
+      <bpmn2:incoming>_2-_3</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
+    <bpmn2:sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3"/>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="RestWIHValidSimple">
+      <bpmndi:BPMNShape id="shape__1" bpmnElement="_1">
+        <dc:Bounds height="56" width="56" x="100" y="100"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__2" bpmnElement="_2">
+        <dc:Bounds height="102" width="154" x="236" y="77"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__3" bpmnElement="_3">
+        <dc:Bounds height="56" width="56" x="470" y="100"/>
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to