Java tutorial
/************************************************************ * Copyright (c) 2015, Lawrence Livermore National Security, LLC. * Produced at the Lawrence Livermore National Laboratory. * Written by Timothy Meier, meier3@llnl.gov, All rights reserved. * LLNL-CODE-673346 * * This file is part of the OpenSM Monitoring Service (OMS) package. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License (as published by * the Free Software Foundation) version 2.1 dated February 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE * * Our Preamble Notice * * A. This notice is required to be provided under our contract with the U.S. * Department of Energy (DOE). This work was produced at the Lawrence Livermore * National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE. * * B. Neither the United States Government nor Lawrence Livermore National * Security, LLC nor any of their employees, makes any warranty, express or * implied, or assumes any liability or responsibility for the accuracy, * completeness, or usefulness of any information, apparatus, product, or * process disclosed, or represents that its use would not infringe privately- * owned rights. * * C. Also, reference herein to any specific commercial products, process, or * services by trade name, trademark, manufacturer or otherwise does not * necessarily constitute or imply its endorsement, recommendation, or favoring * by the United States Government or Lawrence Livermore National Security, * LLC. The views and opinions of authors expressed herein do not necessarily * state or reflect those of the United States Government or Lawrence Livermore * National Security, LLC, and shall not be used for advertising or product * endorsement purposes. * * file: SmtUtilize.java * * Created on: May 31, 2015 * Author: meier3 ********************************************************************/ package gov.llnl.lc.smt.command.utilize; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import gov.llnl.lc.infiniband.opensm.plugin.data.OMS_Collection; import gov.llnl.lc.infiniband.opensm.plugin.data.OMS_List; import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_NodeType; import gov.llnl.lc.infiniband.opensm.plugin.data.OpenSmMonitorService; import gov.llnl.lc.smt.SmtConstants; import gov.llnl.lc.smt.command.SmtCommand; import gov.llnl.lc.smt.command.config.SmtConfig; import gov.llnl.lc.smt.data.SMT_AnalysisChangeListener; import gov.llnl.lc.smt.data.SMT_UpdateService; import gov.llnl.lc.smt.manager.SMT_AnalysisManager; import gov.llnl.lc.smt.manager.SMT_AnalysisUpdater; import gov.llnl.lc.smt.props.SmtProperty; import gov.llnl.lc.time.TimeStamp; /********************************************************************** * Describe purpose and responsibility of SmtUtilize * <p> * @see related classes and interfaces * * @author meier3 * * @version May 31, 2013 2:56:01 PM **********************************************************************/ public class SmtUtilize extends SmtCommand implements SMT_AnalysisChangeListener { SMT_AnalysisManager Analysis_Mgr = SMT_AnalysisManager.getInstance(); OSM_NodeType aType = OSM_NodeType.UNKNOWN; boolean longForm = true; /************************************************************ * Method Name: * doCommand **/ /** * Describe the method here * * @see gov.llnl.lc.smt.command.SmtCommand#doCommand(gov.llnl.lc.smt.command.config.SmtConfig) * * @param config * @return * @throws Exception ***********************************************************/ @Override public boolean doCommand(SmtConfig config) throws Exception { // support online or offline (connected or file based) // support single shot or continuous // // online & single (reqr: two snapshots to form a Delta) // online & continuous (ctrl-c to stop) // offline & single (reqr: OMS History, OSM_DeltaFabric) // offline & continuous (reqr: OMS History file) // // // this is the utilize command, and ultimately we want to be able // to operate off an instance of the the service (OFFLINE) or // dynamically with changing data // ALSO: a mode where a connection is established and used or // reused until done. As opposed to a new connection each time // new data is desired or refreshed. Both have pros/cons, so // provide both. boolean exit = false; initServiceUpdater(config); if (OMService == null) { System.err.println("The service is null"); } else { // this is the GUI command, and it can take a subcommand and an argument String subCommand = null; String subCommandArg = null; String sOnce = null; String sPlay = null; if (config != null) { Map<String, String> map = config.getConfigMap(); subCommand = map.get(SmtProperty.SMT_SUBCOMMAND.getName()); subCommandArg = map.get(subCommand); sOnce = map.get(SmtProperty.SMT_SINGLE_SHOT.getName()); sPlay = map.get(SmtProperty.SMT_PLAY_CONTROL.getName()); } // start all managers /* refer to SmtConsole, may need a manager to do this more cleanly */ exit = (UpdateService == null) || (OMService == null); if (!exit) { // connect the analyzer to the service Analysis_Mgr.setIncludedTypes(aType); UpdateService.addListener(Analysis_Mgr); Analysis_Mgr.addSMT_AnalysisChangeListener(this); if (sPlay == null) sPlay = "false"; boolean playable = sPlay.toLowerCase().startsWith("t") || sPlay.toLowerCase().startsWith("y"); if (sOnce == null) sOnce = "false"; boolean once = sOnce.toLowerCase().startsWith("t") || sOnce.toLowerCase().startsWith("y"); longForm = !(SmtProperty.SMT_DUMP.getName().equalsIgnoreCase(subCommand)); boolean pControl = once ? false : playable; /* * We are either onLine or offLine - isOnLine() * We want a single snaphot, or continuous * if continuous; with or without playBar * We want a short or long form */ // normally run this continuously, but allow for a single shot if (once) { dumpOneUtilization(); System.exit(0); } // if here, display multiple - either from a file, or connection if ((pControl) && (UpdateService instanceof SMT_UpdateService)) // a floating time slider ((SMT_UpdateService) UpdateService).setDetachedFrame(true); if (!isOnLine() && !pControl) { // this is from a file and not using the play control, so just display everything dumpAllUtilization(); System.exit(0); } // if here, we are displaying continuously from a file or from a connection // infinite wait loop while (!exit) { TimeUnit.MINUTES.sleep(5); // if this is connected to a file, check if we have reached the end, and wrap is not true // allow exit to be true, if we have reached the end } } } return true; } /************************************************************ * Method Name: * init **/ /** * Describe the method here * * @see gov.llnl.lc.smt.command.SmtCommand#init() * * @return ***********************************************************/ @Override public boolean init() { USAGE = "[-h=<host url>] [-pn=<port num>] [-rH=<filename> [-pX=<playback multipliers>]] "; HEADER = "\nsmt-utilize - display % bandwidth utilized\n\n"; EXAMPLE = "examples:" + SmtConstants.NEW_LINE + "> smt-utilize -pn 10013 - continuously shows the bandwidth utilization of all ports via the service (long form)" + SmtConstants.NEW_LINE + "> smt-utilize -rH HypeFR.his -pControl -dump -SW - shows the raw switch to switch port utilization from the file using the play controls" + SmtConstants.NEW_LINE + "> smt-utilize -pn 10011 -once -dump -CA - shows the current bandwidth utilization of the ports connected to channel adapters" + SmtConstants.NEW_LINE + "> smt-utilize -rH HypeFR.his -once - shows the first bw utilization for all the ports from the flight recorder file" + SmtConstants.NEW_LINE + "."; // terminate with nl // create and initialize the common options for this command initMinimumOptions(); initConnectionOptions(); initPlayableOptions(); SmtProperty sp = SmtProperty.SMT_READ_OMS_HISTORY; Option rHist = OptionBuilder.hasArg(true).hasArgs(1).withArgName(sp.getArgName()).withValueSeparator('=') .withDescription(sp.getDescription()).withLongOpt(sp.getName()).create(sp.getShortName()); sp = SmtProperty.SMT_DUMP; Option dump = OptionBuilder.hasArg(false).withDescription(sp.getDescription()).withLongOpt(sp.getName()) .create(sp.getShortName()); Option sw_type = OptionBuilder.hasArg(false).withDescription("analyze only switch to switch ports") .withLongOpt("switch2switch").create("SW"); Option ca_type = OptionBuilder.hasArg(false).withDescription("analyze ports to or from channel adapters") .withLongOpt("edgePort").create("CA"); options.addOption(rHist); options.addOption(dump); options.addOption(sw_type); options.addOption(ca_type); return true; } /************************************************************ * Method Name: * parseCommands **/ /** * Parse the command line options here. If any of these need to be persistent * then they need to be "put" into the config map. Otherwise the command line * options need to set "command" flags or variables, which will potentially be * used later, typically by the "doCommand()". * * * @see gov.llnl.lc.smt.command.SmtCommand#parseCommands(java.util.Map, org.apache.commons.cli.CommandLine) * * @param config * @param line * @return ***********************************************************/ @Override public boolean parseCommands(Map<String, String> config, CommandLine line) { boolean status = true; // set the command and sub-command (always do this) to default values config.put(SmtProperty.SMT_COMMAND.getName(), this.getClass().getName()); // config.put(SmtProperty.SMT_SUBCOMMAND.getName(), SmtProperty.SMT_QUERY_ALL.getName()); SmtProperty sp = SmtProperty.SMT_READ_OMS_HISTORY; if (line.hasOption(sp.getName())) { // put the file in both places status = putHistoryProperty(config, line.getOptionValue(sp.getName())); if (status) { config.put(SmtProperty.SMT_FILE_NAME.getName(), convertSpecialFileName(line.getOptionValue(sp.getName()))); config.put(SmtProperty.SMT_OMS_COLLECTION_FILE.getName(), convertSpecialFileName(line.getOptionValue(sp.getName()))); } // see if there was a timestamp specified, and if so, does it make sense String ts = config.get(SmtProperty.SMT_TIMESTAMP.getName()); // it could be null, or if it returns the current time, then its probably crap if ((ts == null) || ((new TimeStamp()).compareTo(new TimeStamp(ts))) == 0) { logger.severe("The timestamp couldn't be created for: (" + ts + ")"); // empty or couldn't convert to timestring (set special directive to use default value) config.put(SmtProperty.SMT_TIMESTAMP.getName(), SmtProperty.SMT_USE_DEFAULT.getName()); } } sp = SmtProperty.SMT_DUMP; if (line.hasOption(sp.getName())) { // the dump option is intended to process a file, and display the results as soon as possible // - playback speed does not apply - instead process next delta as soon as previous finishes // - wrap does not apply - display from beginning to end, then stop // - connection issues do not apply, this is file based config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName()); config.put(sp.getName(), line.getOptionValue(sp.getName())); } if (line.hasOption("SW")) { aType = OSM_NodeType.SW_NODE; } else if (line.hasOption("CA")) { aType = OSM_NodeType.CA_NODE; } // parse (only) the command specific options sp = SmtProperty.SMT_REUSE; if (line.hasOption(sp.getName())) { config.put(sp.getName(), line.getOptionValue(sp.getName())); } sp = SmtProperty.SMT_UPDATE_PERIOD; if (line.hasOption(sp.getName())) { config.put(sp.getName(), line.getOptionValue(sp.getName())); } sp = SmtProperty.SMT_UPDATE_MULTIPLIER; if (line.hasOption(sp.getName())) { config.put(sp.getName(), line.getOptionValue(sp.getName())); } sp = SmtProperty.SMT_WRAP_DATA; if (line.hasOption(sp.getName())) { config.put(sp.getName(), line.getOptionValue(sp.getName())); } sp = SmtProperty.SMT_SINGLE_SHOT; if (line.hasOption(sp.getName())) { config.put(sp.getName(), "true"); } sp = SmtProperty.SMT_PLAY_CONTROL; if (line.hasOption(sp.getName())) { config.put(sp.getName(), "true"); } return status; } private void dumpAllUtilization() { // iterate through the history, and display the analysis boolean exit = (UpdateService == null) || (OMService == null); if (!exit) { if (UpdateService instanceof SMT_UpdateService) { SMT_UpdateService sus = ((SMT_UpdateService) UpdateService); OMS_Collection collection = sus.getCollection(); LinkedHashMap<String, OpenSmMonitorService> omsHistory = collection.getOSM_History(); // loop through the history, and display the utilization (key is timestamp, value is OMS) for (Map.Entry<String, OpenSmMonitorService> entry : omsHistory.entrySet()) { OpenSmMonitorService oms = entry.getValue(); try { // trigger a new analysis Analysis_Mgr.osmServiceUpdate(sus, oms); // give the analyzer some time to complete, and signal the smtAnalysisUpdate, before continuing TimeUnit.SECONDS.sleep(1); } catch (Exception e) { System.err.println("Error doing the delta analysis, or time delay"); } } } else System.err.println("Using the original OMS_UpdateService"); } } private void dumpOneUtilization() { boolean exit = (UpdateService == null) || (OMService == null); if (!exit) { if (UpdateService instanceof SMT_UpdateService) { SMT_UpdateService sus = ((SMT_UpdateService) UpdateService); OMS_Collection collection = sus.getCollection(); OMS_List list = collection.getOMS_List(); if (list.size() > 1) { OpenSmMonitorService[] omsArray = list.getRecentOMSs(2); for (OpenSmMonitorService oms : omsArray) { try { // trigger a new analysis Analysis_Mgr.osmServiceUpdate(sus, oms); // give the analyzer some time to complete, and signal the smtAnalysisUpdate, before continuing TimeUnit.SECONDS.sleep(2); } catch (Exception e) { System.err.println("Error doing the delta analysis, or time delay"); } } } } else System.err.println("Using the original OMS_UpdateService"); } } /************************************************************ * Method Name: * main **/ /** * Describe the method here * * @see describe related java objects * * @param args ***********************************************************/ public static void main(String[] args) throws Exception { System.exit((new SmtUtilize().execute(args)) ? 0 : -1); } /************************************************************ * Method Name: * smtAnalysisUpdate **/ /** * Describe the method here * * @see gov.llnl.lc.smt.data.SMT_AnalysisChangeListener#smtAnalysisUpdate(gov.llnl.lc.smt.manager.SMT_AnalysisUpdater) * * @param updater * @throws Exception ***********************************************************/ @Override public void smtAnalysisUpdate(SMT_AnalysisUpdater updater) throws Exception { if (longForm) System.out.println(Analysis_Mgr.getDeltaAnalysis().getFabricRateUtilizationSummary()); else System.out.println(Analysis_Mgr.getDeltaAnalysis().getDeltaTimeStamp() + ", " + Analysis_Mgr.getDeltaAnalysis().getFabricRateUtilizationShortSummary()); } }