tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hj...@apache.org
Subject [22/30] TAJO-1141: Refactor the packages hierarchy of tajo-client.
Date Wed, 05 Nov 2014 09:52:18 GMT
http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
deleted file mode 100644
index c732fd9..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCli.java
+++ /dev/null
@@ -1,690 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.protobuf.ServiceException;
-import jline.UnsupportedTerminal;
-import jline.console.ConsoleReader;
-import org.apache.commons.cli.*;
-import org.apache.tajo.*;
-import org.apache.tajo.TajoProtos.QueryState;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.client.*;
-import org.apache.tajo.conf.TajoConf;
-import org.apache.tajo.conf.TajoConf.ConfVars;
-import org.apache.tajo.ipc.ClientProtos;
-import org.apache.tajo.util.FileUtil;
-
-import java.io.*;
-import java.lang.reflect.Constructor;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import static org.apache.tajo.cli.ParsedResult.StatementType.META;
-import static org.apache.tajo.cli.ParsedResult.StatementType.STATEMENT;
-import static org.apache.tajo.cli.SimpleParser.ParsingState;
-
-public class TajoCli {
-  public static final String ERROR_PREFIX = "ERROR: ";
-  public static final String KILL_PREFIX = "KILL: ";
-
-  private final TajoConf conf;
-  private TajoClient client;
-  private final TajoCliContext context;
-
-  // Jline and Console related things
-  private final ConsoleReader reader;
-  private final InputStream sin;
-  private final PrintWriter sout;
-  private TajoFileHistory history;
-
-  // Current States
-  private String currentDatabase;
-
-  private TajoCliOutputFormatter displayFormatter;
-
-  private boolean wasError = false;
-
-  private static final Class [] registeredCommands = {
-      DescTableCommand.class,
-      DescFunctionCommand.class,
-      HelpCommand.class,
-      ExitCommand.class,
-      CopyrightCommand.class,
-      VersionCommand.class,
-      ConnectDatabaseCommand.class,
-      ListDatabaseCommand.class,
-      SetCommand.class,
-      UnsetCommand.class,
-      ExecExternalShellCommand.class,
-      HdfsCommand.class,
-      TajoAdminCommand.class,
-      TajoGetConfCommand.class,
-      TajoHAAdminCommand.class
-  };
-  private final Map<String, TajoShellCommand> commands = new TreeMap<String, TajoShellCommand>();
-
-  protected static final Options options;
-  private static final String HOME_DIR = System.getProperty("user.home");
-  private static final String HISTORY_FILE = ".tajo_history";
-
-  static {
-    options = new Options();
-    options.addOption("c", "command", true, "execute only single command, then exit");
-    options.addOption("f", "file", true, "execute commands from file, then exit");
-    options.addOption("h", "host", true, "Tajo server host");
-    options.addOption("p", "port", true, "Tajo server port");
-    options.addOption("B", "background", false, "execute as background process");
-    options.addOption("conf", "conf", true, "configuration value");
-    options.addOption("param", "param", true, "parameter value in SQL file");
-    options.addOption("help", "help", false, "help");
-  }
-
-  public class TajoCliContext extends OverridableConf {
-    public TajoCliContext(TajoConf conf) {
-      super(conf, ConfigKey.ConfigType.SESSION);
-    }
-
-    public TajoClient getTajoClient() {
-      return client;
-    }
-
-    public void setCurrentDatabase(String databasae) {
-      currentDatabase = databasae;
-    }
-
-    public String getCurrentDatabase() {
-      return currentDatabase;
-    }
-
-    public PrintWriter getOutput() {
-      return sout;
-    }
-
-    public TajoConf getConf() {
-      return conf;
-    }
-
-    @VisibleForTesting
-    public String getCliSideVar(String key) {
-      if (SessionVars.exists(key)) {
-        ConfigKey configKey = SessionVars.get(key);
-        return get(configKey);
-      } else {
-        return get(key);
-      }
-    }
-
-    public void setCliSideVar(String key, String value) {
-      Preconditions.checkNotNull(key);
-      Preconditions.checkNotNull(value);
-
-      boolean shouldReloadFormatter = false;
-
-      if (SessionVars.exists(key)) {
-        SessionVars configKey = SessionVars.get(key);
-        put(configKey, value);
-        shouldReloadFormatter = configKey.getMode() == SessionVars.VariableMode.CLI_SIDE_VAR;
-      } else {
-        set(key, value);
-
-        // It is hard to recognize it is a client side variable. So, we always reload formatter.
-        shouldReloadFormatter = true;
-      }
-
-      if (shouldReloadFormatter) {
-        try {
-          initFormatter();
-        } catch (Exception e) {
-          System.err.println(ERROR_PREFIX + e.getMessage());
-        }
-      }
-    }
-
-    public Map<String, TajoShellCommand> getCommands() {
-      return commands;
-    }
-  }
-
-  public TajoCli(TajoConf c, String [] args, InputStream in, OutputStream out) throws Exception {
-    CommandLineParser parser = new PosixParser();
-    CommandLine cmd = parser.parse(options, args);
-
-    this.conf = new TajoConf(c);
-    context = new TajoCliContext(conf);
-    this.sin = in;
-    if (cmd.hasOption("B")) {
-      this.reader = new ConsoleReader(sin, out, new UnsupportedTerminal());
-    } else {
-      this.reader = new ConsoleReader(sin, out);
-    }
-
-    this.reader.setExpandEvents(false);
-    this.sout = new PrintWriter(reader.getOutput());
-    initFormatter();
-
-    if (cmd.hasOption("help")) {
-      printUsage();
-      System.exit(0);
-    }
-
-    String hostName = null;
-    Integer port = null;
-    if (cmd.hasOption("h")) {
-      hostName = cmd.getOptionValue("h");
-    }
-    if (cmd.hasOption("p")) {
-      port = Integer.parseInt(cmd.getOptionValue("p"));
-    }
-
-    String baseDatabase = null;
-    if (cmd.getArgList().size() > 0) {
-      baseDatabase = (String) cmd.getArgList().get(0);
-    }
-
-    if (cmd.getOptionValues("conf") != null) {
-      processConfVarCommand(cmd.getOptionValues("conf"));
-    }
-
-    // if there is no "-h" option,
-    if(hostName == null) {
-      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        hostName = conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
-      }
-    }
-    if (port == null) {
-      if (conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
-        // it checks if the client service address is given in configuration and distributed mode.
-        // if so, it sets entryAddr.
-        port = Integer.parseInt(conf.getVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
-      }
-    }
-
-    if ((hostName == null) ^ (port == null)) {
-      System.err.println(ERROR_PREFIX + "cannot find valid Tajo server address");
-      throw new RuntimeException("cannot find valid Tajo server address");
-    } else if (hostName != null && port != null) {
-      conf.setVar(ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
-      client = new TajoClientImpl(conf, baseDatabase);
-    } else if (hostName == null && port == null) {
-      client = new TajoClientImpl(conf, baseDatabase);
-    }
-
-    try {
-      checkMasterStatus();
-      context.setCurrentDatabase(client.getCurrentDatabase());
-      initHistory();
-      initCommands();
-
-      if (cmd.getOptionValues("conf") != null) {
-        processSessionVarCommand(cmd.getOptionValues("conf"));
-      }
-
-      if (cmd.hasOption("c")) {
-        displayFormatter.setScirptMode();
-        int exitCode = executeScript(cmd.getOptionValue("c"));
-        sout.flush();
-        System.exit(exitCode);
-      }
-      if (cmd.hasOption("f")) {
-        displayFormatter.setScirptMode();
-        cmd.getOptionValues("");
-        File sqlFile = new File(cmd.getOptionValue("f"));
-        if (sqlFile.exists()) {
-          String script = FileUtil.readTextFile(new File(cmd.getOptionValue("f")));
-          script = replaceParam(script, cmd.getOptionValues("param"));
-          int exitCode = executeScript(script);
-          sout.flush();
-          System.exit(exitCode);
-        } else {
-          System.err.println(ERROR_PREFIX + "No such a file \"" + cmd.getOptionValue("f") + "\"");
-          System.exit(-1);
-        }
-      }
-    } catch (Exception e) {
-      System.err.println(ERROR_PREFIX + "Exception was thrown. Caused by " + e.getMessage());
-      
-      if (client != null) {
-        client.close();
-      }
-      
-      throw e;
-    }
-
-    addShutdownHook();
-  }
-
-  private void processConfVarCommand(String[] confCommands) throws ServiceException {
-    for (String eachParam: confCommands) {
-      String[] tokens = eachParam.split("=");
-      if (tokens.length != 2) {
-        continue;
-      }
-
-      if (!SessionVars.exists(tokens[0])) {
-        conf.set(tokens[0], tokens[1]);
-      }
-    }
-  }
-
-  private void processSessionVarCommand(String[] confCommands) throws ServiceException {
-    for (String eachParam: confCommands) {
-      String[] tokens = eachParam.split("=");
-      if (tokens.length != 2) {
-        continue;
-      }
-
-      if (SessionVars.exists(tokens[0])) {
-        ((SetCommand)commands.get("\\set")).set(tokens[0], tokens[1]);
-      }
-    }
-  }
-
-  private void initFormatter() throws Exception {
-    Class formatterClass = context.getClass(SessionVars.CLI_FORMATTER_CLASS);
-    if (displayFormatter == null || !displayFormatter.getClass().equals(formatterClass)) {
-      displayFormatter = (TajoCliOutputFormatter)formatterClass.newInstance();
-    }
-    displayFormatter.init(context);
-  }
-
-  public TajoCliContext getContext() {
-    return context;
-  }
-
-  protected static String replaceParam(String script, String[] params) {
-    if (params == null || params.length == 0) {
-      return script;
-    }
-
-    for (String eachParam: params) {
-      String[] tokens = eachParam.split("=");
-      if (tokens.length != 2) {
-        continue;
-      }
-      script = script.replace("${" + tokens[0] + "}", tokens[1]);
-    }
-
-    return script;
-  }
-
-  private void initHistory() {
-    try {
-      String historyPath = HOME_DIR + File.separator + HISTORY_FILE;
-      if ((new File(HOME_DIR)).exists()) {
-        history = new TajoFileHistory(new File(historyPath));
-        reader.setHistory(history);
-      } else {
-        System.err.println(ERROR_PREFIX + "home directory : '" + HOME_DIR +"' does not exist.");
-      }
-    } catch (Exception e) {
-      System.err.println(ERROR_PREFIX + e.getMessage());
-    }
-  }
-
-  private void initCommands() {
-    for (Class clazz : registeredCommands) {
-      TajoShellCommand cmd = null;
-      try {
-         Constructor cons = clazz.getConstructor(new Class[] {TajoCliContext.class});
-         cmd = (TajoShellCommand) cons.newInstance(context);
-      } catch (Exception e) {
-        System.err.println(e.getMessage());
-        throw new RuntimeException(e.getMessage());
-      }
-      commands.put(cmd.getCommand(), cmd);
-      for (String alias : cmd.getAliases()) {
-        commands.put(alias, cmd);
-      }
-    }
-  }
-
-  private void addShutdownHook() {
-    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          history.flush();
-        } catch (IOException e) {
-        }
-        client.close();
-      }
-    }));
-  }
-
-  private String updatePrompt(ParsingState state) throws ServiceException {
-    if (state == ParsingState.WITHIN_QUOTE) {
-      return "'";
-    } else if (state == ParsingState.TOK_START) {
-      return context.getCurrentDatabase();
-    } else {
-      return "";
-    }
-  }
-
-  public int runShell() throws Exception {
-    String line;
-    String currentPrompt = context.getCurrentDatabase();
-    int exitCode = 0;
-
-    sout.write("Try \\? for help.\n");
-
-    SimpleParser parser = new SimpleParser();
-    
-    try {
-      while((line = reader.readLine(currentPrompt + "> ")) != null) {
-        if (line.equals("")) {
-          continue;
-        }
-        wasError = false;
-        if (line.startsWith("{")) {
-          executeJsonQuery(line);
-        } else {
-          List<ParsedResult> parsedResults = parser.parseLines(line);
-
-          if (parsedResults.size() > 0) {
-            for (ParsedResult parsed : parsedResults) {
-              history.addStatement(parsed.getHistoryStatement() + (parsed.getType() == STATEMENT ? ";" : ""));
-            }
-          }
-
-          exitCode = executeParsedResults(parsedResults);
-          currentPrompt = updatePrompt(parser.getState());
-
-          if (exitCode != 0 && context.getBool(SessionVars.ON_ERROR_STOP)) {
-            return exitCode;
-          }
-        }
-      }
-    } catch (Exception e) {
-      System.err.println(ERROR_PREFIX + "Exception was thrown. Casued by " + e.getMessage());
-      
-      if (client != null) {
-        client.close();
-      }
-      
-      throw e;
-    }
-    return exitCode;
-  }
-
-  private int executeParsedResults(Collection<ParsedResult> parsedResults) throws Exception {
-    int exitCode = 0;
-    for (ParsedResult parsedResult : parsedResults) {
-      if (parsedResult.getType() == META) {
-        exitCode = executeMetaCommand(parsedResult.getStatement());
-      } else {
-        exitCode = executeQuery(parsedResult.getStatement());
-      }
-
-      if (exitCode != 0) {
-        return exitCode;
-      }
-    }
-
-    return exitCode;
-  }
-
-  public int executeMetaCommand(String line) throws Exception {
-    checkMasterStatus();
-    String [] metaCommands = line.split(";");
-    for (String metaCommand : metaCommands) {
-      String arguments [] = metaCommand.split(" ");
-
-      TajoShellCommand invoked = commands.get(arguments[0]);
-      if (invoked == null) {
-        printInvalidCommand(arguments[0]);
-        wasError = true;
-        return -1;
-      }
-
-      try {
-        invoked.invoke(arguments);
-      } catch (IllegalArgumentException ige) {
-        displayFormatter.printErrorMessage(sout, ige);
-        wasError = true;
-        return -1;
-      } catch (Exception e) {
-        displayFormatter.printErrorMessage(sout, e);
-        wasError = true;
-        return -1;
-      } finally {
-        context.getOutput().flush();
-      }
-
-      if (wasError && context.getBool(SessionVars.ON_ERROR_STOP)) {
-        break;
-      }
-    }
-
-    return 0;
-  }
-
-  private void executeJsonQuery(String json) throws ServiceException, IOException {
-    checkMasterStatus();
-    long startTime = System.currentTimeMillis();
-    ClientProtos.SubmitQueryResponse response = client.executeQueryWithJson(json);
-    if (response == null) {
-      displayFormatter.printErrorMessage(sout, "response is null");
-      wasError = true;
-    } else if (response.getResultCode() == ClientProtos.ResultCode.OK) {
-      if (response.getIsForwarded()) {
-        QueryId queryId = new QueryId(response.getQueryId());
-        waitForQueryCompleted(queryId);
-      } else {
-        if (!response.hasTableDesc() && !response.hasResultSet()) {
-          displayFormatter.printMessage(sout, "OK");
-          wasError = true;
-        } else {
-          localQueryCompleted(response, startTime);
-        }
-      }
-    } else {
-      if (response.hasErrorMessage()) {
-        displayFormatter.printErrorMessage(sout, response.getErrorMessage());
-        wasError = true;
-      }
-    }
-  }
-
-  private int executeQuery(String statement) throws ServiceException, IOException {
-    checkMasterStatus();
-    long startTime = System.currentTimeMillis();
-    ClientProtos.SubmitQueryResponse response = null;
-    try{
-      response = client.executeQuery(statement);
-    } catch (ServiceException e){
-      displayFormatter.printErrorMessage(sout, e.getMessage());
-      wasError = true;
-    } catch(Throwable te){
-      displayFormatter.printErrorMessage(sout, te);
-      wasError = true;
-    }
-
-    if (response == null) {
-      displayFormatter.printErrorMessage(sout, "response is null");
-      wasError = true;
-    } else if (response.getResultCode() == ClientProtos.ResultCode.OK) {
-      if (response.getIsForwarded()) {
-        QueryId queryId = new QueryId(response.getQueryId());
-        waitForQueryCompleted(queryId);
-      } else {
-        if (!response.hasTableDesc() && !response.hasResultSet()) {
-          displayFormatter.printMessage(sout, "OK");
-        } else {
-          localQueryCompleted(response, startTime);
-        }
-      }
-    } else {
-      if (response.hasErrorMessage()) {
-        displayFormatter.printErrorMessage(sout, response.getErrorMessage());
-        wasError = true;
-      }
-    }
-
-    return wasError ? -1 : 0;
-  }
-
-  private void localQueryCompleted(ClientProtos.SubmitQueryResponse response, long startTime) {
-    ResultSet res = null;
-    try {
-      QueryId queryId = new QueryId(response.getQueryId());
-      float responseTime = ((float)(System.currentTimeMillis() - startTime) / 1000.0f);
-      TableDesc desc = new TableDesc(response.getTableDesc());
-
-      // non-forwarded INSERT INTO query does not have any query id.
-      // In this case, it just returns succeeded query information without printing the query results.
-      if (response.getMaxRowNum() < 0 && queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-        displayFormatter.printResult(sout, sin, desc, responseTime, res);
-      } else {
-        res = TajoClientUtil.createResultSet(conf, client, response);
-        displayFormatter.printResult(sout, sin, desc, responseTime, res);
-      }
-    } catch (Throwable t) {
-      displayFormatter.printErrorMessage(sout, t);
-      wasError = true;
-    } finally {
-      if (res != null) {
-        try {
-          res.close();
-        } catch (SQLException e) {
-        }
-      }
-    }
-  }
-
-  private void waitForQueryCompleted(QueryId queryId) {
-    // if query is empty string
-    if (queryId.equals(QueryIdFactory.NULL_QUERY_ID)) {
-      return;
-    }
-
-    // query execute
-    ResultSet res = null;
-    QueryStatus status = null;
-    try {
-
-      int initRetries = 0;
-      int progressRetries = 0;
-      while (true) {
-        // TODO - configurable
-        status = client.getQueryStatus(queryId);
-        if(TajoClientUtil.isQueryWaitingForSchedule(status.getState())) {
-          Thread.sleep(Math.min(20 * initRetries, 1000));
-          initRetries++;
-          continue;
-        }
-
-        if (TajoClientUtil.isQueryRunning(status.getState()) || status.getState() == QueryState.QUERY_SUCCEEDED) {
-          displayFormatter.printProgress(sout, status);
-        }
-
-        if (TajoClientUtil.isQueryComplete(status.getState()) && status.getState() != QueryState.QUERY_KILL_WAIT) {
-          break;
-        } else {
-          Thread.sleep(Math.min(200 * progressRetries, 1000));
-          progressRetries += 2;
-        }
-      }
-
-      if (status.getState() == QueryState.QUERY_ERROR || status.getState() == QueryState.QUERY_FAILED) {
-        displayFormatter.printErrorMessage(sout, status);
-        wasError = true;
-      } else if (status.getState() == QueryState.QUERY_KILLED) {
-        displayFormatter.printKilledMessage(sout, queryId);
-        wasError = true;
-      } else {
-        if (status.getState() == QueryState.QUERY_SUCCEEDED) {
-          float responseTime = ((float)(status.getFinishTime() - status.getSubmitTime()) / 1000.0f);
-          ClientProtos.GetQueryResultResponse response = client.getResultResponse(queryId);
-          if (status.hasResult()) {
-            res = TajoClientUtil.createResultSet(conf, client, queryId, response);
-            TableDesc desc = new TableDesc(response.getTableDesc());
-            displayFormatter.printResult(sout, sin, desc, responseTime, res);
-          } else {
-            TableDesc desc = new TableDesc(response.getTableDesc());
-            displayFormatter.printResult(sout, sin, desc, responseTime, res);
-          }
-        }
-      }
-    } catch (Throwable t) {
-      displayFormatter.printErrorMessage(sout, t);
-      wasError = true;
-    } finally {
-      if (res != null) {
-        try {
-          res.close();
-        } catch (SQLException e) {
-        }
-      } else {
-        if (status != null && status.getQueryId() != null) {
-          client.closeQuery(status.getQueryId());
-        }
-      }
-    }
-  }
-
-  public int executeScript(String script) throws Exception {
-    wasError = false;
-    List<ParsedResult> results = SimpleParser.parseScript(script);
-    return executeParsedResults(results);
-  }
-
-  private void printUsage() {
-    HelpFormatter formatter = new HelpFormatter();
-    formatter.printHelp("tsql [options] [database]", options);
-  }
-
-  private void printInvalidCommand(String command) {
-    sout.println("Invalid command " + command + ". Try \\? for help.");
-  }
-
-  public void close() {
-    //for testcase
-    if (client != null) {
-      client.close();
-    }
-  }
-
-  private void checkMasterStatus() throws IOException, ServiceException {
-    String sessionId = client.getSessionId() != null ? client.getSessionId().getId() : null;
-    client = TajoHAClientUtil.getTajoClient(conf, client, context);
-    if(sessionId != null && (client.getSessionId() == null ||
-        !sessionId.equals(client.getSessionId().getId()))) {
-      commands.clear();
-      initHistory();
-      initCommands();
-    }
-  }
-
-  public static void main(String [] args) throws Exception {
-    TajoConf conf = new TajoConf();
-    TajoCli shell = new TajoCli(conf, args, System.in, System.out);
-    System.out.println();
-    System.exit(shell.runShell());
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCliOutputFormatter.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCliOutputFormatter.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoCliOutputFormatter.java
deleted file mode 100644
index 0ad89f2..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoCliOutputFormatter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import org.apache.tajo.QueryId;
-import org.apache.tajo.catalog.TableDesc;
-import org.apache.tajo.client.QueryStatus;
-
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.sql.ResultSet;
-
-public interface TajoCliOutputFormatter {
-  /**
-   * Initialize formatter
-   * @param context
-   */
-  public void init(TajoCli.TajoCliContext context);
-
-  /**
-   * print query result to console
-   * @param sout
-   * @param sin
-   * @param tableDesc
-   * @param responseTime
-   * @param res
-   * @throws Exception
-   */
-  public void printResult(PrintWriter sout, InputStream sin, TableDesc tableDesc,
-                          float responseTime, ResultSet res) throws Exception;
-
-  /**
-   * print no result message
-   * @param sout
-   */
-  public void printNoResult(PrintWriter sout);
-
-  /**
-   * print simple message
-   * @param sout
-   * @param message
-   */
-  public void printMessage(PrintWriter sout, String message);
-
-  /**
-   * print query progress message
-   * @param sout
-   * @param status
-   */
-  public void printProgress(PrintWriter sout, QueryStatus status);
-
-  /**
-   * print error message
-   * @param sout
-   * @param t
-   */
-  public void printErrorMessage(PrintWriter sout, Throwable t);
-
-  /**
-   * print error message
-   * @param sout
-   * @param message
-   */
-  public void printErrorMessage(PrintWriter sout, String message);
-
-  /**
-   * print error message
-   * @param sout
-   * @param queryId
-   */
-  public void printKilledMessage(PrintWriter sout, QueryId queryId);
-
-  /**
-   * print query status error message
-   * @param sout
-   * @param status
-   */
-  void printErrorMessage(PrintWriter sout, QueryStatus status);
-
-  void setScirptMode();
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoFileHistory.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoFileHistory.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoFileHistory.java
deleted file mode 100644
index 3257f28..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoFileHistory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import jline.console.history.FileHistory;
-
-import java.io.File;
-import java.io.IOException;
-
-public class TajoFileHistory extends FileHistory {
-
-  public TajoFileHistory(File file) throws IOException {
-    super(file);
-  }
-
-  public void add(CharSequence item) {
-    // skip add
-  }
-
-  public void addStatement(String item) {
-    internalAdd(item);
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoGetConfCommand.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoGetConfCommand.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoGetConfCommand.java
deleted file mode 100644
index 83ba4dd..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoGetConfCommand.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import org.apache.tajo.client.TajoGetConf;
-
-public class TajoGetConfCommand extends TajoShellCommand {
-  private TajoGetConf getconf;
-
-  public TajoGetConfCommand(TajoCli.TajoCliContext context) {
-    super(context);
-    getconf = new TajoGetConf(context.getConf(), context.getOutput(), context.getTajoClient());
-  }
-
-  @Override
-  public String getCommand() {
-    return "\\getconf";
-  }
-
-  @Override
-  public void invoke(String[] command) throws Exception {
-    try {
-      String[] getConfCommands = new String[command.length - 1];
-      System.arraycopy(command, 1, getConfCommands, 0, getConfCommands.length);
-
-      getconf.runCommand(getConfCommands);
-    } catch (Exception e) {
-      context.getOutput().println("ERROR: " + e.getMessage());
-    }
-  }
-
-  @Override
-  public String getUsage() {
-    return "<command> [options]";
-  }
-
-  @Override
-  public String getDescription() {
-    return "execute a tajo getconf command.";
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoHAAdminCommand.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoHAAdminCommand.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoHAAdminCommand.java
deleted file mode 100644
index ad88b3f..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoHAAdminCommand.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import org.apache.tajo.client.TajoHAAdmin;
-
-public class TajoHAAdminCommand extends TajoShellCommand {
-  private TajoHAAdmin haAdmin;
-
-  public TajoHAAdminCommand(TajoCli.TajoCliContext context) {
-    super(context);
-    haAdmin = new TajoHAAdmin(context.getConf(), context.getOutput(), context.getTajoClient());
-  }
-
-  @Override
-  public String getCommand() {
-    return "\\haadmin";
-  }
-
-  @Override
-  public void invoke(String[] command) throws Exception {
-    try {
-      String[] haAdminCommands = new String[command.length - 1];
-      System.arraycopy(command, 1, haAdminCommands, 0, haAdminCommands.length);
-
-      haAdmin.runCommand(haAdminCommands);
-    } catch (Exception e) {
-      context.getOutput().println("ERROR: " + e.getMessage());
-    }
-  }
-
-  @Override
-  public String getUsage() {
-    return "<command> [options]";
-  }
-
-  @Override
-  public String getDescription() {
-    return "execute a tajo haAdminF command.";
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/TajoShellCommand.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/TajoShellCommand.java b/tajo-client/src/main/java/org/apache/tajo/cli/TajoShellCommand.java
deleted file mode 100644
index 138aec4..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/TajoShellCommand.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import org.apache.tajo.client.TajoClient;
-import org.apache.tajo.conf.TajoConf;
-
-public abstract class TajoShellCommand {
-  public abstract String getCommand();
-  public String [] getAliases() {
-    return new String[] {};
-  }
-  public abstract void invoke(String [] command) throws Exception;
-  public abstract String getUsage();
-  public abstract String getDescription();
-  public void printHelp() {
-    context.getOutput().print(getCommand());
-    context.getOutput().print(" - ");
-    context.getOutput().println(getDescription());
-  }
-
-  protected TajoCli.TajoCliContext context;
-  protected TajoClient client;
-  protected int maxColumn;
-
-  public TajoShellCommand(TajoCli.TajoCliContext context) {
-    maxColumn = context.getConf().getIntVar(TajoConf.ConfVars.$CLI_MAX_COLUMN);
-    this.context = context;
-    client = context.getTajoClient();
-  }
-
-  protected void println() {
-    context.getOutput().println();
-  }
-
-  protected void printLeft(String message, int columnWidth) {
-    int messageLength = message.length();
-
-    if(messageLength >= columnWidth) {
-      context.getOutput().print(message.substring(0, columnWidth - 1));
-    } else {
-      context.getOutput().print(message);
-      print(' ', columnWidth - messageLength - 1);
-    }
-  }
-
-  protected void printCenter(String message, int columnWidth, boolean warp) {
-    int messageLength = message.length();
-
-    if(messageLength > columnWidth) {
-      context.getOutput().print(message.substring(0, columnWidth - 1));
-    } else {
-      int numPadding = (columnWidth - messageLength)/2;
-
-      print(' ', numPadding);
-      context.getOutput().print(message);
-      print(' ', numPadding);
-    }
-    if(warp) {
-      println();
-    }
-  }
-
-  protected void printCenter(String message) {
-    printCenter(message, maxColumn, true);
-  }
-
-  protected void print(char c, int count) {
-    for(int i = 0; i < count; i++) {
-      context.getOutput().print(c);
-    }
-  }
-
-  protected int[] printHeader(String[] headers, float[] columnWidthRates) {
-    int[] columnWidths = new int[columnWidthRates.length];
-
-    int columnWidthSum = 0;
-    for(int i = 0; i < columnWidths.length; i++) {
-      columnWidths[i] = (int)(maxColumn * columnWidthRates[i]);
-      if(i > 0) {
-        columnWidthSum += columnWidths[i - 1];
-      }
-    }
-
-    columnWidths[columnWidths.length - 1] = maxColumn - columnWidthSum;
-
-    String prefix = "";
-    for(int i = 0; i < headers.length; i++) {
-      context.getOutput().print(prefix);
-      printLeft(" " + headers[i], columnWidths[i]);
-      prefix = "|";
-    }
-    println();
-
-    int index = 0;
-    int printPos = columnWidths[index] - 1;
-    for(int i = 0; i < maxColumn; i++) {
-      if(i == printPos) {
-        if(index < columnWidths.length - 1) {
-          print('+', 1);
-          index++;
-          printPos += columnWidths[index];
-        }
-      } else {
-        print('-', 1);
-      }
-    }
-
-    println();
-    return columnWidths;
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/UnsetCommand.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/UnsetCommand.java b/tajo-client/src/main/java/org/apache/tajo/cli/UnsetCommand.java
deleted file mode 100644
index 7b7685f..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/UnsetCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import com.google.common.collect.Lists;
-
-public class UnsetCommand extends TajoShellCommand {
-
-  public UnsetCommand(TajoCli.TajoCliContext context) {
-    super(context);
-  }
-
-  @Override
-  public String getCommand() {
-    return "\\unset";
-  }
-
-  @Override
-  public void invoke(String[] cmd) throws Exception {
-    if (cmd.length == 2) {
-      client.unsetSessionVariables(Lists.newArrayList(cmd[1]));
-    } else {
-      context.getOutput().println("usage: \\unset NAME");
-    }
-  }
-
-  @Override
-  public String getUsage() {
-    return "";
-  }
-
-  @Override
-  public String getDescription() {
-    return "unset a session variable";
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/VersionCommand.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/VersionCommand.java b/tajo-client/src/main/java/org/apache/tajo/cli/VersionCommand.java
deleted file mode 100644
index e92a8d4..0000000
--- a/tajo-client/src/main/java/org/apache/tajo/cli/VersionCommand.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.cli;
-
-import org.apache.tajo.util.VersionInfo;
-
-public class VersionCommand extends TajoShellCommand {
-
-  public VersionCommand(TajoCli.TajoCliContext context) {
-    super(context);
-  }
-
-  @Override
-  public String getCommand() {
-    return "\\version";
-  }
-
-  @Override
-  public void invoke(String[] cmd) throws Exception {
-    context.getOutput().println(VersionInfo.getDisplayVersion());
-  }
-
-  @Override
-  public String getUsage() {
-    return "";
-  }
-
-  @Override
-  public String getDescription() {
-    return "show Tajo version";
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java
new file mode 100644
index 0000000..5ef8d76
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoAdmin.java
@@ -0,0 +1,457 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.cli.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.TajoProtos;
+import org.apache.tajo.client.*;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.ipc.ClientProtos.BriefQueryInfo;
+import org.apache.tajo.ipc.ClientProtos.WorkerResourceInfo;
+import org.apache.tajo.util.NetUtils;
+import org.apache.tajo.util.HAServiceUtil;
+import org.apache.tajo.util.TajoIdUtils;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.net.InetSocketAddress;
+import java.sql.SQLException;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TajoAdmin {
+  private static final org.apache.commons.cli.Options options;
+  private static DecimalFormat decimalF = new DecimalFormat("###.0");
+  private enum WorkerStatus {
+    RUNNING,
+    LOST,
+    DECOMMISSIONED
+  }
+
+  final static String DASHLINE_LEN5 = "-----";
+  final static String DASHLINE_LEN10 = "----------";
+  final static String DASHLINE_LEN12 = "------------";
+  final static String DASHLINE_LEN25 = "-------------------------";
+  final static String DATE_FORMAT  = "yyyy-MM-dd HH:mm:ss";
+
+  static {
+    options = new Options();
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+    options.addOption("list", null, false, "Show Tajo query list");
+    options.addOption("cluster", null, false, "Show Cluster Info");
+    options.addOption("showmasters", null, false, "gets list of tajomasters in the cluster");
+    options.addOption("desc", null, false, "Show Query Description");
+    options.addOption("kill", null, true, "Kill a running query");
+  }
+
+  private TajoConf tajoConf;
+  private TajoClient tajoClient;
+  private Writer writer;
+
+  public TajoAdmin(TajoConf tajoConf, Writer writer) {
+    this(tajoConf, writer, null);
+  }
+
+  public TajoAdmin(TajoConf tajoConf, Writer writer, TajoClient tajoClient) {
+    this.tajoConf = tajoConf;
+    this.writer = writer;
+    this.tajoClient = tajoClient;
+  }
+
+  private void printUsage() {
+    HelpFormatter formatter = new HelpFormatter();
+    formatter.printHelp( "admin [options]", options );
+  }
+
+  public void runCommand(String[] args) throws Exception {
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(options, args);
+
+    String param = "";
+    int cmdType = 0;
+
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    String queryId = null;
+
+    if (cmd.hasOption("list")) {
+      cmdType = 1;
+    } else if (cmd.hasOption("desc")) {
+      cmdType = 2;
+    } else if (cmd.hasOption("cluster")) {
+      cmdType = 3;
+    } else if (cmd.hasOption("kill")) {
+      cmdType = 4;
+      queryId = cmd.getOptionValue("kill");
+    } else if (cmd.hasOption("showmasters")) {
+      cmdType = 5;
+    }
+
+    // if there is no "-h" option,
+    if(hostName == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        hostName = tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        port = Integer.parseInt(tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+
+    if (cmdType == 0) {
+      printUsage();
+      return;
+    }
+
+
+    if ((hostName == null) ^ (port == null)) {
+      System.err.println("ERROR: cannot find valid Tajo server address");
+      return;
+    } else if (hostName != null && port != null) {
+      tajoConf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName + ":" + port);
+      tajoClient = new TajoClientImpl(tajoConf);
+    } else if (hostName == null && port == null) {
+      tajoClient = new TajoClientImpl(tajoConf);
+    }
+
+    switch (cmdType) {
+      case 1:
+        processList(writer);
+        break;
+      case 2:
+        processDesc(writer);
+        break;
+      case 3:
+        processCluster(writer);
+        break;
+      case 4:
+        processKill(writer, queryId);
+        break;
+      case 5:
+        processMasters(writer);
+        break;
+      default:
+        printUsage();
+        break;
+    }
+
+    writer.flush();
+  }
+
+  private void processDesc(Writer writer) throws ParseException, IOException,
+      ServiceException, SQLException {
+    tajoClient = TajoHAClientUtil.getTajoClient(tajoConf, tajoClient);
+    List<BriefQueryInfo> queryList = tajoClient.getRunningQueryList();
+    SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
+    int id = 1;
+    for (BriefQueryInfo queryInfo : queryList) {
+        String queryId = String.format("q_%s_%04d",
+                                       queryInfo.getQueryId().getId(),
+                                       queryInfo.getQueryId().getSeq());
+
+        writer.write("Id: " + id);
+        writer.write("\n");
+        id++;
+        writer.write("Query Id: " + queryId);
+        writer.write("\n");
+        writer.write("Started Time: " + df.format(queryInfo.getStartTime()));
+        writer.write("\n");
+
+        writer.write("Query State: " + queryInfo.getState().name());
+        writer.write("\n");
+        long end = queryInfo.getFinishTime();
+        long start = queryInfo.getStartTime();
+        String executionTime = decimalF.format((end-start) / 1000) + " sec";
+        if (TajoClientUtil.isQueryComplete(queryInfo.getState())) {
+          writer.write("Finished Time: " + df.format(queryInfo.getFinishTime()));
+          writer.write("\n");
+        }
+        writer.write("Execution Time: " + executionTime);
+        writer.write("\n");
+        writer.write("Query Progress: " + queryInfo.getProgress());
+        writer.write("\n");
+        writer.write("Query Statement:");
+        writer.write("\n");
+        writer.write(queryInfo.getQuery());
+        writer.write("\n");
+        writer.write("\n");
+    }
+  }
+
+  private void processCluster(Writer writer) throws ParseException, IOException,
+      ServiceException, SQLException {
+    tajoClient = TajoHAClientUtil.getTajoClient(tajoConf, tajoClient);
+    List<WorkerResourceInfo> workerList = tajoClient.getClusterInfo();
+
+    int runningQueryMasterTasks = 0;
+
+    List<WorkerResourceInfo> liveWorkers = new ArrayList<WorkerResourceInfo>();
+    List<WorkerResourceInfo> deadWorkers = new ArrayList<WorkerResourceInfo>();
+    List<WorkerResourceInfo> decommissionWorkers = new ArrayList<WorkerResourceInfo>();
+
+    List<WorkerResourceInfo> liveQueryMasters = new ArrayList<WorkerResourceInfo>();
+    List<WorkerResourceInfo> deadQueryMasters = new ArrayList<WorkerResourceInfo>();
+
+    for (WorkerResourceInfo eachWorker : workerList) {
+      if(eachWorker.getQueryMasterMode() == true) {
+        if(eachWorker.getWorkerStatus().equals(WorkerStatus.RUNNING.toString())) {
+          liveQueryMasters.add(eachWorker);
+          runningQueryMasterTasks += eachWorker.getNumQueryMasterTasks();
+        }
+        if(eachWorker.getWorkerStatus().equals(WorkerStatus.LOST.toString())) {
+          deadQueryMasters.add(eachWorker);
+        }
+      }
+
+      if(eachWorker.getTaskRunnerMode() == true) {
+        if(eachWorker.getWorkerStatus().equals(WorkerStatus.RUNNING.toString())) {
+          liveWorkers.add(eachWorker);
+        } else if(eachWorker.getWorkerStatus().equals(WorkerStatus.LOST.toString())) {
+          deadWorkers.add(eachWorker);
+        } else if(eachWorker.getWorkerStatus().equals(WorkerStatus.DECOMMISSIONED.toString())) {
+          decommissionWorkers.add(eachWorker);
+        }
+      }
+    }
+
+    String fmtInfo = "%1$-5s %2$-5s %3$-5s%n";
+    String infoLine = String.format(fmtInfo, "Live", "Dead", "Tasks");
+
+    writer.write("Query Master\n");
+    writer.write("============\n\n");
+    writer.write(infoLine);
+    String line = String.format(fmtInfo, DASHLINE_LEN5, DASHLINE_LEN5, DASHLINE_LEN5);
+    writer.write(line);
+
+    line = String.format(fmtInfo, liveQueryMasters.size(),
+                         deadQueryMasters.size(), runningQueryMasterTasks);
+    writer.write(line);
+    writer.write("\n");
+
+    writer.write("Live QueryMasters\n");
+    writer.write("=================\n\n");
+
+    if (liveQueryMasters.isEmpty()) {
+      writer.write("No Live QueryMasters\n");
+    } else {
+      String fmtQueryMasterLine = "%1$-25s %2$-5s %3$-5s %4$-10s %5$-10s%n";
+      line = String.format(fmtQueryMasterLine, "QueryMaster", "Port", "Query",
+                           "Heap", "Status");
+      writer.write(line);
+      line = String.format(fmtQueryMasterLine, DASHLINE_LEN25, DASHLINE_LEN5,
+              DASHLINE_LEN5, DASHLINE_LEN10, DASHLINE_LEN10);
+      writer.write(line);
+      for (WorkerResourceInfo queryMaster : liveQueryMasters) {
+        TajoProtos.WorkerConnectionInfoProto connInfo = queryMaster.getConnectionInfo();
+        String queryMasterHost = String.format("%s:%d", connInfo.getHost(), connInfo.getQueryMasterPort());
+        String heap = String.format("%d MB", queryMaster.getMaxHeap() / 1024 / 1024);
+        line = String.format(fmtQueryMasterLine,
+            queryMasterHost,
+            connInfo.getClientPort(),
+            queryMaster.getNumQueryMasterTasks(),
+            heap,
+            queryMaster.getWorkerStatus());
+        writer.write(line);
+      }
+
+      writer.write("\n\n");
+    }
+
+    if (!deadQueryMasters.isEmpty()) {
+      writer.write("Dead QueryMasters\n");
+      writer.write("=================\n\n");
+
+      String fmtQueryMasterLine = "%1$-25s %2$-5s %3$-10s%n";
+      line = String.format(fmtQueryMasterLine, "QueryMaster", "Port", "Status");
+      writer.write(line);
+      line = String.format(fmtQueryMasterLine, DASHLINE_LEN25, DASHLINE_LEN5, DASHLINE_LEN10);
+      writer.write(line);
+
+      for (WorkerResourceInfo queryMaster : deadQueryMasters) {
+        TajoProtos.WorkerConnectionInfoProto connInfo = queryMaster.getConnectionInfo();
+        String queryMasterHost = String.format("%s:%d", connInfo.getHost(), connInfo.getQueryMasterPort());
+        line = String.format(fmtQueryMasterLine,
+            queryMasterHost,
+            connInfo.getClientPort(),
+            queryMaster.getWorkerStatus());
+        writer.write(line);
+      }
+
+      writer.write("\n\n");
+    }
+
+    writer.write("Worker\n");
+    writer.write("======\n\n");
+
+    String fmtWorkerInfo = "%1$-5s %2$-5s%n";
+    String workerInfoLine = String.format(fmtWorkerInfo, "Live", "Dead");
+    writer.write(workerInfoLine);
+    line = String.format(fmtWorkerInfo, DASHLINE_LEN5, DASHLINE_LEN5);
+    writer.write(line);
+
+    line = String.format(fmtWorkerInfo, liveWorkers.size(), deadWorkers.size());
+    writer.write(line);
+    writer.write("\n");
+
+    writer.write("Live Workers\n");
+    writer.write("============\n\n");
+    if(liveWorkers.isEmpty()) {
+      writer.write("No Live Workers\n\n");
+    } else {
+      writeWorkerInfo(writer, liveWorkers);
+    }
+
+    writer.write("Dead Workers\n");
+    writer.write("============\n\n");
+    if(deadWorkers.isEmpty()) {
+      writer.write("No Dead Workers\n\n");
+    } else {
+      writeWorkerInfo(writer, deadWorkers);
+    }
+  }
+
+  private void writeWorkerInfo(Writer writer, List<WorkerResourceInfo> workers) throws ParseException,
+      IOException, ServiceException, SQLException {
+    String fmtWorkerLine = "%1$-25s %2$-5s %3$-5s %4$-10s %5$-10s %6$-12s %7$-10s%n";
+    String line = String.format(fmtWorkerLine,
+        "Worker", "Port", "Tasks",
+        "Mem", "Disk",
+        "Heap", "Status");
+    writer.write(line);
+    line = String.format(fmtWorkerLine,
+        DASHLINE_LEN25, DASHLINE_LEN5, DASHLINE_LEN5,
+        DASHLINE_LEN10, DASHLINE_LEN10,
+        DASHLINE_LEN12, DASHLINE_LEN10);
+    writer.write(line);
+
+    for (WorkerResourceInfo worker : workers) {
+      TajoProtos.WorkerConnectionInfoProto connInfo = worker.getConnectionInfo();
+      String workerHost = String.format("%s:%d", connInfo.getHost(), connInfo.getPeerRpcPort());
+      String mem = String.format("%d/%d", worker.getUsedMemoryMB(),
+          worker.getMemoryMB());
+      String disk = String.format("%.2f/%.2f", worker.getUsedDiskSlots(),
+          worker.getDiskSlots());
+      String heap = String.format("%d/%d MB", worker.getFreeHeap()/1024/1024,
+          worker.getMaxHeap()/1024/1024);
+
+      line = String.format(fmtWorkerLine, workerHost,
+          connInfo.getPullServerPort(),
+          worker.getNumRunningTasks(),
+          mem, disk, heap, worker.getWorkerStatus());
+      writer.write(line);
+    }
+    writer.write("\n\n");
+  }
+
+  private void processList(Writer writer) throws ParseException, IOException,
+      ServiceException, SQLException {
+    tajoClient = TajoHAClientUtil.getTajoClient(tajoConf, tajoClient);
+    List<BriefQueryInfo> queryList = tajoClient.getRunningQueryList();
+    SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
+    StringBuilder builder = new StringBuilder();
+
+    /* print title */
+    builder.append(StringUtils.rightPad("QueryId", 21));
+    builder.append(StringUtils.rightPad("State", 20));
+    builder.append(StringUtils.rightPad("StartTime", 20));
+    builder.append(StringUtils.rightPad("Query", 30)).append("\n");
+
+    builder.append(StringUtils.rightPad(StringUtils.repeat("-", 20), 21));
+    builder.append(StringUtils.rightPad(StringUtils.repeat("-", 19), 20));
+    builder.append(StringUtils.rightPad(StringUtils.repeat("-", 19), 20));
+    builder.append(StringUtils.rightPad(StringUtils.repeat("-", 29), 30)).append("\n");
+    writer.write(builder.toString());
+
+    builder = new StringBuilder();
+    for (BriefQueryInfo queryInfo : queryList) {
+      builder.append(StringUtils.rightPad(new QueryId(queryInfo.getQueryId()).toString(), 21));
+      builder.append(StringUtils.rightPad(queryInfo.getState().name(), 20));
+      builder.append(StringUtils.rightPad(df.format(queryInfo.getStartTime()), 20));
+      builder.append(StringUtils.abbreviate(queryInfo.getQuery(), 30)).append("\n");
+    }
+    writer.write(builder.toString());
+  }
+
+  public void processKill(Writer writer, String queryIdStr)
+      throws IOException, ServiceException {
+    QueryStatus status = tajoClient.killQuery(TajoIdUtils.parseQueryId(queryIdStr));
+    if (status.getState() == TajoProtos.QueryState.QUERY_KILLED) {
+      writer.write(queryIdStr + " is killed successfully.\n");
+    } else if (status.getState() == TajoProtos.QueryState.QUERY_KILL_WAIT) {
+      writer.write(queryIdStr + " will be finished after a while.\n");
+    } else {
+      writer.write("ERROR:" + status.getErrorMessage());
+    }
+  }
+
+  private void processMasters(Writer writer) throws ParseException, IOException,
+      ServiceException, SQLException {
+    tajoClient = TajoHAClientUtil.getTajoClient(tajoConf, tajoClient);
+    if (tajoConf.getBoolVar(TajoConf.ConfVars.TAJO_MASTER_HA_ENABLE)) {
+
+      List<String> list = HAServiceUtil.getMasters(tajoConf);
+      int i = 0;
+      for (String master : list) {
+        if (i > 0) {
+          writer.write(" ");
+        }
+        writer.write(master);
+        i++;
+      }
+      writer.write("\n");
+    } else {
+      String confMasterServiceAddr = tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_UMBILICAL_RPC_ADDRESS);
+      InetSocketAddress masterAddress = NetUtils.createSocketAddr(confMasterServiceAddr);
+      writer.write(masterAddress.getHostName());
+      writer.write("\n");
+    }
+  }
+
+  public static void main(String [] args) throws Exception {
+    TajoConf conf = new TajoConf();
+
+    Writer writer = new PrintWriter(System.out);
+    try {
+      TajoAdmin admin = new TajoAdmin(conf, writer);
+      admin.runCommand(args);
+    } finally {
+      writer.close();
+      System.exit(0);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoDump.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoDump.java b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoDump.java
new file mode 100644
index 0000000..d05564a
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoDump.java
@@ -0,0 +1,188 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.cli.*;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.DDLBuilder;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.Pair;
+import org.apache.tajo.util.TUtil;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.sql.SQLException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+public class TajoDump {
+  private static final org.apache.commons.cli.Options options;
+
+  static {
+    options = new Options();
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+    options.addOption("a", "all", false, "dump all table DDLs");
+  }
+
+  private static void printUsage() {
+    HelpFormatter formatter = new HelpFormatter();
+    formatter.printHelp( "tajo-dump [options] [database name]", options);
+  }
+
+  private static Pair<String, Integer> getConnectionAddr(TajoConf conf, CommandLine cmd) {
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    if(hostName == null) {
+      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        hostName = conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        port = Integer.parseInt(conf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+    return new Pair<String, Integer>(hostName, port);
+  }
+
+  public static void main(String [] args) throws ParseException, IOException, ServiceException, SQLException {
+    final TajoConf conf = new TajoConf();
+    final CommandLineParser parser = new PosixParser();
+    final CommandLine cmd = parser.parse(options, args);
+    final Pair<String, Integer> hostAndPort = getConnectionAddr(conf, cmd);
+    final String hostName = hostAndPort.getFirst();
+    final Integer port = hostAndPort.getSecond();
+    final UserGroupInformation userInfo = UserGroupInformation.getCurrentUser();
+
+    String baseDatabaseName = null;
+    if (cmd.getArgList().size() > 0) {
+      baseDatabaseName = (String) cmd.getArgList().get(0);
+    }
+
+    boolean isDumpingAllDatabases = cmd.hasOption('a');
+
+    // Neither two choices
+    if (!isDumpingAllDatabases && baseDatabaseName == null) {
+      printUsage();
+      System.exit(-1);
+    }
+
+    TajoClient client = null;
+    if ((hostName == null) ^ (port == null)) {
+      System.err.println("ERROR: cannot find any TajoMaster rpc address in arguments and tajo-site.xml.");
+      System.exit(-1);
+    } else if (hostName != null && port != null) {
+      conf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName+":"+port);
+      client = new TajoClientImpl(conf);
+    } else {
+      client = new TajoClientImpl(conf);
+    }
+
+    PrintWriter writer = new PrintWriter(System.out);
+    dump(client, userInfo, baseDatabaseName, isDumpingAllDatabases, true, true, writer);
+
+    System.exit(0);
+  }
+
+  public static void dump(TajoClient client, UserGroupInformation userInfo, String baseDatabaseName,
+                   boolean isDumpingAllDatabases, boolean includeUserName, boolean includeDate, PrintWriter out)
+      throws SQLException, ServiceException {
+    printHeader(out, userInfo, includeUserName, includeDate);
+
+    if (isDumpingAllDatabases) {
+      // sort database names in an ascending lexicographic order of the names.
+      List<String> sorted = new ArrayList<String>(client.getAllDatabaseNames());
+      Collections.sort(sorted);
+
+      for (String databaseName : sorted) {
+        dumpDatabase(client, databaseName, out);
+      }
+    } else {
+      dumpDatabase(client, baseDatabaseName, out);
+    }
+    out.flush();
+  }
+
+  private static void printHeader(PrintWriter writer, UserGroupInformation userInfo, boolean includeUSerName,
+                                  boolean includeDate) {
+    writer.write("--\n");
+    writer.write("-- Tajo database dump\n");
+    if (includeUSerName) {
+      writer.write("--\n-- Dump user: " + userInfo.getUserName() + "\n");
+    }
+    if (includeDate) {
+      writer.write("--\n-- Dump date: " + toDateString() + "\n");
+    }
+    writer.write("--\n");
+    writer.write("\n");
+  }
+
+  private static void dumpDatabase(TajoClient client, String databaseName, PrintWriter writer)
+      throws SQLException, ServiceException {
+    writer.write("\n");
+    writer.write("--\n");
+    writer.write(String.format("-- Database name: %s%n", CatalogUtil.denormalizeIdentifier(databaseName)));
+    writer.write("--\n");
+    writer.write("\n");
+    writer.write(String.format("CREATE DATABASE IF NOT EXISTS %s;", CatalogUtil.denormalizeIdentifier(databaseName)));
+    writer.write("\n\n");
+
+    // returned list is immutable.
+    List<String> tableNames = TUtil.newList(client.getTableList(databaseName));
+    Collections.sort(tableNames);
+    for (String tableName : tableNames) {
+      try {
+        TableDesc table = client.getTableDesc(CatalogUtil.buildFQName(databaseName, tableName));
+        if (table.isExternal()) {
+          writer.write(DDLBuilder.buildDDLForExternalTable(table));
+        } else {
+          writer.write(DDLBuilder.buildDDLForBaseTable(table));
+        }
+        writer.write("\n\n");
+      } catch (Exception e) {
+        // dump for each table can throw any exception. We need to skip the exception case.
+        // here, the error message prints out via stderr.
+        System.err.println("ERROR:" + tableName + "," + e.getMessage());
+      }
+    }
+  }
+
+  private static String toDateString() {
+    DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+    java.util.Date today = Calendar.getInstance().getTime();
+    return df.format(today);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoGetConf.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoGetConf.java b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoGetConf.java
new file mode 100644
index 0000000..aa7620b
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoGetConf.java
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.cli.*;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.conf.TajoConf;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.sql.SQLException;
+
+public class TajoGetConf {
+  private static final org.apache.commons.cli.Options options;
+
+  static {
+    options = new Options();
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+  }
+
+  private TajoConf tajoConf;
+  private TajoClient tajoClient;
+  private Writer writer;
+
+  public final static String defaultLeftPad = " ";
+  public final static String defaultDescPad = "   ";
+
+  public TajoGetConf(TajoConf tajoConf, Writer writer) {
+    this(tajoConf, writer, null);
+  }
+
+  public TajoGetConf(TajoConf tajoConf, Writer writer, TajoClient tajoClient) {
+    this.tajoConf = tajoConf;
+    this.writer = writer;
+    this.tajoClient = tajoClient;
+  }
+
+  private void printUsage(boolean tsqlMode) {
+    if (!tsqlMode) {
+      HelpFormatter formatter = new HelpFormatter();
+      formatter.printHelp( "getconf <key> [options]", options );
+    }
+    System.out.println(defaultLeftPad + "key" + defaultDescPad + "gets a specific key from the configuration");
+  }
+
+  public void runCommand(String[] args) throws Exception {
+    runCommand(args, true);
+  }
+
+  public void runCommand(String[] args, boolean tsqlMode) throws Exception {
+    CommandLineParser parser = new PosixParser();
+
+    if (args.length == 0) {
+      printUsage(tsqlMode);
+      return;
+    }
+
+    CommandLine cmd = parser.parse(options, args);
+
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    String param;
+    if (cmd.getArgs().length > 1) {
+      printUsage(tsqlMode);
+      return;
+    } else {
+      param = cmd.getArgs()[0];
+    }
+
+    // if there is no "-h" option,
+    if(hostName == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        hostName = tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        port = Integer.parseInt(tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+
+    if ((hostName == null) ^ (port == null)) {
+      return;
+    } else if (hostName != null && port != null) {
+      tajoConf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName + ":" + port);
+      tajoClient = new TajoClientImpl(tajoConf);
+    } else if (hostName == null && port == null) {
+      tajoClient = new TajoClientImpl(tajoConf);
+    }
+
+    processConfKey(writer, param);
+    writer.flush();
+  }
+
+  private void processConfKey(Writer writer, String param) throws ParseException, IOException,
+      ServiceException, SQLException {
+    String value = tajoConf.getTrimmed(param);
+
+    // If there is no value in the configuration file, we need to find all ConfVars.
+    if (value == null) {
+      for(TajoConf.ConfVars vars : TajoConf.ConfVars.values()) {
+        if (vars.varname.equalsIgnoreCase(param)) {
+          value = tajoConf.getVar(vars);
+          break;
+        }
+      }
+    }
+
+    if (value != null) {
+      writer.write(value);
+    } else {
+      writer.write("Configuration " + param + " is missing.");
+    }
+
+    writer.write("\n");
+  }
+
+  public static void main(String [] args) throws Exception {
+    TajoConf conf = new TajoConf();
+
+    Writer writer = new PrintWriter(System.out);
+    try {
+      TajoGetConf admin = new TajoGetConf(conf, writer);
+      admin.runCommand(args, false);
+    } finally {
+      writer.close();
+      System.exit(0);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoHAAdmin.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoHAAdmin.java b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoHAAdmin.java
new file mode 100644
index 0000000..12d94ad
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tools/TajoHAAdmin.java
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tools;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.cli.*;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.client.TajoClientImpl;
+import org.apache.tajo.client.TajoHAClientUtil;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.util.HAServiceUtil;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+public class TajoHAAdmin {
+  private static final Options options;
+
+  static {
+    options = new Options();
+    options.addOption("h", "host", true, "Tajo server host");
+    options.addOption("p", "port", true, "Tajo server port");
+    options.addOption("transitionToActive", null, true, "Transitions the master into Active state");
+    options.addOption("transitionToBackup", null, true, "Transitions the master into Backup state");
+    options.addOption("getState", null, true, "Returns the state of the master");
+    options.addOption("formatHA", null, false, "Format HA status on share storage");
+  }
+
+  private TajoConf tajoConf;
+  private TajoClient tajoClient;
+  private Writer writer;
+
+  public TajoHAAdmin(TajoConf tajoConf, Writer writer) {
+    this(tajoConf, writer, null);
+  }
+
+  public TajoHAAdmin(TajoConf tajoConf, Writer writer, TajoClient tajoClient) {
+    this.tajoConf = tajoConf;
+    this.writer = writer;
+    this.tajoClient = tajoClient;
+  }
+
+  private void printUsage() {
+    HelpFormatter formatter = new HelpFormatter();
+    formatter.printHelp( "haadmin [options]", options );
+  }
+
+  public void runCommand(String[] args) throws Exception {
+    if(args.length == 1 &&
+        (args[0].equalsIgnoreCase("-transitionToActive")
+            || args[0].equalsIgnoreCase("-transitionToBackup")
+            || args[0].equalsIgnoreCase("-getState"))) {
+      writer.write("Not enough arguments: expected 1 but got 0\n");
+      writer.flush();
+      return;
+    }
+
+    CommandLineParser parser = new PosixParser();
+    CommandLine cmd = parser.parse(options, args);
+
+    String param = "";
+    int cmdType = 0;
+
+    String hostName = null;
+    Integer port = null;
+    if (cmd.hasOption("h")) {
+      hostName = cmd.getOptionValue("h");
+    }
+    if (cmd.hasOption("p")) {
+      port = Integer.parseInt(cmd.getOptionValue("p"));
+    }
+
+    if (cmd.hasOption("transitionToActive")) {
+      cmdType = 1;
+      param = cmd.getOptionValue("transitionToActive");
+    } else if (cmd.hasOption("transitionToBackup")) {
+      cmdType = 2;
+      param = cmd.getOptionValue("transitionToBackup");
+    } else if (cmd.hasOption("getState")) {
+      cmdType = 3;
+      param = cmd.getOptionValue("getState");
+    } else if (cmd.hasOption("formatHA")) {
+      cmdType = 4;
+    }
+
+    // if there is no "-h" option,
+    if(hostName == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        hostName = tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[0];
+      }
+    }
+    if (port == null) {
+      if (tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS) != null) {
+        // it checks if the client service address is given in configuration and distributed mode.
+        // if so, it sets entryAddr.
+        port = Integer.parseInt(tajoConf.getVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS).split(":")[1]);
+      }
+    }
+
+    if (cmdType == 0) {
+      printUsage();
+      return;
+    }
+
+
+    if ((hostName == null) ^ (port == null)) {
+      System.err.println("ERROR: cannot find valid Tajo server address");
+      return;
+    } else if (hostName != null && port != null) {
+      tajoConf.setVar(TajoConf.ConfVars.TAJO_MASTER_CLIENT_RPC_ADDRESS, hostName + ":" + port);
+      tajoClient = new TajoClientImpl(tajoConf);
+    } else if (hostName == null && port == null) {
+      tajoClient = new TajoClientImpl(tajoConf);
+    }
+
+    if (!tajoConf.getBoolVar(TajoConf.ConfVars.TAJO_MASTER_HA_ENABLE)) {
+      writer.write("HA is not enabled for this tajo cluster.");
+    } else {
+      switch (cmdType) {
+        case 1:
+          writer.write("Not Yet Implemented\n");
+          break;
+        case 2:
+          writer.write("Not Yet Implemented\n");
+          break;
+        case 3:
+          getState(writer, param);
+          break;
+        case 4:
+          formatHA(writer);
+          break;
+        default:
+          printUsage();
+          break;
+      }
+    }
+
+    writer.flush();
+  }
+
+  private void getState(Writer writer, String param) throws ParseException, IOException,
+      ServiceException {
+    tajoClient = TajoHAClientUtil.getTajoClient(tajoConf, tajoClient);
+    int retValue = HAServiceUtil.getState(param, tajoConf);
+
+    switch (retValue) {
+      case 1:
+        writer.write("The master is active.\n");
+        break;
+      case 0:
+        writer.write("The master is backup.\n");
+        break;
+      case -1:
+        writer.write("Finding failed. - master:" + param + "\n");
+        break;
+      default:
+        writer.write("Cannot find the master. - master:" + param + "\n");
+        break;
+    }
+  }
+
+  private void formatHA(Writer writer) throws ParseException, IOException,
+      ServiceException {
+    int retValue = HAServiceUtil.formatHA(tajoConf);
+
+    switch (retValue) {
+      case 1:
+        writer.write("Formatting finished successfully.\n");
+        break;
+      case 0:
+        writer.write("If you want to format the ha information, you must shutdown tajo masters "
+            + " before formatting.\n");
+        break;
+      default:
+        writer.write("Cannot format ha information.\n");
+        break;
+    }
+  }
+
+  public static void main(String [] args) throws Exception {
+    TajoConf conf = new TajoConf();
+
+    Writer writer = new PrintWriter(System.out);
+    try {
+      TajoHAAdmin admin = new TajoHAAdmin(conf, writer);
+      admin.runCommand(args);
+    } finally {
+      writer.close();
+      System.exit(0);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tsql/DefaultTajoCliOutputFormatter.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tsql/DefaultTajoCliOutputFormatter.java b/tajo-client/src/main/java/org/apache/tajo/cli/tsql/DefaultTajoCliOutputFormatter.java
new file mode 100644
index 0000000..9dd2b1c
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tsql/DefaultTajoCliOutputFormatter.java
@@ -0,0 +1,210 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.SessionVars;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.client.QueryClient;
+import org.apache.tajo.client.QueryStatus;
+import org.apache.tajo.util.FileUtil;
+
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+
+public class DefaultTajoCliOutputFormatter implements TajoCliOutputFormatter {
+  private int printPauseRecords;
+  private boolean printPause;
+  private boolean printErrorTrace;
+  private String nullChar;
+
+  @Override
+  public void init(TajoCli.TajoCliContext context) {
+    this.printPause = context.getBool(SessionVars.CLI_PAGING_ENABLED);
+    this.printPauseRecords = context.getInt(SessionVars.CLI_PAGE_ROWS);
+    this.printErrorTrace = context.getBool(SessionVars.CLI_DISPLAY_ERROR_TRACE);
+    this.nullChar = context.get(SessionVars.CLI_NULL_CHAR);
+  }
+
+  @Override
+  public void setScirptMode() {
+    this.printPause = false;
+  }
+
+  private String getQuerySuccessMessage(TableDesc tableDesc, float responseTime, int totalPrintedRows, String postfix,
+                                        boolean endOfTuple) {
+    TableStats stat = tableDesc.getStats();
+    String volume = stat == null ? (endOfTuple ? "0 B" : "unknown bytes") :
+        FileUtil.humanReadableByteCount(stat.getNumBytes(), false);
+    long resultRows = stat == null ? QueryClient.UNKNOWN_ROW_NUMBER : stat.getNumRows();
+
+    String displayRowNum;
+    if (resultRows == QueryClient.UNKNOWN_ROW_NUMBER) {
+
+      if (endOfTuple) {
+        displayRowNum = totalPrintedRows + " rows";
+      } else {
+        displayRowNum = "unknown row number";
+      }
+
+    } else {
+      displayRowNum = resultRows + " rows";
+    }
+    return "(" + displayRowNum + ", " + getResponseTimeReadable(responseTime) + ", " + volume + " " + postfix + ")";
+  }
+
+  protected String getResponseTimeReadable(float responseTime) {
+    return responseTime + " sec";
+  }
+
+  @Override
+  public void printResult(PrintWriter sout, InputStream sin, TableDesc tableDesc,
+                          float responseTime, ResultSet res) throws Exception {
+    long resultRows = tableDesc.getStats() == null ? -1 : tableDesc.getStats().getNumRows();
+    if (resultRows == -1) {
+      resultRows = Integer.MAX_VALUE;
+    }
+
+    if (res == null) {
+      sout.println(getQuerySuccessMessage(tableDesc, responseTime, 0, "inserted", true));
+      return;
+    }
+    ResultSetMetaData rsmd = res.getMetaData();
+    int numOfColumns = rsmd.getColumnCount();
+    for (int i = 1; i <= numOfColumns; i++) {
+      if (i > 1) sout.print(",  ");
+      String columnName = rsmd.getColumnName(i);
+      sout.print(columnName);
+    }
+    sout.println("\n-------------------------------");
+
+    int numOfPrintedRows = 0;
+    int totalPrintedRows = 0;
+    boolean endOfTuple = true;
+    while (res.next()) {
+      for (int i = 1; i <= numOfColumns; i++) {
+        if (i > 1) sout.print(",  ");
+        String columnValue = res.getString(i);
+        if(res.wasNull()){
+          sout.print(nullChar);
+        } else {
+          sout.print(columnValue);
+        }
+      }
+      sout.println();
+      sout.flush();
+      numOfPrintedRows++;
+      totalPrintedRows++;
+      if (printPause && printPauseRecords > 0 && totalPrintedRows < resultRows && numOfPrintedRows >= printPauseRecords) {
+        if (resultRows < Integer.MAX_VALUE) {
+          sout.print("(" + totalPrintedRows + "/" + resultRows + " rows, continue... 'q' is quit)");
+        } else {
+          sout.print("(" + totalPrintedRows + " rows, continue... 'q' is quit)");
+        }
+        sout.flush();
+        if (sin != null) {
+          if (sin.read() == 'q') {
+            endOfTuple = false;
+            sout.println();
+            break;
+          }
+        }
+        numOfPrintedRows = 0;
+        sout.println();
+      }
+    }
+    sout.println(getQuerySuccessMessage(tableDesc, responseTime, totalPrintedRows, "selected", endOfTuple));
+    sout.flush();
+  }
+
+  @Override
+  public void printNoResult(PrintWriter sout) {
+    sout.println("(0 rows)");
+    sout.flush();
+  }
+
+  @Override
+  public void printProgress(PrintWriter sout, QueryStatus status) {
+    sout.println("Progress: " + (int)(status.getProgress() * 100.0f)
+        + "%, response time: "
+        + getResponseTimeReadable((float)((status.getFinishTime() - status.getSubmitTime()) / 1000.0)));
+    sout.flush();
+  }
+
+  @Override
+  public void printMessage(PrintWriter sout, String message) {
+    sout.println(message);
+    sout.flush();
+  }
+
+  @Override
+  public void printErrorMessage(PrintWriter sout, Throwable t) {
+    sout.println(parseErrorMessage(t.getMessage()));
+    if (printErrorTrace) {
+      sout.println(ExceptionUtils.getStackTrace(t));
+    }
+    sout.flush();
+  }
+
+  @Override
+  public void printErrorMessage(PrintWriter sout, String message) {
+    sout.println(parseErrorMessage(message));
+    sout.flush();
+  }
+
+  @Override
+  public void printKilledMessage(PrintWriter sout, QueryId queryId) {
+    sout.println(TajoCli.KILL_PREFIX + queryId);
+    sout.flush();
+  }
+
+  @Override
+  public void printErrorMessage(PrintWriter sout, QueryStatus status) {
+    if (status.getErrorMessage() != null && !status.getErrorMessage().isEmpty()) {
+      printErrorMessage(sout, parseErrorMessage(status.getErrorMessage()));
+    } else {
+      printErrorMessage(sout, "No error message");
+    }
+    if (printErrorTrace && status.getErrorTrace() != null && !status.getErrorTrace().isEmpty()) {
+      sout.println(status.getErrorTrace());
+    }
+    sout.flush();
+  }
+
+  public static String parseErrorMessage(String message) {
+    if (message == null) {
+      return TajoCli.ERROR_PREFIX + "No error message";
+    }
+    String[] lines = message.split("\n");
+    message = lines[0];
+
+    int index = message.lastIndexOf(TajoCli.ERROR_PREFIX);
+    if (index < 0) {
+      message = TajoCli.ERROR_PREFIX + message;
+    } else {
+      message = message.substring(index);
+    }
+
+    return message;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/c59baa3a/tajo-client/src/main/java/org/apache/tajo/cli/tsql/InvalidStatementException.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/cli/tsql/InvalidStatementException.java b/tajo-client/src/main/java/org/apache/tajo/cli/tsql/InvalidStatementException.java
new file mode 100644
index 0000000..2fed9fe
--- /dev/null
+++ b/tajo-client/src/main/java/org/apache/tajo/cli/tsql/InvalidStatementException.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.cli.tsql;
+
+public class InvalidStatementException extends Exception {
+  public InvalidStatementException(String message) {
+    super(message);
+  }
+}


Mime
View raw message