001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.runtime.hdinsight.cli; 020 021import org.apache.commons.cli.*; 022import org.apache.reef.runtime.hdinsight.client.UnsafeHDInsightRuntimeConfiguration; 023import org.apache.reef.runtime.hdinsight.client.yarnrest.ApplicationState; 024import org.apache.reef.runtime.hdinsight.client.yarnrest.HDInsightInstance; 025import org.apache.reef.tang.Tang; 026import org.codehaus.jackson.map.ObjectMapper; 027 028import javax.inject.Inject; 029import java.io.File; 030import java.io.IOException; 031import java.io.OutputStreamWriter; 032import java.util.List; 033import java.util.logging.Level; 034import java.util.logging.Logger; 035 036/** 037 * Main class for the HDInsight REST commandline 038 */ 039public final class HDICLI { 040 private static final Logger LOG = Logger.getLogger(HDICLI.class.getName()); 041 private static final String KILL = "kill"; 042 private static final String LOGS = "logs"; 043 private static final String LIST = "list"; 044 private static final String STATUS = "status"; 045 046 private final HDInsightInstance hdInsightInstance; 047 private final Options options; 048 private final LogFetcher logFetcher; 049 050 @Inject 051 HDICLI(final HDInsightInstance hdInsightInstance, 052 final LogFetcher logFetcher) { 053 this.hdInsightInstance = hdInsightInstance; 054 this.logFetcher = logFetcher; 055 final OptionGroup commands = new OptionGroup() 056 .addOption(OptionBuilder.withArgName(KILL).hasArg().withDescription("Kills the given application.").create(KILL)) 057 .addOption(OptionBuilder.withArgName(LOGS).hasArg().withDescription("Fetches the logs for the given application.").create(LOGS)) 058 .addOption(OptionBuilder.withArgName(STATUS).hasArg().withDescription("Fetches the status for the given application.").create(STATUS)) 059 .addOption(OptionBuilder.withArgName(LIST).withDescription("Lists the application on the cluster.").create(LIST)); 060 this.options = new Options().addOptionGroup(commands); 061 } 062 063 /** 064 * Helper method to setup apache commons logging. 065 */ 066 private static final void setupLogging() { 067 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Jdk14Logger"); 068 System.setProperty(".level", "INFO"); 069 } 070 071 public static void main(final String[] args) throws Exception { 072 setupLogging(); 073 Tang.Factory.getTang() 074 .newInjector(UnsafeHDInsightRuntimeConfiguration.fromEnvironment()) 075 .getInstance(HDICLI.class).run(args); 076 } 077 078 public void run(final String[] args) throws Exception { 079 final CommandLineParser parser = new PosixParser(); 080 081 final CommandLine line = parser.parse(options, args); 082 final List<String> positionalArguments = line.getArgList(); 083 if (line.hasOption(KILL)) { 084 this.kill(line.getOptionValue(KILL)); 085 } else if (line.hasOption(LOGS)) { 086 final String applicationId = line.getOptionValue(LOGS); 087 if (positionalArguments.isEmpty()) { 088 this.logs(applicationId); 089 } else { 090 this.logs(applicationId, new File(positionalArguments.get(0))); 091 } 092 } else if (line.hasOption(LIST)) { 093 this.list(); 094 } else if (line.hasOption(STATUS)) { 095 this.status(line.getOptionValue(STATUS)); 096 } else { 097 throw new Exception("Unable to parse command line"); 098 } 099 100 } 101 102 /** 103 * Kills the application with the given id. 104 * 105 * @param applicationId 106 */ 107 private void kill(final String applicationId) { 108 LOG.log(Level.INFO, "Killing application [{0}]", applicationId); 109 this.hdInsightInstance.killApplication(applicationId); 110 } 111 112 /** 113 * Fetches the logs for the application with the given id and prints them to System.out. 114 * 115 * @param applicationId 116 * @throws IOException 117 */ 118 private void logs(final String applicationId) throws IOException { 119 LOG.log(Level.INFO, "Fetching logs for application [{0}]", applicationId); 120 this.logFetcher.fetch(applicationId, new OutputStreamWriter(System.out)); 121 } 122 123 /** 124 * Fetches the logs for the application with the given id and stores them in the given folder. One file per container. 125 * 126 * @param applicationId 127 * @param folder 128 * @throws IOException 129 */ 130 private void logs(final String applicationId, final File folder) throws IOException { 131 LOG.log(Level.FINE, "Fetching logs for application [{0}] and storing them in folder [{1}]", 132 new Object[]{applicationId, folder.getAbsolutePath()}); 133 folder.mkdirs(); 134 this.logFetcher.fetch(applicationId, folder); 135 } 136 137 /** 138 * Fetches a list of all running applications. 139 * 140 * @throws IOException 141 */ 142 private void list() throws IOException { 143 LOG.log(Level.FINE, "Listing applications"); 144 final List<ApplicationState> applications = this.hdInsightInstance.listApplications(); 145 for (final ApplicationState appState : applications) { 146 if (appState.getState().equals("RUNNING")) { 147 System.out.println(appState.getId() + "\t" + appState.getName()); 148 } 149 } 150 } 151 152 private void status(final String applicationId) throws IOException { 153 final List<ApplicationState> applications = this.hdInsightInstance.listApplications(); 154 ApplicationState applicationState = null; 155 for (final ApplicationState appState : applications) { 156 if (appState.getId().equals(applicationId)) { 157 applicationState = appState; 158 break; 159 } 160 } 161 162 if (applicationState == null) { 163 throw new IOException("Unknown application: " + applicationId); 164 } 165 final ObjectMapper objectMapper = new ObjectMapper(); 166 final String status = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(applicationState); 167 168 System.out.println(status); 169 170 171 } 172 173}