snmpportal.java
来自「opennms得相关源码 请大家看看」· Java 代码 · 共 746 行 · 第 1/2 页
JAVA
746 行
//// This file is part of the OpenNMS(R) Application.//// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved.// OpenNMS(R) is a derivative work, containing both original code, included code and modified// code that was published under the GNU General Public License. Copyrights for modified // and included code are below.//// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.// // Modifications://// 2003 Aug 21: Added the ability to generate a new DatagramSocket on a random// high number port if needed by setting the port to -1.//// Original code base Copyright (C) 1999-2001 Oculan Corp. 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; either version 2 of the License, or// (at your option) any later version.//// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// For more information contact:// OpenNMS Licensing <license@opennms.org>// http://www.opennms.org/// http://www.opennms.com///// Tab Size = 8//package org.opennms.protocols.snmp;import java.io.ByteArrayOutputStream;import java.io.InterruptedIOException;import java.io.OutputStream;import java.io.PrintStream;import java.lang.reflect.Method;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.SocketException;import java.util.Date;import java.util.LinkedList;import org.opennms.protocols.snmp.asn1.ASN1;import org.opennms.protocols.snmp.asn1.AsnDecodingException;import org.opennms.protocols.snmp.asn1.AsnEncoder;/** * Abstracts the communication related details from the SnmpSession and * SnmpTrapSession. * * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> * @author <a href="mailto:sowmya@opennms.org">Sowmya Nataraj </a> * @author <a href="http://www.opennms.org">OpenNMS </a> * * @see SnmpSession * @see SnmpTrapSession * @see java.net.DatagramSocket */public class SnmpPortal extends Object { /** * The packet handler that is used to process received SNMP packets and * invalid datagrams. The handler must also process any exceptions that * occurs in the receiving thread. * */ private SnmpPacketHandler m_handler; /** * The datagram socket used to send and receive SNMP messages. * */ private DatagramSocket m_comm; /** * the receiver thread that runs the inner class Receiver. */ private Thread m_recvThread; /** * ASN.1 encoder used to decode the SNMP messages. If the decoded fails to * decode the specific messages the is should throw and appropiate ASN.1 * exception * */ private AsnEncoder m_encoder; /** * When set the portal object's close method has been invoked. This is * needed since the internal receiver thread will block on the communication * channel. To "wake" the thread the close() method on the comm channel is * performed. This will cause an exception to be genereated in the receiver * thread. If the value of m_isClosing is true then the exception is * ignored. */ private volatile boolean m_isClosing; /** * Set to true if it is necessary to set the socket timeout value via the * Socket.setSoTimeout() method in order to keep from blocking indefinitely * on a socket I/O call. This value is configurable at runtime via the * system property "org.opennms.joeSNMP.vmhacks.socketSoTimeoutRequired". If * this property is set to 'no', the bSocketSoTimeoutRequired variable will * be set to false and the SNMP trap socket timeout will not be set. If this * property is set to 'yes' or the property does not exist, the * bSocketSoTimeoutRequired variable will be set to true. and the socket * timeout will be set. Default value is true. */ private boolean bSocketSoTimeoutRequired = true; /** * Identifies the system property that may be used to specify whether or not * a timeout value is set on the SNMP trap socket. Valid values are 'yes' * and 'no'. */ private static final String PROP_SOCKET_TIMEOUT_REQUIRED = "org.opennms.joeSNMP.vmhacks.socketSoTimeoutRequired"; /** * Identifies the system property that may be used to specify the number of * milliseconds to use for the socket timeout. */ private static final String PROP_SOCKET_TIMEOUT_PERIOD = "org.opennms.joeSNMP.vmhacks.socketSoTimeoutPeriod"; /** * Private constructor used to disallow the default constructor. * * @exception java.lang.UnsupportedOperationException * Always thrown! */ private SnmpPortal() throws java.lang.UnsupportedOperationException { throw new java.lang.UnsupportedOperationException("Illegal constructor call"); } /** * The SnmpPortal constructor. The constructor is used to build a portal on * the specified port, and forward messages to the defined handler. All * messages are decoded using the encoder specified during construction. * * @param handler * The SNMP packet handler. * @param encoder * The ASN.1 codec object. * @param port * The port to send and receive datagram from. * * @exception java.net.SocketException * Thrown if an error occurs setting up the communication * channel. * @exception java.lang.IllegalArgumentException * Thrown if any of the parameters are null or invalid. * */ SnmpPortal(SnmpPacketHandler handler, AsnEncoder encoder, int port) throws SocketException { if (handler == null || encoder == null) throw new IllegalArgumentException("Invalid argument"); m_handler = handler; if (port >= 0) { m_comm = new DatagramSocket(port); } else { m_comm = new DatagramSocket(); } // // Determine whether or not it is necessary to use the // socket.setSoTimeout() // method to set the socket timeout value thereby mimic'ing non-blocking // socket I/O. // On platforms whose system close() is not preemptive it is necessary // to use the socket timeout // to keep from blocking indefinitely on any socket call that performs // I/O. // bSocketSoTimeoutRequired = true; // Default is to use set the socket // timeout String strSocketSoTimeoutRequired = System.getProperty(PROP_SOCKET_TIMEOUT_REQUIRED); String osName = System.getProperty("os.name"); if (strSocketSoTimeoutRequired != null && strSocketSoTimeoutRequired.equals("no")) { bSocketSoTimeoutRequired = false; } if (bSocketSoTimeoutRequired == true) { String strSocketSoTimeoutPeriod = System.getProperty(PROP_SOCKET_TIMEOUT_PERIOD); int timeout = 3000; // Default socket timeout is 3 seconds if (strSocketSoTimeoutPeriod != null) { try { timeout = Integer.parseInt(strSocketSoTimeoutPeriod); } catch (NumberFormatException e) { timeout = 3000; } } m_comm.setSoTimeout(timeout); } else if (osName != null && osName.equalsIgnoreCase("linux")) { // we must force this issue because we do not know // what VM there running in. If there running in // Sun JDK 1.3.1 with J2SE_PREEMPTCLOSE set then // this is unnecessary. If there not running in 1.3.1 // and the're on linux then THEY MUST have a timeout // set of it will hang a thread. // m_comm.setSoTimeout(100); } m_isClosing = false; m_recvThread = new Thread(new Receiver(), "SnmpPortal-" + m_comm.getPort()); m_encoder = encoder; m_recvThread.start(); } /** * Defines the inner class that monitors the datagram socket and receives * all the PDU responses. If an exception is generated then it is saved in * m_why and can be re-generated with a call to raise(). * */ private class Receiver implements Runnable { /** * Called to setup the communications channel buffers. The method * attempts to set the received buffer size to 64k. If it fails then the * default buffer size is recovered. If the default buffer size cannot * be recovered then a zero is returned. * * @return The communications channel receive buffer size. A zero is * returned on error */ private int setup() { int bufSz = 64 * 1024; // // set the receiver buffer // try { m_comm.setReceiveBufferSize(bufSz); } catch (SocketException err) { bufSz = 0; } if (bufSz == 0) { try { bufSz = m_comm.getReceiveBufferSize(); } catch (SocketException err) { bufSz = 0; } } return bufSz; } /** * The run method is an infinite loop method that receives all datagrams * for the session. If an unrecoverable error occurs then the m_handler * is informed of the error * * If a pdu is recovered from the channel then the associated handler is * invoked to process the pdu. * * @see SnmpPacketHandler */ public void run() { final int bufSz = setup(); if (bufSz == 0) { return; } final LinkedList fastReceiverQ = new LinkedList(); final LinkedList usedBuffers = new LinkedList(); Thread fastReceiver = new Thread(new Runnable() { public void run() { while (!m_isClosing && Thread.interrupted() == false) { byte[] buf = null; synchronized (usedBuffers) { if (!usedBuffers.isEmpty()) buf = (byte[]) usedBuffers.removeFirst(); } if (buf == null || buf.length != bufSz) buf = new byte[bufSz]; try { DatagramPacket pkt = new DatagramPacket(buf, buf.length); m_comm.receive(pkt); synchronized (fastReceiverQ) { fastReceiverQ.addLast(pkt); fastReceiverQ.notify(); } } catch (InterruptedIOException ioe) { synchronized (usedBuffers) { usedBuffers.addLast(buf); } continue; } catch (Exception e) { if (!m_isClosing) { boolean handled = true; try { Class loggerC = Class.forName("org.opennms.core.utils.ThreadCategory"); Class[] methodParmList = { Class.class }; Method loggerM = loggerC.getMethod("getInstance", methodParmList); Object[] parmList = { this.getClass() }; Object loggerI = loggerM.invoke(null, parmList); methodParmList = new Class[] { Object.class, Throwable.class }; Method infoM = loggerC.getMethod("info", methodParmList); parmList = new Object[] { "An unknown error occured decoding the packet", e }; infoM.invoke(loggerI, parmList); } catch (Throwable t) { handled = false; } if (!handled) { System.out.println(new Date() + " - Exception: " + e.getMessage()); } m_handler.processException(e); } } } } }, Thread.currentThread().getName() + "-FastReceiver"); fastReceiver.start(); // // get a buffer for the datagrams // while (!m_isClosing) { DatagramPacket pkt = null; try { // // reset the packet's length // synchronized (fastReceiverQ) { while (fastReceiverQ.isEmpty() && !m_isClosing) fastReceiverQ.wait(300); if (m_isClosing) continue; pkt = (DatagramPacket) fastReceiverQ.removeFirst(); } handlePkt(pkt); } catch (SnmpPduEncodingException err) { boolean handled = true; try { Class loggerC = Class.forName("org.opennms.core.utils.ThreadCategory"); Class[] methodParmList = { Class.class }; Method loggerM = loggerC.getMethod("getInstance", methodParmList); Object[] parmList = { this.getClass() }; Object loggerI = loggerM.invoke(null, parmList); methodParmList = new Class[] { Object.class, Throwable.class }; Method infoM = loggerC.getMethod("info", methodParmList); parmList = new Object[] { "An error occured decoding the protocol data unit", err }; infoM.invoke(loggerI, parmList); methodParmList = new Class[0]; Method debugEnabledM = loggerC.getMethod("isDebugEnabled", methodParmList);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?