/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 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/
*******************************************************************************/
package org.opennms.netmgt.snmp.joesnmp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.core.utils.ThreadCategory;
import org.opennms.netmgt.snmp.CollectionTracker;
import org.opennms.netmgt.snmp.SnmpAgentConfig;
import org.opennms.netmgt.snmp.SnmpObjId;
import org.opennms.netmgt.snmp.SnmpStrategy;
import org.opennms.netmgt.snmp.SnmpTrapBuilder;
import org.opennms.netmgt.snmp.SnmpV1TrapBuilder;
import org.opennms.netmgt.snmp.SnmpV2TrapBuilder;
import org.opennms.netmgt.snmp.SnmpV3TrapBuilder;
import org.opennms.netmgt.snmp.SnmpV3User;
import org.opennms.netmgt.snmp.SnmpValue;
import org.opennms.netmgt.snmp.SnmpValueFactory;
import org.opennms.netmgt.snmp.SnmpWalker;
import org.opennms.netmgt.snmp.TrapNotificationListener;
import org.opennms.netmgt.snmp.TrapProcessorFactory;
import org.opennms.protocols.snmp.SnmpObjectId;
import org.opennms.protocols.snmp.SnmpOctetString;
import org.opennms.protocols.snmp.SnmpParameters;
import org.opennms.protocols.snmp.SnmpPduRequest;
import org.opennms.protocols.snmp.SnmpPduTrap;
import org.opennms.protocols.snmp.SnmpPeer;
import org.opennms.protocols.snmp.SnmpSMI;
import org.opennms.protocols.snmp.SnmpSession;
import org.opennms.protocols.snmp.SnmpSyntax;
import org.opennms.protocols.snmp.SnmpTrapSession;
public class JoeSnmpStrategy implements SnmpStrategy {
private static Map<TrapNotificationListener, RegistrationInfo> s_registrations = new HashMap<TrapNotificationListener, RegistrationInfo>();
private static SnmpTrapSession s_trapSession;
private JoeSnmpValueFactory m_valueFactory;
public SnmpWalker createWalker(SnmpAgentConfig snmpAgentConfig, String name, CollectionTracker tracker) {
return new JoeSnmpWalker(new JoeSnmpAgentConfig(snmpAgentConfig), name, tracker);
}
public SnmpValue set(SnmpAgentConfig snmpAgentConfig, SnmpObjId oid, SnmpValue value ) {
SnmpObjId[] oids = { oid };
SnmpValue[] values = { value };
return set(snmpAgentConfig, oids,values)[0];
}
public SnmpValue[] set(SnmpAgentConfig snmpAgentConfig, SnmpObjId[] oids, SnmpValue[] values) {
JoeSnmpAgentConfig agentConfig = new JoeSnmpAgentConfig(snmpAgentConfig);
SnmpSession session = null;
SnmpSyntax[] syntaxvalues = new SnmpSyntax[values.length];
for (int i=0; i<values.length;i++) {
syntaxvalues[i] = new JoeSnmpValue(values[i].getType(), values[i].getBytes()).getSnmpSyntax();
}
values = null;
try {
SnmpPeer peer = createPeer(agentConfig);
SnmpParameters params = new SnmpParameters();
setParameters(agentConfig, params);
peer.setParameters(params);
configurePeer(peer, agentConfig);
session = new SnmpSession(peer);
SnmpObjectId[] jOids = convertOids(oids);
SnmpSyntax[] results = session.set(jOids,syntaxvalues);
values = convertSnmpSyntaxs(results);
} catch (SocketException e) {
log().error("Could not create JoeSNMP session using AgentConfig: "+agentConfig);
} finally {
if (session != null) {
session.close();
}
}
return values;
}
public SnmpValue get(SnmpAgentConfig snmpAgentConfig, SnmpObjId oid) {
SnmpObjId[] oids = { oid };
return get(snmpAgentConfig, oids)[0];
}
public SnmpValue[] get(SnmpAgentConfig snmpAgentConfig, SnmpObjId[] oids) {
JoeSnmpAgentConfig agentConfig = new JoeSnmpAgentConfig(snmpAgentConfig);
SnmpSession session = null;
SnmpValue[] values = { null };
try {
SnmpPeer peer = createPeer(agentConfig);
SnmpParameters params = new SnmpParameters();
setParameters(agentConfig, params);
peer.setParameters(params);
configurePeer(peer, agentConfig);
session = new SnmpSession(peer);
SnmpObjectId[] jOids = convertOids(oids);
SnmpSyntax[] results = session.get(jOids);
values = convertSnmpSyntaxs(results);
} catch (SocketException e) {
log().error("Could not create JoeSNMP session using AgentConfig: "+agentConfig);
} finally {
if (session != null) {
session.close();
}
}
return values;
}
public SnmpValue getNext(SnmpAgentConfig snmpAgentConfig, SnmpObjId oid) {
SnmpObjId[] oids = { oid };
return getNext(snmpAgentConfig, oids)[0];
}
public SnmpValue[] getNext(SnmpAgentConfig snmpAgentConfig, SnmpObjId[] oids) {
JoeSnmpAgentConfig agentConfig = new JoeSnmpAgentConfig(snmpAgentConfig);
SnmpSession session = null;
SnmpValue[] values = { null };
try {
SnmpPeer peer = createPeer(agentConfig);
SnmpParameters params = new SnmpParameters();
setParameters(agentConfig, params);
peer.setParameters(params);
configurePeer(peer, agentConfig);
session = new SnmpSession(peer);
SnmpObjectId[] jOids = convertOids(oids);
SnmpSyntax[] results = session.getNext(jOids);
values = convertSnmpSyntaxs(results);
} catch (SocketException e) {
log().error("Could not create JoeSNMP session using AgentConfig: "+agentConfig);
} finally {
if (session != null) {
session.close();
}
}
return values;
}
/**
* Convert JoeSnmp SnmpSyntax array to OpenNMS SnmpValue array
*
* @param results
* @return
* values as an OpenNMS SnmpValue array
*/
private SnmpValue[] convertSnmpSyntaxs(SnmpSyntax[] results) {
SnmpValue[] values = { null };
if (results == null || results[0] == null || results.length == 0) {
return values;
}
values = new JoeSnmpValue[results.length];
for (int i=0; i<results.length; i++) {
values[i] = new JoeSnmpValue(results[i]);
}
return values;
}
/**
* Convert the OpenNMS Generic SnmpObjId[] array to a JoeSnmp SnmpObjectId[]
*
* @param oids
* @return
* An array of JoeSnmp SnmpObjectIds
*/
private SnmpObjectId[] convertOids(SnmpObjId[] oids) {
SnmpObjectId[] jOids = new SnmpObjectId[oids.length];
for (int i=0; i<oids.length; i++) {
jOids[i] = new SnmpObjectId(oids[i].toString());
}
return jOids;
}
private void configurePeer(SnmpPeer peer, JoeSnmpAgentConfig agentConfig) {
peer.setPort(agentConfig.getPort());
peer.setRetries(agentConfig.getRetries());
peer.setTimeout(agentConfig.getTimeout());
}
private SnmpPeer createPeer(JoeSnmpAgentConfig agentConfig) {
return new SnmpPeer(agentConfig.getAddress());
}
private void setParameters(JoeSnmpAgentConfig agentConfig, SnmpParameters params) {
params.setVersion(agentConfig.getVersion());
params.setReadCommunity(agentConfig.getReadCommunity());
params.setWriteCommunity(agentConfig.getWriteCommunity());
}
private ThreadCategory log() {
return ThreadCategory.getInstance(this.getClass());
}
public SnmpValue[] getBulk(SnmpAgentConfig agentConfig, SnmpObjId[] oids) {
throw new UnsupportedOperationException("JoeSnmpStrategy.getBulk() not yet implemented.");
}
public static class RegistrationInfo {
private TrapNotificationListener m_listener;
private InetAddress m_address;
private int m_port;
SnmpTrapSession m_trapSession;
JoeSnmpTrapNotifier m_trapHandler;
public RegistrationInfo(final TrapNotificationListener listener, final int trapPort) {
if (listener == null) {
throw new NullPointerException("listener is null");
}
m_listener = listener;
m_port = trapPort;
}
public RegistrationInfo(final TrapNotificationListener listener, InetAddress address, int snmpTrapPort) {
m_listener = listener;
m_address = address;
m_port = snmpTrapPort;
}
public void setSession(final SnmpTrapSession trapSession) {
m_trapSession = trapSession;
}
public SnmpTrapSession getSession() {
return m_trapSession;
}
public void setHandler(final JoeSnmpTrapNotifier trapHandler) {
m_trapHandler = trapHandler;
}
public JoeSnmpTrapNotifier getHandler() {
return m_trapHandler;
}
public InetAddress getAddress() {
return m_address;
}
public int getPort() {
return m_port;
}
public int hashCode() {
return (m_listener.hashCode() + m_address.hashCode() ^ m_port);
}
public boolean equals(final Object obj) {
if (obj instanceof RegistrationInfo) {
final RegistrationInfo info = (RegistrationInfo) obj;
return (m_listener == info.m_listener) && Arrays.equals(m_address.getAddress(), info.getAddress().getAddress()) && m_port == info.getPort();
}
return false;
}
}
public void registerForTraps(final TrapNotificationListener listener, final TrapProcessorFactory processorFactory, InetAddress address, int snmpTrapPort) throws IOException {
final RegistrationInfo info = new RegistrationInfo(listener, address, snmpTrapPort);
final JoeSnmpTrapNotifier m_trapHandler = new JoeSnmpTrapNotifier(listener, processorFactory);
info.setHandler(m_trapHandler);
SnmpTrapSession m_trapSession = new SnmpTrapSession(m_trapHandler, address, snmpTrapPort);
info.setSession(m_trapSession);
s_registrations.put(listener, info);
}
public void registerForTraps(final TrapNotificationListener listener, final TrapProcessorFactory processorFactory, final InetAddress address, final int snmpTrapPort, final List<SnmpV3User> snmpv3Users) throws IOException {
registerForTraps(listener, processorFactory, address, snmpTrapPort);
}
public void registerForTraps(final TrapNotificationListener listener, final TrapProcessorFactory processorFactory, final int snmpTrapPort) throws IOException {
registerForTraps(listener, processorFactory, null, snmpTrapPort);
}
public void unregisterForTraps(final TrapNotificationListener listener, InetAddress address, int snmpTrapPort) {
RegistrationInfo info = s_registrations.remove(listener);
info.getSession().close();
}
public void unregisterForTraps(final TrapNotificationListener listener, final int snmpTrapPort) {
RegistrationInfo info = s_registrations.remove(listener);
info.getSession().close();
}
public SnmpValueFactory getValueFactory() {
if (m_valueFactory == null) {
m_valueFactory = new JoeSnmpValueFactory();
}
return m_valueFactory;
}
public SnmpV1TrapBuilder getV1TrapBuilder() {
return new JoeSnmpV1TrapBuilder();
}
public SnmpTrapBuilder getV2TrapBuilder() {
return new JoeSnmpV2TrapBuilder();
}
public static void send(String destAddr, int destPort, String community, SnmpPduTrap trap) throws Exception {
SnmpTrapSession trapSession = getTrapSession();
SnmpPeer peer = new SnmpPeer(InetAddress.getByName(destAddr), destPort);
SnmpParameters parms = new SnmpParameters(community);
parms.setVersion(SnmpSMI.SNMPV1);
peer.setParameters(parms);
trapSession.send(peer, trap);
}
public static void send(final String destAddr, final int destPort, final String community, final SnmpPduRequest pdu) throws Exception {
SnmpTrapSession trapSession = getTrapSession();
SnmpPeer peer = new SnmpPeer(InetAddress.getByName(destAddr), destPort);
SnmpParameters parms = new SnmpParameters(community);
parms.setVersion(SnmpSMI.SNMPV2);
peer.setParameters(parms);
trapSession.send(peer, pdu);
}
private synchronized static SnmpTrapSession getTrapSession() throws SocketException {
if (s_trapSession == null) {
s_trapSession = new SnmpTrapSession(null, null, -1);
}
return s_trapSession;
}
public static void sendTest(final String destAddr, final int destPort, final String community, final SnmpPduRequest pdu) throws UnknownHostException {
final InetAddress agentAddress = InetAddressUtils.getInetAddress(destAddr);
for (final RegistrationInfo info : s_registrations.values()) {
if (destPort == info.getPort()) {
info.getHandler().snmpReceivedTrap(info.getSession(), agentAddress, destPort, new SnmpOctetString(community.getBytes()), pdu);
}
}
}
public static void sendTest(String destAddr, int destPort, String community, SnmpPduTrap pdu) throws UnknownHostException {
final InetAddress agentAddress = InetAddressUtils.getInetAddress(destAddr);
for (final RegistrationInfo info : s_registrations.values()) {
if (destPort == info.getPort()) {
info.getHandler().snmpReceivedTrap(info.getSession(), agentAddress, destPort, new SnmpOctetString(community.getBytes()), pdu);
}
}
}
public SnmpV3TrapBuilder getV3TrapBuilder() {
throw new UnsupportedOperationException();
}
public SnmpV2TrapBuilder getV2InformBuilder() {
throw new UnsupportedOperationException();
}
public SnmpV3TrapBuilder getV3InformBuilder() {
throw new UnsupportedOperationException();
}
public byte[] getLocalEngineID() {
throw new UnsupportedOperationException();
}
}