Package org.rhq.plugins.www.snmp

Source Code of org.rhq.plugins.www.snmp.SNMPSession_v1

/*
* RHQ Management Platform
* Copyright (C) 2005-2012 Red Hat, Inc.
* All rights reserved.
*
* 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 of the License.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.www.snmp;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TreeEvent;
import org.snmp4j.util.TreeUtils;

/**
* Implements a the SNMPSession interface for SNMPv1 sessions.
*
* @author Ian Springer
*/
class SNMPSession_v1 implements SNMPSession {

    protected static Snmp session;

    protected int version;
    protected CommunityTarget target;

    private final Log log = LogFactory.getLog(this.getClass());

    private static final String ANY_LOCAL_ADDRESS = "0.0.0.0";
    private static final int ANY_FREE_PORT = 0;

    private static final int GETBULK_MAX_REPETITIONS = 10;
    private static final int GETBULK_NON_REPEATERS = 0;

    private static final String PING_OID = "1";
    private static final String PING_MIB_NAME = "iso";

    /**
     * Should only be called by SNMPClient. To get an instance of this class, use SNMPClient.startSession().
     *
     * @see SNMPClient#startSession
     */
    SNMPSession_v1() {
        this.version = SnmpConstants.version1;
    }

    /**
     * Initializes the SNMP session.
     *
     * @param  host      host name or IP address of SNMP agent
     * @param  port      TCP port of SNMP agent
     * @param  community SNMP community of SNMP agent
     * @param  timeout   the timeout, in milliseconds, for requests
     * @param  retries   the number of times to retry requests that have timed out
     *
     * @throws SNMPException on error
     */
    void init(String host, int port, String community, long timeout, int retries) throws SNMPException {
        if (session == null) {
            session = initSession();
        }

        Address address = GenericAddress.parse("udp:" + host + "/" + port);
        this.target = new CommunityTarget();
        this.target.setAddress(address);
        this.target.setCommunity(new OctetString(community));
        this.target.setVersion(this.version);
        this.target.setRetries(retries);
        this.target.setTimeout(timeout);
    }

    public void close() {
        if (session != null) {
            try {
                session.close();
            } catch (Exception e) {
                log.warn("Failed to close the SNMP session. Cause: " + e);
            } finally {
                session = null;
            }
        }
    }

    @NotNull
    public SNMPValue getSingleValue(String name) throws SNMPException {
        return getValue(name, PDU.GET);
    }

    @NotNull
    public SNMPValue getNextValue(String name) throws SNMPException {
        return getValue(name, PDU.GETNEXT);
    }

    @NotNull
    public List<SNMPValue> getColumn(String mibName) throws SNMPException {
        List<SNMPValue> values = new ArrayList<SNMPValue>();
        OID oid = SNMPClient.getMibOID(mibName);
        TreeUtils treeUtils = new TreeUtils(session, new DefaultPDUFactory());
        treeUtils.setMaxRepetitions(GETBULK_MAX_REPETITIONS);
        List<TreeEvent> events = treeUtils.getSubtree(this.target, oid);
        for (TreeEvent event : events) {
            if (event.isError()) {
                throw new SNMPException("Error occurred while retrieving column " + mibName + "(" + oid + "): "
                    + event.getErrorMessage(), event.getException());
            }

            VariableBinding[] varBindings = event.getVariableBindings();
            if (varBindings != null) {
                for (VariableBinding varBinding : varBindings) {
                    values.add(new SNMPValue(varBinding));
                }
            }
        }

        return values;
    }

    @NotNull
    public Map<String, SNMPValue> getTable(String mibName, int index) throws SNMPException {
        Map<String, SNMPValue> map = new LinkedHashMap<String, SNMPValue>();
        OID rootOid = new OID(SNMPClient.getMibOID(mibName)); // copy before modifying, since the OIDs are cached by SNMPClient
        rootOid.append(index);
        List<SNMPValue> values = getColumn(rootOid.toString());
        for (SNMPValue value : values) {
            OID leafOid = new OID(value.getOID());
            OID suffixOid = new OID(leafOid.getValue(), rootOid.size(), leafOid.size() - rootOid.size());
            map.put(suffixOid.toString(), value);
        }

        return map;
    }

