Action Plugins
Actions are the task-level building blocks of Hop workflows. Unlike transforms (which continuously process streams of rows in parallel), actions execute sequentially or conditionally as individual tasks: verifying files, executing scripts, checking database connectivity, or sending notifications.
The Two-Class Pattern
An action plugin requires only two classes:
1. ActionFoo: Extends ActionBase and implements IAction. Serves as both design-time metadata and runtime execution unit.
2. ActionFooDialog: Extends ActionBaseDialog and implements IActionDialog. The user interface configuration dialog.
1. The Action Class (ActionFoo)
Annotate the class with @Action and decorate configurable properties with @HopMetadataProperty:
import org.apache.hop.core.Result;
import org.apache.hop.core.annotations.Action;
import org.apache.hop.core.gui.plugin.GuiPlugin;
import org.apache.hop.metadata.api.HopMetadataProperty;
import org.apache.hop.workflow.action.ActionBase;
import org.apache.hop.workflow.action.IAction;
import lombok.Getter;
import lombok.Setter;
@Action(
id = "PingServer",
name = "i18n::PingServer.Name",
description = "i18n::PingServer.Description",
image = "ping-server.svg",
categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.Utility",
documentationUrl = "/workflow/actions/ping-server.html"
)
@GuiPlugin
@Getter
@Setter
public class ActionPingServer extends ActionBase implements IAction {
@HopMetadataProperty(key = "hostname")
private String hostname;
@HopMetadataProperty(key = "timeout_ms")
private int timeoutMs = 3000;
public ActionPingServer() {
this("");
}
public ActionPingServer(String name) {
super(name, "");
}
@Override
public Result execute(Result prevResult, int nr) {
Result result = prevResult;
result.setNrErrors(0);
// Resolve variables in hostname
String targetHost = resolve(hostname);
try {
logBasic("Pinging host: " + targetHost);
boolean reachable = InetAddress.getByName(targetHost).isReachable(timeoutMs);
if (reachable) {
logBasic("Host " + targetHost + " is reachable.");
result.setResult(true);
} else {
logError("Host " + targetHost + " is unreachable.");
result.setResult(false);
result.setNrErrors(1);
}
} catch (Exception e) {
logError("Error pinging " + targetHost, e);
result.setResult(false);
result.setNrErrors(1);
}
return result;
}
}
Key Action Methods
-
execute(Result prevResult, int nr): The core execution entry point. Always setresult.setResult(true/false)and updateresult.setNrErrors(…). -
isEvaluation(): Returntrueif this action can evaluate to true/false (allowing conditional hops). -
isUnconditional(): Returntrueif hops leaving this action are unconditional (like START).
2. The GUI Dialog (ActionFooDialog)
The dialog extends ActionDialog.
The name field is wName.
Annotate the action fields and build the dialog the same way as a transform.
See Annotation derived widgets, under "Transform and action dialogs".
Concrete Codebase Examples
-
plugins/actions/eval: Evaluates expressions with conditional success/failure. -
plugins/actions/deletefile: File deletion usingHopVfs. -
plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/mail/ActionMail.java: Email notifications, attachments, and authentication.