View Javadoc
1   package org.cyclopsgroup.jmxterm.boot;
2   
3   import org.apache.commons.lang3.StringUtils;
4   import org.cyclopsgroup.jcli.ArgumentProcessor;
5   import org.cyclopsgroup.jcli.GnuParser;
6   import org.cyclopsgroup.jmxterm.SyntaxUtils;
7   import org.cyclopsgroup.jmxterm.cc.CommandCenter;
8   import org.cyclopsgroup.jmxterm.cc.ConsoleCompletor;
9   import org.cyclopsgroup.jmxterm.io.CommandInput;
10  import org.cyclopsgroup.jmxterm.io.CommandOutput;
11  import org.cyclopsgroup.jmxterm.io.FileCommandInput;
12  import org.cyclopsgroup.jmxterm.io.FileCommandOutput;
13  import org.cyclopsgroup.jmxterm.io.InputStreamCommandInput;
14  import org.cyclopsgroup.jmxterm.io.JlineCommandInput;
15  import org.cyclopsgroup.jmxterm.io.PrintStreamCommandOutput;
16  import org.cyclopsgroup.jmxterm.io.VerboseLevel;
17  import org.jline.reader.History;
18  import org.jline.reader.LineReader;
19  import org.jline.reader.LineReaderBuilder;
20  import org.jline.reader.impl.LineReaderImpl;
21  
22  import javax.management.remote.JMXConnector;
23  import java.io.File;
24  import java.io.FileNotFoundException;
25  import java.io.IOException;
26  import java.io.PrintWriter;
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  /**
31   * Main class invoked directly from command line
32   *
33   * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
34   */
35  public class CliMain {
36    private static final PrintWriter STDOUT_WRITER = new PrintWriter(System.out, true);
37  
38    private static final String COMMAND_PROMPT = "$> ";
39  
40    public static final void main(String[] args) throws Exception {
41      System.exit(new CliMain().execute(args));
42    }
43  
44    /**
45     * Execute main class
46     *
47     * @param args Command line arguments
48     * @return Exit code
49     * @throws Exception Allow any exceptions
50     */
51    int execute(String[] args) throws Exception {
52      ArgumentProcessor<CliMainOptions> ap =
53          ArgumentProcessor.newInstance(CliMainOptions.class, new GnuParser());
54      CliMainOptions options = new CliMainOptions();
55      ap.process(args, options);
56      if (options.isHelp()) {
57        ap.printHelp(STDOUT_WRITER);
58        return 0;
59      }
60  
61      VerboseLevel verboseLevel;
62      if (options.getVerboseLevel() != null) {
63        verboseLevel = VerboseLevel.valueOf(options.getVerboseLevel().toUpperCase());
64      } else {
65        verboseLevel = null;
66      }
67  
68      CommandOutput output;
69      if (StringUtils.equals(options.getOutput(), CliMainOptions.STDOUT)) {
70        output = new PrintStreamCommandOutput(System.out, System.err);
71      } else {
72        File outputFile = new File(options.getOutput());
73        output = new FileCommandOutput(outputFile, options.isAppendToOutput());
74      }
75      try {
76        CommandInput input;
77        if (options.getInput().equals(CliMainOptions.STDIN)) {
78          if (options.isNonInteractive()) {
79            input = new InputStreamCommandInput(System.in);
80          } else {
81            LineReaderImpl consoleReader = (LineReaderImpl) LineReaderBuilder.builder().build();
82            File historyFile = new File(System.getProperty("user.home"), ".jmxterm_history");
83            consoleReader.setVariable(LineReader.HISTORY_FILE, historyFile);
84            final History history = consoleReader.getHistory();
85            history.load();
86            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
87              @Override
88              public void run() {
89                try {
90                  history.save();
91                } catch (IOException e) {
92                  System.err.println("Failed to flush command history! " + e);
93                }
94              }
95            }));
96            input = new JlineCommandInput(consoleReader, COMMAND_PROMPT);
97          }
98        } else {
99          File inputFile = new File(options.getInput());
100         if (!inputFile.isFile()) {
101           throw new FileNotFoundException("File " + inputFile + " is not a valid file");
102         }
103         input = new FileCommandInput(new File(options.getInput()));
104       }
105       try {
106         CommandCenter commandCenter = new CommandCenter(output, input);
107         if (input instanceof JlineCommandInput) {
108           ((JlineCommandInput) input).getConsole()
109               .setCompleter(new ConsoleCompletor(commandCenter));
110         }
111         if (options.getUrl() != null) {
112           Map<String, Object> env;
113           if (options.getUser() != null) {
114             env = new HashMap<String, Object>(1);
115             String password = options.getPassword();
116             if (password == null) {
117               password = input.readMaskedString("Authentication password: ");
118             }
119             String[] credentials = {options.getUser(), password};
120             env.put(JMXConnector.CREDENTIALS, credentials);
121           } else {
122             env = null;
123           }
124           commandCenter.connect(
125               SyntaxUtils.getUrl(options.getUrl(), commandCenter.getProcessManager()), env);
126         }
127         if (verboseLevel != null) {
128           commandCenter.setVerboseLevel(verboseLevel);
129         }
130         if (verboseLevel != VerboseLevel.SILENT) {
131           output.printMessage("Welcome to JMX terminal. Type \"help\" for available commands.");
132         }
133         String line;
134         int exitCode = 0;
135         int lineNumber = 0;
136         while ((line = input.readLine()) != null) {
137           lineNumber++;
138           if (!commandCenter.execute(line) && options.isExitOnFailure()) {
139             exitCode = -lineNumber;
140             break;
141           }
142           if (commandCenter.isClosed()) {
143             break;
144           }
145         }
146         commandCenter.close();
147         return exitCode;
148       } finally {
149         input.close();
150       }
151     } finally {
152       output.close();
153     }
154   }
155 }