From 313f387e5b622cced22043ce6c1099043b747049 Mon Sep 17 00:00:00 2001 From: Bart Maertens Date: Wed, 7 Oct 2026 16:50:08 +0200 Subject: [PATCH 1/2] samples for all actions, stubs for actions that need infrastructure in actions/requires-setup. fixes #2238 --- .../samples/read-samples-build-hop-run.hpl | 15 + .../abort/src/main/samples/actions/abort.hwf | 142 ++++++++ .../samples/actions/check-files-locked.hwf | 171 +++++++++ .../actions/copy-move-result-filenames.hwf | 289 ++++++++++++++++ .../samples/actions/requires-setup/dbt.hwf | 184 ++++++++++ .../main/samples/actions/delete-folders.hwf | 213 ++++++++++++ .../actions/delete-result-filenames.hwf | 260 ++++++++++++++ .../src/main/samples/actions/dos-to-unix.hwf | 212 ++++++++++++ .../actions/evaluate-files-metrics.hwf | 306 ++++++++++++++++ .../actions/evaluate-table-content.hwf | 231 +++++++++++++ .../src/main/samples/actions/file-compare.hwf | 248 +++++++++++++ .../src/main/samples/actions/file-exists.hwf | 200 +++++++++++ .../main/samples/actions/folder-is-empty.hwf | 250 ++++++++++++++ .../main/samples/actions/folders-compare.hwf | 326 ++++++++++++++++++ .../actions/requires-setup/http-get.hwf | 202 +++++++++++ .../src/main/samples/actions/move-files.hwf | 283 +++++++++++++++ .../pgp-encrypt-decrypt-verify.hwf | 320 +++++++++++++++++ .../send-nagios-passive-check.hwf | 155 +++++++++ .../samples/actions/set-password-encoder.hwf | 125 +++++++ .../shell/src/main/samples/actions/shell.hwf | 155 +++++++++ .../actions/requires-setup/snmp-trap.hwf | 155 +++++++++ .../src/main/samples/actions/sql-script.hwf | 184 ++++++++++ .../actions/requires-setup/telnet-a-host.hwf | 167 +++++++++ .../main/samples/actions/truncate-tables.hwf | 209 +++++++++++ .../main/samples/actions/wait-for-file.hwf | 169 +++++++++ .../src/main/samples/actions/wait-for-sql.hwf | 189 ++++++++++ .../requires-setup/webservice-available.hwf | 167 +++++++++ .../main/samples/actions/write-to-file.hwf | 150 ++++++++ .../actions/requires-setup/dtd-validator.hwf | 169 +++++++++ .../main/samples/actions/xml-well-formed.hwf | 152 ++++++++ .../main/samples/actions/xsd-validator.hwf | 145 ++++++++ .../samples/actions/xsl-transformation.hwf | 205 +++++++++++ .../files/xml-actions/orders-to-csv.xsl | 29 ++ .../main/samples/files/xml-actions/orders.dtd | 24 ++ .../main/samples/files/xml-actions/orders.xml | 29 ++ .../main/samples/files/xml-actions/orders.xsd | 36 ++ .../databases/as400/src/assembly/assembly.xml | 6 + .../actions/requires-setup/as400-command.hwf | 151 ++++++++ .../mssqlnative/src/assembly/assembly.xml | 6 + .../requires-setup/mssql-bulk-load.hwf | 171 +++++++++ .../databases/mysql/src/assembly/assembly.xml | 6 + .../mysql-bulk-file-and-load.hwf | 191 ++++++++++ .../snowflake/src/assembly/assembly.xml | 6 + .../snowflake-warehouse-manager.hwf | 210 +++++++++++ .../samples/actions/build-documentation.hwf | 153 ++++++++ .../main/samples/actions/mail-validator.hwf | 147 ++++++++ .../requires-setup/mail-send-and-receive.hwf | 274 +++++++++++++++ .../misc/testing/src/assembly/assembly.xml | 6 + .../actions/run-pipeline-tests-pipeline.hpl | 190 ++++++++++ .../samples/actions/run-pipeline-tests.hwf | 148 ++++++++ .../datasets/run-pipeline-tests-golden.csv | 3 + .../datasets/run-pipeline-tests-input.csv | 3 + .../dataset/run-pipeline-tests-golden.json | 40 +++ .../dataset/run-pipeline-tests-input.json | 32 ++ .../unit-test/run-pipeline-tests-unit.json | 62 ++++ .../tech/cassandra/src/assembly/assembly.xml | 6 + .../requires-setup/cassandra-exec-cql.hwf | 153 ++++++++ .../tech/databricks/src/assembly/assembly.xml | 6 + .../databricks-job-run-and-wait.hwf | 243 +++++++++++++ .../requires-setup/ftp-put-get-delete.hwf | 283 +++++++++++++++ .../requires-setup/mongodb-execute-mql.hwf | 158 +++++++++ plugins/tech/sftp/src/assembly/assembly.xml | 6 + .../actions/requires-setup/sftp-put-get.hwf | 230 ++++++++++++ 63 files changed, 9356 insertions(+) create mode 100644 plugins/actions/abort/src/main/samples/actions/abort.hwf create mode 100644 plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf create mode 100644 plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf create mode 100644 plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf create mode 100644 plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf create mode 100644 plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf create mode 100644 plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf create mode 100644 plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf create mode 100644 plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf create mode 100644 plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf create mode 100644 plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf create mode 100644 plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf create mode 100644 plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf create mode 100644 plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf create mode 100644 plugins/actions/movefiles/src/main/samples/actions/move-files.hwf create mode 100644 plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf create mode 100644 plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf create mode 100644 plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf create mode 100644 plugins/actions/shell/src/main/samples/actions/shell.hwf create mode 100644 plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf create mode 100644 plugins/actions/sql/src/main/samples/actions/sql-script.hwf create mode 100644 plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf create mode 100644 plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf create mode 100644 plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf create mode 100644 plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf create mode 100644 plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf create mode 100644 plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf create mode 100644 plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf create mode 100644 plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf create mode 100644 plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf create mode 100644 plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf create mode 100644 plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl create mode 100644 plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd create mode 100644 plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml create mode 100644 plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd create mode 100644 plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf create mode 100644 plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf create mode 100644 plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf create mode 100644 plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf create mode 100644 plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf create mode 100644 plugins/misc/mail/src/main/samples/actions/mail-validator.hwf create mode 100644 plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf create mode 100644 plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl create mode 100644 plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf create mode 100644 plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv create mode 100644 plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv create mode 100644 plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json create mode 100644 plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json create mode 100644 plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json create mode 100644 plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf create mode 100644 plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf create mode 100644 plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf create mode 100644 plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf create mode 100644 plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf diff --git a/integration-tests/samples/read-samples-build-hop-run.hpl b/integration-tests/samples/read-samples-build-hop-run.hpl index 0079094b008..3864602f583 100644 --- a/integration-tests/samples/read-samples-build-hop-run.hpl +++ b/integration-tests/samples/read-samples-build-hop-run.hpl @@ -690,6 +690,21 @@ var hop_run_cmd = './hop-run.sh -j samples -r ' + run_config + ' -f ' + filename + + Y + AND + filename + CONTAINS + + constant + String + /requires-setup/ + -1 + -1 + N + + + diff --git a/plugins/actions/abort/src/main/samples/actions/abort.hwf b/plugins/actions/abort/src/main/samples/actions/abort.hwf new file mode 100644 index 00000000000..c9c0a4ccfa2 --- /dev/null +++ b/plugins/actions/abort/src/main/samples/actions/abort.hwf @@ -0,0 +1,142 @@ + + + + abort + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${PROJECT_HOME}/project-config.json + project-config.json exists? + + FILE_EXISTS + + 272 + 256 + N + + + + Basic + + The file exists, processing continues. + Continue + + WRITE_TO_LOG + + 512 + 256 + N + + + + Required file ${PROJECT_HOME}/project-config.json is missing + Error + Abort + + ABORT + + 272 + 400 + N + + + + + + Start + project-config.json exists? + Y + Y + Y + + + project-config.json exists? + Continue + Y + N + Y + + + project-config.json exists? + Abort + N + N + Y + + + + + The Abort action stops the workflow with an error, optionally with a message. Parent workflows and the hop-run command see the workflow as failed. +It is typically placed on the failure (red) hop of a check, to stop processing when a requirement is not met. + +This sample checks for the project-config.json file of the samples project, which is always there, so the Abort action is not executed. +Change the filename in the File exists action to a file that does not exist to see the Abort action stop the workflow. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 174 + + + + diff --git a/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf b/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf new file mode 100644 index 00000000000..0664b5d23ff --- /dev/null +++ b/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf @@ -0,0 +1,171 @@ + + + + check-files-locked + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/check-files-locked/data.txt + Y + N + Some data + UTF-8 + Write data file + + WRITE_TO_FILE + + 272 + 256 + N + + + + N + N + + + ${java.io.tmpdir}/hop-samples/check-files-locked + .*\.txt + + + Files locked? + + CHECK_FILES_LOCKED + + 464 + 256 + N + + + + Basic + + No file is locked, processing can start. + Ready to process + + WRITE_TO_LOG + + 656 + 256 + N + + + + Error + + At least one file is locked, try again later. + Files are locked + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Write data file + Y + Y + Y + + + Write data file + Files locked? + Y + N + Y + + + Files locked? + Ready to process + Y + N + Y + + + Files locked? + Files are locked + N + N + Y + + + + + The Check files locked action checks whether files are locked by another process, for example a file that is still being written or copied. +It succeeds when none of the files are locked. + +This sample writes a file to ${java.io.tmpdir}/hop-samples/check-files-locked and checks that it is not locked before processing it. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 138 + + + + diff --git a/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf b/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf new file mode 100644 index 00000000000..b4705c01394 --- /dev/null +++ b/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf @@ -0,0 +1,289 @@ + + + + copy-move-result-filenames + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in/file-1.txt + Y + N + File 1 + UTF-8 + Write file 1 + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in/file-2.txt + Y + N + File 2 + UTF-8 + Write file 2 + + WRITE_TO_FILE + + 656 + 256 + N + + + + N + N + N + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in + .*\.txt + + + Add to result filenames + + ADD_RESULT_FILENAMES + + 848 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive + N + Create archive folder + + CREATE_FOLDER + + 1040 + 256 + N + + + + + N + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive + 10 + success_if_no_errors + N + N + N + + N + copy + Y + N + N + N + Copy result files to archive + + COPY_MOVE_RESULT_FILENAMES + + 1232 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive/file-2.txt + file-2.txt archived? + + FILE_EXISTS + + 1424 + 256 + N + + + + Basic + + The result files were copied to the archive folder. + Files archived + + WRITE_TO_LOG + + 1616 + 256 + N + + + + file-2.txt was not copied to the archive folder + Error + Not archived + + ABORT + + 1424 + 400 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write file 1 + Y + N + Y + + + Write file 1 + Write file 2 + Y + N + Y + + + Write file 2 + Add to result filenames + Y + N + Y + + + Add to result filenames + Create archive folder + Y + N + Y + + + Create archive folder + Copy result files to archive + Y + N + Y + + + Copy result files to archive + file-2.txt archived? + Y + N + Y + + + file-2.txt archived? + Files archived + Y + N + Y + + + file-2.txt archived? + Not archived + N + N + Y + + + + + Many actions and transforms add the files they read or write to the result filenames of a workflow. +The Copy or Move result filenames action copies or moves exactly those files, or the ones matching a wildcard, to a destination folder. + +This sample writes two files to ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in, adds them to the result filenames and then copies them to ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1696 + 138 + + + + diff --git a/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf b/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf new file mode 100644 index 00000000000..e6ca39c52a2 --- /dev/null +++ b/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf @@ -0,0 +1,184 @@ + + + + dbt + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + dbt-project + run + dev + + + N + + 600 + N + + + dbt test + + DBT + + 464 + 400 + N + + + + Basic + + dbt models built and tested. + Done + + WRITE_TO_LOG + + 656 + 400 + N + + + + + + Start + dbt run + Y + Y + Y + + + dbt run + dbt test + Y + N + Y + + + dbt test + Done + Y + N + Y + + + + + The dbt action runs a dbt command (run, test, build, seed, ...) for a dbt project, optionally for a selection of models. +Variables and environment variables (for example database credentials) can be passed to dbt, and lineage can be emitted with OpenLineage. + +This sample builds all models of a dbt project and then runs its tests. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 138 + + + Requires setup: this sample needs dbt (dbt-core and an adapter for your database) installed, a dbt project and a dbt project definition called "dbt-project" +in the project metadata, and a database to run the models against. Create those before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 186 + 736 + 110 + + + + diff --git a/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf b/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf new file mode 100644 index 00000000000..b49275e0538 --- /dev/null +++ b/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf @@ -0,0 +1,213 @@ + + + + delete-folders + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/delete-folders/2026-01/report.txt + Y + N + January report + UTF-8 + Write January report + + WRITE_TO_FILE + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/delete-folders/2026-02/report.txt + Y + N + February report + UTF-8 + Write February report + + WRITE_TO_FILE + + 464 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/delete-folders/2026-01 + + + ${java.io.tmpdir}/hop-samples/delete-folders/2026-02 + + + 10 + success_if_no_errors + Delete monthly folders + + DELETE_FOLDERS + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/delete-folders/2026-01 + January folder still there? + + FILE_EXISTS + + 848 + 256 + N + + + + Basic + + The monthly folders and their content were deleted. + Folders deleted + + WRITE_TO_LOG + + 1040 + 256 + N + + + + The January folder still exists + Error + Folder not deleted + + ABORT + + 848 + 400 + N + + + + + + Start + Write January report + Y + Y + Y + + + Write January report + Write February report + Y + N + Y + + + Write February report + Delete monthly folders + Y + N + Y + + + Delete monthly folders + January folder still there? + Y + N + Y + + + January folder still there? + Folders deleted + N + N + Y + + + January folder still there? + Folder not deleted + Y + N + Y + + + + + The Delete folders action deletes one or more folders, including all files and subfolders they contain. + +This sample writes a file into two monthly folders below ${java.io.tmpdir}/hop-samples/delete-folders, deletes both folders and then checks that the first folder is gone. +Deleting a folder that does not exist is not an error, so the workflow can be run again and again. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1120 + 120 + + + + diff --git a/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf b/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf new file mode 100644 index 00000000000..979f1a7ed25 --- /dev/null +++ b/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf @@ -0,0 +1,260 @@ + + + + delete-result-filenames + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/delete-result-filenames + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/delete-result-filenames/data.csv + Y + N + id +1 + UTF-8 + Write data.csv + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/delete-result-filenames/process.log + Y + N + done + UTF-8 + Write process.log + + WRITE_TO_FILE + + 656 + 256 + N + + + + N + N + N + + + ${java.io.tmpdir}/hop-samples/delete-result-filenames + .* + + + Add to result filenames + + ADD_RESULT_FILENAMES + + 848 + 256 + N + + + + + 2 result filenames? + + EVAL + + 1040 + 256 + N + + + + Y + .*\.log + + Remove log files from result + + DELETE_RESULT_FILENAMES + + 1232 + 256 + N + + + + + 1 result filename? + + EVAL + + 1424 + 256 + N + + + + Basic + + Only data.csv is left in the result filenames. + Done + + WRITE_TO_LOG + + 1616 + 256 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write data.csv + Y + N + Y + + + Write data.csv + Write process.log + Y + N + Y + + + Write process.log + Add to result filenames + Y + N + Y + + + Add to result filenames + 2 result filenames? + Y + N + Y + + + 2 result filenames? + Remove log files from result + Y + N + Y + + + Remove log files from result + 1 result filename? + Y + N + Y + + + 1 result filename? + Done + Y + N + Y + + + + + The Delete filenames from result action removes filenames from the result filenames of a workflow. The files themselves are not deleted. +Use a wildcard to only remove some of the filenames, for example to keep the files an action further down the workflow (Mail, Zip file, ...) should process. + +This sample adds a .csv and a .log file from ${java.io.tmpdir}/hop-samples/delete-result-filenames to the result filenames and then removes the .log file from the result. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1696 + 156 + + + + diff --git a/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf b/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf new file mode 100644 index 00000000000..96e7727b6c8 --- /dev/null +++ b/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf @@ -0,0 +1,212 @@ + + + + dos-to-unix + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/dos-to-unix + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/dos-to-unix/lines.txt + Y + N + line 1 +line 2 +line 3 + + UTF-8 + Write Unix file + + WRITE_TO_FILE + + 464 + 256 + N + + + + N + N + 10 + success_if_no_errors + nothing + + + ${java.io.tmpdir}/hop-samples/dos-to-unix + .*\.txt + unixtodos + + + Unix to DOS + + DOS_UNIX_CONVERTER + + 656 + 256 + N + + + + N + N + 10 + success_if_no_errors + nothing + + + ${java.io.tmpdir}/hop-samples/dos-to-unix + .*\.txt + dostounix + + + DOS to Unix + + DOS_UNIX_CONVERTER + + 848 + 256 + N + + + + Basic + + Converted ${java.io.tmpdir}/hop-samples/dos-to-unix/lines.txt to Windows and back to Unix line endings. + Done + + WRITE_TO_LOG + + 1040 + 256 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write Unix file + Y + N + Y + + + Write Unix file + Unix to DOS + Y + N + Y + + + Unix to DOS + DOS to Unix + Y + N + Y + + + DOS to Unix + Done + Y + N + Y + + + + + The Dos To Unix action converts the line endings of text files between Windows (CR+LF) and Unix (LF). +The conversion can be set per file or folder: guess (detect the format and convert to the other one), DOS to Unix or Unix to DOS. + +This sample writes a text file with Unix line endings to ${java.io.tmpdir}/hop-samples/dos-to-unix, converts it to Windows line endings and then back to Unix line endings. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1120 + 138 + + + + diff --git a/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf b/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf new file mode 100644 index 00000000000..7b673e5b786 --- /dev/null +++ b/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf @@ -0,0 +1,306 @@ + + + + evaluate-files-metrics + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-1.csv + Y + N + id,amount +1,10 + UTF-8 + Write file 1 + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-2.csv + Y + N + id,amount +2,20 + UTF-8 + Write file 2 + + WRITE_TO_FILE + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-3.csv + Y + N + id,amount +3,30 + UTF-8 + Write file 3 + + WRITE_TO_FILE + + 848 + 256 + N + + + + bytes + files + count + 3 + + + equal + + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics + .*\.csv + N + + + + + + 3 csv files? + + EVAL_FILES_METRICS + + 1040 + 256 + N + + + + bytes + files + size + 0 + + + greater + + + + ${java.io.tmpdir}/hop-samples/evaluate-files-metrics + .*\.csv + N + + + + + + Files not empty? + + EVAL_FILES_METRICS + + 1232 + 256 + N + + + + Basic + + All 3 csv files were delivered and they contain data. + All files delivered + + WRITE_TO_LOG + + 1424 + 256 + N + + + + Expected 3 csv files + Error + Wrong number of files + + ABORT + + 1040 + 400 + N + + + + The csv files are empty + Error + Empty files + + ABORT + + 1232 + 400 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write file 1 + Y + N + Y + + + Write file 1 + Write file 2 + Y + N + Y + + + Write file 2 + Write file 3 + Y + N + Y + + + Write file 3 + 3 csv files? + Y + N + Y + + + 3 csv files? + Files not empty? + Y + N + Y + + + 3 csv files? + Wrong number of files + N + N + Y + + + Files not empty? + All files delivered + Y + N + Y + + + Files not empty? + Empty files + N + N + Y + + + + + The Evaluate files metrics action evaluates the total size or the number of files in a folder (or in the result filenames) against a value or a range. + +This sample writes three csv files to ${java.io.tmpdir}/hop-samples/evaluate-files-metrics, checks that there are exactly 3 csv files and that they are not empty. +A typical use is checking that the expected number of files was delivered before starting a load. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1504 + 138 + + + + diff --git a/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf b/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf new file mode 100644 index 00000000000..ee001afb439 --- /dev/null +++ b/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf @@ -0,0 +1,231 @@ + + + + evaluate-table-content + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_EVALUATE_TABLE +( + id INT +, name VARCHAR(50) +); + +DELETE FROM PUBLIC.SAMPLE_EVALUATE_TABLE; + +INSERT INTO PUBLIC.SAMPLE_EVALUATE_TABLE VALUES +(1, 'Apache Hop'), +(2, 'Apache Beam'), +(3, 'Apache Spark'); + hop-samples + N + N + N + Create and fill table + + SQL + + 272 + 256 + N + + + + N + Y + N + N + + hop-samples + SAMPLE_EVALUATE_TABLE + PUBLIC + 0 + rows_count_greater + Table not empty? + + EVAL_TABLE_CONTENT + + 464 + 256 + N + + + + N + Y + N + Y + SELECT * FROM PUBLIC.SAMPLE_EVALUATE_TABLE WHERE name = 'Apache Hop' + hop-samples + + + 1 + rows_count_equal + One Apache Hop row? + + EVAL_TABLE_CONTENT + + 656 + 256 + N + + + + Basic + + Both checks on SAMPLE_EVALUATE_TABLE succeeded. + Done + + WRITE_TO_LOG + + 848 + 256 + N + + + + SAMPLE_EVALUATE_TABLE should not be empty + Error + Table is empty + + ABORT + + 464 + 400 + N + + + + Expected exactly one Apache Hop row + Error + Apache Hop not found + + ABORT + + 656 + 400 + N + + + + + + Start + Create and fill table + Y + Y + Y + + + Create and fill table + Table not empty? + Y + N + Y + + + Table not empty? + One Apache Hop row? + Y + N + Y + + + Table not empty? + Table is empty + N + N + Y + + + One Apache Hop row? + Done + Y + N + Y + + + One Apache Hop row? + Apache Hop not found + N + N + Y + + + + + The Evaluate rows number in a table action counts the rows in a table, or the rows returned by a custom SQL query, +and compares the count with a value (equal, different, smaller, greater, ...). + +This sample fills the table SAMPLE_EVALUATE_TABLE with three rows, then checks that the table has more than 0 rows +and that a custom query finds exactly one row named 'Apache Hop'. +The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 928 + 174 + + + + diff --git a/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf b/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf new file mode 100644 index 00000000000..c6e26513908 --- /dev/null +++ b/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf @@ -0,0 +1,248 @@ + + + + file-compare + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/file-compare/a.txt + Y + N + Hello, Apache Hop! + UTF-8 + Write a.txt + + WRITE_TO_FILE + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/file-compare/b.txt + Y + N + Hello, Apache Hop! + UTF-8 + Write b.txt + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/file-compare/c.txt + Y + N + Goodbye! + UTF-8 + Write c.txt + + WRITE_TO_FILE + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/file-compare/a.txt + ${java.io.tmpdir}/hop-samples/file-compare/b.txt + N + a.txt = b.txt? + + FILE_COMPARE + + 848 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/file-compare/a.txt + ${java.io.tmpdir}/hop-samples/file-compare/c.txt + N + a.txt = c.txt? + + FILE_COMPARE + + 1040 + 256 + N + + + + Basic + + a.txt and b.txt are identical, a.txt and c.txt are different. + Files differ + + WRITE_TO_LOG + + 1040 + 400 + N + + + + a.txt and c.txt should be different + Error + Unexpected: a = c + + ABORT + + 1232 + 256 + N + + + + a.txt and b.txt should be identical + Error + Unexpected: a <> b + + ABORT + + 848 + 400 + N + + + + + + Start + Write a.txt + Y + Y + Y + + + Write a.txt + Write b.txt + Y + N + Y + + + Write b.txt + Write c.txt + Y + N + Y + + + Write c.txt + a.txt = b.txt? + Y + N + Y + + + a.txt = b.txt? + a.txt = c.txt? + Y + N + Y + + + a.txt = b.txt? + Unexpected: a <> b + N + N + Y + + + a.txt = c.txt? + Unexpected: a = c + Y + N + Y + + + a.txt = c.txt? + Files differ + N + N + Y + + + + + The File compare action compares the content of two files. It succeeds when both files are identical and fails when they differ. + +This sample writes three files to ${java.io.tmpdir}/hop-samples/file-compare: a.txt and b.txt have the same content, c.txt is different. +Comparing a.txt with b.txt follows the success (green) hop, comparing a.txt with c.txt follows the failure (red) hop. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1312 + 156 + + + + diff --git a/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf b/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf new file mode 100644 index 00000000000..c8776d42f6a --- /dev/null +++ b/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf @@ -0,0 +1,200 @@ + + + + file-exists + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${PROJECT_HOME}/project-config.json + project-config.json exists? + + FILE_EXISTS + + 272 + 256 + N + + + + Basic + + The project configuration file was found. + Found it + + WRITE_TO_LOG + + 512 + 256 + N + + + + Basic + + The project configuration file was not found. + Not found + + WRITE_TO_LOG + + 272 + 400 + N + + + + ${PROJECT_HOME}/not-there.txt + not-there.txt exists? + + FILE_EXISTS + + 752 + 256 + N + + + + Basic + + Somebody created not-there.txt. + Unexpected file + + WRITE_TO_LOG + + 992 + 256 + N + + + + Basic + + not-there.txt does not exist, the failure hop was followed. + File is missing, as expected + + WRITE_TO_LOG + + 752 + 400 + N + + + + + + Start + project-config.json exists? + Y + Y + Y + + + project-config.json exists? + Found it + Y + N + Y + + + project-config.json exists? + Not found + N + N + Y + + + Found it + not-there.txt exists? + Y + N + Y + + + not-there.txt exists? + Unexpected file + Y + N + Y + + + not-there.txt exists? + File is missing, as expected + N + N + Y + + + + + The File exists action checks whether a single file (or folder) exists. The action succeeds when the file is found and fails when it is not. +Use the success (green) and failure (red) hops to choose what happens next. + +This sample checks for the project-config.json file of the samples project, which is always there, and for a file that does not exist. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1072 + 138 + + + + diff --git a/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf b/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf new file mode 100644 index 00000000000..fa12805bcd3 --- /dev/null +++ b/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf @@ -0,0 +1,250 @@ + + + + folder-is-empty + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/folder-is-empty + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folder-is-empty + N + Create empty folder + + CREATE_FOLDER + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folder-is-empty + N + N + + Folder is empty? + + FOLDER_IS_EMPTY + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folder-is-empty/file.txt + Y + N + Some content + UTF-8 + Write a file + + WRITE_TO_FILE + + 848 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folder-is-empty + N + N + + Folder still empty? + + FOLDER_IS_EMPTY + + 1040 + 256 + N + + + + The folder should no longer be empty + Error + Unexpected + + ABORT + + 1232 + 256 + N + + + + Basic + + The folder contains a file now. + Folder is no longer empty + + WRITE_TO_LOG + + 1040 + 400 + N + + + + A new folder should be empty + Error + Folder not empty + + ABORT + + 656 + 400 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Create empty folder + Y + N + Y + + + Create empty folder + Folder is empty? + Y + N + Y + + + Folder is empty? + Write a file + Y + N + Y + + + Folder is empty? + Folder not empty + N + N + Y + + + Write a file + Folder still empty? + Y + N + Y + + + Folder still empty? + Unexpected + Y + N + Y + + + Folder still empty? + Folder is no longer empty + N + N + Y + + + + + The Folder is empty action succeeds when a folder contains no files. Optionally, only files matching a wildcard (regular expression) are counted. + +This sample creates the empty folder ${java.io.tmpdir}/hop-samples/folder-is-empty and checks it, then writes a file into it and checks it again. +The second check fails, which takes the failure (red) hop. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1312 + 138 + + + + diff --git a/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf b/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf new file mode 100644 index 00000000000..062248adca0 --- /dev/null +++ b/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf @@ -0,0 +1,326 @@ + + + + folders-compare + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/folders-compare + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folders-compare/source/a.txt + Y + N + A + UTF-8 + Write source/a.txt + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folders-compare/source/b.txt + Y + N + B + UTF-8 + Write source/b.txt + + WRITE_TO_FILE + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folders-compare/backup/a.txt + Y + N + A + UTF-8 + Write backup/a.txt + + WRITE_TO_FILE + + 848 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folders-compare/backup/b.txt + Y + N + B + UTF-8 + Write backup/b.txt + + WRITE_TO_FILE + + 1040 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/folders-compare/other/a.txt + Y + N + a different A + UTF-8 + Write other/a.txt + + WRITE_TO_FILE + + 1232 + 256 + N + + + + N + Y + Y + only_files + + ${java.io.tmpdir}/hop-samples/folders-compare/source + ${java.io.tmpdir}/hop-samples/folders-compare/backup + source = backup? + + FOLDERS_COMPARE + + 1232 + 400 + N + + + + N + Y + Y + only_files + + ${java.io.tmpdir}/hop-samples/folders-compare/source + ${java.io.tmpdir}/hop-samples/folders-compare/other + source = other? + + FOLDERS_COMPARE + + 1040 + 400 + N + + + + source and other should be different + Error + Unexpected: source = other + + ABORT + + 848 + 400 + N + + + + Basic + + source and backup are identical, source and other are different. + Folders compared + + WRITE_TO_LOG + + 1040 + 544 + N + + + + source and backup should be identical + Error + Unexpected: source <> backup + + ABORT + + 1232 + 544 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write source/a.txt + Y + N + Y + + + Write source/a.txt + Write source/b.txt + Y + N + Y + + + Write source/b.txt + Write backup/a.txt + Y + N + Y + + + Write backup/a.txt + Write backup/b.txt + Y + N + Y + + + Write backup/b.txt + Write other/a.txt + Y + N + Y + + + Write other/a.txt + source = backup? + Y + N + Y + + + source = backup? + source = other? + Y + N + Y + + + source = backup? + Unexpected: source <> backup + N + N + Y + + + source = other? + Unexpected: source = other + Y + N + Y + + + source = other? + Folders compared + N + N + Y + + + + + The Compare folders action compares the content of two folders: the names of the files and folders they contain and, optionally, the size and content of the files. +It succeeds when both folders are identical. + +This sample writes the same two files to ${java.io.tmpdir}/hop-samples/folders-compare/source and ${java.io.tmpdir}/hop-samples/folders-compare/backup, and different files to ${java.io.tmpdir}/hop-samples/folders-compare/other. +source and backup are identical (success, green hop), source and other are not (failure, red hop). + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1312 + 174 + + + + diff --git a/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf b/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf new file mode 100644 index 00000000000..b6d200b7499 --- /dev/null +++ b/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf @@ -0,0 +1,202 @@ + + + + http-get + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + https://hop.apache.org + 5000 + 10000 + Website available? + + WEBSERVICE_AVAILABLE + + 272 + 400 + N + + + + https://hop.apache.org + ${java.io.tmpdir}/hop-samples/http/hop.html + N + N + + + + + + N + N + + + + + Encrypted + N + + Download home page + + HTTP + + 464 + 400 + N + + + + Basic + + Home page downloaded to ${java.io.tmpdir}/hop-samples/http/hop.html + Done + + WRITE_TO_LOG + + 656 + 400 + N + + + + Error + + https://hop.apache.org is not available. + Not available + + WRITE_TO_LOG + + 272 + 544 + N + + + + + + Start + Website available? + Y + Y + Y + + + Website available? + Download home page + Y + N + Y + + + Download home page + Done + Y + N + Y + + + Website available? + Not available + N + N + Y + + + + + The Http action downloads the response of a URL to a file, or uploads a file to a URL. Headers, authentication and proxy settings can be configured, +and the URL can be taken from the result rows to download multiple files. + +This sample checks that the Apache Hop website is available and downloads its home page to ${java.io.tmpdir}/hop-samples/http/hop.html. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 138 + + + Requires setup: this sample needs internet access (or change the URL to a server in your network). +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 186 + 736 + 70 + + + + diff --git a/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf b/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf new file mode 100644 index 00000000000..b3d792e5e22 --- /dev/null +++ b/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf @@ -0,0 +1,283 @@ + + + + move-files + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/move-files + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/move-files/incoming/orders.csv + Y + N + id,amount +1,10 +2,20 + UTF-8 + Write orders.csv + + WRITE_TO_FILE + + 464 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/move-files/incoming/customers.csv + Y + N + id,name +1,Apache Hop + UTF-8 + Write customers.csv + + WRITE_TO_FILE + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/move-files/incoming/import.log + Y + N + import started + UTF-8 + Write import.log + + WRITE_TO_FILE + + 848 + 256 + N + + + + N + N + N + N + N + Y + + + ${java.io.tmpdir}/hop-samples/move-files/incoming + ${java.io.tmpdir}/hop-samples/move-files/processed + .*\.csv + + + 10 + success_if_no_errors + N + N + N + + N + N + overwrite_file + + do_nothing + + N + N + N + N + N + N + Move csv files + + MOVE_FILES + + 1040 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/move-files/processed/orders.csv + orders.csv moved? + + FILE_EXISTS + + 1232 + 256 + N + + + + Basic + + The csv files were moved to the processed folder. + Files moved + + WRITE_TO_LOG + + 1424 + 256 + N + + + + orders.csv was not moved + Error + orders.csv not moved + + ABORT + + 1232 + 400 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Write orders.csv + Y + N + Y + + + Write orders.csv + Write customers.csv + Y + N + Y + + + Write customers.csv + Write import.log + Y + N + Y + + + Write import.log + Move csv files + Y + N + Y + + + Move csv files + orders.csv moved? + Y + N + Y + + + orders.csv moved? + Files moved + Y + N + Y + + + orders.csv moved? + orders.csv not moved + N + N + Y + + + + + The Move files action moves files (optionally selected with a regular expression) from a source to a destination folder. +It can also rename files with a date or time, and decide what to do when a file already exists in the destination. + +This sample writes three files to ${java.io.tmpdir}/hop-samples/move-files/incoming and moves the .csv files to ${java.io.tmpdir}/hop-samples/move-files/processed. The .log file stays where it is. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1504 + 156 + + + + diff --git a/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf new file mode 100644 index 00000000000..90867945b2a --- /dev/null +++ b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf @@ -0,0 +1,320 @@ + + + + pgp-encrypt-decrypt-verify + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${java.io.tmpdir}/hop-samples/pgp/report.csv + Y + N + id,amount +1,100 + UTF-8 + Write file + + WRITE_TO_FILE + + 272 + 400 + N + + + + N + N + N + Y + N + + + encrypt + ${java.io.tmpdir}/hop-samples/pgp/report.csv + ${PGP_USER_ID} + ${java.io.tmpdir}/hop-samples/pgp/report.csv.gpg + + + + 10 + success_if_no_errors + N + N + N + + N + N + overwrite_file + + do_nothing + + N + N + N + N + N + ${PGP_GPG_LOCATION} + Y + Encrypt file + + PGP_ENCRYPT_FILES + + 464 + 400 + N + + + + N + N + N + Y + N + + + ${java.io.tmpdir}/hop-samples/pgp/report.csv.gpg + ${PGP_PASSPHRASE} + ${java.io.tmpdir}/hop-samples/pgp/report-decrypted.csv + + + + 10 + success_if_no_errors + N + N + N + + N + N + overwrite_file + + do_nothing + + N + N + N + N + N + ${PGP_GPG_LOCATION} + Decrypt file + + PGP_DECRYPT_FILES + + 656 + 400 + N + + + + N + N + N + Y + N + + + sign + ${java.io.tmpdir}/hop-samples/pgp/report.csv + ${PGP_USER_ID} + ${java.io.tmpdir}/hop-samples/pgp/report.csv.asc + + + + 10 + success_if_no_errors + N + N + N + + N + N + overwrite_file + + do_nothing + + N + N + N + N + N + ${PGP_GPG_LOCATION} + Y + Sign file + + PGP_ENCRYPT_FILES + + 848 + 400 + N + + + + ${PGP_GPG_LOCATION} + ${java.io.tmpdir}/hop-samples/pgp/report.csv.asc + + N + Verify signature + + PGP_VERIFY_FILES + + 1040 + 400 + N + + + + Basic + + The file was encrypted, decrypted, signed and verified. + Done + + WRITE_TO_LOG + + 1232 + 400 + N + + + + + + Start + Write file + Y + Y + Y + + + Write file + Encrypt file + Y + N + Y + + + Encrypt file + Decrypt file + Y + N + Y + + + Decrypt file + Sign file + Y + N + Y + + + Sign file + Verify signature + Y + N + Y + + + Verify signature + Done + Y + N + Y + + + + + The PGP actions use GnuPG to protect files: Encrypt files with PGP encrypts and/or signs files, Decrypt files with PGP decrypts them +and Verify file signature with PGP checks the signature of a signed file. + +This sample writes a file to ${java.io.tmpdir}/hop-samples/pgp, encrypts it for the key of PGP_USER_ID, decrypts it again, then signs the file and verifies the signature. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1312 + 138 + + + Requires setup: this sample needs GnuPG (gpg) installed, and a key pair in the keyring of the user running Hop. Set the PGP_GPG_LOCATION (for example /usr/bin/gpg), +PGP_USER_ID (the user id or e-mail of the key) and PGP_PASSPHRASE variables before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 186 + 1312 + 110 + + + + diff --git a/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf b/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf new file mode 100644 index 00000000000..4fa62b45cf4 --- /dev/null +++ b/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf @@ -0,0 +1,155 @@ + + + + send-nagios-passive-check + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${NAGIOS_SERVER} + 5667 + 10000 + 5000 + Workflow ${Internal.Workflow.Name} finished successfully + hop-server + hop-samples + 0 + 1 + ${NAGIOS_PASSWORD} + Report OK + + SEND_NAGIOS_PASSIVE_CHECK + + 272 + 400 + N + + + + Basic + + Status sent to Nagios. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Report OK + Y + Y + Y + + + Report OK + Done + Y + N + Y + + + + + The Send Nagios passive check action sends the result of a check to a Nagios server running NSCA, so Nagios can monitor your workflows. +The level (OK, WARNING, CRITICAL, UNKNOWN) and message tell Nagios how the workflow did. + +This sample reports OK for the hop-samples service when the workflow succeeds. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + Requires setup: this sample needs a Nagios server with the NSCA add-on, and a hop-samples service on host hop-server in the Nagios configuration. +Set the NAGIOS_SERVER and NAGIOS_PASSWORD variables before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 168 + 640 + 110 + + + + diff --git a/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf b/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf new file mode 100644 index 00000000000..dce6a828b7e --- /dev/null +++ b/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf @@ -0,0 +1,125 @@ + + + + set-password-encoder + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + Hop + + + Set Hop encoder + + SET_PASSWORD_ENCODER + + 272 + 256 + N + + + + Basic + + Passwords are now encoded with the default Hop encoder. + Done + + WRITE_TO_LOG + + 464 + 256 + N + + + + + + Start + Set Hop encoder + Y + Y + Y + + + Set Hop encoder + Done + Y + N + Y + + + + + The Set password encoder action changes the encoder Hop uses to encrypt and decrypt passwords (for example in database connections) for the rest of the process. +Use it when a workflow has to read metadata that was encrypted with a different encoder, for example the AES2 encoder with the key in the HOP_AES_ENCODER_KEY variable. + +This sample sets the default Hop encoder, which needs no key. Choose AES or AES2 and a key variable or key file to use one of the AES encoders. +Note that the encoder is changed for the whole Hop process: when you run this in Hop Gui, it is used until you restart. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 192 + + + + diff --git a/plugins/actions/shell/src/main/samples/actions/shell.hwf b/plugins/actions/shell/src/main/samples/actions/shell.hwf new file mode 100644 index 00000000000..e2229813126 --- /dev/null +++ b/plugins/actions/shell/src/main/samples/actions/shell.hwf @@ -0,0 +1,155 @@ + + + + shell + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + + ${PROJECT_HOME} + + N + N + + + N + N + Basic + N + N + Y + + Echo + + SHELL + + 272 + 256 + N + + + + Basic + + The script ran successfully. + Done + + WRITE_TO_LOG + + 464 + 256 + N + + + + Error + + The script ended with an error. + Script failed + + WRITE_TO_LOG + + 272 + 400 + N + + + + + + Start + Echo + Y + Y + Y + + + Echo + Done + Y + N + Y + + + Echo + Script failed + N + N + Y + + + + + The Shell action runs a script or an operating system command. The script can be a file or be entered in the action. +On Windows, a script entered in the action runs as a batch file, on Linux and macOS as a shell script. The exit code of the script decides whether the action succeeds. + +This sample runs an echo command, which works on all operating systems, and writes the output to the Hop log. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 138 + + + + diff --git a/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf b/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf new file mode 100644 index 00000000000..73693d2f6e1 --- /dev/null +++ b/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf @@ -0,0 +1,155 @@ + + + + snmp-trap + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${SNMP_SERVER} + 162 + 5000 + 1 + public + Workflow ${Internal.Workflow.Name} needs attention + 1.3.6.1.4.1.12345.1 + community + + + + Send trap + + SNMP_TRAP + + 272 + 400 + N + + + + Basic + + SNMP trap sent. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Send trap + Y + Y + Y + + + Send trap + Done + Y + N + Y + + + + + The Snmp Trap action sends an SNMP trap to a network management system, for example to raise an alert when a workflow fails. +It supports community based (SNMP v1/v2c) and user based (SNMP v3) targets. + +This sample sends a trap with a message to the SNMP manager in the SNMP_SERVER variable. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + Requires setup: this sample needs an SNMP manager that receives traps. Set the SNMP_SERVER variable, and the community string and OID your manager expects, before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 168 + 640 + 70 + + + + diff --git a/plugins/actions/sql/src/main/samples/actions/sql-script.hwf b/plugins/actions/sql/src/main/samples/actions/sql-script.hwf new file mode 100644 index 00000000000..0c13d78ee91 --- /dev/null +++ b/plugins/actions/sql/src/main/samples/actions/sql-script.hwf @@ -0,0 +1,184 @@ + + + + sql-script + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_SQL_SCRIPT +( + id INT +, name VARCHAR(50) +); + +DELETE FROM PUBLIC.SAMPLE_SQL_SCRIPT; + +INSERT INTO PUBLIC.SAMPLE_SQL_SCRIPT VALUES +(1, 'Apache Hop'), +(2, 'Apache Beam'), +(3, 'Apache Spark'); + hop-samples + N + N + N + Create and fill table + + SQL + + 272 + 256 + N + + + + N + Y + N + N + + hop-samples + SAMPLE_SQL_SCRIPT + PUBLIC + 3 + rows_count_equal + 3 rows? + + EVAL_TABLE_CONTENT + + 464 + 256 + N + + + + Basic + + Table SAMPLE_SQL_SCRIPT contains 3 rows. + Done + + WRITE_TO_LOG + + 656 + 256 + N + + + + SAMPLE_SQL_SCRIPT should contain 3 rows + Error + Unexpected row count + + ABORT + + 464 + 400 + N + + + + + + Start + Create and fill table + Y + Y + Y + + + Create and fill table + 3 rows? + Y + N + Y + + + 3 rows? + Done + Y + N + Y + + + 3 rows? + Unexpected row count + N + N + Y + + + + + The SQL action executes one or more SQL statements against a relational database connection. +The statements can be entered in the action or read from a file, and can contain variables. + +This sample creates the table SAMPLE_SQL_SCRIPT, clears it and inserts three rows. +The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 120 + + + + diff --git a/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf b/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf new file mode 100644 index 00000000000..dfc67eb2921 --- /dev/null +++ b/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf @@ -0,0 +1,167 @@ + + + + telnet-a-host + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${DB_HOST} + 5432 + 3000 + Database port open? + + TELNET + + 272 + 400 + N + + + + Basic + + ${DB_HOST}:5432 is reachable. + Reachable + + WRITE_TO_LOG + + 512 + 400 + N + + + + Error + + ${DB_HOST}:5432 is not reachable. + Not reachable + + WRITE_TO_LOG + + 272 + 544 + N + + + + + + Start + Database port open? + Y + Y + Y + + + Database port open? + Reachable + Y + N + Y + + + Database port open? + Not reachable + N + N + Y + + + + + The Telnet a host action checks that a TCP port on a host accepts connections within a timeout (in milliseconds). +Use it to check that a database, mail server or other service is reachable before using it. + +This sample checks that the PostgreSQL port 5432 on the host in the DB_HOST variable is reachable. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + Requires setup: this sample needs a host to connect to. Set the DB_HOST variable, or change the host name and port, before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 168 + 640 + 70 + + + + diff --git a/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf b/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf new file mode 100644 index 00000000000..94ce4b04eb7 --- /dev/null +++ b/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf @@ -0,0 +1,209 @@ + + + + truncate-tables + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_TRUNCATE_TABLES +( + id INT +, name VARCHAR(50) +); + +DELETE FROM PUBLIC.SAMPLE_TRUNCATE_TABLES; + +INSERT INTO PUBLIC.SAMPLE_TRUNCATE_TABLES VALUES +(1, 'Apache Hop'), +(2, 'Apache Beam'), +(3, 'Apache Spark'); + hop-samples + N + N + N + Create and fill table + + SQL + + 272 + 256 + N + + + + N + hop-samples + + + SAMPLE_TRUNCATE_TABLES + PUBLIC + + + Truncate table + + TRUNCATE_TABLES + + 464 + 256 + N + + + + N + Y + N + N + + hop-samples + SAMPLE_TRUNCATE_TABLES + PUBLIC + 0 + rows_count_equal + Table empty? + + EVAL_TABLE_CONTENT + + 656 + 256 + N + + + + Basic + + Table SAMPLE_TRUNCATE_TABLES was truncated. + Done + + WRITE_TO_LOG + + 848 + 256 + N + + + + SAMPLE_TRUNCATE_TABLES should be empty + Error + Table not empty + + ABORT + + 656 + 400 + N + + + + + + Start + Create and fill table + Y + Y + Y + + + Create and fill table + Truncate table + Y + N + Y + + + Truncate table + Table empty? + Y + N + Y + + + Table empty? + Done + Y + N + Y + + + Table empty? + Table not empty + N + N + Y + + + + + The Truncate tables action removes all rows from one or more tables in a relational database connection. +The list of tables can be specified in the action or be taken from the result rows of a previous action. + +This sample creates and fills the table SAMPLE_TRUNCATE_TABLES, truncates it and checks that it is empty. +The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 928 + 120 + + + + diff --git a/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf b/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf new file mode 100644 index 00000000000..b9748a1d662 --- /dev/null +++ b/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf @@ -0,0 +1,169 @@ + + + + wait-for-file + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt + Y + N + go + UTF-8 + Write trigger file + + WRITE_TO_FILE + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt + 30 + 2 + N + N + N + Wait for trigger file + + WAIT_FOR_FILE + + 464 + 256 + N + + + + Basic + + The trigger file arrived. + File arrived + + WRITE_TO_LOG + + 656 + 256 + N + + + + Error + + The trigger file did not arrive within 30 seconds. + Timeout + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Write trigger file + Y + Y + Y + + + Write trigger file + Wait for trigger file + Y + N + Y + + + Wait for trigger file + File arrived + Y + N + Y + + + Wait for trigger file + Timeout + N + N + Y + + + + + The Wait for file action waits until a file appears, checking every few seconds. It can also wait until the size of the file stops changing. +Set a maximum timeout to make sure a workflow does not wait forever, and choose whether the action succeeds or fails when the timeout is reached. + +In a real workflow another process delivers the file. This sample writes ${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt itself, so the action finds it at the first check. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 156 + + + + diff --git a/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf b/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf new file mode 100644 index 00000000000..3d790564532 --- /dev/null +++ b/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf @@ -0,0 +1,189 @@ + + + + wait-for-sql + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_WAIT_FOR_SQL +( + id INT +, name VARCHAR(50) +); + +DELETE FROM PUBLIC.SAMPLE_WAIT_FOR_SQL; + +INSERT INTO PUBLIC.SAMPLE_WAIT_FOR_SQL VALUES +(1, 'Apache Hop'), +(2, 'Apache Beam'), +(3, 'Apache Spark'); + hop-samples + N + N + N + Create and fill table + + SQL + + 272 + 256 + N + + + + Y + N + N + N + + hop-samples + SAMPLE_WAIT_FOR_SQL + PUBLIC + 30 + 5 + N + 3 + rows_count_greater_equal + Wait for 3 rows + + WAIT_FOR_SQL + + 464 + 256 + N + + + + Basic + + SAMPLE_WAIT_FOR_SQL contains at least 3 rows. + Rows arrived + + WRITE_TO_LOG + + 656 + 256 + N + + + + Error + + The rows did not arrive within 30 seconds. + Timeout + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Create and fill table + Y + Y + Y + + + Create and fill table + Wait for 3 rows + Y + N + Y + + + Wait for 3 rows + Rows arrived + Y + N + Y + + + Wait for 3 rows + Timeout + N + N + Y + + + + + The Wait for SQL action runs a query or counts the rows in a table at a regular interval, until the row count meets a condition or a timeout is reached. +A typical use is waiting until another system has finished loading a table, or until a control table says a load is done. + +In a real workflow another process fills the table. This sample creates the table SAMPLE_WAIT_FOR_SQL itself, +so the action finds the expected 3 rows at the first check. +The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 174 + + + + diff --git a/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf b/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf new file mode 100644 index 00000000000..6da64a56020 --- /dev/null +++ b/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf @@ -0,0 +1,167 @@ + + + + webservice-available + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + https://hop.apache.org + 5000 + 10000 + Website available? + + WEBSERVICE_AVAILABLE + + 272 + 400 + N + + + + Basic + + https://hop.apache.org is available. + Available + + WRITE_TO_LOG + + 512 + 400 + N + + + + Error + + https://hop.apache.org is not available. + Not available + + WRITE_TO_LOG + + 272 + 544 + N + + + + + + Start + Website available? + Y + Y + Y + + + Website available? + Available + Y + N + Y + + + Website available? + Not available + N + N + Y + + + + + The Check if webservice is available action succeeds when a URL can be opened within the connect and read timeouts (in milliseconds). +Use it to check that a REST API or website is up before calling it. + +This sample checks the Apache Hop website. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + Requires setup: this sample needs internet access (or change the URL to a server in your network). +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 168 + 640 + 70 + + + + diff --git a/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf b/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf new file mode 100644 index 00000000000..1558e8ff096 --- /dev/null +++ b/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf @@ -0,0 +1,150 @@ + + + + write-to-file + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/write-to-file/run.log + Y + N + Run log of workflow ${Internal.Workflow.Name} + + UTF-8 + Write header + + WRITE_TO_FILE + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/write-to-file/run.log + Y + Y + Project home: ${PROJECT_HOME} + + UTF-8 + Append line + + WRITE_TO_FILE + + 464 + 256 + N + + + + Basic + + Written to ${java.io.tmpdir}/hop-samples/write-to-file/run.log + Done + + WRITE_TO_LOG + + 656 + 256 + N + + + + + + Start + Write header + Y + Y + Y + + + Write header + Append line + Y + N + Y + + + Append line + Done + Y + N + Y + + + + + The Write to file action writes a piece of text to a file. Variables in the text are resolved, the parent folder can be created +and the text can be appended to an existing file instead of replacing it. + +This sample creates ${java.io.tmpdir}/hop-samples/write-to-file/run.log with a header line and then appends a second line to it. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 138 + + + + diff --git a/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf b/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf new file mode 100644 index 00000000000..3e162d95574 --- /dev/null +++ b/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf @@ -0,0 +1,169 @@ + + + + dtd-validator + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${PROJECT_HOME}/files/xml-actions/orders.xml + ${PROJECT_HOME}/files/xml-actions/orders.dtd + N + Validate against DTD + + DTD_VALIDATOR + + 272 + 400 + N + + + + Basic + + orders.xml matches the orders.dtd document type definition. + Valid + + WRITE_TO_LOG + + 512 + 400 + N + + + + Error + + orders.xml could not be validated against orders.dtd. Is XML_ALLOW_DOCTYPE_DECL set to Y? + Invalid + + WRITE_TO_LOG + + 272 + 544 + N + + + + + + Start + Validate against DTD + Y + Y + Y + + + Validate against DTD + Valid + Y + N + Y + + + Validate against DTD + Invalid + N + N + Y + + + + + The DTD validator action validates an XML file against a Document Type Definition (DTD). +The DTD can be a separate file, like in this sample, or be included in the XML file itself (the "Intern DTD" option). + +This sample validates ${PROJECT_HOME}/files/xml-actions/orders.xml against ${PROJECT_HOME}/files/xml-actions/orders.dtd. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 138 + + + Requires setup: DTD validation needs DOCTYPE declarations, which Hop does not allow by default to protect against XML external entity (XXE) attacks. +Set the XML_ALLOW_DOCTYPE_DECL variable to Y in the system properties of hop-config.json (or use hop-conf) and restart Hop before running this sample. +Only allow DOCTYPE declarations when you trust the XML files you process. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 186 + 640 + 100 + + + + diff --git a/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf b/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf new file mode 100644 index 00000000000..b6b954127da --- /dev/null +++ b/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf @@ -0,0 +1,152 @@ + + + + xml-well-formed + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + N + + + ${PROJECT_HOME}/files/xml-actions + .*\.xml + + + 10 + success_if_no_errors + all_filenames + XML files well formed? + + XML_WELL_FORMED + + 272 + 256 + N + + + + Basic + + All XML files are well formed. + All well formed + + WRITE_TO_LOG + + 512 + 256 + N + + + + Error + + At least one XML file is not well formed. + Malformed XML + + WRITE_TO_LOG + + 272 + 400 + N + + + + + + Start + XML files well formed? + Y + Y + Y + + + XML files well formed? + All well formed + Y + N + Y + + + XML files well formed? + Malformed XML + N + N + Y + + + + + The Check if XML file is well formed action checks that files are syntactically correct XML: one root element, properly nested and closed tags, quoted attributes, ... +It does not check the content against a schema, use the XSD or DTD validator actions for that. + +This sample checks all .xml files in ${PROJECT_HOME}/files/xml-actions. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + + diff --git a/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf b/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf new file mode 100644 index 00000000000..e864be39f0f --- /dev/null +++ b/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf @@ -0,0 +1,145 @@ + + + + xsd-validator + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + filename + ${PROJECT_HOME}/files/xml-actions/orders.xml + ${PROJECT_HOME}/files/xml-actions/orders.xsd + N + Validate against XSD + + XSD_VALIDATOR + + 272 + 256 + N + + + + Basic + + orders.xml matches the orders.xsd schema. + Valid + + WRITE_TO_LOG + + 512 + 256 + N + + + + Error + + orders.xml does not match the orders.xsd schema. + Invalid + + WRITE_TO_LOG + + 272 + 400 + N + + + + + + Start + Validate against XSD + Y + Y + Y + + + Validate against XSD + Valid + Y + N + Y + + + Validate against XSD + Invalid + N + N + Y + + + + + The XSD validator action validates an XML file against an XML schema definition (XSD). +The schema can be specified as a file, or be taken from the schema location in the XML document. + +This sample validates ${PROJECT_HOME}/files/xml-actions/orders.xml against ${PROJECT_HOME}/files/xml-actions/orders.xsd. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + + diff --git a/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf b/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf new file mode 100644 index 00000000000..7fd574c4d01 --- /dev/null +++ b/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf @@ -0,0 +1,205 @@ + + + + xsl-transformation + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/xslt + + + 10 + success_if_no_errors + Remove work folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/xslt + N + Create work folder + + CREATE_FOLDER + + 464 + 256 + N + + + + ${PROJECT_HOME}/files/xml-actions/orders.xml + ${PROJECT_HOME}/files/xml-actions/orders-to-csv.xsl + ${java.io.tmpdir}/hop-samples/xslt/orders.csv + 1 + Orders to CSV + + XSLT + + 656 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/xslt/orders.csv + orders.csv created? + + FILE_EXISTS + + 848 + 256 + N + + + + Basic + + The orders were written to ${java.io.tmpdir}/hop-samples/xslt/orders.csv + Done + + WRITE_TO_LOG + + 1040 + 256 + N + + + + orders.csv was not created + Error + No output + + ABORT + + 848 + 400 + N + + + + + + Start + Remove work folder + Y + Y + Y + + + Remove work folder + Create work folder + Y + N + Y + + + Create work folder + Orders to CSV + Y + N + Y + + + Orders to CSV + orders.csv created? + Y + N + Y + + + orders.csv created? + Done + Y + N + Y + + + orders.csv created? + No output + N + N + Y + + + + + The XSL transformation action transforms an XML file with an XSL stylesheet and writes the result to a file. + +This sample transforms ${PROJECT_HOME}/files/xml-actions/orders.xml into the CSV file ${java.io.tmpdir}/hop-samples/xslt/orders.csv with the orders-to-csv.xsl stylesheet. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1120 + 102 + + + + diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl b/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl new file mode 100644 index 00000000000..6b90fabeb16 --- /dev/null +++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl @@ -0,0 +1,29 @@ + + + + + + id,customer,amount + + ,, + + + + diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd new file mode 100644 index 00000000000..b81e1d08494 --- /dev/null +++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd @@ -0,0 +1,24 @@ + + + + + + + diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml new file mode 100644 index 00000000000..f10148b3ea4 --- /dev/null +++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml @@ -0,0 +1,29 @@ + + + + + Apache Hop + 100.50 + + + Apache Beam + 42.00 + + diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd new file mode 100644 index 00000000000..60ef80bf54e --- /dev/null +++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + diff --git a/plugins/databases/as400/src/assembly/assembly.xml b/plugins/databases/as400/src/assembly/assembly.xml index d71020ec0a3..712f1ec0983 100644 --- a/plugins/databases/as400/src/assembly/assembly.xml +++ b/plugins/databases/as400/src/assembly/assembly.xml @@ -31,6 +31,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + ${maven.multiModuleProjectDirectory}/assemblies/shared/hop-plugin-libs.xml diff --git a/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf b/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf new file mode 100644 index 00000000000..590eab35e0a --- /dev/null +++ b/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf @@ -0,0 +1,151 @@ + + + + as400-command + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${AS400_SERVER} + ${AS400_USER} + ${AS400_PASSWORD} + CALL PGM(MYLIB/MYPGM) + + + Run CL command + + AS400Command + + 272 + 400 + N + + + + Basic + + The AS/400 command completed. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Run CL command + Y + Y + Y + + + Run CL command + Done + Y + N + Y + + + + + The AS/400 Command action runs a CL command on an IBM i (AS/400) system, for example to call a program or submit a job. +The action succeeds when the command completes successfully. + +This sample calls the program MYPGM in library MYLIB. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 120 + + + Requires setup: this sample needs an IBM i (AS/400) system. Set the AS400_SERVER, AS400_USER and AS400_PASSWORD variables +(for example in an environment configuration file) and change the command before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 168 + 640 + 110 + + + + diff --git a/plugins/databases/mssqlnative/src/assembly/assembly.xml b/plugins/databases/mssqlnative/src/assembly/assembly.xml index 15752e266da..9c0e49e808c 100644 --- a/plugins/databases/mssqlnative/src/assembly/assembly.xml +++ b/plugins/databases/mssqlnative/src/assembly/assembly.xml @@ -36,6 +36,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf b/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf new file mode 100644 index 00000000000..755f5dd3390 --- /dev/null +++ b/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf @@ -0,0 +1,171 @@ + + + + mssql-bulk-load + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + dbo + customers + /data/customers.csv + char + , + + RAW + + 2 + 0 + + N + + N + N + N + N + + N + Asc + 0 + 0 + 0 + N + Y + mssql + Bulk load customers + + MSSQL_BULK_LOAD + + 272 + 400 + N + + + + Basic + + customers loaded. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Bulk load customers + Y + Y + Y + + + Bulk load customers + Done + Y + N + Y + + + + + The SQL Server bulk loader action loads a data file into a SQL Server table with the BULK INSERT statement. It is much faster than inserting rows one by one. +Note that SQL Server reads the file itself: the file has to be accessible from the database server, not only from the machine running Hop. + +This sample truncates the table dbo.customers and loads the comma separated file /data/customers.csv, skipping the header line. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 156 + + + Requires setup: this sample needs a SQL Server database and a relational database connection called "mssql" in the project metadata, +a dbo.customers table and a data file the database server can read. Create those before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 204 + 640 + 110 + + + + diff --git a/plugins/databases/mysql/src/assembly/assembly.xml b/plugins/databases/mysql/src/assembly/assembly.xml index 11e8a4261eb..0a43f062a19 100644 --- a/plugins/databases/mysql/src/assembly/assembly.xml +++ b/plugins/databases/mysql/src/assembly/assembly.xml @@ -31,6 +31,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf b/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf new file mode 100644 index 00000000000..ceb4ca3a26c --- /dev/null +++ b/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf @@ -0,0 +1,191 @@ + + + + mysql-bulk-file-and-load + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + customers + + /tmp/customers.csv + , + " + \n + 0 + + N + Y + 0 + 0 + N + mysql + Export customers + + MYSQL_BULK_FILE + + 272 + 400 + N + + + + + customers_copy + ${PROJECT_HOME}/files/customers.csv + , + " + \\ + + \n + 1 + Y + + Y + 0 + N + mysql + Load customers_copy + + MYSQL_BULK_LOAD + + 464 + 400 + N + + + + Basic + + customers exported, customers_copy loaded. + Done + + WRITE_TO_LOG + + 656 + 400 + N + + + + + + Start + Export customers + Y + Y + Y + + + Export customers + Load customers_copy + Y + N + Y + + + Load customers_copy + Done + Y + N + Y + + + + + The MySQL bulk file action exports a table to a file with SELECT ... INTO OUTFILE. The file is written by the database server, on the database server. +The MySQL bulk load action loads a file into a table with LOAD DATA [LOCAL] INFILE. With the "Local" option the file is read from the machine running Hop. + +This sample exports the table customers to /tmp/customers.csv on the database server, and loads ${PROJECT_HOME}/files/customers.csv into the table customers_copy. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 156 + + + Requires setup: this sample needs a MySQL database and a relational database connection called "mysql" in the project metadata, +the customers and customers_copy tables, and the database user needs the FILE privilege. Create those before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 204 + 736 + 110 + + + + diff --git a/plugins/databases/snowflake/src/assembly/assembly.xml b/plugins/databases/snowflake/src/assembly/assembly.xml index 4d5fb0ad8d5..1237844745b 100644 --- a/plugins/databases/snowflake/src/assembly/assembly.xml +++ b/plugins/databases/snowflake/src/assembly/assembly.xml @@ -31,6 +31,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf b/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf new file mode 100644 index 00000000000..6982ae0c4dd --- /dev/null +++ b/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf @@ -0,0 +1,210 @@ + + + + snowflake-warehouse-manager + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + snowflake + create + HOP_SAMPLES_WH + N + N + N + XSMALL + Standard + 1 + 1 + 60 + N + Y + + Created by the Apache Hop samples + Create warehouse + + SnowflakeWarehouseManager + + 272 + 400 + N + + + + snowflake + resume + HOP_SAMPLES_WH + N + N + Y + N + N + Resume warehouse + + SnowflakeWarehouseManager + + 464 + 400 + N + + + + snowflake + suspend + HOP_SAMPLES_WH + N + N + Y + N + N + Suspend warehouse + + SnowflakeWarehouseManager + + 656 + 400 + N + + + + Basic + + HOP_SAMPLES_WH was resumed and suspended. + Done + + WRITE_TO_LOG + + 848 + 400 + N + + + + + + Start + Create warehouse + Y + Y + Y + + + Create warehouse + Resume warehouse + Y + N + Y + + + Resume warehouse + Suspend warehouse + Y + N + Y + + + Suspend warehouse + Done + Y + N + Y + + + + + The Snowflake warehouse manager action creates, drops, resumes, suspends or alters a Snowflake virtual warehouse. +A typical use is resuming a warehouse before a load and suspending it afterwards, so you only pay for what you use. + +This sample creates the HOP_SAMPLES_WH warehouse (if it does not exist yet), resumes it and suspends it again. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 928 + 156 + + + Requires setup: this sample needs a Snowflake account and a Snowflake relational database connection called "snowflake" in the project metadata, +with a role that can create and operate warehouses. Create the connection before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 204 + 928 + 110 + + + + diff --git a/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf b/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf new file mode 100644 index 00000000000..eafbd585329 --- /dev/null +++ b/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf @@ -0,0 +1,153 @@ + + + + build-documentation + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + + + ${java.io.tmpdir}/hop-samples/documentation + + + 10 + success_if_no_errors + Remove output folder + + DELETE_FOLDERS + + 272 + 256 + N + + + + ${java.io.tmpdir}/hop-samples/documentation + Y + Y + Y + Y + N + Build documentation + + DOCUMENTATION + + 464 + 256 + N + + + + Basic + + Documentation written to ${java.io.tmpdir}/hop-samples/documentation + Done + + WRITE_TO_LOG + + 656 + 256 + N + + + + + + Start + Remove output folder + Y + Y + Y + + + Remove output folder + Build documentation + Y + N + Y + + + Build documentation + Done + Y + N + Y + + + + + The Documentation action generates documentation for the current project: an overview of all pipelines and workflows with their +descriptions, parameters and notes, and optionally of the project metadata. It writes Markdown and, optionally, HTML. + +This sample documents the samples project in ${java.io.tmpdir}/hop-samples/documentation. Open index.html in that folder in a browser. +Write the documentation to a folder outside the project, so it does not document its own output the next time it runs. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 736 + 192 + + + + diff --git a/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf b/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf new file mode 100644 index 00000000000..36a625e5e03 --- /dev/null +++ b/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf @@ -0,0 +1,147 @@ + + + + mail-validator + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + N + 0 + + + dev@hop.apache.org users@hop.apache.org + Valid address? + + MAIL_VALIDATOR + + 272 + 256 + N + + + + Basic + + All addresses are valid. + Valid + + WRITE_TO_LOG + + 512 + 256 + N + + + + Error + + At least one address is invalid. + Invalid + + WRITE_TO_LOG + + 272 + 400 + N + + + + + + Start + Valid address? + Y + Y + Y + + + Valid address? + Valid + Y + N + Y + + + Valid address? + Invalid + N + N + Y + + + + + The Mail validator action checks email addresses. Separate multiple addresses with a space. +Without the SMTP check, only the format of the addresses is checked. With the SMTP check enabled, the action also looks up the mail server of the domain +and asks it whether the address exists. That deep check needs network access and is disabled in this sample. + +This sample checks two valid addresses. An invalid address takes the failure (red) hop and counts as an error in the workflow result. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 156 + + + + diff --git a/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf b/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf new file mode 100644 index 00000000000..1e00c7b76d4 --- /dev/null +++ b/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf @@ -0,0 +1,274 @@ + + + + mail-send-and-receive + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${java.io.tmpdir}/hop-samples/mail/report.txt + Y + N + Report generated by Apache Hop + UTF-8 + Write attachment + + WRITE_TO_FILE + + 272 + 400 + N + + + + N + N + N + + + ${java.io.tmpdir}/hop-samples/mail + report\.txt + + + Add to result filenames + + ADD_RESULT_FILENAMES + + 464 + 400 + N + + + + ${MAIL_SMTP_SERVER} + ${MAIL_TO} + + + ${MAIL_USER} + Apache Hop + Report from Apache Hop + N + + + Please find the report attached. + Y + + GENERAL + + N + + Y + N + ${MAIL_USER} + ${MAIL_PASSWORD} + N + N + Y + N + + Y + ${MAIL_SMTP_PORT} + TLS + UTF-8 + + + + Mail + + MAIL + + 656 + 400 + N + + + + get + ignore + imaplistall + nothing + ${MAIL_IMAP_SERVER} + ${MAIL_USER} + ${MAIL_PASSWORD} + Y + 993 + N + N + ${java.io.tmpdir}/hop-samples/mail/inbox + name_{SYS|hhmmss_MMddyyyy|}_#IdFile#.mail + 0 + N + IMAP + Y + Y + N + 0 + INBOX + N + N + N + N + N + N + N + Y + Get mails + + GET_POP + + 848 + 400 + N + + + + Basic + + Mail sent, inbox downloaded to ${java.io.tmpdir}/hop-samples/mail/inbox + Done + + WRITE_TO_LOG + + 1040 + 400 + N + + + + + + Start + Write attachment + Y + Y + Y + + + Write attachment + Add to result filenames + Y + N + Y + + + Add to result filenames + Mail + Y + N + Y + + + Mail + Get mails + Y + N + Y + + + Get mails + Done + Y + N + Y + + + + + The Mail action sends an email, optionally with the result files of the workflow as attachments. It can use a server and credentials, +or a mail server connection from the project metadata. + +The Get mails (POP3/IMAP) action reads emails from a mailbox and saves the messages and/or attachments to a folder. It can also delete or move the messages it read. + +This sample sends an email with a file attached and then downloads the messages of the inbox to ${java.io.tmpdir}/hop-samples/mail/inbox. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1120 + 192 + + + Requires setup: this sample needs a mail server. Set the MAIL_SMTP_SERVER, MAIL_SMTP_PORT, MAIL_IMAP_SERVER, MAIL_USER, MAIL_PASSWORD and MAIL_TO variables +(for example in an environment configuration file) before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 240 + 1120 + 110 + + + + diff --git a/plugins/misc/testing/src/assembly/assembly.xml b/plugins/misc/testing/src/assembly/assembly.xml index a482c02c004..be174f99ee8 100644 --- a/plugins/misc/testing/src/assembly/assembly.xml +++ b/plugins/misc/testing/src/assembly/assembly.xml @@ -31,6 +31,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + ${maven.multiModuleProjectDirectory}/assemblies/shared/hop-plugin-libs.xml diff --git a/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl new file mode 100644 index 00000000000..084b372d3f9 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl @@ -0,0 +1,190 @@ + + + + + + N + 1000 + 100 + 0 + + run-pipeline-tests-pipeline + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + DataGrid + Order lines + + + + + + product + String + + -1 + -1 + N + + + + + + quantity + Integer + + -1 + -1 + N + + + + + + price + Integer + + -1 + -1 + N + + + + + Hop T-shirt + 2 + 20 + + + Hop mug + 3 + 10 + + + Hop sticker + 10 + 1 + + + Y + 1 + + 80 + 176 + + + + none + + + + + + Calculator + Line total + + total + MULTIPLY + quantity + price + Integer + -1 + -1 + N + + Y + Y + 1 + + 272 + 176 + + + + none + + + + + + Dummy + Output + Y + 1 + + 464 + 176 + + + + none + + + + + + + Order lines + Line total + Y + + + Line total + Output + Y + + + + + This pipeline is tested by the run-pipeline-tests-unit unit test, which is executed by the run-pipeline-tests workflow. +The unit test replaces the rows of the Order lines data grid with the run-pipeline-tests-input data set +and compares the rows arriving in Output with the run-pipeline-tests-golden data set. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 90 + + + + + diff --git a/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf new file mode 100644 index 00000000000..753b9127ef3 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf @@ -0,0 +1,148 @@ + + + + run-pipeline-tests + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 256 + N + + + + + + run-pipeline-tests-unit + + + Run unit tests + + RunPipelineTests + + 272 + 256 + N + + + + Basic + + All unit tests passed. + All tests passed + + WRITE_TO_LOG + + 464 + 256 + N + + + + Error + + At least one unit test failed. + Tests failed + + WRITE_TO_LOG + + 272 + 400 + N + + + + + + Start + Run unit tests + Y + Y + Y + + + Run unit tests + All tests passed + Y + N + Y + + + Run unit tests + Tests failed + N + N + Y + + + + + The Run pipeline unit tests action runs one or more pipeline unit tests and fails when one of them fails. +Use it to run your unit tests from a workflow, for example in a CI/CD pipeline with hop-run. + +This sample runs the run-pipeline-tests-unit test. That test replaces the data grid of run-pipeline-tests-pipeline.hpl with the +run-pipeline-tests-input data set, and compares the output with the run-pipeline-tests-golden data set. +Open the pipeline in Hop Gui and select the unit test to see how it is set up. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 156 + + + + diff --git a/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv new file mode 100644 index 00000000000..b48c5b4803e --- /dev/null +++ b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv @@ -0,0 +1,3 @@ +product,quantity,price,total +Hop hoodie,1,50,50 +Hop mug,4,10,40 diff --git a/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv new file mode 100644 index 00000000000..41117151d56 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv @@ -0,0 +1,3 @@ +product,quantity,price +Hop hoodie,1,50 +Hop mug,4,10 diff --git a/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json new file mode 100644 index 00000000000..dae99a2f808 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json @@ -0,0 +1,40 @@ +{ + "base_filename": "run-pipeline-tests-golden.csv", + "name": "run-pipeline-tests-golden", + "description": "", + "dataset_fields": [ + { + "field_comment": "", + "field_length": -1, + "field_type": 2, + "field_precision": -1, + "field_format": "", + "field_name": "product" + }, + { + "field_comment": "", + "field_length": -1, + "field_type": 5, + "field_precision": -1, + "field_format": "", + "field_name": "quantity" + }, + { + "field_comment": "", + "field_length": -1, + "field_type": 5, + "field_precision": -1, + "field_format": "", + "field_name": "price" + }, + { + "field_comment": "", + "field_length": -1, + "field_type": 5, + "field_precision": -1, + "field_format": "", + "field_name": "total" + } + ], + "folder_name": "" +} \ No newline at end of file diff --git a/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json new file mode 100644 index 00000000000..f329999ff66 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json @@ -0,0 +1,32 @@ +{ + "base_filename": "run-pipeline-tests-input.csv", + "name": "run-pipeline-tests-input", + "description": "", + "dataset_fields": [ + { + "field_comment": "", + "field_length": -1, + "field_type": 2, + "field_precision": -1, + "field_format": "", + "field_name": "product" + }, + { + "field_comment": "", + "field_length": -1, + "field_type": 5, + "field_precision": -1, + "field_format": "", + "field_name": "quantity" + }, + { + "field_comment": "", + "field_length": -1, + "field_type": 5, + "field_precision": -1, + "field_format": "", + "field_name": "price" + } + ], + "folder_name": "" +} \ No newline at end of file diff --git a/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json b/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json new file mode 100644 index 00000000000..24638bda943 --- /dev/null +++ b/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json @@ -0,0 +1,62 @@ +{ + "variableValues": [], + "database_replacements": [], + "autoOpening": true, + "basePath": "", + "golden_data_sets": [ + { + "field_mappings": [ + { + "transform_field": "product", + "data_set_field": "product" + }, + { + "transform_field": "quantity", + "data_set_field": "quantity" + }, + { + "transform_field": "price", + "data_set_field": "price" + }, + { + "transform_field": "total", + "data_set_field": "total" + } + ], + "field_order": [ + "product" + ], + "transform_name": "Output", + "data_set_name": "run-pipeline-tests-golden" + } + ], + "input_data_sets": [ + { + "field_mappings": [ + { + "transform_field": "product", + "data_set_field": "product" + }, + { + "transform_field": "quantity", + "data_set_field": "quantity" + }, + { + "transform_field": "price", + "data_set_field": "price" + } + ], + "field_order": [ + "product" + ], + "transform_name": "Order lines", + "data_set_name": "run-pipeline-tests-input" + } + ], + "name": "run-pipeline-tests-unit", + "description": "Unit test sample, executed by the run-pipeline-tests workflow", + "trans_test_tweaks": [], + "persist_filename": "", + "pipeline_filename": "./actions/run-pipeline-tests-pipeline.hpl", + "test_type": "UNIT_TEST" +} \ No newline at end of file diff --git a/plugins/tech/cassandra/src/assembly/assembly.xml b/plugins/tech/cassandra/src/assembly/assembly.xml index 564aee1cca8..c552f8456c6 100644 --- a/plugins/tech/cassandra/src/assembly/assembly.xml +++ b/plugins/tech/cassandra/src/assembly/assembly.xml @@ -30,6 +30,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf b/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf new file mode 100644 index 00000000000..6f6afd9eeaf --- /dev/null +++ b/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf @@ -0,0 +1,153 @@ + + + + cassandra-exec-cql + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + cassandra + + N + Create keyspace and table + + CASSANDRA_EXEC_CQL + + 272 + 400 + N + + + + Basic + + Keyspace hop_samples and table customers are ready. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Create keyspace and table + Y + Y + Y + + + Create keyspace and table + Done + Y + N + Y + + + + + The Cassandra Exec Cql action executes CQL statements against a Cassandra (or compatible) database. + +This sample creates a keyspace and a table. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 84 + + + Requires setup: this sample needs a Cassandra cluster and a Cassandra connection called "cassandra" in the project metadata. +Create the connection (pointing to your cluster) before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 132 + 640 + 110 + + + + diff --git a/plugins/tech/databricks/src/assembly/assembly.xml b/plugins/tech/databricks/src/assembly/assembly.xml index 4133e9dd453..35a726456cf 100644 --- a/plugins/tech/databricks/src/assembly/assembly.xml +++ b/plugins/tech/databricks/src/assembly/assembly.xml @@ -31,6 +31,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf b/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf new file mode 100644 index 00000000000..202e70a19d1 --- /dev/null +++ b/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf @@ -0,0 +1,243 @@ + + + + databricks-job-run-and-wait + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + databricks + RUN_EXISTING + 123456789 + + + + + dbfs:/FileStore/hop + N + + + + + + + 1 + + + + + N + FIRE_AND_FORGET + 3600 + 15 + DatabricksJobId + DatabricksRunId + DatabricksStatus + DatabricksRunPageUrl + DatabricksError + Start job + + DATABRICKS_JOB_RUN + + 272 + 400 + N + + + + Basic + + Databricks run ${DatabricksRunId} started: ${DatabricksRunPageUrl} + Log run page + + WRITE_TO_LOG + + 464 + 400 + N + + + + databricks + ${DatabricksRunId} + 3600 + 15 + Y + DatabricksJobId + DatabricksRunId + DatabricksStatus + DatabricksRunPageUrl + DatabricksError + Wait for run + + DATABRICKS_JOB_WAIT + + 656 + 400 + N + + + + Basic + + Databricks run ${DatabricksRunId} finished with status ${DatabricksStatus} + Done + + WRITE_TO_LOG + + 848 + 400 + N + + + + Error + + Databricks run ${DatabricksRunId} failed: ${DatabricksError} + Run failed + + WRITE_TO_LOG + + 656 + 544 + N + + + + + + Start + Start job + Y + Y + Y + + + Start job + Log run page + Y + N + Y + + + Log run page + Wait for run + Y + N + Y + + + Wait for run + Done + Y + N + Y + + + Wait for run + Run failed + N + N + Y + + + + + The Databricks job run action starts a Databricks job: an existing job, a one-off run from JSON, or a Hop pipeline it deploys itself. +It can wait for the run to finish, or start it and continue ("fire and forget"). The ids, status and page URL of the run are stored in variables. + +The Databricks job wait action waits for a run that was started earlier, for example by a job run action in fire and forget mode. + +This sample starts an existing job without waiting, writes the run page URL to the log and then waits for the run to finish. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 928 + 210 + + + Requires setup: this sample needs a Databricks workspace and a Databricks connection called "databricks" (host and access token) in the project metadata. +Create the connection and change the job id to one of your jobs before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 258 + 928 + 100 + + + + diff --git a/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf b/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf new file mode 100644 index 00000000000..1f4ae926eef --- /dev/null +++ b/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf @@ -0,0 +1,283 @@ + + + + ftp-put-get-delete + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${java.io.tmpdir}/hop-samples/ftp/hop-ftp-sample.txt + Y + N + Uploaded by Apache Hop + UTF-8 + Write file + + WRITE_TO_FILE + + 272 + 400 + N + + + + + ${FTP_SERVER} + ${FTP_PORT} + ${FTP_USER} + ${FTP_PASSWORD} + + ${java.io.tmpdir}/hop-samples/ftp + hop-ftp-sample\.txt + N + 0 + N + N + N + ISO-8859-1 + + + + Encrypted + + 1080 + + Encrypted + Put a file with FTP + + FTP_PUT + + 464 + 400 + N + + + + + ${FTP_SERVER} + ${FTP_USER} + ${FTP_PASSWORD} + + ${java.io.tmpdir}/hop-samples/ftp/download + hop-ftp-sample\.txt + N + 0 + N + N + N + ISO-8859-1 + N + + N + N + N + + N + N + N + ${FTP_PORT} + + + + Encrypted + + 1080 + + Encrypted + ifFileExistsSkip + 10 + success_if_no_errors + Get a file with FTP + + FTP + + 656 + 400 + N + + + + + + ${FTP_SERVER} + ${FTP_PORT} + ${FTP_USER} + ${FTP_PASSWORD} + + hop-ftp-sample\.txt + 0 + N + N + + Encrypted + N + + + + Encrypted + + 1080 + + Encrypted + FTP + 10 + success_if_no_errors + N + FTP delete + + FTP_DELETE + + 848 + 400 + N + + + + Basic + + The file was uploaded, downloaded and deleted. + Done + + WRITE_TO_LOG + + 1040 + 400 + N + + + + + + Start + Write file + Y + Y + Y + + + Write file + Put a file with FTP + Y + N + Y + + + Put a file with FTP + Get a file with FTP + Y + N + Y + + + Get a file with FTP + FTP delete + Y + N + Y + + + FTP delete + Done + Y + N + Y + + + + + The FTP actions transfer files to and from an FTP server: Put a file with FTP uploads files, Get a file with FTP downloads them and FTP delete removes them. +Files are selected with a regular expression. Instead of a server name and credentials, the actions can also use an FTP connection from the project metadata. + +This sample writes a file to ${java.io.tmpdir}/hop-samples/ftp, uploads it, downloads it again to ${java.io.tmpdir}/hop-samples/ftp/download and deletes it from the server. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 1120 + 156 + + + Requires setup: this sample needs an FTP server. Set the FTP_SERVER, FTP_PORT, FTP_USER and FTP_PASSWORD variables +(for example in an environment configuration file) before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 204 + 1120 + 110 + + + + diff --git a/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf b/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf new file mode 100644 index 00000000000..58d5d356d61 --- /dev/null +++ b/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf @@ -0,0 +1,158 @@ + + + + mongodb-execute-mql + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + [ + {"create": "hop_samples"}, + { + "insert": "hop_samples", + "documents": [ + {"name": "Apache Hop", "type": "data orchestration"}, + {"name": "Apache Beam", "type": "data processing"} + ] + } +] + mongodb + N + + N + Create and fill collection + + MQL + + 272 + 400 + N + + + + Basic + + Collection hop_samples created. + Done + + WRITE_TO_LOG + + 464 + 400 + N + + + + + + Start + Create and fill collection + Y + Y + Y + + + Create and fill collection + Done + Y + N + Y + + + + + The MongoDB Execute MQL action runs one or more MongoDB database commands, written as a JSON array. The commands can also be read from a file. + +This sample creates a collection and inserts two documents in it. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 640 + 102 + + + Requires setup: this sample needs a MongoDB server and a MongoDB connection called "mongodb" in the project metadata. +Create the connection before running this sample. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 150 + 640 + 110 + + + + diff --git a/plugins/tech/sftp/src/assembly/assembly.xml b/plugins/tech/sftp/src/assembly/assembly.xml index 3abec811bdb..b151034e342 100644 --- a/plugins/tech/sftp/src/assembly/assembly.xml +++ b/plugins/tech/sftp/src/assembly/assembly.xml @@ -30,6 +30,12 @@ true + + + ${project.basedir}/src/main/samples + config/projects/samples/ + + diff --git a/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf b/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf new file mode 100644 index 00000000000..492c51afb6e --- /dev/null +++ b/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf @@ -0,0 +1,230 @@ + + + + sftp-put-get + Y + + + - + - + 2026/10/07 10:00:00.000 + 2026/10/07 10:00:00.000 + + + + + + + N + 0 + 0 + 60 + 1 + 1 + 0 + 12 + N + Start + + SPECIAL + + 80 + 400 + N + + + + ${java.io.tmpdir}/hop-samples/sftp/hop-sftp-sample.txt + Y + N + Uploaded by Apache Hop + UTF-8 + Write file + + WRITE_TO_FILE + + 272 + 400 + N + + + + ${SFTP_SERVER} + ${SFTP_PORT} + ${SFTP_USER} + ${SFTP_PASSWORD} + /upload + ${java.io.tmpdir}/hop-samples/sftp + hop-sftp-sample\.txt + N + N + N + N + + Encrypted + none + Y + nothing + N + + + + + Encrypted + + N + N + Put a file with SFTP + + SFTPPUT + + 464 + 400 + N + + + + ${SFTP_SERVER} + ${SFTP_PORT} + ${SFTP_USER} + ${SFTP_PASSWORD} + /upload + ${java.io.tmpdir}/hop-samples/sftp/download + hop-sftp-sample\.txt + N + N + Y + N + N + Y + + Encrypted + none + + + + + Encrypted + Get a file with SFTP + + SFTP + + 656 + 400 + N + + + + Basic + + The file was uploaded and downloaded again. + Done + + WRITE_TO_LOG + + 848 + 400 + N + + + + + + Start + Write file + Y + Y + Y + + + Write file + Put a file with SFTP + Y + N + Y + + + Put a file with SFTP + Get a file with SFTP + Y + N + Y + + + Get a file with SFTP + Done + Y + N + Y + + + + + The SFTP actions transfer files over SSH: Put a file with SFTP uploads files and Get a file with SFTP downloads them. +Files are selected with a regular expression. Authentication can use a password or a private key file. + +This sample writes a file to ${java.io.tmpdir}/hop-samples/sftp, uploads it to the /upload folder and downloads it again to ${java.io.tmpdir}/hop-samples/sftp/download. + N + GENERAL + Segoe UI + 11 + N + N + 14 + 58 + 90 + 201 + 232 + 251 + 14 + 58 + 90 + 80 + 32 + 928 + 138 + + + Requires setup: this sample needs an SFTP server. Set the SFTP_SERVER, SFTP_PORT, SFTP_USER and SFTP_PASSWORD variables +(for example in an environment configuration file) before running it. +This sample is excluded from the samples integration tests. + N + GENERAL + Segoe UI + 11 + N + N + 110 + 50 + 0 + 255 + 220 + 180 + 230 + 126 + 34 + 80 + 186 + 928 + 110 + + + + From 70f41e6a048b3c8714323272cc08e970743d14d7 Mon Sep 17 00:00:00 2001 From: Bart Maertens Date: Thu, 8 Oct 2026 08:51:23 +0200 Subject: [PATCH 2/2] Issue #2238 : Sign with local_user in the PGP sample, abort on a failed Shell sample script --- .../actions/requires-setup/pgp-encrypt-decrypt-verify.hwf | 2 +- plugins/actions/shell/src/main/samples/actions/shell.hwf | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf index 90867945b2a..3497b287dcb 100644 --- a/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf +++ b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf @@ -160,7 +160,7 @@ limitations under the License. sign ${java.io.tmpdir}/hop-samples/pgp/report.csv - ${PGP_USER_ID} + ${PGP_USER_ID} ${java.io.tmpdir}/hop-samples/pgp/report.csv.asc diff --git a/plugins/actions/shell/src/main/samples/actions/shell.hwf b/plugins/actions/shell/src/main/samples/actions/shell.hwf index e2229813126..3b0cba52cbc 100644 --- a/plugins/actions/shell/src/main/samples/actions/shell.hwf +++ b/plugins/actions/shell/src/main/samples/actions/shell.hwf @@ -88,12 +88,11 @@ limitations under the License. + The script ended with an error. Error - - The script ended with an error. Script failed - WRITE_TO_LOG + ABORT 272 400