| /* |
| * 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.geode.management.internal.cli.commands.lifecycle; |
| |
| import static org.apache.geode.internal.process.ProcessStreamReader.waitAndCaptureProcessStandardErrorStream; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import javax.management.remote.JMXServiceURL; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.springframework.shell.core.annotation.CliCommand; |
| import org.springframework.shell.core.annotation.CliOption; |
| |
| import org.apache.geode.internal.util.IOUtils; |
| import org.apache.geode.management.cli.CliMetaData; |
| import org.apache.geode.management.internal.cli.GfshParser; |
| import org.apache.geode.management.internal.cli.commands.OfflineGfshCommand; |
| import org.apache.geode.management.internal.cli.i18n.CliStrings; |
| import org.apache.geode.management.internal.cli.result.model.InfoResultModel; |
| import org.apache.geode.management.internal.cli.result.model.ResultModel; |
| import org.apache.geode.management.internal.cli.util.JdkTool; |
| |
| public class StartJConsoleCommand extends OfflineGfshCommand { |
| |
| @CliCommand(value = CliStrings.START_JCONSOLE, help = CliStrings.START_JCONSOLE__HELP) |
| @CliMetaData(shellOnly = true, relatedTopic = {CliStrings.TOPIC_GEODE_MANAGER, |
| CliStrings.TOPIC_GEODE_JMX, CliStrings.TOPIC_GEODE_M_AND_M}) |
| public ResultModel startJConsole( |
| @CliOption(key = CliStrings.START_JCONSOLE__INTERVAL, unspecifiedDefaultValue = "4", |
| help = CliStrings.START_JCONSOLE__INTERVAL__HELP) final int interval, |
| @CliOption(key = CliStrings.START_JCONSOLE__NOTILE, specifiedDefaultValue = "true", |
| unspecifiedDefaultValue = "false", |
| help = CliStrings.START_JCONSOLE__NOTILE__HELP) final boolean notile, |
| @CliOption(key = CliStrings.START_JCONSOLE__PLUGINPATH, |
| help = CliStrings.START_JCONSOLE__PLUGINPATH__HELP) final String pluginpath, |
| @CliOption(key = CliStrings.START_JCONSOLE__VERSION, specifiedDefaultValue = "true", |
| unspecifiedDefaultValue = "false", |
| help = CliStrings.START_JCONSOLE__VERSION__HELP) final boolean version, |
| @CliOption(key = CliStrings.START_JCONSOLE__J, optionContext = GfshParser.J_OPTION_CONTEXT, |
| help = CliStrings.START_JCONSOLE__J__HELP) final String[] jvmArgs) |
| throws InterruptedException, IOException { |
| String[] jconsoleCommandLine = |
| createJConsoleCommandLine(interval, notile, pluginpath, version, jvmArgs); |
| |
| ResultModel resultModel = new ResultModel(); |
| InfoResultModel infoResult = resultModel.addInfo(); |
| if (isDebugging()) { |
| getGfsh().printAsInfo( |
| String.format("JConsole command-line ($1%s)", Arrays.toString(jconsoleCommandLine))); |
| } |
| |
| Process jconsoleProcess = getProcess(jconsoleCommandLine); |
| |
| StringBuilder message; |
| |
| if (version) { |
| jconsoleProcess.waitFor(); |
| message = getErrorStringBuilder(jconsoleProcess); |
| } else { |
| message = new StringBuilder(); |
| getGfsh().printAsInfo(CliStrings.START_JCONSOLE__RUN); |
| |
| String jconsoleProcessOutput = getProcessOutput(jconsoleProcess); |
| |
| if (StringUtils.isNotBlank(jconsoleProcessOutput)) { |
| message.append(System.lineSeparator()); |
| message.append(jconsoleProcessOutput); |
| } |
| } |
| |
| infoResult.addLine(message.toString()); |
| |
| return resultModel; |
| } |
| |
| StringBuilder getErrorStringBuilder(Process jconsoleProcess) throws IOException { |
| StringBuilder message; |
| message = new StringBuilder(); |
| BufferedReader reader = |
| new BufferedReader(new InputStreamReader(jconsoleProcess.getErrorStream())); |
| |
| for (String line = reader.readLine(); line != null; line = reader.readLine()) { |
| message.append(line); |
| message.append(System.lineSeparator()); |
| } |
| |
| IOUtils.close(reader); |
| return message; |
| } |
| |
| String getProcessOutput(Process jconsoleProcess) { |
| return waitAndCaptureProcessStandardErrorStream(jconsoleProcess); |
| } |
| |
| Process getProcess(String[] jconsoleCommandLine) throws IOException { |
| return Runtime.getRuntime().exec(jconsoleCommandLine); |
| } |
| |
| protected String[] createJConsoleCommandLine(final int interval, |
| final boolean notile, final String pluginpath, |
| final boolean version, |
| final String[] jvmArgs) { |
| List<String> commandLine = new ArrayList<>(); |
| |
| commandLine.add(JdkTool.getJConsolePathname()); |
| |
| if (version) { |
| commandLine.add("-version"); |
| } else { |
| commandLine.add("-interval=" + interval); |
| |
| if (notile) { |
| commandLine.add("-notile"); |
| } |
| |
| if (StringUtils.isNotBlank(pluginpath)) { |
| commandLine.add("-pluginpath " + pluginpath); |
| } |
| |
| if (jvmArgs != null) { |
| for (final String arg : jvmArgs) { |
| commandLine.add("-J" + arg); |
| } |
| } |
| |
| JMXServiceURL jmxServiceUrl = getJmxServiceUrl(); |
| if (isConnectedAndReady() && jmxServiceUrl != null) { |
| commandLine.add(jmxServiceUrl.toString()); |
| } |
| } |
| |
| return commandLine.toArray(new String[commandLine.size()]); |
| } |
| } |