org.rhq.plugins.www.snmp.SNMPSession_v1 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhq-apache-plugin Show documentation
Show all versions of rhq-apache-plugin Show documentation
a plugin for managing Apache web servers (1.3 and later)
/*
* 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 getColumn(String mibName) throws SNMPException {
List values = new ArrayList();
OID oid = SNMPClient.getMibOID(mibName);
TreeUtils treeUtils = new TreeUtils(session, new DefaultPDUFactory());
treeUtils.setMaxRepetitions(GETBULK_MAX_REPETITIONS);
List 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 getTable(String mibName, int index) throws SNMPException {
Map map = new LinkedHashMap();
OID rootOid = new OID(SNMPClient.getMibOID(mibName)); // copy before modifying, since the OIDs are cached by SNMPClient
rootOid.append(index);
List 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 getBulk(String mibName) throws SNMPException {
List values = new ArrayList();
PDU request = createPDU(mibName, PDU.GETBULK);
request.setMaxRepetitions(GETBULK_MAX_REPETITIONS);
request.setNonRepeaters(GETBULK_NON_REPEATERS);
PDU response = sendRequest(request, mibName);
Vector 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;
}
}