You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
12 KiB
344 lines
12 KiB
/*
|
|
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
package com.sun.jmx.snmp.daemon;
|
|
|
|
|
|
|
|
// java import
|
|
//
|
|
import java.util.Enumeration;
|
|
import java.util.logging.Level;
|
|
// jmx imports
|
|
//
|
|
import com.sun.jmx.snmp.SnmpPdu;
|
|
import com.sun.jmx.snmp.SnmpVarBind;
|
|
import com.sun.jmx.snmp.SnmpOid;
|
|
import com.sun.jmx.snmp.SnmpValue;
|
|
import com.sun.jmx.snmp.SnmpDefinitions;
|
|
import com.sun.jmx.snmp.SnmpStatusException;
|
|
import com.sun.jmx.snmp.SnmpEngine;
|
|
// SNMP Runtime import
|
|
//
|
|
import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
|
|
import com.sun.jmx.snmp.agent.SnmpMibAgent;
|
|
import com.sun.jmx.snmp.internal.SnmpIncomingRequest;
|
|
import com.sun.jmx.snmp.ThreadContext;
|
|
|
|
class SnmpSubBulkRequestHandler extends SnmpSubRequestHandler {
|
|
private SnmpAdaptorServer server = null;
|
|
|
|
/**
|
|
* The constructor initialize the subrequest with the whole varbind list contained
|
|
* in the original request.
|
|
*/
|
|
protected SnmpSubBulkRequestHandler(SnmpEngine engine,
|
|
SnmpAdaptorServer server,
|
|
SnmpIncomingRequest incRequest,
|
|
SnmpMibAgent agent,
|
|
SnmpPdu req,
|
|
int nonRepeat,
|
|
int maxRepeat,
|
|
int R) {
|
|
super(engine, incRequest, agent, req);
|
|
init(server, req, nonRepeat, maxRepeat, R);
|
|
}
|
|
|
|
/**
|
|
* The constructor initialize the subrequest with the whole varbind list contained
|
|
* in the original request.
|
|
*/
|
|
protected SnmpSubBulkRequestHandler(SnmpAdaptorServer server,
|
|
SnmpMibAgent agent,
|
|
SnmpPdu req,
|
|
int nonRepeat,
|
|
int maxRepeat,
|
|
int R) {
|
|
super(agent, req);
|
|
init(server, req, nonRepeat, maxRepeat, R);
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
|
|
size= varBind.size();
|
|
|
|
try {
|
|
// Invoke a getBulk operation
|
|
//
|
|
/* NPCTE fix for bugId 4492741, esc 0, 16-August-2001 */
|
|
final ThreadContext oldContext =
|
|
ThreadContext.push("SnmpUserData",data);
|
|
try {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"run", "[" + Thread.currentThread() +
|
|
"]:getBulk operation on " + agent.getMibName());
|
|
}
|
|
agent.getBulk(createMibRequest(varBind,version,data),
|
|
nonRepeat, maxRepeat);
|
|
} finally {
|
|
ThreadContext.restore(oldContext);
|
|
}
|
|
/* end of NPCTE fix for bugId 4492741 */
|
|
|
|
} catch(SnmpStatusException x) {
|
|
errorStatus = x.getStatus() ;
|
|
errorIndex= x.getErrorIndex();
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
|
|
"run", "[" + Thread.currentThread() +
|
|
"]:an Snmp error occurred during the operation", x);
|
|
}
|
|
}
|
|
catch(Exception x) {
|
|
errorStatus = SnmpDefinitions.snmpRspGenErr ;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
|
|
"run", "[" + Thread.currentThread() +
|
|
"]:a generic error occurred during the operation", x);
|
|
}
|
|
}
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"run", "[" + Thread.currentThread() +
|
|
"]:operation completed");
|
|
}
|
|
}
|
|
|
|
private void init(SnmpAdaptorServer server,
|
|
SnmpPdu req,
|
|
int nonRepeat,
|
|
int maxRepeat,
|
|
int R) {
|
|
this.server = server;
|
|
this.nonRepeat= nonRepeat;
|
|
this.maxRepeat= maxRepeat;
|
|
this.globalR= R;
|
|
|
|
final int max= translation.length;
|
|
final SnmpVarBind[] list= req.varBindList;
|
|
final NonSyncVector<SnmpVarBind> nonSyncVarBind =
|
|
((NonSyncVector<SnmpVarBind>)varBind);
|
|
for(int i=0; i < max; i++) {
|
|
translation[i]= i;
|
|
// we need to allocate a new SnmpVarBind. Otherwise the first
|
|
// sub request will modify the list...
|
|
//
|
|
final SnmpVarBind newVarBind =
|
|
new SnmpVarBind(list[i].oid, list[i].value);
|
|
nonSyncVarBind.addNonSyncElement(newVarBind);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The method updates find out which element to use at update time. Handle oid overlapping as well
|
|
*/
|
|
private SnmpVarBind findVarBind(SnmpVarBind element,
|
|
SnmpVarBind result) {
|
|
|
|
if (element == null) return null;
|
|
|
|
if (result.oid == null) {
|
|
return element;
|
|
}
|
|
|
|
if (element.value == SnmpVarBind.endOfMibView) return result;
|
|
|
|
if (result.value == SnmpVarBind.endOfMibView) return element;
|
|
|
|
final SnmpValue val = result.value;
|
|
|
|
int comp = element.oid.compareTo(result.oid);
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","Comparing OID element : " + element.oid +
|
|
" with result : " + result.oid);
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","Values element : " + element.value +
|
|
" result : " + result.value);
|
|
}
|
|
if (comp < 0) {
|
|
// Take the smallest (lexicographically)
|
|
//
|
|
return element;
|
|
}
|
|
else {
|
|
if(comp == 0) {
|
|
// Must compare agent used for reply
|
|
// Take the deeper within the reply
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind"," oid overlapping. Oid : " +
|
|
element.oid + "value :" + element.value);
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","Already present varBind : " +
|
|
result);
|
|
}
|
|
SnmpOid oid = result.oid;
|
|
SnmpMibAgent deeperAgent = server.getAgentMib(oid);
|
|
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","Deeper agent : " + deeperAgent);
|
|
}
|
|
if(deeperAgent == agent) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","The current agent is the deeper one. Update the value with the current one");
|
|
}
|
|
return element;
|
|
} else {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","The current agent is not the deeper one. return the previous one.");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Vector v = new Vector();
|
|
SnmpMibRequest getReq = createMibRequest(v,
|
|
version,
|
|
null);
|
|
SnmpVarBind realValue = new SnmpVarBind(oid);
|
|
getReq.addVarBind(realValue);
|
|
try {
|
|
deeperAgent.get(getReq);
|
|
} catch(SnmpStatusException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
if(isDebugOn())
|
|
trace("findVarBind", "Biggest priority value is : " +
|
|
realValue.value);
|
|
|
|
return realValue;
|
|
*/
|
|
|
|
}
|
|
else {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"findVarBind","The right varBind is the already present one");
|
|
}
|
|
return 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.
|
|
*/
|
|
@Override
|
|
protected void updateResult(SnmpVarBind[] result) {
|
|
// we can assume that the run method is over ...
|
|
//
|
|
|
|
final Enumeration<SnmpVarBind> e= varBind.elements();
|
|
final int max= result.length;
|
|
|
|
// First go through all the values once ...
|
|
for(int i=0; i < size; i++) {
|
|
// May be we should control the position ...
|
|
//
|
|
if (e.hasMoreElements() == false)
|
|
return;
|
|
|
|
// bugId 4641694: must check position in order to avoid
|
|
// ArrayIndexOutOfBoundException
|
|
final int pos=translation[i];
|
|
if (pos >= max) {
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
|
|
"updateResult","Position '"+pos+"' is out of bound...");
|
|
}
|
|
continue;
|
|
}
|
|
|
|
final SnmpVarBind element= e.nextElement();
|
|
|
|
if (element == null) continue;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"updateResult","Non repeaters Current element : " +
|
|
element + " from agent : " + agent);
|
|
}
|
|
final SnmpVarBind res = findVarBind(element,result[pos]);
|
|
|
|
if(res == null) continue;
|
|
|
|
result[pos] = res;
|
|
}
|
|
|
|
// Now update the values which have been repeated
|
|
// more than once.
|
|
int localR= size - nonRepeat;
|
|
for (int i = 2 ; i <= maxRepeat ; i++) {
|
|
for (int r = 0 ; r < localR ; r++) {
|
|
final int pos = (i-1)* globalR + translation[nonRepeat + r] ;
|
|
if (pos >= max)
|
|
return;
|
|
if (e.hasMoreElements() ==false)
|
|
return;
|
|
final SnmpVarBind element= e.nextElement();
|
|
|
|
if (element == null) continue;
|
|
if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
|
|
SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
|
|
"updateResult","Repeaters Current element : " +
|
|
element + " from agent : " + agent);
|
|
}
|
|
final SnmpVarBind res = findVarBind(element, result[pos]);
|
|
|
|
if(res == null) continue;
|
|
|
|
result[pos] = res;
|
|
}
|
|
}
|
|
}
|
|
|
|
// PROTECTED VARIABLES
|
|
//------------------
|
|
|
|
/**
|
|
* Specific to the sub request
|
|
*/
|
|
protected int nonRepeat=0;
|
|
|
|
protected int maxRepeat=0;
|
|
|
|
/**
|
|
* R as defined in RCF 1902 for the global request the sub-request is associated to.
|
|
*/
|
|
protected int globalR=0;
|
|
|
|
protected int size=0;
|
|
}
|