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: SmtEvent.java * * Created on: Aug 6, 2015 * Author: meier3 ********************************************************************/ package gov.llnl.lc.smt.command.event; import java.util.LinkedHashMap; import java.util.Map; 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.OSM_Fabric; import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_FabricDelta; import gov.llnl.lc.infiniband.opensm.plugin.data.OpenSmMonitorService; import gov.llnl.lc.infiniband.opensm.plugin.event.OSM_EventStats; import gov.llnl.lc.infiniband.opensm.plugin.event.OsmEvent; import gov.llnl.lc.infiniband.opensm.plugin.net.OsmServerStatus; 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_UpdateService; import gov.llnl.lc.smt.props.SmtProperty; /********************************************************************** * Describe purpose and responsibility of SmtEvent * <p> * @see related classes and interfaces * * @author meier3 * * @version Mar 20, 2013 12:08:04 PM **********************************************************************/ public class SmtEvent extends SmtCommand { /************************************************************ * 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.SmtCommandInterface#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) config.put(SmtProperty.SMT_COMMAND.getName(), this.getClass().getName()); // if the host and port is supplied on the command line, assume we are making // a connection to the service - no matter what // // if an OMS_FILE or FABRIC_FILE is supplied, it could be for reading or writing // but NOT BOTH. We need to determine which based on; // // if host and port is supplied, then its for WRITING // // if host and port is NOT supplied AND there is persistent host and port configured // AND the -R flag is NOT provided on the command line, then its for WRITING // // if host and port is NOT supplied AND there is no persistent host and port configured // then its for READING // // if the -R flag is provided on the command line, then its for READING // parse (only) the command specific options SmtProperty sp = SmtProperty.SMT_READ_OMS_HISTORY; if (line.hasOption(sp.getName())) { // save this, only if its a valid file status = putHistoryProperty(config, line.getOptionValue(sp.getName())); if (status) { config.put(SmtProperty.SMT_OMS_COLLECTION_FILE.getName(), convertSpecialFileName(line.getOptionValue(sp.getName()))); } config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName()); } // parse (only) the command specific options sp = SmtProperty.SMT_QUERY_TYPE; if (line.hasOption(sp.getName())) { config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName()); config.put(sp.getName(), line.getOptionValue(sp.getName())); } sp = SmtProperty.SMT_QUERY_LIST; if (line.hasOption(sp.getName())) { config.put(SmtProperty.SMT_SUBCOMMAND.getName(), SmtProperty.SMT_QUERY_TYPE.getName()); config.put(SmtProperty.SMT_QUERY_TYPE.getName(), SmtProperty.SMT_LIST.getName()); } sp = SmtProperty.SMT_STATUS; if (line.hasOption(sp.getName())) { config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName()); config.put(sp.getName(), line.getOptionValue(sp.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())); } return status; } /************************************************************ * 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 obtaining the fabric on-line, or from an OMS or Fabric // file. Only one at a time.... // which is all done by default within the execute() command of the // parent superclass smt-command // only one way of obtaining fabric data should be specified, but IF more // than one is, prefer; // // on-line (if host or port is specified) // OMS file // Fabric file // on-line using localhost and port 10011 initServiceUpdater(config); Map<String, String> map = smtConfig.getConfigMap(); String subCommand = map.get(SmtProperty.SMT_SUBCOMMAND.getName()); if (subCommand == null) subCommand = SmtProperty.SMT_HELP.getName(); // there should only be one subcommand if (subCommand.equalsIgnoreCase(SmtProperty.SMT_QUERY_TYPE.getName())) { EventQuery qType = EventQuery.getByName(map.get(SmtProperty.SMT_QUERY_TYPE.getName())); if (qType == null) { logger.severe("Invalid SmtEvent query option"); subCommand = SmtProperty.SMT_HELP.getName(); return false; } switch (qType) { case EVENT_LIST: System.out.println(EventQuery.describeAllQueryTypes()); break; case EVENT_TYPES: System.out.println(OsmEvent.getEventEnumTable()); break; case EVENT_STATUS: if (OMService != null) System.out.println(getEventSummary(getOSM_FabricDelta(false), "")); else System.err.println("An OMS instance is required (connection or file)"); break; default: System.out.println("That's not an option"); break; } } else if (subCommand.equalsIgnoreCase(SmtProperty.SMT_STATUS.getName())) { System.out.println(getEventSummary(getOSM_FabricDelta(false), "")); } else if (subCommand.equalsIgnoreCase(SmtProperty.SMT_DUMP.getName())) { int eNum = -1; // by default, do all String eventNum = map.get(SmtProperty.SMT_DUMP.getName()); if (eventNum != null) eNum = Integer.parseInt(eventNum); // System.err.println("The event number is: " + eventNum); // System.err.println("The event number is: " + eNum); // OsmEvent e = OsmEvent.get(eNum); // if(e != null) // System.err.println("The event is: " + e.getEventName()); /* iterate through all the OMS, and dump the counters */ if (UpdateService != null) { if ((UpdateService instanceof SMT_UpdateService)) dumpAllEvents(e); } else System.err.println("The update service appears to be null"); return true; } else if (OMService != null) System.out.println(getStatus(OMService)); return true; } private void dumpAllEvents(OsmEvent e) { // dump event data for all OMS records // if the OsmEvent parameter is NOT null, then just list that event // otherwise, list all events in OSM_EventStats // using an SMT_Updater, AND I have already read the file, so just set the collection SMT_UpdateService sus = (SMT_UpdateService) UpdateService; OMS_Collection collection = sus.getCollection(); LinkedHashMap<String, OpenSmMonitorService> omsHistory = collection.getOSM_History(); // display all the Events, or just a single one? // loop through the history and dump the event stats for each timestamp for (Map.Entry<String, OpenSmMonitorService> entry : omsHistory.entrySet()) { OpenSmMonitorService oms = entry.getValue(); OSM_Fabric fabric = oms.getFabric(); OSM_EventStats EventStats = fabric.getOsmEventStats(); if (e == null) System.out.println(fabric.getTimeStamp() + ": " + EventStats.toString()); else { System.out.println(fabric.getTimeStamp() + ": " + EventStats.toEventString(e)); // System.out.println(fabric.getTimeStamp() + ": " + EventStats.getCounter(e)); } } } public static String getStatus(OpenSmMonitorService OMService) { /* TODO create a HASHMAP or some sort of name value pair thing, that can be formatted later */ // return a string representation of the subnet status, similar to the opensm console // or smt-console if (OMService == null) { logger.severe("Can't get status from a null object"); return "Can't get status from a null OMS object"; } OSM_Fabric Fabric = OMService.getFabric(); StringBuffer buff = new StringBuffer(); // total nodes, ports and links, broken down by type OsmServerStatus RStatus = OMService.getRemoteServerStatus(); buff.append(String.format(" Event Status\n")); buff.append(SmtConstants.NEW_LINE); buff.append(String.format("Fabric Name: %20s\n", Fabric.getFabricName())); if (RStatus != null) buff.append(String.format("Up since: %20s\n", OMService.getRemoteServerStatus().Server.getStartTime().toString())); buff.append(String.format("timestamp: %20s\n", Fabric.getTimeStamp().toString())); buff.append(SmtConstants.NEW_LINE); String formatString = "%-19s %12d"; buff.append("---event type---------------------count--" + SmtConstants.NEW_LINE); OSM_EventStats EventStats = Fabric.getOsmEventStats(); for (OsmEvent s : OsmEvent.OSM_STAT_EVENTS) buff.append(String.format(formatString, s.getEventName() + ":", EventStats.getCounter(s)) + SmtConstants.NEW_LINE); return buff.toString(); } public static String getEventSummary(OSM_FabricDelta fd, String prePend) { // xx: error state <- (link info) -> guid:portnum name StringBuffer buff = new StringBuffer(); String formatString = "%s %19s: %7d, (%5d)"; if (fd != null) { OSM_Fabric fabric = fd.getFabric2(); // System.err.println(fd.getFabric1().getTimeStamp()); // System.err.println(fd.getFabric2().getTimeStamp()); // System.err.println(fd.getAgeDifference(TimeUnit.MINUTES)); OSM_EventStats DiffStats = fd.getEventChanges(); OSM_EventStats EventStats = fabric.getOsmEventStats(); buff.append(" Event Summary" + SmtConstants.NEW_LINE); buff.append(" " + fabric.getTimeStamp() + " (delta: " + fd.getDeltaSeconds() + "s)" + SmtConstants.NEW_LINE); buff.append(" count (delta count)" + SmtConstants.NEW_LINE); for (OsmEvent s : OsmEvent.OSM_STAT_EVENTS) buff.append(String.format(formatString, prePend, s.getEventName(), EventStats.getCounter(s), DiffStats.getCounter(s)) + SmtConstants.NEW_LINE); } return buff.toString(); } /************************************************************ * Method Name: * init **/ /** * Describe the method here * * @see gov.llnl.lc.smt.command.SmtCommand#init() * @see gov.llnl.lc.smt.command.SmtCommand#initCommonOptions() * * @return ***********************************************************/ @Override public boolean init() { USAGE = "[-h=<host url>] [-pn=<port num>] -sr"; HEADER = "smt-event - a tool for obtaining event information"; EXAMPLE = "examples:" + SmtConstants.NEW_LINE + "> smt-event -pn 10013" + SmtConstants.NEW_LINE + "> smt-event -pn 10013 -sr" + SmtConstants.NEW_LINE + "> smt-event -rH surface3h.his -dump 10" + SmtConstants.NEW_LINE + "> smt-event -q events" + SmtConstants.NEW_LINE + "> smt-event -rH surface3h.his -q status" + SmtConstants.NEW_LINE + "."; // terminate with nl // create and initialize the common options for this command initCommonOptions(); // add non-common options initMulitReadFileOptions(); // read the remainder of the file types SmtProperty sp = SmtProperty.SMT_QUERY_TYPE; Option qType = OptionBuilder.hasArg(true).hasArgs(1).withArgName(sp.getArgName()).withValueSeparator('=') .withDescription(sp.getDescription()).withLongOpt(sp.getName()).create(sp.getShortName()); sp = SmtProperty.SMT_QUERY_LIST; Option qList = new Option(sp.getShortName(), sp.getName(), false, sp.getDescription()); sp = SmtProperty.SMT_DUMP; Option dump = OptionBuilder.hasOptionalArg().withDescription(sp.getDescription()).withLongOpt(sp.getName()) .create(sp.getShortName()); sp = SmtProperty.SMT_STATUS; Option status = OptionBuilder.hasArg(false).withDescription(sp.getDescription()).withLongOpt(sp.getName()) .create(sp.getShortName()); options.addOption(status); options.addOption(qType); options.addOption(qList); options.addOption(dump); return true; } /************************************************************ * Method Name: * main **/ /** * Describe the method here * * @see describe related java objects * * @param args * @throws Exception ***********************************************************/ public static void main(String[] args) throws Exception { System.exit((new SmtEvent().execute(args)) ? 0 : -1); } }