FileDocCategorySizeDatePackage
SnmpSubRequestHandler.javaAPI DocJava SE 5 API20171Fri Aug 26 14:55:06 BST 2005com.sun.jmx.snmp.daemon

SnmpSubRequestHandler

public class SnmpSubRequestHandler extends Object implements Runnable, com.sun.jmx.snmp.SnmpDefinitions

Fields Summary
protected com.sun.jmx.snmp.internal.SnmpIncomingRequest
incRequest
protected com.sun.jmx.snmp.SnmpEngine
engine
protected String
dbgTag
protected int
version
Store the protocol version to handle
protected int
type
Store the operation type. Remember if the type is Walk, it means that we have to invoke the check method ...
protected com.sun.jmx.snmp.agent.SnmpMibAgent
agent
Agent directly handled by the sub-request handler.
protected int
errorStatus
Error status.
protected int
errorIndex
Index of error. A value of -1 means no error.
protected Vector
varBind
The varbind list specific to the current sub request. The vector must contain object of type SnmpVarBind.
protected int[]
translation
The array giving the index translation between the content of varBind and the varbind list as specified in the request.
protected Object
data
Contextual object allocated by the SnmpUserDataFactory.
private com.sun.jmx.snmp.agent.SnmpMibRequest
mibRequest
The SnmpMibRequest that will be passed to the agent.
private com.sun.jmx.snmp.SnmpPdu
reqPdu
The SnmpPdu that will be passed to the request.
Constructors Summary
protected SnmpSubRequestHandler(com.sun.jmx.snmp.SnmpEngine engine, com.sun.jmx.snmp.internal.SnmpIncomingRequest incRequest, com.sun.jmx.snmp.agent.SnmpMibAgent agent, com.sun.jmx.snmp.SnmpPdu req)
V3 enabled Adaptor. Each Oid is added using updateRequest method.

                   
      
				     
				      
				      
        this(agent, req);
	init(engine, incRequest);
    
protected SnmpSubRequestHandler(com.sun.jmx.snmp.SnmpEngine engine, com.sun.jmx.snmp.internal.SnmpIncomingRequest incRequest, com.sun.jmx.snmp.agent.SnmpMibAgent agent, com.sun.jmx.snmp.SnmpPdu req, boolean nouse)
V3 enabled Adaptor.

        this(agent, req, nouse);
	init(engine, incRequest);
    
protected SnmpSubRequestHandler(com.sun.jmx.snmp.agent.SnmpMibAgent agent, com.sun.jmx.snmp.SnmpPdu req)
SNMP V1/V2 . To be called with updateRequest.

        
        dbgTag = makeDebugTag();
        if (isTraceOn()) {
            trace("constructor", "creating instance for request " + String.valueOf(req.requestId));
        }
	
        version= req.version;
        type= req.type;
        this.agent= agent;
	
	// We get a ref on the pdu in order to pass it to SnmpMibRequest.
	reqPdu = req;
	
        //Pre-allocate room for storing varbindlist and translation table.
        //
        int length= req.varBindList.length;
        translation= new int[length];
        varBind= new NonSyncVector(length);
    
protected SnmpSubRequestHandler(com.sun.jmx.snmp.agent.SnmpMibAgent agent, com.sun.jmx.snmp.SnmpPdu req, boolean nouse)
SNMP V1/V2 The constuctor initialize the subrequest with the whole varbind list contained in the original request.

        this(agent,req); 
    
        // The translation table is easy in this case ...
        //
        int max= translation.length;
        SnmpVarBind[] list= req.varBindList;
        for(int i=0; i < max; i++) {
            translation[i]= i;
            ((NonSyncVector)varBind).addNonSyncElement(list[i]);
        }
    
Methods Summary
com.sun.jmx.snmp.agent.SnmpMibRequestcreateMibRequest(java.util.Vector vblist, int protocolVersion, java.lang.Object userData)


	// This is an optimization: 
	//    The SnmpMibRequest created in the check() phase is
	//    reused in the set() phase.
	//
	if (type == pduSetRequestPdu && mibRequest != null)
	    return mibRequest;
	
	//This is a request comming from an SnmpV3AdaptorServer.
	//Full power.
	SnmpMibRequest result = null;
	if(incRequest != null) {
	    result = SnmpMibAgent.newMibRequest(engine,
						reqPdu,
						vblist,
						protocolVersion,
						userData,
						incRequest.getPrincipal(),
						incRequest.getSecurityLevel(),
						incRequest.getSecurityModel(),
						incRequest.getContextName(),
						incRequest.getAccessContext());
	} else {
	    result = SnmpMibAgent.newMibRequest(reqPdu,
						vblist,
						protocolVersion,
						userData);
	}
	// If we're doing the check() phase, we store the SnmpMibRequest
	// so that we can reuse it in the set() phase.
	//
	if (type == pduWalkRequest)
	    mibRequest = result;

	return result;
    
protected voiddebug(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
    
protected voiddebug(java.lang.String func, java.lang.Throwable t)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, dbgTag, func, t);
    
protected voiddebug(java.lang.String func, java.lang.String info)

        debug(dbgTag, func, info);
    
protected intgetErrorIndex()
The method returns the error index as a position in the var bind list. The value returned by the method corresponds to the index in the original var bind list as received by the SNMP protocol adaptor.

        if  (errorStatus == snmpRspNoError)
            return -1;
    
        // An error occurs. We need to be carefull because the index
        // we are getting is a valid SNMP index (so range starts at 1).
        // FIX ME: Shall we double-check the range here ?
        // The response is : YES :
        if ((errorIndex == 0) || (errorIndex == -1))
            errorIndex = 1;
	
        return translation[errorIndex -1];
    
protected intgetErrorStatus()
The method returns the error status of the operation. The method takes into account the protocol version.

        if (errorStatus == snmpRspNoError)
            return snmpRspNoError;
	    
        return mapErrorStatus(errorStatus,version,type);
    
private voidinit(com.sun.jmx.snmp.SnmpEngine engine, com.sun.jmx.snmp.internal.SnmpIncomingRequest incRequest)

	this.incRequest = incRequest;
	this.engine = engine;	
    
protected booleanisDebugOn()

        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
    
protected booleanisTraceOn()

        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP);
    
protected java.lang.StringmakeDebugTag()

        return "SnmpSubRequestHandler";
    
static final intmapErrorStatus(int errorStatus, int protocolVersion, int reqPduType)

        if (errorStatus == SnmpDefinitions.snmpRspNoError)
            return SnmpDefinitions.snmpRspNoError;
	
        // Too bad, an error occurs ... we need to translate it ...
        //
	if (protocolVersion == SnmpDefinitions.snmpVersionOne)
	    return mapErrorStatusToV1(errorStatus,reqPduType);
        if (protocolVersion == SnmpDefinitions.snmpVersionTwo ||
	    protocolVersion == SnmpDefinitions.snmpVersionThree)
	    return mapErrorStatusToV2(errorStatus,reqPduType);
	
        return SnmpDefinitions.snmpRspGenErr;
    
static final intmapErrorStatusToV1(int errorStatus, int reqPduType)

	// Map v2 codes onto v1 codes
	// 
        if (errorStatus == SnmpDefinitions.snmpRspNoError)
            return SnmpDefinitions.snmpRspNoError;

        if (errorStatus == SnmpDefinitions.snmpRspGenErr)
            return SnmpDefinitions.snmpRspGenErr;

        if (errorStatus == SnmpDefinitions.snmpRspNoSuchName)
            return SnmpDefinitions.snmpRspNoSuchName;
	
	if ((errorStatus == SnmpStatusException.noSuchInstance) ||
	    (errorStatus == SnmpStatusException.noSuchObject)   ||
	    (errorStatus == SnmpDefinitions.snmpRspNoAccess)    ||
	    (errorStatus == SnmpDefinitions.snmpRspInconsistentName) ||
	    (errorStatus == SnmpDefinitions.snmpRspAuthorizationError)){
	    
	    return SnmpDefinitions.snmpRspNoSuchName;
	    
	} else if ((errorStatus == 
		    SnmpDefinitions.snmpRspAuthorizationError)         ||
		   (errorStatus == SnmpDefinitions.snmpRspNotWritable)) {
	    
	    if (reqPduType == SnmpDefinitions.pduWalkRequest)
		return SnmpDefinitions.snmpRspReadOnly;
	    else
		return SnmpDefinitions.snmpRspNoSuchName;
	    
	} else if ((errorStatus == SnmpDefinitions.snmpRspNoCreation)) {
	    
		return SnmpDefinitions.snmpRspNoSuchName;

	} else if ((errorStatus == SnmpDefinitions.snmpRspWrongType)      ||
		   (errorStatus == SnmpDefinitions.snmpRspWrongLength)    ||
		   (errorStatus == SnmpDefinitions.snmpRspWrongEncoding)  ||
		   (errorStatus == SnmpDefinitions.snmpRspWrongValue)     ||
		   (errorStatus == SnmpDefinitions.snmpRspWrongLength)    ||
		   (errorStatus == 
		    SnmpDefinitions.snmpRspInconsistentValue)) {
	    
	    if ((reqPduType == SnmpDefinitions.pduSetRequestPdu) || 
		(reqPduType == SnmpDefinitions.pduWalkRequest))
		return SnmpDefinitions.snmpRspBadValue;
	    else
		return SnmpDefinitions.snmpRspNoSuchName;
	    
	} else if ((errorStatus == 
		    SnmpDefinitions.snmpRspResourceUnavailable) ||
		   (errorStatus == 
		    SnmpDefinitions.snmpRspCommitFailed)        ||
		   (errorStatus == SnmpDefinitions.snmpRspUndoFailed)) {
	    
	    return SnmpDefinitions.snmpRspGenErr;
	    
	}

	// At this point we should have a V1 error code
	//
	if (errorStatus == SnmpDefinitions.snmpRspTooBig)
	    return SnmpDefinitions.snmpRspTooBig;

	if( (errorStatus == SnmpDefinitions.snmpRspBadValue) ||
	    (errorStatus == SnmpDefinitions.snmpRspReadOnly)) {
	    if ((reqPduType == SnmpDefinitions.pduSetRequestPdu) || 
		(reqPduType == SnmpDefinitions.pduWalkRequest))
		return errorStatus;
	    else 
		return SnmpDefinitions.snmpRspNoSuchName;
	}

	// We have a snmpRspGenErr, or something which is not defined
	// in RFC1905 => return a snmpRspGenErr
	//
	return SnmpDefinitions.snmpRspGenErr;

    
static final intmapErrorStatusToV2(int errorStatus, int reqPduType)

	// Map v1 codes onto v2 codes
	// 
        if (errorStatus == SnmpDefinitions.snmpRspNoError)
            return SnmpDefinitions.snmpRspNoError;

        if (errorStatus == SnmpDefinitions.snmpRspGenErr)
            return SnmpDefinitions.snmpRspGenErr;

        if (errorStatus == SnmpDefinitions.snmpRspTooBig)
            return SnmpDefinitions.snmpRspTooBig;

	// For get / getNext / getBulk the only global error
	// (PDU-level) possible is genErr.
	//
	if ((reqPduType != SnmpDefinitions.pduSetRequestPdu) && 
	    (reqPduType != SnmpDefinitions.pduWalkRequest)) {
	    if(errorStatus == SnmpDefinitions.snmpRspAuthorizationError)
		return errorStatus;
	    else
		return SnmpDefinitions.snmpRspGenErr;
	}

	// Map to noSuchName
	//	if ((errorStatus == SnmpDefinitions.snmpRspNoSuchName) ||
	//   (errorStatus == SnmpStatusException.noSuchInstance) ||
	//  (errorStatus == SnmpStatusException.noSuchObject))
	//  return SnmpDefinitions.snmpRspNoSuchName;

	// SnmpStatusException.noSuchInstance and 
	// SnmpStatusException.noSuchObject can't happen...

	if (errorStatus == SnmpDefinitions.snmpRspNoSuchName)
	    return SnmpDefinitions.snmpRspNoAccess;

	// Map to notWritable
 	if (errorStatus == SnmpDefinitions.snmpRspReadOnly)
		return SnmpDefinitions.snmpRspNotWritable;

	// Map to wrongValue
 	if (errorStatus == SnmpDefinitions.snmpRspBadValue)
	    return SnmpDefinitions.snmpRspWrongValue;
	
	// Other valid V2 codes
	if ((errorStatus == SnmpDefinitions.snmpRspNoAccess) ||
	    (errorStatus == SnmpDefinitions.snmpRspInconsistentName) ||
	    (errorStatus == SnmpDefinitions.snmpRspAuthorizationError) ||
	    (errorStatus == SnmpDefinitions.snmpRspNotWritable) ||
	    (errorStatus == SnmpDefinitions.snmpRspNoCreation) ||
	    (errorStatus == SnmpDefinitions.snmpRspWrongType) ||
	    (errorStatus == SnmpDefinitions.snmpRspWrongLength) ||
	    (errorStatus == SnmpDefinitions.snmpRspWrongEncoding) ||
	    (errorStatus == SnmpDefinitions.snmpRspWrongValue) ||
	    (errorStatus == SnmpDefinitions.snmpRspWrongLength) ||
	    (errorStatus == SnmpDefinitions.snmpRspInconsistentValue) ||
	    (errorStatus == SnmpDefinitions.snmpRspResourceUnavailable) ||
	    (errorStatus == SnmpDefinitions.snmpRspCommitFailed) ||
	    (errorStatus == SnmpDefinitions.snmpRspUndoFailed)) 
	    return errorStatus;

	// Ivalid V2 code => genErr
	return SnmpDefinitions.snmpRspGenErr;
    
