/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) 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 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) 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 OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
/*
*
* OMSAStorageMonitor with per volume support.
* Jason Aras <jason.aras@gmail.com>
*
*/
package org.opennms.netmgt.poller.monitors;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.InetAddress;
import java.util.Map;
import org.apache.log4j.Level;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.core.utils.ParameterMap;
import org.opennms.netmgt.config.SnmpPeerFactory;
import org.opennms.netmgt.model.PollStatus;
import org.opennms.netmgt.poller.Distributable;
import org.opennms.netmgt.poller.DistributionContext;
import org.opennms.netmgt.poller.MonitoredService;
import org.opennms.netmgt.poller.NetworkInterface;
import org.opennms.netmgt.snmp.SnmpAgentConfig;
import org.opennms.netmgt.snmp.SnmpInstId;
import org.opennms.netmgt.snmp.SnmpObjId;
import org.opennms.netmgt.snmp.SnmpUtils;
import org.opennms.netmgt.snmp.SnmpValue;
/**
* <p>OmsaStorageMonitor class.</p>
* <p>
* This does SNMP and therefore relies on the SNMP configuration so it is not distributable.
* </p>
*
* @author ranger
* @version $Id: $
*/
@Distributable(DistributionContext.DAEMON)
final public class OmsaStorageMonitor extends SnmpMonitorStrategy {
private static final String m_serviceName = "OMSAStorage";
private static final String virtualDiskRollUpStatus = ".1.3.6.1.4.1.674.10893.1.20.140.1.1.19";
private static final String arrayDiskLogicalConnectionVirtualDiskNumber = ".1.3.6.1.4.1.674.10893.1.20.140.3.1.5";
private static final String arrayDiskNexusID = ".1.3.6.1.4.1.674.10893.1.20.130.4.1.26";
private static final String arrayDiskLogicalConnectionArrayDiskNumber =".1.3.6.1.4.1.674.10893.1.20.140.3.1.3";
private static final String arrayDiskState=".1.3.6.1.4.1.674.10893.1.20.130.4.1.4";
/**
* <p>serviceName</p>
*
* @return a {@link java.lang.String} object.
*/
public String serviceName() {
return m_serviceName;
}
/** {@inheritDoc} */
public void initialize(Map<String, Object> parameters) {
try {
SnmpPeerFactory.init();
} catch (IOException ex) {
log().fatal("initialize: Failed to load SNMP configuration", ex);
throw new UndeclaredThrowableException(ex);
}
return;
}
/**
* <p>initialize</p>
*
* @param svc a {@link org.opennms.netmgt.poller.MonitoredService} object.
*/
public void initialize(MonitoredService svc) {
super.initialize(svc);
return;
}
/** {@inheritDoc} */
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
NetworkInterface<InetAddress> iface = svc.getNetInterface();
PollStatus status = PollStatus.available();
InetAddress ipaddr = (InetAddress) iface.getAddress();
final StringBuffer returnValue = new StringBuffer();
SnmpAgentConfig agentConfig = configureAgent(parameters, iface, ipaddr);
Integer virtualDiskNumber = ParameterMap.getKeyedInteger(parameters, "virtualDiskNumber", 1);
if (log().isDebugEnabled()) log().debug("poll: service= SNMP address= " + agentConfig);
final String hostAddress = InetAddressUtils.str(ipaddr);
try {
if (log().isDebugEnabled()) {
log().debug("OMSAStorageMonitor.poll: SnmpAgentConfig address: " +agentConfig);
}
SnmpObjId virtualDiskRollUpStatusSnmpObject = SnmpObjId.get(virtualDiskRollUpStatus + "." + virtualDiskNumber);
SnmpValue virtualDiskRollUpStatus = SnmpUtils.get(agentConfig, virtualDiskRollUpStatusSnmpObject);
if(virtualDiskRollUpStatus == null || virtualDiskRollUpStatus.isNull()) {
log().debug("SNMP poll failed: no results, addr=" + hostAddress + " oid=" + virtualDiskRollUpStatusSnmpObject);
return PollStatus.unavailable();
}
if(virtualDiskRollUpStatus.toInt() != 3){
// array or one of its components is not happy lets find out which
returnValue.append("log vol(").append(virtualDiskNumber).append(") degraded"); // XXX should degraded be the virtualDiskState ?
SnmpObjId arrayDiskLogicalConnectionVirtualDiskNumberSnmpObject = SnmpObjId.get(arrayDiskLogicalConnectionVirtualDiskNumber);
Map<SnmpInstId,SnmpValue> arrayDisks = SnmpUtils.getOidValues(agentConfig, "OMSAStorageMonitor", arrayDiskLogicalConnectionVirtualDiskNumberSnmpObject);
SnmpObjId arrayDiskLogicalConnectionArrayDiskNumberSnmpObject = SnmpObjId.get(arrayDiskLogicalConnectionArrayDiskNumber);
Map<SnmpInstId,SnmpValue> arrayDiskConnectionNumber = SnmpUtils.getOidValues(agentConfig,"OMSAStorageMonitor", arrayDiskLogicalConnectionArrayDiskNumberSnmpObject);
for (Map.Entry<SnmpInstId, SnmpValue> disk: arrayDisks.entrySet()) {
log().debug("OMSAStorageMonitor :: arrayDiskNembers=" + disk.getValue());
if(disk.getValue().toInt()==virtualDiskNumber){
log().debug("OMSAStorageMonitor :: Disk Found! ");
log().debug("OMSAStorageMonitor :: Found This Array Disk Value " + disk.getKey());
SnmpObjId arrayDiskStateSnmpObject = SnmpObjId.get(arrayDiskState + "." + arrayDiskConnectionNumber.get(disk.getKey()));
SnmpValue diskValue = SnmpUtils.get(agentConfig,arrayDiskStateSnmpObject);
log().debug("OmsaStorageMonitor :: Disk State=" + diskValue );
if(diskValue.toInt() != 3) {
String arrayDiskState = getArrayDiskStatus(diskValue);
SnmpObjId arrayDiskNexusIDSnmpObject = SnmpObjId.get(arrayDiskNexusID + "." + disk.getKey().toString());
SnmpValue nexusValue = SnmpUtils.get(agentConfig,arrayDiskNexusIDSnmpObject);
returnValue.append(" phy drv(").append(nexusValue).append(") ").append(arrayDiskState);
}
}
}
return PollStatus.unavailable(returnValue.toString());
}
} catch (NumberFormatException e) {
status = logDown(Level.ERROR, "Number operator used on a non-number " + e.getMessage());
} catch (IllegalArgumentException e) {
status = logDown(Level.ERROR, "Invalid SNMP Criteria: " + e.getMessage());
} catch (Throwable t) {
status = logDown(Level.WARN, "Unexpected exception during SNMP poll of interface " + hostAddress, t);
}
return status;
}
private SnmpAgentConfig configureAgent(Map<String, Object> parameters, NetworkInterface<InetAddress> iface, InetAddress ipaddr) throws RuntimeException {
// Retrieve this interface's SNMP peer object
//
SnmpAgentConfig agentConfig = SnmpPeerFactory.getInstance().getAgentConfig(ipaddr);
if (agentConfig == null) throw new RuntimeException("SnmpAgentConfig object not available for interface " + ipaddr);
log().debug("poll: setting SNMP peer attribute for interface " + InetAddressUtils.str(ipaddr));
agentConfig.setTimeout(ParameterMap.getKeyedInteger(parameters, "timeout", agentConfig.getTimeout()));
agentConfig.setRetries(ParameterMap.getKeyedInteger(parameters, "retry", ParameterMap.getKeyedInteger(parameters, "retries", agentConfig.getRetries())));
agentConfig.setPort(ParameterMap.getKeyedInteger(parameters, "port", agentConfig.getPort()));
return agentConfig;
}
private String getArrayDiskStatus(SnmpValue diskValue) {
switch(diskValue.toInt()){
case 1: return "Ready";
case 2: return "Failed";
case 3: return "Online";
case 4: return "Offline";
case 6: return "Degraded"; // how does that happen for a disk and not a volume?
case 7: return "Recovering";
case 11: return "Removed";
case 15: return "Resynching";
case 24: return "Rebuilding";
case 25: return "noMedia";
case 26: return "Formating";
case 28: return "Running Diagnostics";
case 35: return "Initializing";
default: break;
}
return null;
}
}