| /* |
| * 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.Assert.assertState; |
| import static org.apache.geode.internal.process.ProcessStreamReader.waitAndCaptureProcessStandardErrorStream; |
| |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.FileNotFoundException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.springframework.shell.core.annotation.CliCommand; |
| import org.springframework.shell.core.annotation.CliOption; |
| |
| import org.apache.geode.annotations.Immutable; |
| import org.apache.geode.internal.lang.SystemUtils; |
| import org.apache.geode.internal.util.IOUtils; |
| import org.apache.geode.management.cli.CliMetaData; |
| 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; |
| |
| public class StartVsdCommand extends OfflineGfshCommand { |
| @CliCommand(value = CliStrings.START_VSD, help = CliStrings.START_VSD__HELP) |
| @CliMetaData(shellOnly = true, |
| relatedTopic = {CliStrings.TOPIC_GEODE_M_AND_M, CliStrings.TOPIC_GEODE_STATISTICS}) |
| public ResultModel startVsd(@CliOption(key = CliStrings.START_VSD__FILE, |
| help = CliStrings.START_VSD__FILE__HELP) final String[] statisticsArchiveFilePathnames) |
| throws Exception { |
| |
| String geodeHome = System.getenv("GEODE_HOME"); |
| |
| assertState(org.apache.commons.lang3.StringUtils.isNotBlank(geodeHome), |
| CliStrings.GEODE_HOME_NOT_FOUND_ERROR_MESSAGE); |
| |
| assertState(IOUtils.isExistingPathname(getPathToVsd()), |
| String.format(CliStrings.START_VSD__NOT_FOUND_ERROR_MESSAGE, geodeHome)); |
| |
| String[] vsdCommandLine = createdVsdCommandLine(statisticsArchiveFilePathnames); |
| |
| if (isDebugging()) { |
| getGfsh().printAsInfo( |
| String.format("GemFire VSD command-line (%1$s)", Arrays.toString(vsdCommandLine))); |
| } |
| |
| Process vsdProcess = Runtime.getRuntime().exec(vsdCommandLine); |
| |
| getGfsh().printAsInfo(CliStrings.START_VSD__RUN); |
| |
| String vsdProcessOutput = waitAndCaptureProcessStandardErrorStream(vsdProcess); |
| |
| ResultModel result = new ResultModel(); |
| InfoResultModel info = result.addInfo("info"); |
| |
| if (org.apache.commons.lang3.StringUtils.isNotBlank(vsdProcessOutput)) { |
| info.addLine(vsdProcessOutput); |
| } |
| |
| return result; |
| } |
| |
| protected String[] createdVsdCommandLine(final String[] statisticsArchiveFilePathnames) |
| throws FileNotFoundException { |
| List<String> commandLine = new ArrayList<>(); |
| |
| commandLine.add(getPathToVsd()); |
| commandLine.addAll(processStatisticsArchiveFiles(statisticsArchiveFilePathnames)); |
| |
| return commandLine.toArray(new String[commandLine.size()]); |
| } |
| |
| protected String getPathToVsd() { |
| String vsdPathname = |
| IOUtils.appendToPath(System.getenv("GEODE_HOME"), "tools", "vsd", "bin", "vsd"); |
| |
| if (SystemUtils.isWindows()) { |
| vsdPathname += ".bat"; |
| } |
| |
| return vsdPathname; |
| } |
| |
| protected Set<String> processStatisticsArchiveFiles(final String[] statisticsArchiveFilePathnames) |
| throws FileNotFoundException { |
| Set<String> statisticsArchiveFiles = new TreeSet<>(); |
| |
| if (statisticsArchiveFilePathnames != null) { |
| for (String pathname : statisticsArchiveFilePathnames) { |
| File path = new File(pathname); |
| |
| if (path.exists()) { |
| if (path.isFile()) { |
| if (StatisticsArchiveFileFilter.INSTANCE.accept(path)) { |
| statisticsArchiveFiles.add(pathname); |
| } else { |
| throw new IllegalArgumentException( |
| "A Statistics Archive File must end with a .gfs file extension."); |
| } |
| } else { // the File (path) is a directory |
| processStatisticsArchiveFiles(path, statisticsArchiveFiles); |
| } |
| } else { |
| throw new FileNotFoundException(String.format( |
| "The pathname (%1$s) does not exist. Please check the path and try again.", |
| path.getAbsolutePath())); |
| } |
| } |
| } |
| |
| return statisticsArchiveFiles; |
| } |
| |
| @SuppressWarnings("null") |
| protected void processStatisticsArchiveFiles(final File path, |
| final Set<String> statisticsArchiveFiles) { |
| if (path != null && path.isDirectory()) { |
| for (File file : path.listFiles(StatisticsArchiveFileAndDirectoryFilter.INSTANCE)) { |
| if (file.isDirectory()) { |
| processStatisticsArchiveFiles(file, statisticsArchiveFiles); |
| } else if (StatisticsArchiveFileFilter.INSTANCE.accept(file)) { |
| statisticsArchiveFiles.add(file.getAbsolutePath()); |
| } |
| } |
| } |
| } |
| |
| |
| protected static class StatisticsArchiveFileFilter implements FileFilter { |
| |
| @Immutable |
| protected static final StatisticsArchiveFileFilter INSTANCE = new StatisticsArchiveFileFilter(); |
| |
| @Override |
| public boolean accept(final File pathname) { |
| return (pathname.isFile() && pathname.getAbsolutePath().endsWith(".gfs")); |
| } |
| } |
| |
| protected static class StatisticsArchiveFileAndDirectoryFilter |
| extends StatisticsArchiveFileFilter { |
| |
| @Immutable |
| protected static final StatisticsArchiveFileAndDirectoryFilter INSTANCE = |
| new StatisticsArchiveFileAndDirectoryFilter(); |
| |
| @Override |
| public boolean accept(final File pathname) { |
| return (pathname.isDirectory() || super.accept(pathname)); |
| } |
| } |
| } |