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

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


The following commit(s) were added to refs/heads/main by this push:
     new 8e4ab33650 Fix#8545   Http/HttpPost/Rest check reports error for 
successful URL/method field validation (#8558)
8e4ab33650 is described below

commit 8e4ab33650f848878de3dc693fe03e1e0731d1c9
Author: Lance <[email protected]>
AuthorDate: Thu Sep 24 21:32:09 2026 +0800

    Fix#8545   Http/HttpPost/Rest check reports error for successful URL/method 
field validation (#8558)
    
    * Fix HTTP/HTTPPost/REST check() reports ERROR for successful URL/method 
field validation
    
    Signed-off-by: leehaut <[email protected]>
    
    * some code hardening
    
    ---------
    
    Signed-off-by: leehaut <[email protected]>
    Co-authored-by: mattcasters <[email protected]>
    Co-authored-by: Hans Van Akelyen <[email protected]>
---
 .../hop/pipeline/transforms/http/HttpMeta.java     |  2 +-
 .../hop/pipeline/transforms/http/HttpMetaTest.java | 39 ++++++++++
 .../hop/pipeline/transforms/httppost/HttpPost.java | 48 ++++++------
 .../transforms/httppost/HttpPostDialog.java        | 54 +++++++-------
 .../pipeline/transforms/httppost/HttpPostMeta.java | 47 ++++++++++--
 .../transforms/httppost/HttpPostExecutionTest.java | 41 +++++++++++
 .../transforms/httppost/HttpPostMetaTest.java      | 85 ++++++++++++++++++++++
 .../hop/pipeline/transforms/rest/RestMeta.java     |  2 +-
 .../hop/pipeline/transforms/rest/RestMetaTest.java | 11 ++-
 9 files changed, 264 insertions(+), 65 deletions(-)

diff --git 
a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
 
b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
index 5fcb64ea7f..502a5710eb 100644
--- 
a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
+++ 
b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpMeta.java
@@ -271,7 +271,7 @@ public class HttpMeta extends BaseTransformMeta<Http, 
HttpData> {
       } else {
         cr =
             new CheckResult(
-                ICheckResult.TYPE_RESULT_ERROR,
+                ICheckResult.TYPE_RESULT_OK,
                 BaseMessages.getString(PKG, "HTTPMeta.CheckResult.UrlfieldOk"),
                 transformMeta);
       }
diff --git 
a/plugins/transforms/http/src/test/java/org/apache/hop/pipeline/transforms/http/HttpMetaTest.java
 
b/plugins/transforms/http/src/test/java/org/apache/hop/pipeline/transforms/http/HttpMetaTest.java
index 31228a90b2..518454864a 100644
--- 
a/plugins/transforms/http/src/test/java/org/apache/hop/pipeline/transforms/http/HttpMetaTest.java
+++ 
b/plugins/transforms/http/src/test/java/org/apache/hop/pipeline/transforms/http/HttpMetaTest.java
@@ -24,13 +24,21 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.HopClientEnvironment;
+import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.exception.HopXmlException;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.variables.Variables;
 import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
 import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil;
+import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.TransformMeta;
 import org.jetbrains.annotations.NotNull;
 import org.junit.jupiter.api.BeforeAll;
@@ -108,4 +116,35 @@ class HttpMetaTest {
     assertEquals("headerField3", h2.getField());
     assertEquals("headerParameter3", h2.getParameter());
   }
+
+  @Test
+  void testCheckWithUrlInField() {
+    HttpMeta meta = new HttpMeta();
+    meta.setUrlInField(true);
+    meta.setUrlField("url");
+
+    List<ICheckResult> remarks = new ArrayList<>();
+    IRowMeta prev = new RowMeta();
+    String[] input = new String[] {"Generate rows"};
+
+    meta.check(
+        remarks,
+        new PipelineMeta(),
+        new TransformMeta(),
+        prev,
+        input,
+        new String[0],
+        new RowMeta(),
+        new Variables(),
+        null);
+
+    long errorCount =
+        remarks.stream().filter(r -> r.getType() == 
ICheckResult.TYPE_RESULT_ERROR).count();
+    assertEquals(0, errorCount);
+    String okMessage = BaseMessages.getString(HttpMeta.class, 
"HTTPMeta.CheckResult.UrlfieldOk");
+    assertTrue(
+        remarks.stream()
+            .anyMatch(
+                r -> r.getType() == ICheckResult.TYPE_RESULT_OK && 
okMessage.equals(r.getText())));
+  }
 }
diff --git 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPost.java
 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPost.java
index 5e1169c7b9..ec7b10e8aa 100644
--- 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPost.java
+++ 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPost.java
@@ -246,20 +246,21 @@ public class HttpPost extends BaseTransform<HttpPostMeta, 
HttpPostData> {
         }
 
         int returnFieldsOffset = data.inputRowMeta.size();
-        if (!Utils.isEmpty(meta.getResultFields().get(0).getName())) {
+        HttpPostResultField resultField = meta.getFirstResultField();
+        if (!Utils.isEmpty(resultField.getName())) {
           newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, body);
           returnFieldsOffset++;
         }
 
-        if (!Utils.isEmpty(meta.getResultFields().get(0).getCode())) {
+        if (!Utils.isEmpty(resultField.getCode())) {
           newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, (long) 
statusCode);
           returnFieldsOffset++;
         }
-        if 
(!Utils.isEmpty(meta.getResultFields().get(0).getResponseTimeFieldName())) {
+        if (!Utils.isEmpty(resultField.getResponseTimeFieldName())) {
           newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, 
responseTime);
           returnFieldsOffset++;
         }
-        if 
(!Utils.isEmpty(meta.getResultFields().get(0).getResponseHeaderFieldName())) {
+        if (!Utils.isEmpty(resultField.getResponseHeaderFieldName())) {
           newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, 
headerString);
         }
       } finally {
@@ -384,8 +385,11 @@ public class HttpPost extends BaseTransform<HttpPostMeta, 
HttpPostData> {
           }
         }
       }
