/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2008-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.ovapi; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import junit.framework.TestCase; import org.opennms.mock.snmp.MockSnmpAgent; import org.opennms.nnm.SnmpObjId; import org.opennms.nnm.swig.NNM; import org.opennms.nnm.swig.OVsnmpPdu; import org.opennms.nnm.swig.OVsnmpSession; import org.opennms.nnm.swig.OVsnmpVarBind; import org.opennms.nnm.swig.SnmpCallback; import org.opennms.nnm.swig.fd_set; import org.opennms.nnm.swig.timeval; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class OVsnmpSessionTest extends TestCase { MockSnmpAgent m_agent; String m_host; public void setUp() throws Exception { Resource snmpData = new ClassPathResource("snmpTestData1.properties"); m_host = InetAddress.getLocalHost().getHostAddress(); m_agent = MockSnmpAgent.createAgentAndRun(snmpData, m_host+"/9161"); } protected void tearDown() throws Exception { Thread.sleep(1000); m_agent.shutDownAndWait(); } public void testOpenClose() throws Exception { OVsnmpSession sess = open("localhost", 9161); assertNotNull(sess); close(sess); } OVsnmpSession open(String peername, int remotePort) { return OVsnmpSession.open(peername, remotePort, null); } void close(OVsnmpSession session) { session.close(); } public void testCreatePdu() throws Exception { SnmpObjId sysName = SnmpObjId.get(".1.3.6.1.2.1.1.5.0"); OVsnmpPdu request = OVsnmpPdu.create(NNM.GET_REQ_MSG); assertNull(request.getVarBinds()); request.addNullVarBind(sysName.getIds()); OVsnmpVarBind varBind = request.getVarBinds(); assertNotNull(varBind); assertEquals(sysName.toString(), varBind.getObjectId()); assertNull(varBind.getNextVarBind()); request.free(); } public void testBlockingSend() { SnmpObjId sysName = SnmpObjId.get(".1.3.6.1.2.1.1.5.0"); OVsnmpPdu request = OVsnmpPdu.create(NNM.GET_REQ_MSG); request.addNullVarBind(sysName.getIds()); OVsnmpSession session = open(m_host, 9161); OVsnmpPdu reply = session.blockingSend(request); assertNotNull(reply); OVsnmpVarBind varbind = reply.getVarBinds(); assertNotNull(varbind); assertNull(varbind.getNextVarBind()); assertEquals(NNM.ASN_OCTET_STR, varbind.getType()); byte[] octets = new byte[varbind.getValLength()]; assertTrue(varbind.getValue().getOctetString(octets)); assertEquals("brozow.local", new String(octets)); reply.free(); close(session); } private static class Walker extends SnmpCallback { boolean m_finished = false; String m_peername; int m_port; SnmpObjId m_base; OVsnmpSession m_session; public Walker(String peername, int port, SnmpObjId base) { m_peername = peername; m_port = port; m_base = base; } public void start() { m_session = OVsnmpSession.open(m_peername, m_port, this); m_finished = false; sendNext(m_base); } public void callback(int reason, OVsnmpSession session, OVsnmpPdu reply) { try { if (reason == NNM.SNMP_ERR_NO_RESPONSE) { System.err.println("NO_RESPONSE"); timedOut(); return; } SnmpObjId recvdOid = processVarBinds(reply.getVarBinds()); if (m_base.isPrefixOf(recvdOid)) { sendNext(recvdOid); } else { finished(); } } finally { if (reply != null) { reply.free(); } } } private SnmpObjId processVarBinds(OVsnmpVarBind varBind) { SnmpObjId oid = SnmpObjId.get(varBind.getObjectId()); System.err.println("Received: "+oid+ " type: "+Integer.toHexString(varBind.getType())+" "+getValue(varBind)); return oid; } private String getValue(OVsnmpVarBind varBind) { int type = varBind.getType(); if (type == NNM.ASN_BOOLEAN) { return (varBind.getValue().getIntValue() == 0 ? "false" : "true"); } else if (type == NNM.ASN_INTEGER) { return Integer.toString(varBind.getValue().getIntValue()); } else if (type == NNM.ASN_OCTET_STR) { byte[] bytes = new byte[varBind.getValLength()]; varBind.getValue().getOctetString(bytes); return new String(bytes); } else if (type == NNM.ASN_U_INTEGER) { return ""+varBind.getValue().getUnsigned32Value(); } else if (type == NNM.ASN_OBJECT_ID) { return varBind.getValue().getObjectId(varBind.getValLength()); } else if (type == NNM.ASN_TIMETICKS) { int centis = varBind.getValue().getIntValue(); return ""+centis/100+"."+centis%100+" s"; } else if (type == NNM.ASN_COUNTER32) { return ""+varBind.getValue().getUnsigned32Value(); } else if (type == NNM.ASN_COUNTER64) { return ""+varBind.getValue().getCounter64Value(); } else if (type == NNM.ASN_GAUGE) { return ""+varBind.getValue().getUnsigned32Value(); } else if (type == NNM.ASN_IPADDRESS) { byte[] bytes = new byte[4]; varBind.getValue().getOctetString(bytes); try { return InetAddress.getByAddress(bytes).getHostAddress(); } catch (UnknownHostException e) { return "UnknownHost that can't happen"; } } else { return "UNKNOWN TYPE: "+type; } /* #define ASN_BOOLEAN (0x01) #define ASN_INTEGER (0x02) #define ASN_BIT_STR (0x03) #define ASN_U_INTEGER (0x07) #define ASN_OCTET_STR (0x04) #define ASN_NULL (0x05) #define ASN_OBJECT_ID (0x06) #define ASN_SEQUENCE (0x10) #define ASN_SET (0x11) #define ASN_IPADDRESS (ASN_APPLICATION | 0) #define ASN_COUNTER (ASN_APPLICATION | 1) #define ASN_GAUGE (ASN_APPLICATION | 2) #define ASN_TIMETICKS (ASN_APPLICATION | 3) #define ASN_OPAQUE (ASN_APPLICATION | 4) #define ASN_COUNTER64 (ASN_APPLICATION | 6) #define ASN_UNSIGNED32 ASN_GAUGE #define ASN_GAUGE32 ASN_GAUGE #define ASN_COUNTER32 ASN_COUNTER #define ASN_NOSUCHOBJECT (ASN_CONTEXT | ASN_PRIMITIVE | 0x0) #define ASN_NOSUCHINSTANCE (ASN_CONTEXT | ASN_PRIMITIVE | 0x1) #define ASN_ENDOFMIBVIEW (ASN_CONTEXT | ASN_PRIMITIVE | 0x2) */ } private void timedOut() { m_finished = true; System.err.println("Timed Out"); close(); } private void finished() { m_finished = true; System.err.println("Finished"); close(); } private void sendNext(SnmpObjId oid) { OVsnmpPdu next = OVsnmpPdu.create(NNM.GETNEXT_REQ_MSG); next.addNullVarBind(oid.getIds()); m_session.send(next); } private void close() { m_session.close(); } public boolean isFinished() { return m_finished; } } public void testAsynchronousCallbacks() throws Exception { Thread.sleep(20000); Walker system = new Walker(m_host, 9161, SnmpObjId.get(".1.3.6.1.2.1.1")); Walker ifTable = new Walker(m_host, 9161, SnmpObjId.get(".1.3.6.1.2.1.2")); Walker ipAddrTable = new Walker(m_host, 9161, SnmpObjId.get(".1.3.6.1.2.1.4.20.1")); List walkers = new LinkedList(); walkers.add(system); walkers.add(ifTable); walkers.add(ipAddrTable); fd_set fdset = new fd_set(); timeval timeout = new timeval(); for(Iterator it = walkers.iterator(); it.hasNext(); ) { Walker walker = (Walker)it.next(); walker.start(); System.err.println("New Walker"); while(!walker.isFinished()) { int maxFDs = OVsnmpSession.getRetryInfo(fdset, timeout); int count = NNM.select(maxFDs, fdset, null, null, timeout); if (count > 0) { OVsnmpSession.read(fdset); } OVsnmpSession.doRetry(); } } } }