SnmpSubRequestHandlerpublic 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 | versionStore the protocol version to handle | protected int | typeStore 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 | agentAgent directly handled by the sub-request handler. | protected int | errorStatusError status. | protected int | errorIndexIndex of error.
A value of -1 means no error. | protected Vector | varBindThe varbind list specific to the current sub request.
The vector must contain object of type SnmpVarBind. | protected int[] | translationThe array giving the index translation between the content of
varBind and the varbind list as specified in the request. | protected Object | dataContextual object allocated by the SnmpUserDataFactory. | private com.sun.jmx.snmp.agent.SnmpMibRequest | mibRequestThe SnmpMibRequest that will be passed to the agent. | private com.sun.jmx.snmp.SnmpPdu | reqPduThe 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.SnmpMibRequest | createMibRequest(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 void | debug(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 void | debug(java.lang.String func, java.lang.Throwable t)
Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, dbgTag, func, t);
| protected void | debug(java.lang.String func, java.lang.String info)
debug(dbgTag, func, info);
| protected int | getErrorIndex()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 int | getErrorStatus()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 void | init(com.sun.jmx.snmp.SnmpEngine engine, com.sun.jmx.snmp.internal.SnmpIncomingRequest incRequest)
this.incRequest = incRequest;
this.engine = engine;
| protected boolean | isDebugOn()
return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
| protected boolean | isTraceOn()
return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP);
| protected java.lang.String | makeDebugTag()
return "SnmpSubRequestHandler";
| static final int | mapErrorStatus(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 int | mapErrorStatusToV1(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 int | mapErrorStatusToV2(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 void | run()
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");
}
| void | setUserData(java.lang.Object userData)
data = userData;
| protected void | trace(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 void | trace(java.lang.String func, java.lang.String info)
trace(dbgTag, func, info);
| protected void | updateRequest(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 void | updateResult(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...");
}
}
|
|