+      HttpPostLookupField lookupField = meta.getFirstLookupField();
+      List<HttpPostArgumentField> argumentFields = 
lookupField.getArgumentField();
+      List<HttpPostQuery> queryFields = lookupField.getQueryField();
       // set body parameters
-      int nrargs = meta.getLookupFields().get(0).getArgumentField().size();
+      int nrargs = argumentFields.size();
       if (nrargs > 0) {
         data.useBodyParameters = false;
         data.useHeaderParameters = false;
@@ -393,7 +397,7 @@ public class HttpPost extends BaseTransform<HttpPostMeta, 
HttpPostData> {
         int nrheader = 0;
         int nrbody = 0;
         for (int i = 0; i < nrargs; i++) { // split into body / header
-          if 
(meta.getLookupFields().get(0).getArgumentField().get(i).isHeader()) {
+          if (argumentFields.get(i).isHeader()) {
             data.useHeaderParameters = true; // at least one header parameter
             nrheader++;
           } else {
@@ -408,65 +412,57 @@ public class HttpPost extends BaseTransform<HttpPostMeta, 
HttpPostData> {
         int posHeader = 0;
         int posBody = 0;
         for (int i = 0; i < nrargs; i++) {
-          int fieldIndex =
-              data.inputRowMeta.indexOfValue(
-                  
meta.getLookupFields().get(0).getArgumentField().get(i).getName());
+          int fieldIndex = 
data.inputRowMeta.indexOfValue(argumentFields.get(i).getName());
           if (fieldIndex < 0) {
             logError(
                 BaseMessages.getString(PKG, PKG_ERROR_FINDING_FIELD)
-                    + 
meta.getLookupFields().get(0).getArgumentField().get(i).getName()
+                    + argumentFields.get(i).getName()
                     + "]");
             throw new HopTransformException(
                 BaseMessages.getString(
-                    PKG,
-                    "HTTPPOST.Exception.CouldnotFindField",
-                    
meta.getLookupFields().get(0).getArgumentField().get(i).getName()));
+                    PKG, "HTTPPOST.Exception.CouldnotFindField", 
argumentFields.get(i).getName()));
           }
-          if 
(meta.getLookupFields().get(0).getArgumentField().get(i).isHeader()) {
+          if (argumentFields.get(i).isHeader()) {
             data.header_parameters_nrs[posHeader] = fieldIndex;
             data.headerParameters[posHeader] =
                 new BasicNameValuePair(
-                    
resolve(meta.getLookupFields().get(0).getArgumentField().get(i).getParameter()),
+                    resolve(argumentFields.get(i).getParameter()),
                     data.outputRowMeta.getString(r, 
data.header_parameters_nrs[posHeader]));
             posHeader++;
-            if (CONTENT_TYPE.equalsIgnoreCase(
-                
meta.getLookupFields().get(0).getArgumentField().get(i).getParameter())) {
+            if 
(CONTENT_TYPE.equalsIgnoreCase(argumentFields.get(i).getParameter())) {
               data.contentTypeHeaderOverwrite = true; // Content-type will be 
overwritten
             }
           } else {
             data.body_parameters_nrs[posBody] = fieldIndex;
             data.bodyParameters[posBody] =
                 new BasicNameValuePair(
-                    
resolve(meta.getLookupFields().get(0).getArgumentField().get(i).getParameter()),
+                    resolve(argumentFields.get(i).getParameter()),
                     data.outputRowMeta.getString(r, 
data.body_parameters_nrs[posBody]));
             posBody++;
           }
         }
       }
       // set query parameters
-      int nrQuery = meta.getLookupFields().get(0).getQueryField().size();
+      int nrQuery = queryFields.size();
       if (nrQuery > 0) {
         data.useQueryParameters = true;
         data.query_parameters_nrs = new int[nrQuery];
         data.queryParameters = new NameValuePair[nrQuery];
         for (int i = 0; i < nrQuery; i++) {
           data.query_parameters_nrs[i] =
-              data.inputRowMeta.indexOfValue(
-                  
meta.getLookupFields().get(0).getQueryField().get(i).getName());
+              data.inputRowMeta.indexOfValue(queryFields.get(i).getName());
           if (data.query_parameters_nrs[i] < 0) {
             logError(
                 BaseMessages.getString(PKG, PKG_ERROR_FINDING_FIELD)
-                    + 
meta.getLookupFields().get(0).getQueryField().get(i).getName()
+                    + queryFields.get(i).getName()
                     + "]");
             throw new HopTransformException(
                 BaseMessages.getString(
-                    PKG,
-                    "HTTPPOST.Exception.CouldnotFindField",
-                    
meta.getLookupFields().get(0).getQueryField().get(i).getName()));
+                    PKG, "HTTPPOST.Exception.CouldnotFindField", 
queryFields.get(i).getName()));
           }
           data.queryParameters[i] =
               new BasicNameValuePair(
-                  
resolve(meta.getLookupFields().get(0).getQueryField().get(i).getParameter()),
+                  resolve(queryFields.get(i).getParameter()),
                   data.outputRowMeta.getString(r, 
data.query_parameters_nrs[i]));
         }
       }
diff --git 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java
 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java
index 50d415a325..d5d0edceeb 100644
--- 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java
+++ 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java
@@ -365,8 +365,8 @@ public class HttpPostDialog extends BaseTransformDialog {
     wlQuery.setLayoutData(fdlQuery);
 
     int queryRows = 0;
-    if (input.getLookupFields().get(0).getQueryField() != null) {
-      queryRows = input.getLookupFields().get(0).getQueryField().size();
+    if (input.getFirstLookupField().getQueryField() != null) {
+      queryRows = input.getFirstLookupField().getQueryField().size();
     }
 
     colinfquery =
@@ -474,8 +474,8 @@ public class HttpPostDialog extends BaseTransformDialog {
     wlFields.setLayoutData(fdlFields);
 
     int fieldsRows = 0;
-    if (input.getLookupFields().get(0).getArgumentField() != null) {
-      fieldsRows = input.getLookupFields().get(0).getArgumentField().size();
+    if (input.getFirstLookupField().getArgumentField() != null) {
+      fieldsRows = input.getFirstLookupField().getArgumentField().size();
     }
 
     colinf =
@@ -1278,27 +1278,27 @@ public class HttpPostDialog extends BaseTransformDialog 
{
       logDebug(BaseMessages.getString(PKG, 
"HTTPPOSTDialog.Log.GettingKeyInfo"));
     }
 
-    if (input.getLookupFields().get(0).getArgumentField() != null) {
-      for (int i = 0; i < 
input.getLookupFields().get(0).getArgumentField().size(); i++) {
+    HttpPostLookupField lookupField = input.getFirstLookupField();
+    if (lookupField.getArgumentField() != null) {
+      for (int i = 0; i < lookupField.getArgumentField().size(); i++) {
         TableItem item = wFields.table.getItem(i);
-        if (input.getLookupFields().get(0).getArgumentField().get(i).getName() 
!= null) {
-          item.setText(1, 
input.getLookupFields().get(0).getArgumentField().get(i).getName());
+        if (lookupField.getArgumentField().get(i).getName() != null) {
+          item.setText(1, lookupField.getArgumentField().get(i).getName());
         }
-        if 
(input.getLookupFields().get(0).getArgumentField().get(i).getParameter() != 
null) {
-          item.setText(2, 
input.getLookupFields().get(0).getArgumentField().get(i).getParameter());
+        if (lookupField.getArgumentField().get(i).getParameter() != null) {
+          item.setText(2, 
lookupField.getArgumentField().get(i).getParameter());
         }
-        item.setText(
-            3, 
(input.getLookupFields().get(0).getArgumentField().get(i).isHeader()) ? YES : 
NO);
+        item.setText(3, lookupField.getArgumentField().get(i).isHeader() ? YES 
: NO);
       }
     }
-    if (input.getLookupFields().get(0).getQueryField() != null) {
-      for (int i = 0; i < 
input.getLookupFields().get(0).getQueryField().size(); i++) {
+    if (lookupField.getQueryField() != null) {
+      for (int i = 0; i < lookupField.getQueryField().size(); i++) {
         TableItem item = wQuery.table.getItem(i);
-        if (input.getLookupFields().get(0).getQueryField().get(i).getName() != 
null) {
-          item.setText(1, 
input.getLookupFields().get(0).getQueryField().get(i).getName());
+        if (lookupField.getQueryField().get(i).getName() != null) {
+          item.setText(1, lookupField.getQueryField().get(i).getName());
         }
-        if 
(input.getLookupFields().get(0).getQueryField().get(i).getParameter() != null) {
-          item.setText(2, 
input.getLookupFields().get(0).getQueryField().get(i).getParameter());
+        if (lookupField.getQueryField().get(i).getParameter() != null) {
+          item.setText(2, lookupField.getQueryField().get(i).getParameter());
         }
       }
     }
@@ -1313,14 +1313,15 @@ public class HttpPostDialog extends BaseTransformDialog 
{
     if (input.getRequestEntity() != null) {
       wRequestEntity.setText(input.getRequestEntity());
     }
-    if (input.getResultFields().get(0).getName() != null) {
-      wResult.setText(input.getResultFields().get(0).getName());
+    HttpPostResultField resultField = input.getFirstResultField();
+    if (resultField.getName() != null) {
+      wResult.setText(resultField.getName());
     }
-    if (input.getResultFields().get(0).getCode() != null) {
-      wResultCode.setText(input.getResultFields().get(0).getCode());
+    if (resultField.getCode() != null) {
+      wResultCode.setText(resultField.getCode());
     }
-    if (input.getResultFields().get(0).getResponseTimeFieldName() != null) {
-      
wResponseTime.setText(input.getResultFields().get(0).getResponseTimeFieldName());
+    if (resultField.getResponseTimeFieldName() != null) {
+      wResponseTime.setText(resultField.getResponseTimeFieldName());
     }
     if (input.getEncoding() != null) {
       wEncoding.setText(input.getEncoding());
@@ -1347,8 +1348,8 @@ public class HttpPostDialog extends BaseTransformDialog {
     wProxyUsername.setText(Const.NVL(input.getProxyUsername(), ""));
     wProxyPassword.setText(Const.NVL(input.getProxyPassword(), ""));
     wNonProxyHosts.setText(Const.NVL(input.getNonProxyHosts(), ""));
-    if (input.getResultFields().get(0).getResponseHeaderFieldName() != null) {
-      
wResponseHeader.setText(input.getResultFields().get(0).getResponseHeaderFieldName());
+    if (resultField.getResponseHeaderFieldName() != null) {
+      wResponseHeader.setText(resultField.getResponseHeaderFieldName());
     }
 
     wSocketTimeOut.setText(Const.NVL(input.getSocketTimeout(), ""));
@@ -1394,7 +1395,6 @@ public class HttpPostDialog extends BaseTransformDialog {
     }
     for (int i = 0; i < nrqueryparams; i++) {
       TableItem item = wQuery.getNonEmpty(i);
-      input.getLookupFields().get(0).getQueryField().clear();
       HttpPostQuery httpPostQuery = new HttpPostQuery(item.getText(1), 
item.getText(2));
       loookupField.getQueryField().add(httpPostQuery);
     }
diff --git 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
index 0d0b100535..9cca1501c7 100644
--- 
a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
+++ 
b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMeta.java
@@ -154,6 +154,36 @@ public class HttpPostMeta extends 
BaseTransformMeta<HttpPost, HttpPostData> {
     super(); // allocate BaseTransformMeta
   }
 
+  /**
+   * Returns the first lookup-field group, or an empty one when the list is 
missing or empty.
+   * Pipelines saved without a {@code <lookup>} element leave {@link 
#lookupFields} empty.
+   *
+   * <p>This is a pure read: the empty group is not added to the list. The 
metadata is shared by all
+   * copies of the transform and read by dialogs that may be cancelled, so 
reading it must never
+   * change it. Writers replace the whole list (see the dialog's ok()).
+   */
+  public HttpPostLookupField getFirstLookupField() {
+    if (lookupFields == null || lookupFields.isEmpty()) {
+      return new HttpPostLookupField();
+    }
+    return lookupFields.getFirst();
+  }
+
+  /**
+   * Returns the first result-field group, or an empty one when the list is 
missing or empty. Like
+   * {@link #getFirstLookupField()}, this never changes the list.
+   *
+   * <p>The empty group names no fields at all. The no-argument constructor is 
not used for it
+   * because it defaults the status-code field to "result", which would add an 
output field nobody
+   * configured.
+   */
+  public HttpPostResultField getFirstResultField() {
+    if (resultFields == null || resultFields.isEmpty()) {
+      return new HttpPostResultField(null, null, null, null);
+    }
+    return resultFields.getFirst();
+  }
+
   @Override
   public void setDefault() {
     encoding = Const.UTF_8;
@@ -176,21 +206,22 @@ public class HttpPostMeta extends 
BaseTransformMeta<HttpPost, HttpPostData> {
       IVariables variables,
       IHopMetadataProvider metadataProvider)
       throws HopTransformException {
-    if (!Utils.isEmpty(resultFields.get(0).getName())) {
-      IValueMeta v = new ValueMetaString(resultFields.get(0).getName());
+    HttpPostResultField resultField = getFirstResultField();
+    if (!Utils.isEmpty(resultField.getName())) {
+      IValueMeta v = new ValueMetaString(resultField.getName());
       inputRowMeta.addValueMeta(v);
     }
 
-    if (!Utils.isEmpty(resultFields.get(0).getCode())) {
-      IValueMeta v = new ValueMetaInteger(resultFields.get(0).getCode());
+    if (!Utils.isEmpty(resultField.getCode())) {
+      IValueMeta v = new ValueMetaInteger(resultField.getCode());
       inputRowMeta.addValueMeta(v);
     }
-    if (!Utils.isEmpty(resultFields.get(0).getResponseTimeFieldName())) {
+    if (!Utils.isEmpty(resultField.getResponseTimeFieldName())) {
       IValueMeta v =
-          new 
ValueMetaInteger(variables.resolve(resultFields.get(0).getResponseTimeFieldName()));
+          new 
ValueMetaInteger(variables.resolve(resultField.getResponseTimeFieldName()));
       inputRowMeta.addValueMeta(v);
     }
-    String headerFieldName = 
variables.resolve(resultFields.get(0).getResponseHeaderFieldName());
+    String headerFieldName = 
variables.resolve(resultField.getResponseHeaderFieldName());
     if (!Utils.isEmpty(headerFieldName)) {
       IValueMeta v = new ValueMetaString(headerFieldName);
       v.setOrigin(name);
@@ -240,7 +271,7 @@ public class HttpPostMeta extends 
BaseTransformMeta<HttpPost, HttpPostData> {
       } else {
         cr =
             new CheckResult(
-                ICheckResult.TYPE_RESULT_ERROR,
+                ICheckResult.TYPE_RESULT_OK,
                 BaseMessages.getString(PKG, 
"HTTPPOSTMeta.CheckResult.UrlfieldOk"),
                 transformMeta);
       }
diff --git 
a/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostExecutionTest.java
 
b/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostExecutionTest.java
index 8bdf9655f3..bc3ef968ad 100644
--- 
a/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostExecutionTest.java
+++ 
b/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostExecutionTest.java
@@ -22,18 +22,25 @@ import static 
org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 import com.sun.net.httpserver.HttpServer;
 import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.net.InetSocketAddress;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.hc.core5.http.NameValuePair;
 import org.apache.hc.core5.http.message.BasicNameValuePair;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.HopClientEnvironment;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.RowMeta;
 import org.apache.hop.core.row.value.ValueMetaString;
 import org.apache.hop.pipeline.PipelineMeta;
@@ -44,6 +51,7 @@ import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
 
 /** Integration-style tests for {@link HttpPost#callHttpPOST} using an 
embedded HTTP server. */
 class HttpPostExecutionTest {
@@ -356,6 +364,39 @@ class HttpPostExecutionTest {
     assertTrue(!lastRequestContentType.get().contains("text/xml"));
   }
 
+  /**
+   * Pipelines saved without a {@code <lookup>} or {@code <result>} element 
load with empty lists.
+   * The first row must still go through (no IndexOutOfBoundsException), add 
no result fields, and
+   * leave the shared metadata untouched.
+   */
+  @Test
+  void processRowWithEmptyLookupAndResultListsPassesTheRowThrough() throws 
Exception {
+    HttpPostMeta meta = new HttpPostMeta();
+    meta.setDefault();
+    meta.setUrl(baseUrl() + "/body");
+    meta.setLookupFields(new ArrayList<>());
+    meta.setResultFields(new ArrayList<>());
+
+    HttpPostData data = new HttpPostData();
+    HttpPost http = spy(newPost(meta, data));
+    RowMeta rowMeta = new RowMeta();
+    rowMeta.addValueMeta(new ValueMetaString("city"));
+    doReturn(new Object[] {"Berlin"}).when(http).getRow();
+    doReturn(rowMeta).when(http).getInputRowMeta();
+    doNothing().when(http).putRow(any(IRowMeta.class), any(Object[].class));
+
+    assertTrue(http.init());
+    assertTrue(http.processRow());
+
+    ArgumentCaptor<IRowMeta> outputMeta = 
ArgumentCaptor.forClass(IRowMeta.class);
+    ArgumentCaptor<Object[]> outputRow = 
ArgumentCaptor.forClass(Object[].class);
+    verify(http).putRow(outputMeta.capture(), outputRow.capture());
+    assertEquals(1, outputMeta.getValue().size());
+    assertEquals("Berlin", outputRow.getValue()[0]);
+    assertTrue(meta.getLookupFields().isEmpty());
+    assertTrue(meta.getResultFields().isEmpty());
+  }
+
   // ---- reflection helpers ----
 
   private static Long getDataVolumeIn(HttpPost http) throws Exception {
diff --git 
a/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMetaTest.java
 
b/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMetaTest.java
index 79a85539a0..c8ddcaea3b 100644
--- 
a/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMetaTest.java
+++ 
b/plugins/transforms/httppost/src/test/java/org/apache/hop/pipeline/transforms/httppost/HttpPostMetaTest.java
@@ -18,14 +18,26 @@
 package org.apache.hop.pipeline.transforms.httppost;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Random;
 import java.util.UUID;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transform.TransformMeta;
 import org.apache.hop.pipeline.transforms.loadsave.LoadSaveTester;
 import 
org.apache.hop.pipeline.transforms.loadsave.validator.IFieldLoadSaveValidator;
 import 
org.apache.hop.pipeline.transforms.loadsave.validator.IFieldLoadSaveValidatorFactory;
@@ -62,6 +74,79 @@ class HttpPostMetaTest {
     assertEquals(Const.UTF_8, meta.getEncoding());
   }
 
+  @Test
+  void testCheckWithUrlInField() {
+    HttpPostMeta meta = new HttpPostMeta();
+    meta.setUrlInField(true);
+    meta.setUrlField("url");
+
+    List<ICheckResult> remarks = new ArrayList<>();
+    IRowMeta prev = new RowMeta();
+    String[] input = new String[] {"Generate rows"};
+
+    meta.check(
+        remarks,
+        new PipelineMeta(),
+        new TransformMeta(),
+        prev,
+        input,
+        new String[0],
+        new RowMeta(),
+        new Variables(),
+        null);
+
+    long errorCount =
+        remarks.stream().filter(r -> r.getType() == 
ICheckResult.TYPE_RESULT_ERROR).count();
+    assertEquals(0, errorCount);
+    String urlFieldOk =
+        BaseMessages.getString(HttpPostMeta.class, 
"HTTPPOSTMeta.CheckResult.UrlfieldOk");
+    assertTrue(
+        remarks.stream()
+            .anyMatch(
+                r -> r.getType() == ICheckResult.TYPE_RESULT_OK && 
urlFieldOk.equals(r.getText())));
+  }
+
+  @Test
+  void testFirstLookupFieldWhenListEmptyDoesNotChangeTheMeta() {
+    HttpPostMeta meta = new HttpPostMeta();
+    assertTrue(meta.getLookupFields().isEmpty());
+
+    HttpPostLookupField lookupField = meta.getFirstLookupField();
+    assertNotNull(lookupField);
+    assertTrue(lookupField.getArgumentField().isEmpty());
+    assertTrue(lookupField.getQueryField().isEmpty());
+    assertTrue(meta.getLookupFields().isEmpty());
+  }
+
+  @Test
+  void testFirstResultFieldWhenListEmptyDoesNotChangeTheMeta() {
+    HttpPostMeta meta = new HttpPostMeta();
+    assertTrue(meta.getResultFields().isEmpty());
+
+    assertNotNull(meta.getFirstResultField());
+    assertTrue(meta.getResultFields().isEmpty());
+  }
+
+  @Test
+  void testFirstFieldsReturnTheStoredGroups() {
+    HttpPostMeta meta = new HttpPostMeta();
+    meta.setDefault();
+
+    assertSame(meta.getLookupFields().get(0), meta.getFirstLookupField());
+    assertSame(meta.getResultFields().get(0), meta.getFirstResultField());
+  }
+
+  @Test
+  void testGetFieldsWithEmptyResultListAddsNothing() throws Exception {
+    HttpPostMeta meta = new HttpPostMeta();
+    IRowMeta rowMeta = new RowMeta();
+
+    meta.getFields(rowMeta, "HTTP Post", null, null, new Variables(), null);
+
+    assertTrue(rowMeta.isEmpty());
+    assertTrue(meta.getResultFields().isEmpty());
+  }
+
   public static final class HttpPostLookupFieldValidator
       implements IFieldLoadSaveValidator<HttpPostLookupField> {
 
diff --git 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
index b67fc2f98b..98adc8fd63 100644
--- 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
+++ 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
@@ -457,7 +457,7 @@ public class RestMeta extends BaseTransformMeta<Rest, 
RestData> {
       } else {
         cr =
             new CheckResult(
-                ICheckResult.TYPE_RESULT_ERROR,
+                ICheckResult.TYPE_RESULT_OK,
                 BaseMessages.getString(PKG, 
"RestMeta.CheckResult.MethodFieldOk"),
                 transformMeta);
       }
diff --git 
a/plugins/transforms/rest/src/test/java/org/apache/hop/pipeline/transforms/rest/RestMetaTest.java
 
b/plugins/transforms/rest/src/test/java/org/apache/hop/pipeline/transforms/rest/RestMetaTest.java
index 148c07274e..a009b9c087 100644
--- 
a/plugins/transforms/rest/src/test/java/org/apache/hop/pipeline/transforms/rest/RestMetaTest.java
+++ 
b/plugins/transforms/rest/src/test/java/org/apache/hop/pipeline/transforms/rest/RestMetaTest.java
@@ -40,6 +40,7 @@ import org.apache.hop.core.row.value.ValueMetaString;
 import org.apache.hop.core.util.EnvUtil;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.variables.Variables;
+import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.pipeline.PipelineMeta;
@@ -523,8 +524,14 @@ class RestMetaTest implements IInitializer<ITransformMeta> 
{
 
     meta.check(remarks, pipelineMeta, transform, prev, input, output, info, 
variables, null);
 
-    // Check that there's a check result for the method field
-    assertFalse(remarks.isEmpty());
+    long errorCount =
+        remarks.stream().filter(r -> r.getType() == 
ICheckResult.TYPE_RESULT_ERROR).count();
+    assertEquals(0, errorCount);
+    String okMessage = BaseMessages.getString(RestMeta.class, 
"RestMeta.CheckResult.MethodFieldOk");
+    assertTrue(
+        remarks.stream()
+            .anyMatch(
+                r -> r.getType() == ICheckResult.TYPE_RESULT_OK && 
okMessage.equals(r.getText())));
   }
 
   @Override

Reply via email to