    @NotNull
    public List<SNMPValue> getBulk(String mibName) throws SNMPException {
        List<SNMPValue> values = new ArrayList<SNMPValue>();
        PDU request = createPDU(mibName, PDU.GETBULK);
        request.setMaxRepetitions(GETBULK_MAX_REPETITIONS);
        request.setNonRepeaters(GETBULK_NON_REPEATERS);
        PDU response = sendRequest(request, mibName);
        Vector<VariableBinding> varBindings = response.getVariableBindings();
        for (VariableBinding varBinding : varBindings) {
            values.add(new SNMPValue(varBinding));
        }

        return values;
    }

    public boolean ping() {
        PDU response;
        try {
            PDU pdu = createPDU(PING_OID, PDU.GETNEXT);
            response = sendRequest(pdu, PING_MIB_NAME);
        } catch (SNMPException e) {
            if (e instanceof SNMPTimeoutException) {
                long timeoutMillis = target.getTimeout() * (target.getRetries() + 1);
                log.debug("Timed out after " + timeoutMillis + " while pinging " + this.version + " agent at " + this
                                + ".");
            } else {
                log.debug("Error while pinging SNMP " + this.version + " agent at " + this
                    + ". SNMP GETNEXT request for iso(1) failed: " + e);
            }
            return false;
        }

        boolean errorOccurred = (response.getErrorStatus() != PDU.noError);
        if (errorOccurred) {
            log.error("Error while pinging SNMP " + this.version + " agent at " + this
                + ". SNMP GETNEXT request for iso(1) failed: " + response.getErrorStatusText());
        }

        return !errorOccurred;
    }

    @Override
    public String toString() {
        return target.getAddress() + "/" + this.target.getCommunity();
    }

    protected PDU createPDU(String mibName, int type) throws MIBLookupException {
        PDU pdu = new DefaultPDUFactory().createPDU(this.target);
        pdu.setType(type);
        OID oid = SNMPClient.getMibOID(mibName);
        pdu.add(new VariableBinding(oid));
        return pdu;
    }

    private Snmp initSession() throws SNMPException {
        try {
            InetAddress host = InetAddress.getByName(ANY_LOCAL_ADDRESS);
            int port = ANY_FREE_PORT;
            UdpAddress addr = new UdpAddress(host, port);
            session = new Snmp(new DefaultUdpTransportMapping(addr));
            session.listen();
        } catch (IOException e) {
            throw new SNMPException("Failed to initialize SNMP session.", e);
        }

        return session;
    }

    private SNMPValue getValue(String mibName, int pduType) throws SNMPException {
        PDU request = createPDU(mibName, pduType);
        PDU response = sendRequest(request, mibName);
        return new SNMPValue(response.get(GETBULK_NON_REPEATERS));
    }

    @NotNull
    private PDU sendRequest(PDU request, String mibName) throws SNMPException {
        String requestType = PDU.getTypeString(request.getType());
        ResponseEvent responseEvent;
        try {
            responseEvent = session.send(request, this.target);
        } catch (IOException e) {
            throw new SNMPException("Failed to send " + requestType + " request for [" + mibName + "]", e);
        }

        if (responseEvent == null) {
            throw new SNMPException("No response to " + requestType + " request for [" + mibName + "].");
        }

        PDU response = responseEvent.getResponse();
        if (response == null) {
            throw new SNMPTimeoutException(requestType + " request for [" + mibName + "] timed out.");
        }

        return response;
    }

}
TOP

Related Classes of org.rhq.plugins.www.snmp.SNMPSession_v1

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.