You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by ha...@apache.org on 2023/04/28 07:16:56 UTC

[hop] branch master updated: fix #2840 NullPointerException in workflow executor

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

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


The following commit(s) were added to refs/heads/master by this push:
     new d947988a9c fix #2840 NullPointerException in workflow executor
     new 4247906047 Merge pull request #2875 from sramazzina/2840
d947988a9c is described below

commit d947988a9cd6eaadb45213e2c573974ddd66e20d
Author: sramazzina <se...@serasoft.it>
AuthorDate: Thu Apr 27 15:42:08 2023 +0200

    fix #2840 NullPointerException in workflow executor
---
 .../workflowexecutor/WorkflowExecutor.java         | 56 +++++++++++++++++-----
 .../messages/messages_en_US.properties             |  2 +-
 .../messages/messages_it_IT.properties             | 16 +++----
 3 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/plugins/transforms/workflowexecutor/src/main/java/org/apache/hop/pipeline/transforms/workflowexecutor/WorkflowExecutor.java b/plugins/transforms/workflowexecutor/src/main/java/org/apache/hop/pipeline/transforms/workflowexecutor/WorkflowExecutor.java
index 41c0fba1a2..d033d3a813 100644
--- a/plugins/transforms/workflowexecutor/src/main/java/org/apache/hop/pipeline/transforms/workflowexecutor/WorkflowExecutor.java
+++ b/plugins/transforms/workflowexecutor/src/main/java/org/apache/hop/pipeline/transforms/workflowexecutor/WorkflowExecutor.java
@@ -18,6 +18,7 @@
 package org.apache.hop.pipeline.transforms.workflowexecutor;
 
 import com.google.common.annotations.VisibleForTesting;
+import java.util.ArrayList;
 import org.apache.commons.lang.StringUtils;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.Result;
@@ -43,8 +44,6 @@ import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
 import org.apache.hop.workflow.engine.WorkflowEngineFactory;
 
