All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fluxtion.server.plugin.adminconsole.TelnetAdminCommandProcessor Maven / Gradle / Ivy

There is a newer version: 0.1.7
Show newest version
/*
 * SPDX-FileCopyrightText: © 2024 Gregory Higgins 
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package com.fluxtion.server.plugin.adminconsole;

import com.fluxtion.runtime.annotations.runtime.ServiceRegistered;
import com.fluxtion.runtime.lifecycle.Lifecycle;
import com.fluxtion.server.service.admin.AdminCommandRegistry;
import com.fluxtion.server.service.admin.AdminCommandRequest;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.jline.builtins.telnet.Telnet;
import org.jline.reader.Candidate;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.jline.utils.AttributedString;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Log4j2
public class TelnetAdminCommandProcessor implements Lifecycle {
    private AdminCommandRegistry adminCommandRegistry;
    @Getter
    @Setter
    private int listenPort = 2019;
    private Telnet telnet;

    public TelnetAdminCommandProcessor(int listenPort) {
        this.listenPort = listenPort;
    }

    public TelnetAdminCommandProcessor() {
    }

    @ServiceRegistered
    public void adminRegistry(AdminCommandRegistry adminCommandRegistry, String name) {
        log.info("Admin registry: '{}' name: '{}'", adminCommandRegistry, name);
        this.adminCommandRegistry = adminCommandRegistry;
    }

    @Override
    public void init() {

    }

    @Override
    public void start() {
        try {
            log.info("Starting Jline admin command service port: {}", listenPort);
            Terminal terminal = TerminalBuilder.terminal();
            telnet = new Telnet(terminal, this::shell);
            telnet.telnetd(new String[]{"telnetd", "-i127.0.0.1", "-p" + listenPort, "start"});
        } catch (Exception e) {
            log.error("problem starting Jline admin command service", e);
        }
    }

    @Override
    public void tearDown() {
        try {
            log.info("Stopping Jline admin command service port: {}", listenPort);
            telnet.telnetd(new String[]{"stop"});
        } catch (Exception e) {
            log.error("problem stopping Jline admin command service", e);
        }
    }

    private void shell(Terminal terminal, Map environment) {
        try {
            LineReader reader = LineReaderBuilder.builder()
                    .terminal(terminal)
                    .completer((reader1, line, candidates) -> {
                        for (String string : adminCommandRegistry.commandList()) {
                            candidates.add(new Candidate(AttributedString.stripAnsi(string), string, null, null, null, null, true));
                        }
                        candidates.add(new Candidate(AttributedString.stripAnsi("quit"), "quit", null, null, null, null, true));
                    })
                    .build();

            processCommand(terminal, new String[]{"?"});
            processCommand(terminal, new String[]{"commands"});
            while (true) {
                String line = reader.readLine("command > ").trim();
                if (line == null || line.equalsIgnoreCase("quit")) {
                    break;
                }

                String[] commandArgs = line.trim().split("\\s+");

                if (commandArgs.length > 0) {
                    reader.getHistory().add(line);
                    processCommand(terminal, commandArgs);
                }
            }
        } catch (Exception e) {
            log.error("problem executing shell", e);
        }
    }

    private void processCommand(Terminal terminal, String[] commandArgs) {
        AdminCommandRequest adminCommandRequest = new AdminCommandRequest();
        List commandArgsList = new ArrayList<>(Arrays.asList(commandArgs));
        commandArgsList.remove(0);

        adminCommandRequest.setCommand(commandArgs[0]);
        adminCommandRequest.setArguments(commandArgsList);
        adminCommandRequest.setOutput(terminal.writer()::println);
        adminCommandRequest.setErrOutput(terminal.writer()::println);

        log.info("adminCommandRequest: " + adminCommandRequest);
        if (adminCommandRegistry != null) {
            adminCommandRegistry.processAdminCommandRequest(adminCommandRequest);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy