gov.llnl.lc.smt.command.link.SmtLink.java Source code

Java tutorial

Introduction

Here is the source code for gov.llnl.lc.smt.command.link.SmtLink.java

Source

/************************************************************
 * 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: SmtLink.java
 *
 *  Created on: Aug 6, 2015
 *      Author: meier3
 ********************************************************************/
package gov.llnl.lc.smt.command.link;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;

import gov.llnl.lc.infiniband.core.IB_Guid;
import gov.llnl.lc.infiniband.core.IB_Link;
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.OSM_LinkSpeed;
import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_Node;
import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_Nodes;
import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_Port;
import gov.llnl.lc.infiniband.opensm.plugin.data.OSM_Ports;
import gov.llnl.lc.infiniband.opensm.plugin.data.OpenSmMonitorService;
import gov.llnl.lc.infiniband.opensm.plugin.graph.IB_Edge;
import gov.llnl.lc.infiniband.opensm.plugin.graph.IB_Vertex;
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.props.SmtProperty;

/**********************************************************************
 * Describe purpose and responsibility of SmtRoute
 * <p>
 * @see  related classes and interfaces
 *
 * @author meier3
 * 
 * @version Sep 11, 2013 8:13:06 AM
 **********************************************************************/
public class SmtLink extends SmtCommand {

    /************************************************************
     * 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 {
        // this is a Link command, and it can take a subcommand and an argument
        String subCommand = null;
        Map<String, String> map = smtConfig.getConfigMap();

        int pNum = getPortNumber(config);
        IB_Guid g = getNodeGuid(config, pNum);

        if (config != null) {
            //      config.printConfig();
            map = config.getConfigMap();
            subCommand = map.get(SmtProperty.SMT_SUBCOMMAND.getName());
            if (subCommand != null)
                logger.info(subCommand);

            // check to see if the subCommand takes any arguments or values
            if (subCommand == null) {
                subCommand = SmtProperty.SMT_HELP.getName();
            }
        }

        // attempt to identify the port
        OSM_Fabric fabric = null;
        OSM_Port p = null;
        if ((OMService != null) && (g != null)) {
            fabric = OMService.getFabric();
            p = fabric.getOSM_Port(OSM_Port.getOSM_PortKey(g.getGuid(), (short) pNum));
        }
        if (OMService == null)
            logger.severe("The service is null");

        // this is the LINK command, and it can take a subcommand and an argument
        String subCommandArg = null;
        boolean onlyMissing = false;
        boolean includeMissing = true;

        subCommandArg = map.get(subCommand);

        String oMstring = map.get(SmtProperty.SMT_ONLY_MISSING.getName());
        if ((oMstring != null) && (oMstring.startsWith("t") || (oMstring.startsWith("T"))))
            onlyMissing = true;

        String iMstring = map.get(SmtProperty.SMT_INCLUDE_MISSING.getName());
        if ((iMstring != null) && (iMstring.startsWith("f") || (iMstring.startsWith("F"))))
            includeMissing = false;

        // there should only be one subcommand (use big if statement)
        if (subCommand.equalsIgnoreCase(SmtProperty.SMT_QUERY_TYPE.getName())) {
            LinkQuery qType = LinkQuery.getByName(map.get(SmtProperty.SMT_QUERY_TYPE.getName()));

            if (qType == null) {
                logger.severe("Invalid SmtLink query option");
                subCommand = SmtProperty.SMT_HELP.getName();
                return false;
            }

            OSM_FabricDelta fd = null;
            LinkedHashMap<String, IB_Link> links = null;
            if ((OMService != null) && (g != null)) {
                fd = getOSM_FabricDelta(false);
                if (fd == null) {
                    // this should not happen, but if so, can't go further
                    logger.severe("Could not produce FabricDelta's, suspect corrupt file.  Try -dump");
                    System.out.println("Could not produce FabricDelta's, suspect corrupt file.  Try -dump");
                    System.exit(0);
                }

                fabric = fd.getFabric2();
                links = fabric.getIB_Links(g);
            }
            switch (qType) {
            case LINK_LIST:
                System.out.println(LinkQuery.describeAllQueryTypes());
                break;

            case LINK_STATUS:
                IB_Link link = IB_Link.getIB_Link(getAllLinks(), p);
                if (link != null)
                    System.out.println(SmtLink.getLinkSummary(OMService, link));
                else
                    showStatus();
                break;

            case LINK_LEVELS:
                showLevels();
                break;

            case LINK_ALL:
                printStringMap(IB_LinkInfo.getLinkInfoRecords(OMService, fd, true, true));
                break;

            case LINK_ACTIVE:
                printStringMap(IB_LinkInfo.getLinkInfoRecords(OMService, fd, true, false));
                break;

            case LINK_DOWN:
                printStringMap(IB_LinkInfo.getLinkInfoRecords(OMService, fd, false, true));
                break;

            case LINK_ERROR:
                printStringMap(IB_LinkInfo.getErrorLinkInfoRecords(OMService, fd));
                break;

            case LINK_SWITCHES:
                printStringMap(IB_LinkInfo.getSWLinkInfoRecords(OMService, fd, !onlyMissing, includeMissing));
                break;

            case LINK_HOSTS:
                printStringMap(IB_LinkInfo.getCALinkInfoRecords(OMService, fd, !onlyMissing, includeMissing));
                break;

            case LINK_SPEED:
                OSM_LinkSpeed ls = getLinkSpeed(config);
                dumpAllLinks(ls);
                System.exit(0);
                break;

            default:
                System.out.println("That's not an option");
                break;
            }
            System.exit(0);
        } else if (subCommand.equalsIgnoreCase(SmtProperty.SMT_STATUS.getName())) {
            showStatus();
        } else if (subCommand.equalsIgnoreCase(SmtProperty.SMT_DUMP.getName())) {
            dumpAllLinks();
        } else if (subCommand.equalsIgnoreCase(SmtProperty.SMT_LIST.getName())) {
            System.err.println("List");
        } else if (subCommand.equals(SmtProperty.SMT_QUERY_LEVEL.getName()) && subCommandArg != null) {
            Integer level = new Integer(subCommandArg);
            LinkedHashMap<String, String> lmap = IB_LinkInfo.getLinkInfoRecordsByDepth(OMService,
                    getOSM_FabricDelta(false), level.intValue());
            System.out.println("Link Level " + level.intValue() + ": " + lmap.size() + " links");
            printStringMap(lmap);
        } else if (subCommand.equals(SmtProperty.SMT_STATUS.getName())) {
            showStatus();
        } else if (g == null) {
            showStatus();
        }

        if ((g != null) || (p != null)) {
            if (pNum < 1)
                printStringMap(IB_LinkInfo.getLinkInfoRecordsByGuid(g, OMService, getOSM_FabricDelta(false),
                        !onlyMissing, includeMissing));
            else
                printStringMap(IB_LinkInfo.getLinkInfoRecordsByPort(p, OMService, getOSM_FabricDelta(false)));
        }
        return true;
    }

    /************************************************************
     * Method Name:
     *  dumpAllLinks
    **/
    /**
     * Describe the method here
     *
     * @see     describe related java objects
     *
     * @param ls
     ***********************************************************/
    private void dumpAllLinks(OSM_LinkSpeed lspeed) {
        // "ALL" IB_Links
        ArrayList<IB_Link> ibla = getAllLinks();
        if ((ibla != null) && (lspeed != null))
            for (IB_Link l : ibla) {
                if (lspeed == l.getSpeed())
                    printLinkInfo(l);
            }
    }

    /************************************************************
     * 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>] ";
        HEADER = "smt-link - a tool for obtaining high level link information";
        EXAMPLE = "examples:" + SmtConstants.NEW_LINE
                + "> smt-link -pn 10011 -q status           - provide a link summary" + SmtConstants.NEW_LINE
                + "> smt-link -pn 10013 -q errors           - show the links that are currently experiencing errors"
                + SmtConstants.NEW_LINE
                + "> smt-link -q status 196 17              - show the link associated with lid 196 port 17"
                + SmtConstants.NEW_LINE
                + "> smt-link -pn 10013 -q switches -oM T   - show only the down links between switches"
                + SmtConstants.NEW_LINE + "> smt-link -q speed EDR                  - show all of the EDR links"
                + SmtConstants.NEW_LINE + "> smt-link -rH surface3h.his -dump       - dump all the link information"
                + SmtConstants.NEW_LINE + "."; // terminate with nl

        // create and initialize the common options for this command
        initCommonOptions();

        //    // add non-common options

        // initialize the command specific options
        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_STATUS;
        Option status = OptionBuilder.hasArg(false).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());

        sp = SmtProperty.SMT_QUERY_LEVEL;
        Option level = OptionBuilder.hasArg(true).hasArgs(1).withArgName(sp.getArgName()).withValueSeparator('=')
                .withDescription(sp.getDescription()).withLongOpt(sp.getName()).create(sp.getShortName());

        sp = SmtProperty.SMT_ONLY_MISSING;
        Option oMissing = OptionBuilder.hasArg(true).hasArgs(1).withArgName(sp.getArgName()).withValueSeparator('=')
                .withDescription(sp.getDescription()).withLongOpt(sp.getName()).create(sp.getShortName());

        options.addOption(qType);
        options.addOption(qList);
        options.addOption(status);
        options.addOption(dump);

        options.addOption(level);
        options.addOption(oMissing);

        return true;
    }

    /************************************************************
     * Method Name:
     *  parseCommands
     **/
    /**
     * Describe the method here
     *
     * @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, args, and sub-command
        config.put(SmtProperty.SMT_COMMAND.getName(), this.getClass().getName());

        // hopefully the node description is here, so save it
        saveCommandArgs(line.getArgs(), config);

        SmtProperty sp = SmtProperty.SMT_READ_OMS_HISTORY;
        if (line.hasOption(sp.getName())) {
            status = putHistoryProperty(config, 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())) {
            config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName());
            config.put(sp.getName(), line.getOptionValue(sp.getName()));
        }

        config.put(SmtProperty.SMT_INCLUDE_MISSING.getName(), "true");
        config.put(SmtProperty.SMT_ONLY_MISSING.getName(), "false");

        sp = SmtProperty.SMT_ONLY_MISSING;
        if (line.hasOption(sp.getName())) {
            // if true,  then include missing is true also
            // if false, then include missing is false also
            config.put(sp.getName(), line.getOptionValue(sp.getName()));
            config.put(SmtProperty.SMT_INCLUDE_MISSING.getName(), line.getOptionValue(sp.getName()));
        }

        sp = SmtProperty.SMT_LIST;
        if (line.hasOption(sp.getName())) {
            config.put(sp.getName(), line.getOptionValue(sp.getName()));
            config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName());
        }

        sp = SmtProperty.SMT_QUERY_LEVEL;
        if (line.hasOption(sp.getName())) {
            config.put(sp.getName(), line.getOptionValue(sp.getName()));
            config.put(SmtProperty.SMT_SUBCOMMAND.getName(), sp.getName());
        }

        return status;
    }

    private int getNumAtLevel(LinkedHashMap<String, IB_Edge> eMap, int level) {
        // given a map of edges, return only those at the desired level (sort by guid then port number)
        int num = 0;

        // iterate through the map, and add only those with the desired depth or level
        for (Entry<String, IB_Edge> entry : eMap.entrySet()) {
            IB_Edge e = entry.getValue();
            if (e.getDepth() == level)
                num++;
        }
        return num;
    }

    private int getNumLevels(LinkedHashMap<String, IB_Edge> eMap) {
        // given a map of edges, find the maximum depth, it must be the number of levels
        int maxLevel = 0;

        for (Entry<String, IB_Edge> entry : eMap.entrySet()) {
            IB_Edge e = entry.getValue();
            maxLevel = maxLevel > e.getDepth() ? maxLevel : e.getDepth();
        }
        return maxLevel + 1;
    }

    /************************************************************
     * Method Name:
     *  dumpAllLinks
    **/
    /**
     * Describe the method here
     *
     * @see     describe related java objects
     *
     ***********************************************************/
    private void dumpAllLinks() {
        // "ALL" IB_Links
        ArrayList<IB_Link> ibla = getAllLinks();
        for (IB_Link l : ibla) {
            System.out.println(l.toContent());
        }
    }

    /************************************************************
     * Method Name:
     *  dumpAllLinks
    **/
    /**
     * Describe the method here
     *
     * @see     describe related java objects
     *
     ***********************************************************/
    private ArrayList<IB_Link> getAllLinks() {
        // "ALL" IB_Links
        ArrayList<IB_Link> ibla = null;
        OSM_Fabric Fabric = OMService.getFabric();
        OSM_Nodes AllNodes = (Fabric == null) ? null : Fabric.getOsmNodes();
        OSM_Ports AllPorts = (Fabric == null) ? null : Fabric.getOsmPorts();

        if ((AllPorts != null) && (AllNodes != null)) {
            // create IB_Links
            ibla = AllPorts.createIB_Links(AllNodes);
        }
        return ibla;
    }

    private void showStatus() {
        System.out.println(IB_LinkInfo.getStatus(OMService));
    }

    private void showLevels() {
        StringBuffer buff = new StringBuffer();
        String formatString = "%9s: %s";
        LinkedHashMap<String, IB_Edge> edgeMap = getEdgeMap();
        if (edgeMap != null) {
            buff.append(String.format(formatString, "total", edgeMap.size() + " links") + SmtConstants.NEW_LINE);

            int maxLevel = getNumLevels(edgeMap);
            for (int l = 0; l < maxLevel; l++) {
                buff.append(String.format(formatString, "level " + l, getNumAtLevel(edgeMap, l) + " links")
                        + SmtConstants.NEW_LINE);
            }
            System.out.println(buff.toString());

        }
    }

    private LinkedHashMap<String, IB_Edge> getEdgeMap() {
        OSM_Fabric Fabric = OMService.getFabric();

        // vertex map  needs to be created first, so depths can be assigned
        return IB_Vertex.createEdgeMap(IB_Vertex.createVertexMap(Fabric));
    }

    private boolean printStringMap(LinkedHashMap<String, String> map) {
        // the tops are all calculated, find the links associated with these
        // ports
        // and return the top unique links

        for (Map.Entry<String, String> mapEntry : map.entrySet()) {
            String s = mapEntry.getValue();
            System.out.println(s);
        }
        return true;
    }

    private boolean printLinkInfo(IB_Link link) {
        IB_LinkInfo li = new IB_LinkInfo(link, OMService);
        System.out.println(li.getLinkInfoLine(OMService));
        return true;
    }

    public static String getLinkSummary(OpenSmMonitorService oms, IB_Link link) {
        String formatString = "%17s:  %s";

        StringBuffer buff = new StringBuffer();
        if (oms != null) {
            OSM_Fabric fabric = oms.getFabric();
            if (fabric != null) {
                if (link != null) {
                    OSM_Port p = link.getEndpoint1();
                    IB_Guid g = p.getNodeGuid();
                    OSM_Node n = fabric.getOSM_Node(g);
                    short pNum = (short) p.getPortNumber();

                    buff.append(String.format(formatString, "First Node name",
                            n.pfmNode.node_name + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "guid", g.toColonString() + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "lid", p.getAddress().getLocalIdHexString() + " ("
                            + p.getAddress().getLocalId() + ")" + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "port #", pNum + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "port address",
                            OSM_Port.getOSM_PortKey(p) + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "errors", p.hasError() + SmtConstants.NEW_LINE));
                    buff.append(SmtConstants.NEW_LINE);

                    buff.append(
                            String.format(formatString, "state", link.getStateString() + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "rate",
                            link.getRate().getRateName() + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "speed",
                            link.getSpeed().getSpeedName() + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "width",
                            link.getWidth().getWidthName() + SmtConstants.NEW_LINE));
                    buff.append(SmtConstants.NEW_LINE);

                    p = link.getEndpoint2();
                    g = p.getNodeGuid();
                    n = fabric.getOSM_Node(g);
                    pNum = (short) p.getPortNumber();

                    buff.append(String.format(formatString, "Second Node name",
                            n.pfmNode.node_name + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "guid", g.toColonString() + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "lid", p.getAddress().getLocalIdHexString() + " ("
                            + p.getAddress().getLocalId() + ")" + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "port #", pNum + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "port address",
                            OSM_Port.getOSM_PortKey(p) + SmtConstants.NEW_LINE));
                    buff.append(String.format(formatString, "errors", p.hasError() + SmtConstants.NEW_LINE));
                }
            }
        }
        return buff.toString();
    }

    private IB_Guid getNodeGuid(SmtConfig config, int pNum) {
        // if there are any arguments, they normally reference a node or port identifier
        // return null, indicating couldn't be found, or nothing specified
        //
        // a node identifier is a name, guid, or lid
        // a port identifier is a node identifier, followed by an int
        if (config != null) {
            Map<String, String> map = config.getConfigMap();
            String portid = map.get(SmtProperty.SMT_COMMAND_ARGS.getName());
            if (portid != null) {
                // should be at least one word
                //  if more than one, check to see if the pNum arg
                //  passed in, is non-zero.
                // If so,
                //   then use everything except the last word for the guid
                // If not,
                //   then use everything to find the guid

                String[] args = portid.split(" ");
                int num = args.length;
                int argNum = 0;
                StringBuffer nodeid = new StringBuffer();
                if ((num == 1) || (pNum == 0))
                    return getNodeGuid(portid.trim());

                // all but the last arg
                for (String arg : args) {
                    if (++argNum < num)
                        nodeid.append(arg + " ");
                }
                return getNodeGuid(nodeid.toString().trim());
            }
        }
        return null;
    }

    private static OSM_LinkSpeed getLinkSpeed(SmtConfig config) {
        // the query argument should represent the desired link speed
        if (config != null) {
            Map<String, String> map = config.getConfigMap();
            String lSpeed = map.get(SmtProperty.SMT_COMMAND_ARGS.getName());
            if (lSpeed != null)
                return OSM_LinkSpeed.getByName(lSpeed, true);
        }
        return null;
    }

    private static int getPortNumber(SmtConfig config) {
        // if there are any arguments, they normally reference a port identifier
        // return 0, indicating couldn't be found, or nothing specified
        if (config != null) {
            Map<String, String> map = config.getConfigMap();
            String portid = map.get(SmtProperty.SMT_COMMAND_ARGS.getName());
            if (portid != null) {
                // should be at least two words
                //  the very last word, is supposed to be the port number
                //  if only one word, then check to see if there are 4 colons, if so, port number is after that
                String[] args = portid.split(" ");
                if ((args != null) && (args.length > 0)) {
                    int p = 0;
                    if (args.length == 1) {
                        // see if a port number is tagged on as the last value of a colon delimited guid+port string
                        String[] octets = portid.split(":");
                        if (octets.length > 4)
                            p = Integer.parseInt(octets[octets.length - 1]);
                    } else {
                        try {
                            p = Integer.parseInt(args[args.length - 1]);
                        } catch (NumberFormatException nfe) {
                            // this must not be a port number, so return 0
                            p = 0;
                        }
                    }
                    return p;
                }
            }
        }
        return 0;
    }

    private void saveCommandArgs(String[] args, Map<String, String> config) {
        // stash the command line arguments away, because we will use them later
        // see getNodeGuid()
        if ((args != null && args.length > 0)) {
            // save all the arguments in a single parameter
            StringBuffer cmdArgs = new StringBuffer();
            for (String arg : args) {
                cmdArgs.append(arg + " ");
            }
            config.put(SmtProperty.SMT_COMMAND_ARGS.getName(), cmdArgs.toString().trim());
        }
    }

    /************************************************************
     * 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 SmtLink().execute(args)) ? 0 : -1);
    }
}