File Commander is a file-based remote interface that allows you to inject commands into the Aspectran Daemon and control the system via the filesystem, without exposing separate management APIs or requiring direct SSH interaction. This guide explains the internal operation of File Commander and how to use it to safely manage running servers.
1. Design Philosophy and Background
Why Remote Command Injection?
Controlling a running application server (e.g., Aspectow) traditionally involves building a dedicated management API (like REST) or connecting via SSH to execute shell commands. However, these methods have limitations:
- Security Risks: Exposing management ports externally or managing SSH access permissions can create vulnerabilities.
- Integration Complexity: Implementing complex protocols is often required for external monitoring systems or automation scripts to change specific internal states of the server.
File Commander’s Approach
File Commander starts from the simple concept that “one file is one command.” By simply creating a file in a designated format within a specific directory, the daemon detects it and executes the internal logic. This reduces coupling between systems and provides a secure control channel using only the filesystem’s permission system.
2. Internal Operation and Directory Structure
File Commander uses a physically separated directory structure to manage the lifecycle of a command. All state transitions are performed via Atomic Move, which fundamentally prevents task loss or duplicate execution.
Detailed Directory Roles
incoming/(Input Queue)- The gateway for external injection. When a user creates a
.aponfile containing a control command here, the processing begins. - The poller monitors this directory at set intervals and ensures sequential processing by sorting files by name.
- The gateway for external injection. When a user creates a
queued/(Processing)- Indicates that the daemon has accepted the command and it is currently executing.
- The presence of a file in this directory is a critical status indicator meaning “task in progress or abnormally interrupted.”
completed/(Success History)- Stores the results of all successfully executed commands.
- A timestamp in the format
yyyyMMddTHHmmssSSSis added to the filename for accurate tracking of execution time.
failed/(Failure Reports)- Stores commands that failed to execute or had syntax errors.
- Rather than just keeping the file, an integrated report is generated combining the error stack trace and the original content to aid in post-mortem analysis.
3. Core Mechanics: Stability and Reliability
Step-by-Step Transaction Guarantee
File Commander does not just read files; it goes through the following sophisticated transaction steps:
- Detection and Atomic Staging: When moving a file from
incomingtoqueued, it uses Java NIO’sStandardCopyOption.ATOMIC_MOVE. Since this is performed as a single operation at the OS level, there is no risk of file corruption during copying. - Asynchronous Execution and Immediate Rollback: Commands are executed asynchronously in a separate thread pool. If execution is rejected because the thread pool is full, File Commander immediately returns the file from
queuedtoincoming. This rollback mechanism solves the ‘silent loss’ problem where commands disappear without being executed. - Automatic Error Reporting: If an error occurs during the file parsing stage, an integrated APON file is created that preserves the original content in the
sourcefield and records the detailed exception in theerrorfield.
Isolated Command
Commands such as system restart (restart) or shutdown (quit) can lead to unpredictable results if performed simultaneously with other business logic.
- Commands where
Command.isIsolated()istrueare guaranteed exclusive execution within the daemon. - If an isolated command arrives while other general tasks are running, its execution is deferred or rolled back to wait for a safe point.
Abnormal Termination Recovery (Requeue)
Even if the daemon crashes unexpectedly, the files being processed remain in the queued directory. When the daemon restarts, the requeue() process runs and restores these files to incoming. This ensures that even in the event of a system failure, every injected control command is guaranteed to be executed at least once.
4. Creating and Registering Custom Commands
Users can define their own commands according to the characteristics of their service.
Step 1: Implementation
Inherit from AbstractCommand and write the control logic in the execute method. The following example implements a feature to switch a running server to maintenance mode.
public class MaintenanceModeCommand extends AbstractCommand {
@Override
public CommandResult execute(CommandParameters parameters) {
try {
// Extract mode (on/off) from injected parameters
String mode = null;
ItemHolderParameters itemHolder = parameters.getParameters();
if (itemHolder != null) {
mode = itemHolder.getString("mode");
}
if (mode == null) {
return failed("The 'mode' parameter is required. (on/off)");
}
boolean enable = "on".equalsIgnoreCase(mode);
// Get a specific service bean from the application and change its state
MaintenanceService service = getDaemonService().getActivityContext().getBeanRegistry().getBean("maintenanceService");
service.setMaintenanceMode(enable);
String status = enable ? "enabled" : "disabled";
return success("Service maintenance mode has been " + status + ".");
} catch (Exception e) {
// Calling failed(e) automatically records the stack trace in the 'error' field.
return failed("Error changing maintenance mode", e);
}
}
@Override
public boolean isIsolated() {
return true; // Ensure exclusive execution as it is a state-changing operation
}
@Override
public Descriptor getDescriptor() {
return new CommandDescriptor("custom", "maintenance", "Control service maintenance mode");
}
}
Step 2: Registration
Register the implemented class in the aspectran-config.apon file. For details on daemon configuration, please refer to the Daemon Application Configuration (daemon) section.
daemon: {
executor: {
maxThreads: 5
}
polling: {
pollingInterval: 1000
requeuable: true
incoming: /app/cmd/incoming
enabled: true
}
commands: [
com.aspectran.undertow.daemon.command.UndertowCommand
com.aspectran.daemon.command.builtins.InvokeActionCommand
com.aspectran.daemon.command.builtins.TransletCommand
com.aspectran.daemon.command.builtins.ComponentCommand
com.aspectran.daemon.command.builtins.SysInfoCommand
com.aspectran.daemon.command.builtins.PollingIntervalCommand
com.aspectran.daemon.command.builtins.RestartCommand
com.aspectran.daemon.command.builtins.QuitCommand
com.yourpackage.MaintenanceModeCommand # Register custom command
]
}
5. Practical Command Examples (Samples)
Below are various command examples that can be used immediately in a real production environment (Aspectow). All examples follow the APON format with newlines for readability.
5.1 System and Control Settings
You can change the daemon’s operational settings in real-time or query system information.
- Change Polling Interval (
10-pollingInterval.apon)command: pollingInterval arguments: { item: { value: 4000 valueType: long } } - Query System Information (
11-sysinfo.apon)command: sysinfo arguments: { item: { value: mem } item: { value: props } }
5.2 Undertow Server Control
Manage the state of the web server remotely.
- Start Undertow Server (
20-undertow-start.apon)# Start the Undertow server command: undertow parameters: { item: { name: mode value: start } item: { name: server value: tow.server } } - Restart Undertow Server (
21-undertow-restart.apon)# Restart the Undertow server command: undertow parameters: { item: { name: mode value: restart } item: { name: server value: tow.server } }
5.3 Business Logic and Template Execution
Directly call specific functions within the application.
- Call Bean Method (
30-hello-action.apon)command: invokeAction bean: helloActivity method: helloWorld - Execute Translet (
31-hello-translet.apon)command: translet translet: hello - Render Template (
32-hello-template.apon)command: template template: hello parameters: { item: { name: what value: World } }
5.4 Monitoring Components and Tasks
Get detailed information about the resources registered in the daemon.
- Query All Translets and Details
# List all (41-translet-list-all.apon) command: component parameters: { item: { name: type, value: translet } item: { name: mode, value: list-all } } # Specific Translet details (43-translet-detail-hello.apon) command: component parameters: { item: { name: type, value: translet } item: { name: mode, value: detail } item: { type: array, name: targets, value: [ hello ] } } - Query Jobs (Scheduler) and Aspects
# List running jobs (60-job-list.apon) command: component parameters: { item: { name: type, value: job } item: { name: mode, value: list } } # Detailed Aspect information (51-aspect-detail-all.apon) command: component parameters: { item: { name: type, value: aspect } item: { name: mode, value: detail } }
5.5 Lifecycle Management
Restart or shutdown the daemon itself.
- Restart Daemon (
98-restart.apon)command: restart - Shutdown Daemon (
99-quit.apon)command: quit requeuable: false
6. Operational Considerations
Preventing Restart Loops
The requeuable property of CommandParameters is true by default. However, for the quit command that shuts down the system, if this value is true, the following situation may occur:
quitcommand injected → Daemon is forced to close while attempting to shutdown.- Daemon restarts →
requeuerestores thequitcommand toincoming. - Daemon shuts down again immediately upon startup (infinite loop).
Therefore, it is safer to explicitly set requeuable: false when issuing shutdown or destructive control commands.
7. Conclusion and Future Extensibility
Aspectran Daemon’s File Commander provides a powerful and secure remote control environment through the most universal medium: the filesystem. The enhanced atomic transaction and detailed reporting features meet the high reliability requirements of enterprise environments.
While maintaining this philosophy, File Commander is poised to evolve into a more professional distributed control system by extending the injection medium beyond the filesystem to Database (DB) or Redis-based queue services.