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.nio.charset.StandardCharsets; 033import java.util.List; 034import java.util.logging.Level; 035import java.util.logging.Logger; 036 037/** 038 * Main class for the HDInsight REST commandline. 039 */ 040public final class HDICLI { 041 private static final Logger LOG = Logger.getLogger(HDICLI.class.getName()); 042 private static final String KILL = "kill"; 043 private static final String LOGS = "logs"; 044 private static final String LIST = "list"; 045 private static final String STATUS = "status"; 046 047 private final HDInsightInstance hdInsightInstance; 048 private final Options options; 049 private final LogFetcher logFetcher; 050 051 @Inject 052 HDICLI(final HDInsightInstance hdInsightInstance, 053 final LogFetcher logFetcher) { 054 this.hdInsightInstance = hdInsightInstance; 055 this.logFetcher = logFetcher; 056 final OptionGroup commands = new OptionGroup() 057 .addOption(OptionBuilder.withArgName(KILL).hasArg() 058 .withDescription("Kills the given application.").create(KILL)) 059 .addOption(OptionBuilder.withArgName(LOGS).hasArg() 060 .withDescription("Fetches the logs for the given application.").create(LOGS)) 061 .addOption(OptionBuilder.withArgName(STATUS).hasArg() 062 .withDescription("Fetches the status for the given application.").create(STATUS)) 063 .addOption(OptionBuilder.withArgName(LIST) 064 .withDescription("Lists the application on the cluster.").create(LIST)); 065 this.options = new Options().addOptionGroup(commands); 066 } 067 068 /** 069 * Helper method to setup apache commons logging. 070 */ 071 private static void setupLogging() { 072 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Jdk14Logger"); 073 System.setProperty(".level", "INFO"); 074 } 075 076 public static void main(final String[] args) throws Exception { 077 setupLogging(); 078 Tang.Factory.getTang() 079 .newInjector(UnsafeHDInsightRuntimeConfiguration.fromEnvironment()) 080 .getInstance(HDICLI.class).run(args); 081 } 082 083 public void run(final String[] args) throws Exception { 084 final CommandLineParser parser = new PosixParser(); 085 086 final CommandLine line = parser.parse(options, args); 087 final List<String> positionalArguments = line.getArgList(); 088 if (line.hasOption(KILL)) { 089 this.kill(line.getOptionValue(KILL)); 090 } else if (line.hasOption(LOGS)) { 091 final String applicationId = line.getOptionValue(LOGS); 092 if (positionalArguments.isEmpty()) { 093 this.logs(applicationId); 094 } else { 095 this.logs(applicationId, new File(positionalArguments.get(0))); 096 } 097 } else if (line.hasOption(LIST)) { 098 this.list(); 099 } else if (line.hasOption(STATUS)) { 100 this.status(line.getOptionValue(STATUS)); 101 } else { 102 throw new Exception("Unable to parse command line"); 103 } 104 105 } 106 107 /** 108 * Kills the application with the given id. 109 * 110 * @param applicationId 111 * @throws IOException 112 */ 113 private void kill(final String applicationId) throws IOException { 114 LOG.log(Level.INFO, "Killing application [{0}]", applicationId); 115 this.hdInsightInstance.killApplication(applicationId); 116 } 117 118 /** 119 * Fetches the logs for the application with the given id and prints them to System.out. 120 * 121 * @param applicationId 122 * @throws IOException 123 */ 124 private void logs(final String applicationId) throws IOException { 125 LOG.log(Level.INFO, "Fetching logs for application [{0}]", applicationId); 126 this.logFetcher.fetch(applicationId, new OutputStreamWriter(System.out, StandardCharsets.UTF_8)); 127 } 128 129 /** 130 * Fetches the logs for the application with the given id and stores them in the given folder. One file per container. 131 * 132 * @param applicationId 133 * @param folder 134 * @throws IOException 135 */ 136 private void logs(final String applicationId, final File folder) throws IOException { 137 LOG.log(Level.FINE, "Fetching logs for application [{0}] and storing them in folder [{1}]", 138 new Object[]{applicationId, folder.getAbsolutePath()}); 139 if (!folder.exists() && !folder.mkdirs()) { 140 LOG.log(Level.WARNING, "Failed to create [{0}]", folder.getAbsolutePath()); 141 } 142 this.logFetcher.fetch(applicationId, folder); 143 } 144 145 /** 146 * Fetches a list of all running applications. 147 * 148 * @throws IOException 149 */ 150 private void list() throws IOException { 151 LOG.log(Level.FINE, "Listing applications"); 152 final List<ApplicationState> applications = this.hdInsightInstance.listApplications(); 153 for (final ApplicationState appState : applications) { 154 if (appState.getState().equals("RUNNING")) { 155 System.out.println(appState.getId() + "\t" + appState.getName()); 156 } 157 } 158 } 159 160 private void status(final String applicationId) throws IOException { 161 final List<ApplicationState> applications = this.hdInsightInstance.listApplications(); 162 ApplicationState applicationState = null; 163 for (final ApplicationState appState : applications) { 164 if (appState.getId().equals(applicationId)) { 165 applicationState = appState; 166 break; 167 } 168 } 169 170 if (applicationState == null) { 171 throw new IOException("Unknown application: " + applicationId); 172 } 173 final ObjectMapper objectMapper = new ObjectMapper(); 174 final String status = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(applicationState); 175 176 System.out.println(status); 177 178 179 } 180 181}