-import java.util.ArrayList;
-
 /** Execute a workflow for every input row. */
 public class WorkflowExecutor extends BaseTransform<WorkflowExecutorMeta, WorkflowExecutorData> {
   private static final Class<?> PKG = WorkflowExecutorMeta.class; // For Translator
@@ -283,24 +282,59 @@ public class WorkflowExecutor extends BaseTransform<WorkflowExecutorMeta, Workfl
 
     // Optionally also send the result rows to a specified target transform...
     //
+    boolean rowConsistencyChecked = false;
+    boolean consistencyPassed = true;
+    String missingFields = "";
+    String expectedTypes = "";
+    String currentTypes = "";
+
     if (meta.getResultRowsTargetTransformMeta() != null && result.getRows() != null) {
+
       for (RowMetaAndData row : result.getRows()) {
 
-        Object[] targetRow = RowDataUtil.allocateRowData(data.resultRowsOutputRowMeta.size());
+        // .. but before, perform all the consistency checks just one time just in the first result
+        // row
+        if (!rowConsistencyChecked) {
+          for (int i = 0; i < meta.getResultRowsField().length; i++) {
+            IValueMeta valueMeta = row.getRowMeta().getValueMeta(i);
+            if (valueMeta == null) {
+              missingFields +=
+                  (missingFields.length() > 0 ? missingFields = "," : "")
+                      + meta.getResultRowsField()[i];
+              consistencyPassed = false;
+            }
 
-        for (int i = 0; i < meta.getResultRowsField().length; i++) {
-          IValueMeta valueMeta = row.getRowMeta().getValueMeta(i);
-          if (valueMeta.getType() != meta.getResultRowsType()[i]) {
-            throw new HopException(
+            if (valueMeta != null && valueMeta.getType() != meta.getResultRowsType()[i]) {
+              expectedTypes +=
+                  (expectedTypes.length() > 0 ? expectedTypes = "," : "")
+                      + ValueMetaFactory.getValueMetaName(meta.getResultRowsType()[i]);
+              currentTypes +=
+                  (currentTypes.length() > 0 ? currentTypes = "," : "") + valueMeta.getTypeDesc();
+              consistencyPassed = false;
+            }
+          }
+          rowConsistencyChecked = true;
+        }
+
+        if (!consistencyPassed) {
+          if (missingFields.length() > 0) {
+            logError("Unable to find required fields [" + missingFields + "] in result row!");
+          }
+
+          if (currentTypes.length() > 0) {
+            logError(
                 BaseMessages.getString(
-                    PKG,
-                    "WorkflowExecutor.IncorrectDataTypePassed",
-                    valueMeta.getTypeDesc(),
-                    ValueMetaFactory.getValueMetaName(meta.getResultRowsType()[i])));
+                    PKG, "WorkflowExecutor.IncorrectDataTypePassed", currentTypes, expectedTypes));
           }
+          
+          throw new HopException("We got into troubles while performing a consistency check on incoming result rows!");
+        }
+        Object[] targetRow = RowDataUtil.allocateRowData(data.resultRowsOutputRowMeta.size());
 
+        for (int i = 0; i < meta.getResultRowsField().length; i++) {
           targetRow[i] = row.getData()[i];
         }
+
         putRowTo(data.resultRowsOutputRowMeta, targetRow, data.resultRowsRowSet);
       }
     }
diff --git a/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_en_US.properties b/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_en_US.properties
index 47d9128cf7..a3461cb8d3 100644
--- a/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_en_US.properties
+++ b/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_en_US.properties
@@ -32,7 +32,7 @@ WorkflowExecutorMeta.Exception.UnableToLoadWorkflow=It was not possible to load
 WorkflowExecutorDialog.ColumnInfo.Length=Length
 WorkflowExecutorMeta.ExecutionResults.FieldName.Label=Field name
 WorkflowExecutorDialog.GroupSize.Label=Number of rows to send to workflow\:
-WorkflowExecutor.IncorrectDataTypePassed=The ''{0}'' data type passed from the workflows result rows does not correspond to the specified ''{1}'' data type.  Make sure you are passing rows with the expected layout.
+WorkflowExecutor.IncorrectDataTypePassed=The ''{0}'' data types passed from the workflows result rows does not correspond to the specified ''{1}'' data types.  Make sure you are passing rows with the expected layout.
 WorkflowExecutorMeta.ResultRowsStream.Description=This output will contain the result rows after execution
 WorkflowExecutorDialog.ExecutionLinesDeletedField.Label=Number of rows deleted
 WorkflowExecutorDialog.ResultFiles.Tooltip=This tab allows you to specify where to send result files information to.
diff --git a/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_it_IT.properties b/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_it_IT.properties
index 147416dca2..106ce6093f 100644
--- a/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_it_IT.properties
+++ b/plugins/transforms/workflowexecutor/src/main/resources/org/apache/hop/pipeline/transforms/workflowexecutor/messages/messages_it_IT.properties
@@ -21,14 +21,14 @@ WorkflowExecutorDialog.ColumnInfo.Field=Nome del campo
 WorkflowExecutor.UnexpectedError=Errore inatteso\:
 WorkflowExecutorMeta.Exception.ErrorLoadingJobExecutorDetailsFromXML=Errore di caricamento dei dettagli dell''esecutore workflow da XML
 WorkflowExecutorDialog.RunConfiguration.Label=Run configuration
-WorkflowExecutorDialog.ResultFields.Label=Il layout atteso delle righe di risultato\:
+WorkflowExecutorDialog.ResultFields.Label=Layout atteso delle righe di risultato\:
 WorkflowExecutorDialog.ExecutionFilesRetrievedField.Label=Nome campo con il numero dei file recuperati
 WorkflowExecutorDialog.Parameters.Title=Parametri
 WorkflowExecutorDialog.Parameters.column.Input=Valore statico di input
 WorkflowExecutorDialog.ExecutionTimeField.Label=Nome campo con il tempo di esecuzione (ms)
 WorkflowExecutorDialog.ColumnInfo.Length=Lunghezza
-WorkflowExecutorDialog.GroupSize.Label=Il numero di righe da inviare al workflow
-WorkflowExecutor.IncorrectDataTypePassed=Il tipo di dati ''{0}'' passato dalle righe di risultato del workflow non corrisponde al tipo di dati ''{1}''. Assicurarsi di passare le righe con il layout atteso.
+WorkflowExecutorDialog.GroupSize.Label=Numero di righe da inviare al workflow
+WorkflowExecutor.IncorrectDataTypePassed=I tipi di dati ''{0}'' passati dalle righe di risultato del workflow non corrispondono ai tipi dati attesi ''{1}''. Assicurarsi di passare righe con il layout atteso.
 WorkflowExecutorMeta.ResultRowsStream.Description=Quest''opzione conterr\u00E0 le righe di risultato dopo l''esecuzione
 WorkflowExecutorDialog.ExecutionLinesDeletedField.Label=Nome campo con il numero delle righe cancellate
 WorkflowExecutorDialog.ResultFiles.Tooltip=Questa tab consente di specificare dove spedire le informazioni del file di risultato.
@@ -38,7 +38,7 @@ WorkflowExecutorMeta.CheckResult.TransformReceivingFieldsFromOtherTransforms=Que
 WorkflowExecutorDialog.ExecutionLogChannelIdField.Label=Nome campo con l''ID del canale di log
 WorkflowExecutorDialog.ExecutionResults.Title=Risultati di esecuzione
 WorkflowExecutorMeta.ReferencedObject.Description=Workflow
-WorkflowExecutorDialog.ExecutionResultTarget.Label=Il transform di destinazione per i risultati d''esecuzione
+WorkflowExecutorDialog.ExecutionResultTarget.Label=Transform di destinazione per i risultati d''esecuzione
 WorkflowExecutorMeta.Exception.UnableToLoadWorkflow=Non \u00E8 stato possibile caricare il workflow specificato
 WorkflowExecutor.Exception.GroupFieldNotFound=Il campo di gruppo ''{0}'' non \u00E8 stato trovato nell''input stream
 WorkflowExecutorDialog.Parameters.Tooltip=E'' possibile specificare i parametri da passare al workflow basati su valori fissi o sulla prima riga nei gruppi di righe passate al workflow.
@@ -52,25 +52,25 @@ WorkflowExecutorMeta.CheckResult.TransformReceivingFields=Questo transform sta r
 WorkflowExecutorDialog.Parameters.column.Field=Campo da utilizzare
 WorkflowExecutorDialog.RowGroup.Tooltip=Determina quante righe di dati vengono passate al workflow prima dell''esecuzione
 WorkflowExecutorDialog.ExecutionLinesReadField.Label=Nome campo con il numero delle righe lette
-WorkflowExecutorDialog.ResultFileNameField.Label=Il campo con il nome del file del risultato
+WorkflowExecutorDialog.ResultFileNameField.Label=Campo con nome del file del risultato
 WorkflowExecutorMeta.ResultFilesStream.Description=Quest''output conterr\u00E0 i nomi file del risultato dopo l''esecuzione.
 WorkflowExecutorDialog.Parameters.column.Variable=Nome variabile / parametro
 WorkflowExecutorDialog.ErrorLoadingSpecifiedJob.Title=Errore
 WorkflowExecutorDialog.GroupField.Label=Campo su cui raggruppare le righe
 WorkflowExecutorDialog.ExecutionExitStatusField.Label=Nome campo con lo stato d''uscita
 WorkflowExecutorDialog.ColumnInfo.Type=Tipo di dati
-WorkflowExecutorDialog.GroupTime.Label=Il tempo di attesa durante il recupero delle righe prima dell''esecuzione (ms)
+WorkflowExecutorDialog.GroupTime.Label=Tempo di attesa per il recupero delle righe prima dell''esecuzione (ms)
 WorkflowExecutorDialog.ExecutionLinesWrittenField.Label=Nome campo con il numero delle righe scritte
 WorkflowExecutorDialog.Shell.Title=Esecutore workflow
 WorkflowExecutorDialog.ResultRows.Title=Righe di risultato
 WorkflowExecutorMeta.ResultStream.Description=Quest''opzione conterr\u00E0 il risultato dell''esecuzione
 WorkflowExecutorDialog.RowGroup.Title=Raggruppamento righe
-WorkflowExecutorDialog.ResultRowsTarget.Label=Il transform di destinazione per le righe di risultato
+WorkflowExecutorDialog.ResultRowsTarget.Label=Transform di destinazione per le righe di risultato
 WorkflowExecutorDialog.ErrorLoadingSpecifiedJob.Message=Errore durante il caricamento del workflow specificato\:
 WorkflowExecutorDialog.Parameters.InheritAll=Ereditare tutte le variabili dalla pipeline?
 WorkflowExecutorDialog.ExecutionLinesInputField.Label=Nome campo con il numero delle righe di input
 WorkflowExecutorMeta.CheckResult.NotReceivingAnyFields=Nessun campo di input ricevuto dai transforms precedenti
-WorkflowExecutorDialog.ResultFilesTarget.Label=Il transform a cui spedire le informazioni del file di risultato
+WorkflowExecutorDialog.ResultFilesTarget.Label=Transform a cui spedire le informazioni del file di risultato
 WorkflowExecutorDialog.ResultRows.Tooltip=E'' possibile specificare la destinazione e la specifica delle righe di risultato che devono essere passate dal workflow.
 WorkflowExecutorMeta.CheckResult.NoInputReceived=Nessun input ricevuto dai transforms precedenti
 WorkflowExecutorDialog.TransformName.Label=Nome transform