345 lines · 13.2 KB · Java
RawDownload
/* * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */  package com.sun.jmx.snmp.daemon;   // java import//import java.util.Enumeration;import java.util.Vector;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.agent.SnmpMibRequest;import com.sun.jmx.snmp.ThreadContext;import com.sun.jmx.snmp.daemon.SnmpAdaptorServer;import com.sun.jmx.snmp.internal.SnmpIncomingRequest;import com.sun.jmx.snmp.ThreadContext; class SnmpSubBulkRequestHandler extends SnmpSubRequestHandler {    private SnmpAdaptorServer server = null;     /**     * The constuctor 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 constuctor 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);    }     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 occured 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 occured 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.     */    protected void updateResult(SnmpVarBind[] result) {        // we can assume that the run method is over ...        //         final Enumeration 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= (SnmpVarBind) 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= (SnmpVarBind) 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;}