001    /* ============================================================
002     * JRobin : Pure java implementation of RRDTool's functionality
003     * ============================================================
004     *
005     * Project Info:  http://www.jrobin.org
006     * Project Lead:  Sasa Markovic (saxon@jrobin.org);
007     *
008     * (C) Copyright 2003-2005, by Sasa Markovic.
009     *
010     * Developers:    Sasa Markovic (saxon@jrobin.org)
011     *
012     *
013     * This library is free software; you can redistribute it and/or modify it under the terms
014     * of the GNU Lesser General Public License as published by the Free Software Foundation;
015     * either version 2.1 of the License, or (at your option) any later version.
016     *
017     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
018     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
019     * See the GNU Lesser General Public License for more details.
020     *
021     * You should have received a copy of the GNU Lesser General Public License along with this
022     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
023     * Boston, MA 02111-1307, USA.
024     */
025    
026    package org.jrobin.cmd;
027    
028    import org.jrobin.core.RrdException;
029    
030    import java.io.BufferedReader;
031    import java.io.File;
032    import java.io.IOException;
033    import java.io.InputStreamReader;
034    
035    /**
036     * Class to be used to execute various RRDTool commands (original syntax of RRDTool 1.0.x must be used).
037     * Currently supported commands are CREATE, UPDATE, LAST, FETCH, DUMP, RESTORE, XPORT, GRAPH, TUNE, INFO
038     */
039    public class RrdCommander {
040            private static final RrdToolCmd[] rrdCommands = {
041                            new RrdCreateCmd(),
042                            new RrdUpdateCmd(),
043                            new RrdLastCmd(),
044                            new RrdFetchCmd(),
045                            new RrdDumpCmd(),
046                            new RrdRestoreCmd(),
047                            new RrdXportCmd(),
048                            new RrdGraphCmd(),
049                            new RrdTuneCmd(),
050                            new RrdInfoCmd()
051            };
052    
053            /**
054             * Checks if the output from any RRDTool command will be visible on the standard output device
055             * (console). Default setting is <code>true</code>.
056             *
057             * @return true, if the output will be visible on the standard output device; false, otherwise.
058             */
059            public static synchronized boolean isStandardOutUsed() {
060                    return RrdToolCmd.isStandardOutUsed();
061            }
062    
063            /**
064             * Method used to control access to stdout (System.out, console) for all RRDTool commands. By default,
065             * all RRDTool commands are allowed to print results to stdout, in a form used by RRDTool.
066             *
067             * @param standardOutUsed <code>true</code> if the output should be visible on the
068             *                        standard output device, <code>false</code> otherwise.
069             */
070            public static synchronized void setStandardOutUsed(boolean standardOutUsed) {
071                    RrdToolCmd.setStandardOutUsed(standardOutUsed);
072            }
073    
074            /**
075             * Checks if the class uses {@link org.jrobin.core.RrdDbPool} internally while executing
076             * RRDTool commands.
077             *
078             * @return true if the pool is used, false otherwise
079             */
080            public static synchronized boolean isRrdDbPoolUsed() {
081                    return RrdToolCmd.isRrdDbPoolUsed();
082            }
083    
084            /**
085             * Forces or prohibits {@link org.jrobin.core.RrdDbPool} usage internally while executing
086             * RRDTool commands
087             *
088             * @param rrdDbPoolUsed true, to force pool usage, false otherwise.
089             */
090            public static synchronized void setRrdDbPoolUsed(boolean rrdDbPoolUsed) {
091                    RrdToolCmd.setRrdDbPoolUsed(rrdDbPoolUsed);
092            }
093    
094            /**
095             * Executes single RRDTool command. The command string should start with some
096             * well known RRDTool command word (create, update, fetch, graph...)<p>
097             *
098             * @param command RRDTool command like: <p>
099             *                <pre>
100             *                create test.rrd --start "noon yesterday" --step 300 DS:x:GAUGE:600:U:U RRA:AVERAGE:0.5:5:1000
101             *                update test.rrd N:1000
102             *                last test.rrd
103             *                ...
104             *                </pre>
105             * @return Result of specific RRDTool command. It is guaranteed that the result of any
106             *         successfully executed command will be always different from null.
107             *         Unsuccessfully executed commands will always throw
108             *         an exception, so you need not check for null results.<p>
109             *         Exact type of the result depends from the
110             *         type of executed RRDTool command:<p>
111             *         <ul>
112             *         <li><b>create</b>: returns java.lang.String containing path to the newly created RRD file.
113             *         <li><b>last</b>: returns java.lang.Long representing timestamp of the last update.
114             *         <li><b>update</b>: returns java.lang.Long representing timestamp of the last update.
115             *         <li><b>dump</b>: returns (very long) java.lang.String representing the content of a RRD file
116             *         in XML format.
117             *         <li><b>fetch</b>: returns {@link org.jrobin.core.FetchData} object representing fetched data.
118             *         <li><b>restore</b>: returns path to the restored RRD file.
119             *         <li><b>xport</b>: returns java.lang.String containing exported data
120             *         <li><b>graph</b>: returns {@link org.jrobin.graph.RrdGraphInfo} object containing graph info
121             *         <li><b>tune</b>: returns path to the tuned RRD file
122             *         </ul>
123             * @throws IOException  thrown in case of I/O error
124             * @throws RrdException thrown for all other errors (parsing errors,
125             *                      unknown RRDTool syntax/command/option, internal RRD errors...)
126             */
127            public static synchronized Object execute(String command) throws IOException, RrdException {
128                    String cmd = command.trim(), rrdtool = "rrdtool ";
129                    if (cmd.startsWith(rrdtool)) {
130                            cmd = cmd.substring(rrdtool.length());
131                    }
132                    for (RrdToolCmd rrdCommand : rrdCommands) {
133                            if (cmd.startsWith(rrdCommand.getCmdType() + " ")) {
134                                    return rrdCommand.executeCommand(cmd);
135                            }
136                    }
137                    throw new RrdException("Unknown RRDTool command: " + command);
138            }
139    
140            /**
141             * A small demo which allows you to pass arbitrary RRDTool commands to JRobin
142             *
143             * @param args Not used
144             * @throws IOException
145             */
146            public static void main(String[] args) throws IOException {
147                    System.out.println("== JRobin's RRDTool commander ==");
148                    System.out.println("Type a RRDTool command after the dollar sign and press Enter.");
149                    System.out.println("Start your RRDTool command with 'create', 'update', 'fetch' etc.");
150                    System.out.println("Start line with 'create', 'update', 'fetch' etc.");
151                    System.out.println("Enter dot ('.') to bail out");
152                    System.out.println("Current directory is: " + new File(".").getCanonicalPath());
153                    System.out.println("================================");
154                    RrdToolCmd.setRrdDbPoolUsed(false);
155                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
156                    while (true) {
157                            try {
158                                    System.out.print("$ ");
159                                    String s = r.readLine().trim();
160                                    if (s.length() > 0) {
161                                            if (!s.startsWith(".")) {
162                                                    execute(s);
163                                            }
164                                            else {
165                                                    break;
166                                            }
167                                    }
168                            }
169                            catch (Exception e) {
170                                    e.printStackTrace(System.err);
171                            }
172                    }
173            }
174    }