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); + } +}
