Interface CommandExecutable


public interface CommandExecutable
Mixin interface providing command execution actions via @Action annotations.

This interface demonstrates the mixin pattern in Java using interface default methods with Action annotations. Classes implementing this interface automatically gain the ability to execute commands from workflow YAML without duplicating code.

Usage

Implement this interface and provide a CommandExecutor:

public class NodeInterpreter extends Interpreter implements CommandExecutable {
    private final CommandExecutor executor;

    public NodeInterpreter(Node node, IIActorSystem system) {
        this.executor = new SshCommandExecutor(node);
    }

    @Override
    public CommandExecutor getCommandExecutor() {
        return executor;
    }
}

Workflow YAML

Once implemented, the following actions become available in workflow YAML:

steps:
  - states: ["0", "1"]
    actions:
      - actor: this
        method: executeCommand
        arguments: ["ls -la"]

  - states: ["1", "2"]
    actions:
      - actor: this
        method: executeSudoCommand
        arguments: ["apt-get update"]

Design Rationale

This interface solves the problem of code duplication between NodeInterpreter and NodeGroupInterpreter. Previously, each class needed its own implementation of command execution actions. With this mixin approach:

  • Both classes implement the same interface
  • The @Action methods are defined once in the interface
  • Each class provides its own CommandExecutor (SSH or local)
  • IIActorRef discovers the @Action methods via reflection
Since:
2.15.0
Author:
devteam@scivicslab.com
See Also:
  • Method Details

    • getCommandExecutor

      Returns the command executor for this instance.

      Implementing classes must provide an appropriate executor:

      Returns:
      the command executor
    • getOutputCallback

      Returns an optional output callback for command execution.

      When not null, command output is streamed to this callback in real-time. Default implementation returns null (no streaming).

      Returns:
      the output callback, or null
    • doExecuteCommand

      default com.scivicslab.pojoactor.core.ActionResult doExecuteCommand(String args)
      Executes a command and returns the result (action handler).

      This action is callable from workflow YAML as:

      - actor: this
        method: executeCommand
        arguments: ["your-command-here"]
      

      Note: The Java method name is different from the action name to avoid conflicts with existing methods on implementing classes that have different return types.

      Parameters:
      args - JSON array containing the command as the first element
      Returns:
      ActionResult with success status and command output
    • doExecuteSudoCommand

      default com.scivicslab.pojoactor.core.ActionResult doExecuteSudoCommand(String args)
      Executes a command with sudo privileges (action handler).

      This action is callable from workflow YAML as:

      - actor: this
        method: executeSudoCommand
        arguments: ["your-command-here"]
      

      Requires SUDO_PASSWORD environment variable to be set.

      Note: The Java method name is different from the action name to avoid conflicts with existing methods on implementing classes that have different return types.

      Parameters:
      args - JSON array containing the command as the first element
      Returns:
      ActionResult with success status and command output
    • extractCommand

      private static String extractCommand(String args)
      Extracts the command string from JSON array arguments.
      Parameters:
      args - JSON array string (e.g., '["ls -la"]')
      Returns:
      the extracted command string
    • toActionResult

      private static com.scivicslab.pojoactor.core.ActionResult toActionResult(Node.CommandResult result)
      Converts a Node.CommandResult to ActionResult.
      Parameters:
      result - the command result
      Returns:
      the action result