This is an automated email from the ASF dual-hosted git repository.
bamaer 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 19e9ce7bbe UDJC test pipeline should have info and output transforms,
fixes #4584 (#8586)
19e9ce7bbe is described below
commit 19e9ce7bbe99bca7171607b0bbcdffe52df9b92e
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Fri Sep 25 11:54:28 2026 +0200
UDJC test pipeline should have info and output transforms, fixes #4584
(#8586)
---
.../UserDefinedJavaClassDialog.java | 107 +--------
.../UserDefinedJavaClassTestPipeline.java | 239 +++++++++++++++++++++
.../UserDefinedJavaClassTestPipelineTest.java | 214 ++++++++++++++++++
3 files changed, 464 insertions(+), 96 deletions(-)
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
index 2e922c1169..b698329d37 100644
---
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
@@ -17,11 +17,9 @@
package org.apache.hop.pipeline.transforms.userdefinedjavaclass;
-import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Date;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@@ -29,8 +27,6 @@ import org.apache.hop.core.Const;
import org.apache.hop.core.Props;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.exception.HopXmlException;
-import org.apache.hop.core.plugins.PluginRegistry;
-import org.apache.hop.core.plugins.TransformPluginType;
import org.apache.hop.core.row.IRowMeta;
import org.apache.hop.core.row.IValueMeta;
import org.apache.hop.core.row.value.ValueMetaFactory;
@@ -38,11 +34,9 @@ import org.apache.hop.core.util.Utils;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.i18n.BaseMessages;
import org.apache.hop.pipeline.Pipeline;
-import org.apache.hop.pipeline.PipelineHopMeta;
import org.apache.hop.pipeline.PipelineMeta;
import org.apache.hop.pipeline.transform.TransformMeta;
import org.apache.hop.pipeline.transforms.janino.JaninoMeta;
-import org.apache.hop.pipeline.transforms.rowgenerator.GeneratorField;
import org.apache.hop.pipeline.transforms.rowgenerator.RowGeneratorMeta;
import
org.apache.hop.pipeline.transforms.userdefinedjavaclass.UserDefinedJavaClassCodeSnippets.Category;
import
org.apache.hop.pipeline.transforms.userdefinedjavaclass.UserDefinedJavaClassCodeSnippets.Snippet;
@@ -1305,7 +1299,6 @@ public class UserDefinedJavaClassDialog extends
BaseTransformDialog {
}
private boolean test() {
- PluginRegistry registry = PluginRegistry.getInstance();
String scriptTransformName = wTransformName.getText();
if (!checkForTransformClass()) {
@@ -1340,8 +1333,10 @@ public class UserDefinedJavaClassDialog extends
BaseTransformDialog {
return false;
}
- // What fields are coming into the transform?
- IRowMeta rowMeta = pipelineMeta.getPrevTransformFields(variables,
transformName).clone();
+ // What fields are coming into the transform over the main input?
+ IRowMeta rowMeta =
+ UserDefinedJavaClassTestPipeline.getMainInputFields(
+ variables, pipelineMeta, transformName, udjcMeta);
if (rowMeta != null) {
// Create a new RowGenerator transform to generate rows for the test
// data...
@@ -1349,101 +1344,21 @@ public class UserDefinedJavaClassDialog extends
BaseTransformDialog {
// Otherwise he/she has to key in the same test data all the
// time
if (genMeta == null) {
- genMeta = new RowGeneratorMeta();
- genMeta.setRowLimit("10");
- for (int i = 0; i < rowMeta.size(); i++) {
- IValueMeta valueMeta = rowMeta.getValueMeta(i);
- if (valueMeta.isStorageBinaryString()) {
- valueMeta.setStorageType(IValueMeta.STORAGE_TYPE_NORMAL);
- }
- GeneratorField field = new GeneratorField();
- field.setName(valueMeta.getName());
- field.setType(valueMeta.getTypeDesc());
- field.setLength(valueMeta.getLength());
- field.setPrecision(valueMeta.getPrecision());
- field.setCurrency(valueMeta.getCurrencySymbol());
- field.setDecimal(valueMeta.getDecimalSymbol());
- field.setGroup(valueMeta.getGroupingSymbol());
-
- String string = null;
- switch (valueMeta.getType()) {
- case IValueMeta.TYPE_DATE:
- field.setFormat("yyyy/MM/dd HH:mm:ss");
- valueMeta.setConversionMask(field.getFormat());
- string = valueMeta.getString(new Date());
- break;
- case IValueMeta.TYPE_STRING:
- string = "test value test value";
- break;
- case IValueMeta.TYPE_INTEGER:
- field.setFormat("#");
- valueMeta.setConversionMask(field.getFormat());
- string = valueMeta.getString(0L);
- break;
- case IValueMeta.TYPE_NUMBER:
- field.setFormat("#.#");
- valueMeta.setConversionMask(field.getFormat());
- string = valueMeta.getString(0.0D);
- break;
- case IValueMeta.TYPE_BIGNUMBER:
- field.setFormat("#.#");
- valueMeta.setConversionMask(field.getFormat());
- string = valueMeta.getString(BigDecimal.ZERO);
- break;
- case IValueMeta.TYPE_BOOLEAN:
- string = valueMeta.getString(Boolean.TRUE);
- break;
- case IValueMeta.TYPE_BINARY:
- string =
- valueMeta.getString(
- new byte[] {
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- });
- break;
- default:
- break;
- }
-
- field.setValue(string);
- genMeta.getFields().add(field);
- }
+ genMeta =
UserDefinedJavaClassTestPipeline.createTestDataGenerator(rowMeta);
}
- TransformMeta genTransform =
- new TransformMeta(
- registry.getPluginId(TransformPluginType.class, genMeta),
- "## TEST DATA ##",
- genMeta);
- genTransform.setLocation(50, 50);
-
- TransformMeta scriptTransform =
- new TransformMeta(
- registry.getPluginId(TransformPluginType.class, udjcMeta),
- Const.NVL(scriptTransformName, "## SCRIPT ##"),
- udjcMeta);
- scriptTransformName = scriptTransform.getName();
- scriptTransform.setLocation(150, 50);
-
- // Create a hop between both transforms...
- //
- PipelineHopMeta hop = new PipelineHopMeta(genTransform,
scriptTransform);
-
- // Generate a new test pipeline...
- //
- PipelineMeta pipelineMeta = new PipelineMeta();
- pipelineMeta.setName(wTransformName.getText() + " - PREVIEW");
- pipelineMeta.addTransform(genTransform);
- pipelineMeta.addTransform(scriptTransform);
- pipelineMeta.addPipelineHop(hop);
+ scriptTransformName = Const.NVL(scriptTransformName, "## SCRIPT ##");
+ PipelineMeta testPipelineMeta =
+ UserDefinedJavaClassTestPipeline.build(
+ variables, pipelineMeta, scriptTransformName, udjcMeta,
genMeta);
+ testPipelineMeta.setName(wTransformName.getText() + " - PREVIEW");
- // OK, now we ask the user to edit this dialog...
- //
// Now run this pipeline and grab the results...
//
PipelinePreviewProgressDialog progressDialog =
new PipelinePreviewProgressDialog(
shell,
variables,
- pipelineMeta,
+ testPipelineMeta,
new String[] {
scriptTransformName,
},
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipeline.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipeline.java
new file mode 100644
index 0000000000..9a0b1eb518
--- /dev/null
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipeline.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.pipeline.transforms.userdefinedjavaclass;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import org.apache.hop.core.Const;
+import org.apache.hop.core.exception.HopTransformException;
+import org.apache.hop.core.exception.HopValueException;
+import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.core.plugins.TransformPluginType;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.util.Utils;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.pipeline.PipelineHopMeta;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.pipeline.transforms.dummy.DummyMeta;
+import org.apache.hop.pipeline.transforms.rowgenerator.GeneratorField;
+import org.apache.hop.pipeline.transforms.rowgenerator.RowGeneratorMeta;
+
+/**
+ * Builds the throwaway pipeline behind the "Test class" button of the User
Defined Java Class
+ * dialog: generated test data for the main input, and stand-ins for the info
and target transforms
+ * the class reads from and writes to by name.
+ */
+public final class UserDefinedJavaClassTestPipeline {
+ public static final String TEST_DATA_TRANSFORM_NAME = "## TEST DATA ##";
+
+ private UserDefinedJavaClassTestPipeline() {}
+
+ /**
+ * @param variables the variables to resolve the source pipeline's fields
with
+ * @param sourcePipelineMeta the pipeline the transform lives in, used to
derive field layouts
+ * @param scriptTransformName the name of the transform under test
+ * @param udjcMeta the metadata of the transform under test, as currently
edited
+ * @param mainGenMeta the test data generator for the main input
+ * @return the test pipeline
+ */
+ public static PipelineMeta build(
+ IVariables variables,
+ PipelineMeta sourcePipelineMeta,
+ String scriptTransformName,
+ UserDefinedJavaClassMeta udjcMeta,
+ RowGeneratorMeta mainGenMeta)
+ throws HopTransformException {
+ PluginRegistry registry = PluginRegistry.getInstance();
+
+ TransformMeta genTransform =
+ new TransformMeta(
+ registry.getPluginId(TransformPluginType.class, mainGenMeta),
+ TEST_DATA_TRANSFORM_NAME,
+ mainGenMeta);
+ genTransform.setLocation(50, 50);
+
+ TransformMeta scriptTransform =
+ new TransformMeta(
+ registry.getPluginId(TransformPluginType.class, udjcMeta),
+ scriptTransformName,
+ udjcMeta);
+ scriptTransform.setLocation(250, 50);
+
+ PipelineMeta testPipelineMeta = new PipelineMeta();
+ testPipelineMeta.addTransform(genTransform);
+ testPipelineMeta.addTransform(scriptTransform);
+ testPipelineMeta.addPipelineHop(new PipelineHopMeta(genTransform,
scriptTransform));
+
+ // The class can read from info transforms and write to target transforms
by name.
+ // Those don't exist in the test pipeline, so stand in for them: generated
test data
+ // for every info transform, a dummy for every target transform.
+ //
+ int y = 150;
+ for (InfoTransformDefinition infoDefinition :
udjcMeta.getInfoTransformDefinitions()) {
+ String infoTransformName = infoDefinition.getTransformName();
+ if (Utils.isEmpty(infoTransformName)
+ || testPipelineMeta.findTransform(infoTransformName) != null) {
+ continue;
+ }
+ IRowMeta infoRowMeta = sourcePipelineMeta.getTransformFields(variables,
infoTransformName);
+ RowGeneratorMeta infoGenMeta =
+ createTestDataGenerator(infoRowMeta == null ? new RowMeta() :
infoRowMeta.clone());
+ TransformMeta infoTransform =
+ new TransformMeta(
+ registry.getPluginId(TransformPluginType.class, infoGenMeta),
+ infoTransformName,
+ infoGenMeta);
+ infoTransform.setLocation(50, y);
+ y += 100;
+ testPipelineMeta.addTransform(infoTransform);
+ testPipelineMeta.addPipelineHop(new PipelineHopMeta(infoTransform,
scriptTransform));
+ }
+ y = 150;
+ for (TargetTransformDefinition targetDefinition :
udjcMeta.getTargetTransformDefinitions()) {
+ String targetTransformName = targetDefinition.transformName;
+ if (Utils.isEmpty(targetTransformName)
+ || testPipelineMeta.findTransform(targetTransformName) != null) {
+ continue;
+ }
+ DummyMeta dummyMeta = new DummyMeta();
+ TransformMeta targetTransform =
+ new TransformMeta(
+ registry.getPluginId(TransformPluginType.class, dummyMeta),
+ targetTransformName,
+ dummyMeta);
+ targetTransform.setLocation(450, y);
+ y += 100;
+ testPipelineMeta.addTransform(targetTransform);
+ testPipelineMeta.addPipelineHop(new PipelineHopMeta(scriptTransform,
targetTransform));
+ }
+
+ // Point the info and target definitions at the stand-ins so the info hops
are
+ // recognised as such and the class finds its row sets.
+ //
+ udjcMeta.searchInfoAndTargetTransforms(testPipelineMeta.getTransforms());
+
+ return testPipelineMeta;
+ }
+
+ /**
+ * The fields entering the transform over its main input, leaving out the
info transforms
+ * configured in the given (possibly not yet saved) metadata.
+ */
+ public static IRowMeta getMainInputFields(
+ IVariables variables,
+ PipelineMeta pipelineMeta,
+ String transformName,
+ UserDefinedJavaClassMeta udjcMeta)
+ throws HopTransformException {
+ TransformMeta thisTransform = pipelineMeta.findTransform(transformName);
+ if (thisTransform == null) {
+ return null;
+ }
+ List<String> infoTransformNames = new ArrayList<>();
+ for (InfoTransformDefinition infoDefinition :
udjcMeta.getInfoTransformDefinitions()) {
+ infoTransformNames.add(Const.NVL(infoDefinition.getTransformName(), ""));
+ }
+
+ IRowMeta rowMeta = new RowMeta();
+ for (TransformMeta prevTransform :
pipelineMeta.findPreviousTransforms(thisTransform, true)) {
+ if (Const.indexOfString(prevTransform.getName(), infoTransformNames) >=
0) {
+ continue;
+ }
+ IRowMeta prevRowMeta =
+ pipelineMeta.getTransformFields(variables, prevTransform,
thisTransform, null);
+ for (IValueMeta valueMeta : prevRowMeta.getValueMetaList()) {
+ if (rowMeta.searchValueMeta(valueMeta.getName()) == null) {
+ rowMeta.addValueMeta(valueMeta.clone());
+ }
+ }
+ }
+ return rowMeta;
+ }
+
+ /** A row generator producing 10 rows of test values for the given fields. */
+ public static RowGeneratorMeta createTestDataGenerator(IRowMeta rowMeta) {
+ RowGeneratorMeta generatorMeta = new RowGeneratorMeta();
+ generatorMeta.setRowLimit("10");
+ for (int i = 0; i < rowMeta.size(); i++) {
+ IValueMeta valueMeta = rowMeta.getValueMeta(i);
+ if (valueMeta.isStorageBinaryString()) {
+ valueMeta.setStorageType(IValueMeta.STORAGE_TYPE_NORMAL);
+ }
+ GeneratorField field = new GeneratorField();
+ field.setName(valueMeta.getName());
+ field.setType(valueMeta.getTypeDesc());
+ field.setLength(valueMeta.getLength());
+ field.setPrecision(valueMeta.getPrecision());
+ field.setCurrency(valueMeta.getCurrencySymbol());
+ field.setDecimal(valueMeta.getDecimalSymbol());
+ field.setGroup(valueMeta.getGroupingSymbol());
+
+ String string = null;
+ try {
+ switch (valueMeta.getType()) {
+ case IValueMeta.TYPE_DATE:
+ field.setFormat("yyyy/MM/dd HH:mm:ss");
+ valueMeta.setConversionMask(field.getFormat());
+ string = valueMeta.getString(new Date());
+ break;
+ case IValueMeta.TYPE_STRING:
+ string = "test value test value";
+ break;
+ case IValueMeta.TYPE_INTEGER:
+ field.setFormat("#");
+ valueMeta.setConversionMask(field.getFormat());
+ string = valueMeta.getString(0L);
+ break;
+ case IValueMeta.TYPE_NUMBER:
+ field.setFormat("#.#");
+ valueMeta.setConversionMask(field.getFormat());
+ string = valueMeta.getString(0.0D);
+ break;
+ case IValueMeta.TYPE_BIGNUMBER:
+ field.setFormat("#.#");
+ valueMeta.setConversionMask(field.getFormat());
+ string = valueMeta.getString(BigDecimal.ZERO);
+ break;
+ case IValueMeta.TYPE_BOOLEAN:
+ string = valueMeta.getString(Boolean.TRUE);
+ break;
+ case IValueMeta.TYPE_BINARY:
+ string =
+ valueMeta.getString(
+ new byte[] {
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ });
+ break;
+ default:
+ break;
+ }
+ } catch (HopValueException e) {
+ // Leave the test value empty
+ }
+
+ field.setValue(string);
+ generatorMeta.getFields().add(field);
+ }
+ return generatorMeta;
+ }
+}
diff --git
a/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipelineTest.java
b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipelineTest.java
new file mode 100644
index 0000000000..9001083b73
--- /dev/null
+++
b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassTestPipelineTest.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.pipeline.transforms.userdefinedjavaclass;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.exception.HopTransformException;
+import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.core.plugins.TransformPluginType;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
+import org.apache.hop.pipeline.PipelineHopMeta;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.engines.local.LocalPipelineEngine;
+import org.apache.hop.pipeline.transform.ITransform;
+import org.apache.hop.pipeline.transform.RowAdapter;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.pipeline.transforms.dummy.DummyMeta;
+import org.apache.hop.pipeline.transforms.rowgenerator.GeneratorField;
+import org.apache.hop.pipeline.transforms.rowgenerator.RowGeneratorMeta;
+import
org.apache.hop.pipeline.transforms.userdefinedjavaclass.UserDefinedJavaClassDef.ClassType;
+import
org.apache.hop.pipeline.transforms.userdefinedjavaclass.UserDefinedJavaClassMeta.FieldInfo;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/**
+ * The "Test class" button runs the class in a throwaway pipeline. A class
reading from an info
+ * transform or writing to a target transform must find those there too
(#4584).
+ */
+class UserDefinedJavaClassTestPipelineTest {
+
+ @RegisterExtension
+ static RestoreHopEngineEnvironmentExtension env = new
RestoreHopEngineEnvironmentExtension();
+
+ private static final String UDJC_NAME = "udjc";
+ private static final String INFO_NAME = "lookup";
+ private static final String TARGET_NAME = "out";
+
+ private static final String CLASS_SOURCE =
+ """
+ private long infoRows;
+
+ public boolean processRow() throws HopException {
+ if (first) {
+ first = false;
+ IRowSet info = findInfoRowSet("info");
+ while (getRowFrom(info) != null) {
+ infoRows++;
+ }
+ // Throws when the target transform can't be found
+ findTargetRowSet("target");
+ }
+ Object[] r = getRow();
+ if (r == null) {
+ setOutputDone();
+ return false;
+ }
+ r = createOutputRow(r, data.outputRowMeta.size());
+ get(Fields.Out, "info_rows").setValue(r, Long.valueOf(infoRows));
+ putRow(data.outputRowMeta, r);
+ return true;
+ }
+ """;
+
+ private final IVariables variables = new Variables();
+ private PipelineMeta sourcePipelineMeta;
+ private UserDefinedJavaClassMeta udjcMeta;
+
+ @BeforeAll
+ static void initEnvironment() throws Exception {
+ HopEnvironment.init();
+ }
+
+ @BeforeEach
+ void setUp() throws Exception {
+ udjcMeta = new UserDefinedJavaClassMeta();
+ udjcMeta.replaceDefinitions(
+ List.of(new UserDefinedJavaClassDef(ClassType.TRANSFORM_CLASS,
"Processor", CLASS_SOURCE)));
+ udjcMeta.setFieldInfo(
+ new ArrayList<>(List.of(new FieldInfo("info_rows",
IValueMeta.TYPE_INTEGER, -1, -1))));
+
+ InfoTransformDefinition infoDefinition = new InfoTransformDefinition();
+ infoDefinition.setTag("info");
+ infoDefinition.setTransformName(INFO_NAME);
+ udjcMeta.getInfoTransformDefinitions().add(infoDefinition);
+
+ TargetTransformDefinition targetDefinition = new
TargetTransformDefinition();
+ targetDefinition.tag = "target";
+ targetDefinition.transformName = TARGET_NAME;
+ udjcMeta.getTargetTransformDefinitions().add(targetDefinition);
+
+ // The pipeline the transform lives in: main input, info input and target
output.
+ //
+ sourcePipelineMeta = new PipelineMeta();
+ TransformMeta main =
+ addTransform(generator(field("id", "Integer", "1"), field("name",
"String", "x")), "main");
+ TransformMeta lookup =
+ addTransform(
+ generator(field("key", "String", "k"), field("value", "Integer",
"2")), INFO_NAME);
+ TransformMeta udjc = addTransform(udjcMeta, UDJC_NAME);
+ TransformMeta out = addTransform(new DummyMeta(), TARGET_NAME);
+ sourcePipelineMeta.addPipelineHop(new PipelineHopMeta(main, udjc));
+ sourcePipelineMeta.addPipelineHop(new PipelineHopMeta(lookup, udjc));
+ sourcePipelineMeta.addPipelineHop(new PipelineHopMeta(udjc, out));
+ udjcMeta.searchInfoAndTargetTransforms(sourcePipelineMeta.getTransforms());
+
+ udjcMeta.cookClasses();
+ assertTrue(udjcMeta.getCookErrors().isEmpty(), () ->
udjcMeta.getCookErrors().toString());
+ }
+
+ @Test
+ void mainInputFieldsLeaveOutInfoTransforms() throws Exception {
+ IRowMeta rowMeta =
+ UserDefinedJavaClassTestPipeline.getMainInputFields(
+ variables, sourcePipelineMeta, UDJC_NAME, udjcMeta);
+
+ assertEquals(List.of("id", "name"), List.of(rowMeta.getFieldNames()));
+ }
+
+ @Test
+ void testPipelineProvidesInfoAndTargetTransforms() throws Exception {
+ IRowMeta mainRowMeta =
+ UserDefinedJavaClassTestPipeline.getMainInputFields(
+ variables, sourcePipelineMeta, UDJC_NAME, udjcMeta);
+ RowGeneratorMeta mainGenMeta =
+ UserDefinedJavaClassTestPipeline.createTestDataGenerator(mainRowMeta);
+
+ PipelineMeta testPipelineMeta =
+ UserDefinedJavaClassTestPipeline.build(
+ variables, sourcePipelineMeta, UDJC_NAME, udjcMeta, mainGenMeta);
+
+ TransformMeta infoStandIn = testPipelineMeta.findTransform(INFO_NAME);
+ assertNotNull(infoStandIn);
+ assertNotNull(testPipelineMeta.findTransform(TARGET_NAME));
+ assertEquals(
+ List.of("key", "value"),
+ List.of(testPipelineMeta.getTransformFields(variables,
infoStandIn).getFieldNames()));
+
+ LocalPipelineEngine pipeline = new LocalPipelineEngine(testPipelineMeta);
+ pipeline.prepareExecution();
+ List<Object[]> rows = new ArrayList<>();
+ List<IRowMeta> rowMetas = new ArrayList<>();
+ ITransform udjc = pipeline.getTransform(UDJC_NAME, 0);
+ udjc.addRowListener(
+ new RowAdapter() {
+ @Override
+ public void rowWrittenEvent(IRowMeta rowMeta, Object[] row) {
+ rowMetas.add(rowMeta);
+ rows.add(row);
+ }
+ });
+ pipeline.startThreads();
+ pipeline.waitUntilFinished();
+
+ assertEquals(0, pipeline.getErrors());
+ assertEquals(10, rows.size());
+ int infoRowsIndex = rowMetas.get(0).indexOfValue("info_rows");
+ for (Object[] row : rows) {
+ assertEquals(10L, row[infoRowsIndex]);
+ }
+ assertEquals(10, pipeline.getTransform(TARGET_NAME, 0).getLinesRead());
+ }
+
+ private TransformMeta addTransform(
+ org.apache.hop.pipeline.transform.ITransformMeta meta, String name)
+ throws HopTransformException {
+ String pluginId =
PluginRegistry.getInstance().getPluginId(TransformPluginType.class, meta);
+ TransformMeta transformMeta = new TransformMeta(pluginId, name, meta);
+ sourcePipelineMeta.addTransform(transformMeta);
+ return transformMeta;
+ }
+
+ private static RowGeneratorMeta generator(GeneratorField... fields) {
+ RowGeneratorMeta meta = new RowGeneratorMeta();
+ meta.setRowLimit("5");
+ meta.getFields().addAll(List.of(fields));
+ return meta;
+ }
+
+ private static GeneratorField field(String name, String type, String value) {
+ GeneratorField field = new GeneratorField();
+ field.setName(name);
+ field.setType(type);
+ field.setLength(-1);
+ field.setPrecision(-1);
+ field.setValue(value);
+ return field;
+ }
+}