/projects/jre-1.6.0/src/com/sun/jmx/snmp/daemon/SnmpInformRequest.java
https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 1203 lines · 693 code · 156 blank · 354 comment · 94 complexity · 5daf89657f21a68bcff1817998b09e5d MD5 · raw file
- /*
- * %Z%file %M%
- * %Z%author Sun Microsystems, Inc.
- * %Z%version %I%
- * %Z%date %D%
- *
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
- */
- package com.sun.jmx.snmp.daemon ;
- // JAVA imports
- //
- import java.io.Serializable;
- import java.net.InetAddress;
- import java.util.Vector;
- import java.util.Date;
- // JMX imports
- //
- import com.sun.jmx.snmp.SnmpMessage;
- import com.sun.jmx.snmp.SnmpVarBind;
- import com.sun.jmx.snmp.SnmpPduFactory;
- import com.sun.jmx.snmp.SnmpPduPacket;
- import com.sun.jmx.snmp.SnmpPduRequest;
- import com.sun.jmx.snmp.SnmpPduBulk;
- import com.sun.jmx.snmp.SnmpDefinitions;
- import com.sun.jmx.snmp.SnmpStatusException;
- import com.sun.jmx.snmp.SnmpTooBigException;
- import com.sun.jmx.snmp.SnmpVarBindList;
- import com.sun.jmx.snmp.SnmpPdu;
- import com.sun.jmx.snmp.SnmpPduRequestType;
- // SNMP Runtime imports
- //
- import com.sun.jmx.trace.Trace;
- /**
- * This class is used by the {@link com.sun.jmx.snmp.daemon.SnmpAdaptorServer SNMP adaptor server} to send inform requests
- * to an SNMP manager and receive inform responses.
- * <P>
- * This class provides basic functions that enable you to fire inform requests,
- * handle retries, timeouts, and process responses from the manager.
- * <BR>
- * The SNMP adaptor server specifies the destination of the inform request and controls
- * the size of a single inform request/response to fit into its <CODE>bufferSize</CODE>.
- * It specifies the maximum number of tries and the timeout to be used for the inform requests.
- * It also provides resources such as the authentication mechanism (using its PDU factory),
- * controlling all inform requests created by it, and finally the inform response to the user.
- * <P>
- * Each inform request, when ready to be sent, is assigned a unique identifier which helps
- * in identifying the inform request with matching inform responses to the protocol engine
- * lying transparently underneath. The engine does the job of retrying the inform requests
- * when the timer expires and calls the SNMP adaptor server when a timeout occurs after exhausting
- * the maximum number of tries.
- * <P>
- * The inform request object provides the method, {@link #waitForCompletion waitForCompletion(long time)},
- * which enables a user to operate in a synchronous mode with an inform request.
- * This is done by blocking the user thread for the desired time interval.
- * The user thread gets notified whenever a request reaches completion, independently of the status of the response.
- * <P>
- * If an {@link com.sun.jmx.snmp.daemon.SnmpInformHandler inform callback} is provided when sending the inform request,
- * the user operates in an asynchronous mode with the inform request. The user thread is not blocked
- * and the specific inform callback implementation provided by the user is invoked when the inform response is received.
- *
- * <P>
- * <B>Note:</B>
- * <BR>From RFC 1905, the SNMP inform request is defined as a request generated and transmitted
- * by an SNMPv2 entity acting in a manager role to another SNMPv2 entity also acting in a manager role.
- * The mechanisms to implement this behaviour are defined in the SNMP manager API.
- * <BR>
- * Nevertheless, this feature has derived and in some documentations, the inform request appears
- * like an SNMPv2 trap that gets responded.
- * <BR>The <CODE>SnmpInformRequest</CODE> class is used to fullfill this latter case.
- * <p><b>This API is a Sun Microsystems internal API and is subject
- * to change without notice.</b></p>
- */
- public class SnmpInformRequest implements SnmpDefinitions {
-
- // VARIABLES
- //----------
-
- /**
- * This object maintains a global counter for the inform request ID.
- */
- private static SnmpRequestCounter requestCounter = new SnmpRequestCounter();
-
- /**
- * This contains a list of <CODE>SnmpVarBind</CODE> objects for making the SNMP inform requests.
- */
- private SnmpVarBindList varBindList = null;
-
- /**
- * The error status associated with the inform response packet.
- */
- int errorStatus = 0;
-
- /**
- * The index in <CODE>SnmpVarBindList</CODE> that caused the exception.
- */
- int errorIndex = 0;
-
- //private SnmpVarBind internalVarBind[] = null;
- SnmpVarBind internalVarBind[] = null;
- //private String reason = null;
- String reason = null;
-
- /**
- * The SNMP adaptor associated with this inform request.
- */
- private transient SnmpAdaptorServer adaptor;
-
- /**
- * The session object associated with this inform request.
- */
- private transient SnmpSession informSession;
-
- /**
- * The user implementation of the callback interface for this request.
- */
- private SnmpInformHandler callback = null;
-
- /**
- * The inform request PDU.
- */
- //private SnmpPduPacket requestPdu;
- SnmpPdu requestPdu;
- /**
- * The inform response PDU.
- */
- //private SnmpPduRequest responsePdu;
- SnmpPduRequestType responsePdu;
-
- /**
- * Base status of an inform request.
- */
- final static private int stBase = 1;
-
- /**
- * Status of an inform request: in progress.
- */
- final static public int stInProgress = stBase;
-
- /**
- * Status of an inform request: waiting to be sent.
- */
- final static public int stWaitingToSend = (stBase << 1) | stInProgress;
-
- /**
- * Status of an inform request: waiting for reply.
- */
- final static public int stWaitingForReply = (stBase << 2) | stInProgress;
-
- /**
- * Status of an inform request: reply received.
- */
- final static public int stReceivedReply = (stBase << 3) | stInProgress;
-
- /**
- * Status of an inform request: request aborted.
- */
- final static public int stAborted = (stBase << 4);
-
- /**
- * Status of an inform request: timeout.
- */
- final static public int stTimeout = (stBase << 5);
-
- /**
- * Status of an inform request: internal error occured.
- */
- final static public int stInternalError = (stBase << 6);
-
- /**
- * Status of an inform request: result available for the request.
- */
- final static public int stResultsAvailable = (stBase << 7);
-
- /**
- * Status of an inform request: request never used.
- */
- final static public int stNeverUsed = (stBase << 8);
-
- /**
- * Number of tries performed for the current polling operation.
- */
- private int numTries = 0;
- /**
- * Timeout.
- * The default amount of time is 3000 millisec.
- */
- private int timeout = 3 * 1000; // 3 seconds.
- /**
- */
- private int reqState = stNeverUsed;
- // Polling control parameters.
- private long prevPollTime = 0; // value of 0 means poll never happened.
- private long nextPollTime = 0;
- private long waitTimeForResponse;
- private Date debugDate = new Date();
- /**
- * The request ID for an active inform request.
- */
- private int requestId = 0;
-
- private int port = 0;
- private InetAddress address = null;
- private String communityString = null;
-
- String dbgTag = "SnmpInformRequest";
-
- // CONSTRUCTORS
- //-------------
- /**
- * For SNMP Runtime internal use only.
- * Constructor for creating new inform request. This object can be created only by an SNMP adaptor object.
- * @param session <CODE>SnmpSession</CODE> object for this inform request.
- * @param adp <CODE>SnmpAdaptorServer</CODE> object for this inform request.
- * @param addr The <CODE>InetAddress</CODE> destination for this inform request.
- * @param cs The community string to be used for the inform request.
- * @param requestCB Callback interface for the inform request.
- * @exception SnmpStatusException SNMP adaptor is not ONLINE or session is dead.
- */
- SnmpInformRequest(SnmpSession session,
- SnmpAdaptorServer adp,
- InetAddress addr,
- String cs,
- int p,
- SnmpInformHandler requestCB)
- throws SnmpStatusException {
-
- informSession = session;
- adaptor = adp;
- address = addr;
- communityString = cs;
- port = p;
- callback = requestCB;
- informSession.addInformRequest(this); // add to adaptor queue.
- setTimeout(adaptor.getTimeout()) ;
- }
- // PUBLIC METHODS
- //---------------
- /**
- * Gets the request id (invoke identifier) of the current inform request.
- * @return The request id.
- */
- final public synchronized int getRequestId () {
- return requestId;
- }
- /**
- * Gets the destination address of the current inform request.
- * @return The destination address.
- */
- synchronized InetAddress getAddress() {
- return address;
- }
- /**
- * Gets the current status of the inform request.
- * @return The current status of the inform request.
- */
- final public synchronized int getRequestStatus() {
- return reqState ;
- }
-
- /**
- * Indicates whether or not the inform request was aborted.
- * @return <CODE>true</CODE> if the inform request was aborted, <CODE>false</CODE> otherwise.
- */
- final public synchronized boolean isAborted() {
- return ((reqState & stAborted) == stAborted);
- }
- /**
- * Indicates whether or not the inform request is in progress.
- * @return <CODE>true</CODE> if the inform request is in progress, <CODE>false</CODE> otherwise.
- */
- final public synchronized boolean inProgress() {
- return ((reqState & stInProgress) == stInProgress);
- }
- /**
- * Indicates whether or not the inform request result is available.
- * @return <CODE>true</CODE> if the inform request result is available, <CODE>false</CODE> otherwise.
- */
- final public synchronized boolean isResultAvailable() {
- return (reqState == stResultsAvailable);
- }
-
- /**
- * Gets the status associated with the <CODE>SnmpVarBindList</CODE>.
- * @return The error status.
- */
- final public synchronized int getErrorStatus() {
- return errorStatus;
- }
- /**
- * Gets the index.
- * <P>NOTE: this value is equal to the <CODE>errorIndex</CODE> field minus 1.
- * @return The error index.
- */
- final public synchronized int getErrorIndex() {
- return errorIndex;
- }
- /**
- * Gets the maximum number of tries before declaring that the manager is not responding.
- * @return The maximum number of times an inform request should be tried.
- */
- final public int getMaxTries() {
- return adaptor.getMaxTries();
- }
-
- /**
- * Gets the number of tries performed for the current inform request.
- * @return The number of tries performed.
- */
- final public synchronized int getNumTries() {
- return numTries ;
- }
-
- /**
- * For SNMP Runtime internal use only.
- */
- final synchronized void setTimeout(int value) {
- timeout = value ;
- }
-
- /**
- * Gets absolute time in milliseconds (based on epoch time) when the next
- * polling activity will begin.
- * @return The absolute time when polling will begin.
- */
- final public synchronized long getAbsNextPollTime () {
- return nextPollTime ;
- }
-
- /**
- * Gets absolute time in milliseconds (based on epoch time) before which an inform
- * response is expected from a manager.
- * @return The absolute time within which an inform response is expected.
- */
- final public synchronized long getAbsMaxTimeToWait() {
- if (prevPollTime == 0) {
- return System.currentTimeMillis() ; // should never happen.
- } else {
- return waitTimeForResponse ;
- }
- }
-
- /**
- * Gets the <CODE>SnmpVarBindList</CODE> of the inform response.
- * It returns a null value if the inform request is in progress.
- * This ensures accidental manipulation does not occur when a request is in progress.
- * In case of an error, <CODE>SnmpVarBindList</CODE> is the copy
- * of the original <CODE>SnmpVarBindList</CODE> at the time of making the inform request.
- * @return The list of <CODE>SnmpVarBind</CODE> objects returned by the manager or the null value if the request
- * is in progress.
- */
- public final synchronized SnmpVarBindList getResponseVarBindList() {
- if (inProgress())
- return null;
- return varBindList;
- }
-
- /**
- * Used in synchronous mode only.
- * Provides a hook that enables a synchronous operation on a previously sent inform request.
- * Only one inform request can be in synchronous mode on a given thread.
- * The blocked thread is notified when the inform request state reaches completion.
- * If the inform request is not active, the method returns immediately.
- * The user must get the error status of the inform request to determine the
- * exact status of the request.
- *
- * @param time The amount of time to wait. Zero means block until complete.
- * @return <CODE>true</CODE> if the inform request has completed, <CODE>false</CODE> if it is still active.
- */
- final public boolean waitForCompletion(long time) {
-
- if (! inProgress()) // check if request is in progress.
- return true;
- if (informSession.thisSessionContext()) {
- // We can manipulate callback safely as we are in session thread.
- //
- SnmpInformHandler savedCallback = callback;
- callback = null;
- informSession.waitForResponse(this, time);
- callback = savedCallback;
- } else {
- // This is being done from a different thread. So notifyClient will do the notification.
- //
- synchronized (this) {
- SnmpInformHandler savedCallback = callback ;
- try {
- callback = null ;
- this.wait(time) ;
- } catch (InterruptedException e) {
- }
- callback = savedCallback ;
- }
- }
-
- return (! inProgress()); // true if request completed.
- }
- /**
- * Cancels the active inform request and removes itself from the polling list.
- */
- final public void cancelRequest() {
- errorStatus = snmpReqAborted;
- stopRequest();
- deleteRequest();
- notifyClient();
- }
- /**
- * Notifies the registered client about the completion of an operation.
- */
- final public synchronized void notifyClient() {
- this.notifyAll();
- }
- /**
- * Finalizer of the <CODE>SnmpInformRequest</CODE> objects.
- * This method is called by the garbage collector on an object
- * when garbage collection determines that there are no more references to the object.
- * <P>Sets all the references to this SNMP inform request object to <CODE>null</CODE>.
- */
- public void finalize() {
- callback = null;
- varBindList = null;
- internalVarBind = null;
- adaptor = null;
- informSession = null;
- requestPdu = null;
- responsePdu = null;
- }
- /**
- * Returns the <CODE>String</CODE> representation of an error code.
- * @param errcode The error code as an integer.
- * @return The error code as a <CODE>String</CODE>.
- */
- public static String snmpErrorToString(int errcode) {
- switch (errcode) {
- case snmpRspNoError :
- return "noError" ;
- case snmpRspTooBig :
- return "tooBig" ;
- case snmpRspNoSuchName :
- return "noSuchName" ;
- case snmpRspBadValue :
- return "badValue" ;
- case snmpRspReadOnly :
- return "readOnly" ;
- case snmpRspGenErr :
- return "genErr" ;
- case snmpRspNoAccess :
- return "noAccess" ;
- case snmpRspWrongType :
- return "wrongType" ;
- case snmpRspWrongLength :
- return "wrongLength" ;
- case snmpRspWrongEncoding :
- return "wrongEncoding" ;
- case snmpRspWrongValue :
- return "wrongValue" ;
- case snmpRspNoCreation :
- return "noCreation" ;
- case snmpRspInconsistentValue :
- return "inconsistentValue" ;
- case snmpRspResourceUnavailable :
- return "resourceUnavailable" ;
- case snmpRspCommitFailed :
- return "commitFailed" ;
- case snmpRspUndoFailed :
- return "undoFailed" ;
- case snmpRspAuthorizationError :
- return "authorizationError" ;
- case snmpRspNotWritable :
- return "notWritable" ;
- case snmpRspInconsistentName :
- return "inconsistentName" ;
- case snmpReqTimeout :
- return "reqTimeout" ;
- case snmpReqAborted :
- return "reqAborted" ;
- case snmpRspDecodingError :
- return "rspDecodingError" ;
- case snmpReqEncodingError :
- return "reqEncodingError" ;
- case snmpReqPacketOverflow :
- return "reqPacketOverflow" ;
- case snmpRspEndOfTable :
- return "rspEndOfTable" ;
- case snmpReqRefireAfterVbFix :
- return "reqRefireAfterVbFix" ;
- case snmpReqHandleTooBig :
- return "reqHandleTooBig" ;
- case snmpReqTooBigImpossible :
- return "reqTooBigImpossible" ;
- case snmpReqInternalError :
- return "reqInternalError" ;
- case snmpReqSocketIOError :
- return "reqSocketIOError" ;
- case snmpReqUnknownError :
- return "reqUnknownError" ;
- case snmpWrongSnmpVersion :
- return "wrongSnmpVersion" ;
- case snmpUnknownPrincipal:
- return "snmpUnknownPrincipal";
- case snmpAuthNotSupported:
- return "snmpAuthNotSupported";
- case snmpPrivNotSupported:
- return "snmpPrivNotSupported";
- case snmpBadSecurityLevel:
- return "snmpBadSecurityLevel";
- case snmpUsmBadEngineId:
- return "snmpUsmBadEngineId";
- case snmpUsmInvalidTimeliness:
- return "snmpUsmInvalidTimeliness";
- }
- return "Unknown Error = " + errcode;
- }
-
- // PRIVATE AND PACKAGE METHODS
- //----------------------------
-
- /**
- * For SNMP Runtime internal use only.
- * Starts an inform request in asynchronous mode. The callback interface
- * is used to notify the user upon request completion.
- * @param vblst The list of <CODE>SnmpVarBind</CODE> to be used.
- * @exception SnmpStatusException This inform request is already in progress.
- */
- synchronized void start(SnmpVarBindList vblst) throws SnmpStatusException {
- if (inProgress())
- throw new SnmpStatusException("Inform request already in progress.");
- setVarBindList(vblst);
- initializeAndFire();
- }
- private synchronized void initializeAndFire() {
- requestPdu = null;
- responsePdu = null;
- reason = null;
- startRequest(System.currentTimeMillis());
- setErrorStatusAndIndex(0, 0);
- }
-
- /**
- * This method submits the inform request for polling and marks the request
- * active. It does nothing if the request is already active.
- * The poll will be scheduled to happen immediately.
- * @param starttime The start time for polling.
- */
- private synchronized void startRequest(long starttime) {
- nextPollTime = starttime;
- prevPollTime = 0;
- schedulePoll();
- }
-
- /**
- * This method creates a new request ID. The ID is submitted to the poll server for scheduling.
- */
- private void schedulePoll() {
- numTries = 0;
- initNewRequest();
- setRequestStatus(stWaitingToSend);
- informSession.getSnmpQManager().addRequest(this);
- }
-
- /**
- * This method determines whether the inform request is to be retried. This is used if the
- * peer did not respond to a previous request. If the request exceeds
- * the maxTries limit, a timeout is signaled.
- */
- void action() {
- if (inProgress() == false)
- return;
- while (true) {
- try {
- if (numTries == 0) {
- invokeOnReady();
- } else if (numTries < getMaxTries()) {
- invokeOnRetry();
- } else {
- invokeOnTimeout();
- }
- return ;
- } catch (OutOfMemoryError omerr) {
- // Consider it as a try !
- //
- numTries++;
- if (isDebugOn()) {
- debug("action", "Inform request hit out of memory situation...");
- }
- Thread.currentThread().yield();
- }
- }
- }
-
- final private void invokeOnReady() {
- if (requestPdu == null) {
- requestPdu = constructPduPacket();
- }
- if (requestPdu != null) {
- if (sendPdu() == false)
- queueResponse();
- }
- }
- final private void invokeOnRetry() {
- invokeOnReady();
- }
-
- final private void invokeOnTimeout() {
- errorStatus = snmpReqTimeout;
- queueResponse();
- }
-
- final private void queueResponse() {
- informSession.addResponse(this);
- }
-
- /**
- * Constructs an inform request PDU.
- */
- synchronized SnmpPdu constructPduPacket() {
- SnmpPduPacket reqpdu = null;
- Exception excep = null;
- try {
- reqpdu = new SnmpPduRequest();
- reqpdu.port = port;
- reqpdu.type = pduInformRequestPdu;
- reqpdu.version = snmpVersionTwo;
- reqpdu.community = communityString.getBytes("8859_1");
- reqpdu.requestId = getRequestId();
- reqpdu.varBindList = internalVarBind;
- if (isTraceOn()) {
- trace("constructPduPacket", "Packet built");
- }
- } catch (Exception e) {
- excep = e;
- errorStatus = snmpReqUnknownError;
- reason = e.getMessage();
- }
- if (excep != null) {
- if (isDebugOn()) {
- debug("constructPduPacket", excep);
- }
- reqpdu = null;
- queueResponse();
- }
- return reqpdu;
- }
-
- boolean sendPdu() {
- try {
- responsePdu = null;
-
- SnmpPduFactory pduFactory = adaptor.getPduFactory();
- SnmpMessage msg = (SnmpMessage)pduFactory.encodeSnmpPdu((SnmpPduPacket)requestPdu, adaptor.getBufferSize().intValue());
- if (msg == null) {
- if (isDebugOn()) {
- debug("sendPdu", "pdu factory returned a null value");
- }
- throw new SnmpStatusException(snmpReqUnknownError);
- // This exception will caught hereafter and reported as an snmpReqUnknownError
- // FIXME: may be it's not the best behaviour ?
- }
- int maxPktSize = adaptor.getBufferSize().intValue();
- byte[] encoding = new byte[maxPktSize];
- int encodingLength = msg.encodeMessage(encoding);
-
- if (isTraceOn()) {
- trace("sendPdu", "Dump : \n" + msg.printMessage());
- }
- sendPduPacket(encoding, encodingLength);
- return true;
- } catch (SnmpTooBigException ar) {
-
- if (isDebugOn()) {
- debug("sendPdu", ar);
- }
-
- setErrorStatusAndIndex(snmpReqPacketOverflow, ar.getVarBindCount());
- requestPdu = null;
- reason = ar.getMessage();
- if (isDebugOn()) {
- debug("sendPdu", "Packet Overflow while building inform request");
- }
- } catch (java.io.IOException ioe) {
- setErrorStatusAndIndex(snmpReqSocketIOError, 0);
- reason = ioe.getMessage();
- } catch (Exception e) {
- if (isDebugOn()) {
- debug("sendPdu", e);
- }
- setErrorStatusAndIndex(snmpReqUnknownError, 0);
- reason = e.getMessage();
- }
- return false;
- }
- /**
- * Sends the prepared PDU packet to the manager and updates the data structure
- * to expect a response. It acquires a lock on the socket to prevent a case
- * where a response arrives before this thread could insert the
- * request into the wait queue.
- * @exception IOException Signals that an I/O exception of some sort has occurred.
- */
- final void sendPduPacket(byte[] buffer, int length) throws java.io.IOException {
-
- if (isTraceOn()) {
- trace("sendPduPacket", "Send to peer. Peer/Port : " + address.getHostName() + "/" + port +
- ". Length = " + length + "\nDump : \n" + SnmpMessage.dumpHexBuffer(buffer,0, length));
- }
- SnmpSocket theSocket = informSession.getSocket();
- synchronized (theSocket) {
- theSocket.sendPacket(buffer, length, address, port);
- setRequestSentTime(System.currentTimeMillis());
- }
- }
- /**
- * For SNMP Runtime internal use only.
- */
- final void processResponse() {
-
- if (isTraceOn()) {
- trace("processResponse", "errstatus = " + errorStatus);
- }
- if (inProgress() == false) { // check if this request is still alive.
- responsePdu = null;
- return; // the request may have cancelled.
- }
- if (errorStatus >= snmpReqInternalError) {
- handleInternalError("Internal Error...");
- return;
- }
- try {
- parsePduPacket(responsePdu);
- //responsePdu = null;
- // At this point the errorIndex is rationalized to start with 0.
- switch (errorStatus) {
- case snmpRspNoError :
- handleSuccess();
- return;
- case snmpReqTimeout :
- handleTimeout();
- return;
- case snmpReqInternalError :
- handleInternalError("Unknown internal error. deal with it later!");
- return;
- case snmpReqHandleTooBig :
- setErrorStatusAndIndex(snmpRspTooBig, 0);
- handleError("Cannot handle too-big situation...");
- return;
- case snmpReqRefireAfterVbFix :
- // Refire request after fixing varbindlist.
- initializeAndFire();
- return;
- default :
- handleError("Error status set in packet...!!");
- return;
- }
- } catch (Exception e) {
- if (isDebugOn()) {
- debug("processResponse", e);
- }
- reason = e.getMessage();
- }
- handleInternalError(reason);
- }
-
- /**
- * Parses the inform response packet. If the agent responds with error set,
- * it does not parse any further.
- */
- synchronized void parsePduPacket(SnmpPduRequestType rpdu) {
-
- if (rpdu == null)
- return;
-
- errorStatus = rpdu.getErrorStatus();
- errorIndex = rpdu.getErrorIndex();
-
- if (errorStatus == snmpRspNoError) {
- updateInternalVarBindWithResult(((SnmpPdu)rpdu).varBindList);
- return;
- }
-
- if (errorStatus != snmpRspNoError)
- --errorIndex; // rationalize for index to start with 0.
-
- if (isTraceOn()) {
- trace("parsePduPacket", "received inform response. ErrorStatus/ErrorIndex = " + errorStatus + "/" + errorIndex);
- }
- }
-
- /**
- * Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface.
- */
- private void handleSuccess() {
-
- setRequestStatus(stResultsAvailable);
- if (isTraceOn()) {
- trace("handleSuccess", "Invoking user defined callback...");
- }
- deleteRequest(); // delete only non-poll request.
- notifyClient();
-
- requestPdu = null;
- //responsePdu = null;
- internalVarBind = null;
- try { // catch all user exception which may happen in callback.
- if (callback != null)
- callback.processSnmpPollData(this, errorStatus, errorIndex, getVarBindList());
- } catch (Exception e) {
- if (isDebugOn()) {
- debug("handleSuccess", "Exception generated by user callback");
- debug("handleSuccess", e);
- }
- } catch (OutOfMemoryError ome) {
- if (isDebugOn()) {
- debug("handleSuccess", "OutOfMemory Error generated by user callback");
- debug("handleSuccess", ome);
- }
- Thread.currentThread().yield();
- }
- return;
- }
- /**
- * Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface.
- */
- private void handleTimeout() {
-
- setRequestStatus(stTimeout);
-
- if (isDebugOn()) {
- debug("handleTimeout", "Snmp error/index = " + snmpErrorToString(errorStatus) + "/" +
- errorIndex + ". Invoking timeout user defined callback...");
- }
- deleteRequest();
- notifyClient();
- requestPdu = null;
- responsePdu = null;
- internalVarBind = null;
- try {
- if (callback != null)
- callback.processSnmpPollTimeout(this);
- } catch (Exception e) { // catch any exception a user might not handle.
- if (isDebugOn()) {
- debug("handleTimeout", "Exception generated by user callback");
- debug("handleTimeout", e);
- }
- } catch (OutOfMemoryError ome) {
- if (isDebugOn()) {
- debug("handleTimeout", "OutOfMemory Error generated by user callback");
- debug("handleTimeout", ome);
- }
- Thread.currentThread().yield();
- }
- return;
- }
-
- /**
- * Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface.
- */
- private void handleError(String msg) {
-
- setRequestStatus(stResultsAvailable);
- if (isDebugOn()) {
- debug("handleError", "Snmp error/index = " + snmpErrorToString(errorStatus) + "/" +
- errorIndex + ". Invoking error user defined callback...\n" + getVarBindList());
- }
- deleteRequest();
- notifyClient();
-
- requestPdu = null;
- responsePdu = null;
- internalVarBind = null;
-
- try {
- if (callback != null)
- callback.processSnmpPollData(this, getErrorStatus(), getErrorIndex(), getVarBindList());
- } catch (Exception e) { // catch any exception a user might not handle.
- if (isDebugOn()) {
- debug("handleError", "Exception generated by user callback");
- debug("handleError", e);
- }
- } catch (OutOfMemoryError ome) {
- if (isDebugOn()) {
- debug("handleError", "OutOfMemory Error generated by user callback");
- debug("handleError", ome);
- }
- Thread.currentThread().yield();
- }
- }
- /**
- * Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface.
- */
- private void handleInternalError(String msg) {
-
- setRequestStatus(stInternalError);
- if (reason == null)
- reason = msg;
- if (isDebugOn()) {
- debug("handleInternalError", "Snmp error/index = " + snmpErrorToString(errorStatus) + "/" +
- errorIndex + ". Invoking internal error user defined callback...\n" + getVarBindList());
- }
- deleteRequest();
- notifyClient();
- requestPdu = null;
- responsePdu = null;
- internalVarBind = null;
-
- try {
- if (callback != null)
- callback.processSnmpInternalError(this, reason);
- } catch (Exception e) { // catch any exception a user might not handle.
- if (isDebugOn()) {
- debug("handleInternalError", "Exception generated by user callback");
- debug("handleInternalError", e);
- }
- } catch (OutOfMemoryError ome) {
- if (isDebugOn()) {
- debug("handleInternalError", "OutOfMemory Error generated by user callback");
- debug("handleInternalError", ome);
- }
- Thread.currentThread().yield();
- }
- }
- void updateInternalVarBindWithResult(SnmpVarBind[] list) {
-
- if ((list == null) || (list.length == 0))
- return;
-
- int idx = 0;
-
- for(int i = 0; i < internalVarBind.length && idx < list.length; i++) {
- SnmpVarBind avar = internalVarBind[i];
- if (avar == null)
- continue;
-
- SnmpVarBind res = list[idx];
- avar.setSnmpValue(res.getSnmpValue());
- idx++;
- }
- }
-
- /**
- * For SNMP Runtime internal use only.
- */
- final void invokeOnResponse(Object resp) {
- if (resp != null) {
- if (resp instanceof SnmpPduRequestType)
- responsePdu = (SnmpPduRequestType) resp;
- else
- return;
- }
- setRequestStatus(stReceivedReply);
- queueResponse();
- }
-
- /**
- * This method cancels an active inform request and removes it from the polling list.
- */
- private void stopRequest() {
-
- // Remove the clause synchronized of the stopRequest method.
- // Synchronization is isolated as possible to avoid thread lock.
- // Note: the method removeRequest from SendQ is synchronized.
- // fix bug jaw.00392.B
- //
- synchronized(this) {
- setRequestStatus(stAborted);
- }
- informSession.getSnmpQManager().removeRequest(this);
- synchronized(this) {
- requestId = 0;
- }
- }
-
- final synchronized void deleteRequest() {
- informSession.removeInformRequest(this);
- }
-
- /**
- * For SNMP Runtime internal use only.
- * Gets the active <CODE>SnmpVarBindList</CODE>. The contents of it
- * are not guaranteed to be consistent when the inform request is active.
- * @return The list of <CODE>SnmpVarBind</CODE> objects.
- */
- final synchronized SnmpVarBindList getVarBindList() {
- return varBindList;
- }
- /**
- * For SNMP Runtime internal use only.
- * You should specify the <CODE>SnmpVarBindList</CODE> at SnmpInformRequest creation time.
- * You cannot modify it during the life-time of the object.
- */
- final synchronized void setVarBindList(SnmpVarBindList newvblst) {
- varBindList = newvblst;
- if (internalVarBind == null || internalVarBind.length != varBindList.size()) {
- internalVarBind = new SnmpVarBind[varBindList.size()];
- }
- varBindList.copyInto(internalVarBind);
- }
- /**
- * For SNMP Runtime internal use only.
- */
- final synchronized void setErrorStatusAndIndex(int stat, int idx) {
- errorStatus = stat;
- errorIndex = idx;
- }
-
- /**
- * For SNMP Runtime internal use only.
- */
- final synchronized void setPrevPollTime(long prev) {
- prevPollTime = prev;
- }
- /**
- * For SNMP Runtime internal use only.
- */
- final void setRequestSentTime(long sendtime) {
- numTries++;
- setPrevPollTime(sendtime);
- waitTimeForResponse = prevPollTime + timeout*numTries;
- setRequestStatus(stWaitingForReply);
-
- if (isTraceOn()) {
- trace("setRequestSentTime", "Inform request Successfully sent");
- }
-
- informSession.getSnmpQManager().addWaiting(this);
- }
- /**
- * Initializes the request id from the request counter.
- */
- final synchronized void initNewRequest() {
- requestId = requestCounter.getNewId();
- }
- /**
- * For SNMP Runtime internal use only.
- */
- long timeRemainingForAction(long currtime) {
- switch (reqState) {
- case stWaitingToSend :
- return nextPollTime - currtime;
- case stWaitingForReply :
- return waitTimeForResponse - currtime;
- default :
- return -1;
- }
- }
- /**
- * Returns the string state corresponding to the specified integer state.
- * @param state The integer state.
- * @return The string state.
- */
- final static String statusDescription(int state) {
- switch (state) {
- case stWaitingToSend :
- return "Waiting to send.";
- case stWaitingForReply :
- return "Waiting for reply.";
- case stReceivedReply :
- return "Response arrived.";
- case stAborted :
- return "Aborted by user.";
- case stTimeout :
- return "Timeout Occured.";
- case stInternalError :
- return "Internal error.";
- case stResultsAvailable :
- return "Results available";
- case stNeverUsed :
- return "Inform request in createAndWait state";
- }
- return "Unknown inform request state.";
- }
- /**
- * Sets the request status to the specified value.
- * @param reqst The new status request.
- */
- final synchronized void setRequestStatus(int reqst) {
- reqState = reqst;
- }
- /**
- * Gives a status report of the request.
- * @return The status report of the request.
- */
- public synchronized String toString() {
- StringBuffer s = new StringBuffer(300) ;
- s.append(tostring()) ;
- s.append("\nPeer/Port : " + address.getHostName() + "/" + port) ;
- return s.toString() ;
- }
-
- private synchronized String tostring() {
- StringBuffer s = new StringBuffer("InformRequestId = " + requestId);
- s.append(" " + "Status = " + statusDescription(reqState));
- s.append(" Timeout/MaxTries/NumTries = " + timeout*numTries + "/" +
- + getMaxTries() + "/" + numTries);
- if (prevPollTime > 0) {
- debugDate.setTime(prevPollTime);
- s.append("\nPrevPolled = " + debugDate.toString());
- } else
- s.append("\nNeverPolled");
- s.append(" / RemainingTime(millis) = " +
- timeRemainingForAction(System.currentTimeMillis()));
- return s.toString();
- }
- // TRACES & DEBUG
- //---------------
-
- boolean isTraceOn() {
- return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP);
- }
- void trace(String clz, String func, String info) {
- Trace.send(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
- }
- void trace(String func, String info) {
- trace(dbgTag, func, info);
- }
-
- boolean isDebugOn() {
- return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
- }
- void debug(String clz, String func, String info) {
- Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
- }
- void debug(String clz, String func, Throwable exception) {
- Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, exception);
- }
-
- void debug(String func, String info) {
- debug(dbgTag, func, info);
- }
-
- void debug(String func, Throwable exception) {
- debug(dbgTag, func, exception);
- }
-
- }