public voidrun()

    
        try {
	    final ThreadContext oldContext = 
		ThreadContext.push("SnmpUserData",data);
	    try {
		switch(type) {
		case pduGetRequestPdu:
		    // Invoke a get operation
		    //
		    if (isTraceOn()) {
			trace("run", "[" + Thread.currentThread() + 
			      "]:get operation on " + agent.getMibName());
		    }
		
		    agent.get(createMibRequest(varBind,version,data));
		    break;
	
		case pduGetNextRequestPdu:
		    if (isTraceOn()) {
			trace("run", "[" + Thread.currentThread() + 
			      "]:getNext operation on " + agent.getMibName());
		    }
		    //#ifdef DEBUG
		    agent.getNext(createMibRequest(varBind,version,data));
		    break;
		    
		case pduSetRequestPdu:
		    if (isTraceOn()) {
			trace("run", "[" + Thread.currentThread() +
			      "]:set operation on " + agent.getMibName());
		    }
		    agent.set(createMibRequest(varBind,version,data));
		    break;
		    
		case pduWalkRequest:
		    if (isTraceOn()) {
			trace("run", "[" + Thread.currentThread() + 
			      "]:check operation on " + agent.getMibName());
		    }
		    agent.check(createMibRequest(varBind,version,data));
		    break;
		    
		default:
		    if (isDebugOn()) {
			debug("run", "[" + Thread.currentThread() + 
			      "]:unknown operation (" +  type + ") on " + 
			      agent.getMibName());
		    }
		    errorStatus= snmpRspGenErr;
		    errorIndex= 1;
		    break;
		    
		}// end of switch
		
	    } finally {
		ThreadContext.restore(oldContext);
	    }
	} catch(SnmpStatusException x) {
	    errorStatus = x.getStatus() ;
	    errorIndex=  x.getErrorIndex();
	    if (isDebugOn()) {
		debug("run", "[" + Thread.currentThread() + 
		      "]:an Snmp error occured during the operation");
		debug("run", x);
	    }
	}
	catch(Exception x) {
	    errorStatus = SnmpDefinitions.snmpRspGenErr ;
	    if (isTraceOn()) {
		trace("run", "[" + Thread.currentThread() + 
		      "]:a generic error occured during the operation");
	    }
	    if (isDebugOn()) {
		debug("run", "Error is: " + x);
		debug("run", x);
	    }
	}
	if (isTraceOn()) {
	    trace("run", "[" + Thread.currentThread() +
		  "]:operation completed");
	}
    
voidsetUserData(java.lang.Object userData)

	data = userData;
    
protected voidtrace(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
    
protected voidtrace(java.lang.String func, java.lang.String info)

        trace(dbgTag, func, info);
    
protected voidupdateRequest(com.sun.jmx.snmp.SnmpVarBind var, int pos)
The method updates the varbind list of the subrequest.

        int size= varBind.size();
        translation[size]= pos;
        varBind.addElement(var);
    
protected voidupdateResult(com.sun.jmx.snmp.SnmpVarBind[] result)
The method updates a given var bind list with the result of a previsouly invoked operation. Prior to calling the method, one must make sure that the operation was successful. As such the method getErrorIndex or getErrorStatus should be called.

  
	if (result == null) return;
        final int max=varBind.size();
	final int len=result.length;
        for(int i= 0; i< max ; i++) {
	    // bugId 4641694: must check position in order to avoid 
	    //       ArrayIndexOutOfBoundException
	    final int pos=translation[i];
	    if (pos < len) {
		result[pos] = 
		    (SnmpVarBind)((NonSyncVector)varBind).elementAtNonSync(i);
	    } else {
		debug("updateResult","Position `"+pos+"' is out of bound...");
	    }
        }