alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SnmpSubRequestHandler.java)

This example Java source code file (SnmpSubRequestHandler.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

jmx, log, logging, nonsyncvector, object, runnable, snmp, snmpdefinitions, snmpengine, snmpincomingrequest, snmpmibagent, snmpmibrequest, snmppdu, snmpsubrequesthandler, snmpuserdata, snmpvarbind, suppresswarnings, threadcontext, util

The SnmpSubRequestHandler.java Java example source code

/*
 * Copyright (c) 1998, 2013, 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.logging.Level;
import java.util.Vector;

// jmx imports
//
import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
import com.sun.jmx.snmp.SnmpPdu;
import com.sun.jmx.snmp.SnmpVarBind;
import com.sun.jmx.snmp.SnmpDefinitions;
import com.sun.jmx.snmp.SnmpStatusException;
import com.sun.jmx.snmp.SnmpEngine;

// SNMP Runtime import
//
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.internal.SnmpIncomingRequest;

class SnmpSubRequestHandler implements SnmpDefinitions, Runnable {

    protected SnmpIncomingRequest incRequest = null;
    protected SnmpEngine engine = null;
    /**
     * V3 enabled Adaptor. Each Oid is added using updateRequest method.
     */
    protected SnmpSubRequestHandler(SnmpEngine engine,
                                    SnmpIncomingRequest incRequest,
                                    SnmpMibAgent agent,
                                    SnmpPdu req) {
        this(agent, req);
        init(engine, incRequest);
    }

    /**
     * V3 enabled Adaptor.
     */
    protected SnmpSubRequestHandler(SnmpEngine engine,
                                    SnmpIncomingRequest incRequest,
                                    SnmpMibAgent agent,
                                    SnmpPdu req,
                                    boolean nouse) {
        this(agent, req, nouse);
        init(engine, incRequest);
    }
    /**
     * SNMP V1/V2 . To be called with updateRequest.
     */
    protected SnmpSubRequestHandler(SnmpMibAgent agent, SnmpPdu req) {
        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
                "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<SnmpVarBind>(length);
    }

    /**
     * SNMP V1/V2 The constructor initialize the subrequest with the whole varbind list contained
     * in the original request.
     */
    @SuppressWarnings("unchecked")  // cast to NonSyncVector<SnmpVarBind>
    protected SnmpSubRequestHandler(SnmpMibAgent agent,
                                    SnmpPdu req,
                                    boolean nouse) {
        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<SnmpVarBind>)varBind).addNonSyncElement(list[i]);
        }
    }

    SnmpMibRequest createMibRequest(Vector<SnmpVarBind> vblist,
                                    int protocolVersion,
                                    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;
    }

    void setUserData(Object userData) {
        data = userData;
    }

    public void run() {

        try {
            final ThreadContext oldContext =
                ThreadContext.push("SnmpUserData",data);
            try {
                switch(type) {
                case pduGetRequestPdu:
                    // Invoke a get operation
                    //
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
                            "run", "[" + Thread.currentThread() +
                              "]:get operation on " + agent.getMibName());
                    }

                    agent.get(createMibRequest(varBind,version,data));
                    break;

                case pduGetNextRequestPdu:
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
                            "run", "[" + Thread.currentThread() +
                              "]:getNext operation on " + agent.getMibName());
                    }
                    //#ifdef DEBUG
                    agent.getNext(createMibRequest(varBind,version,data));
                    break;

                case pduSetRequestPdu:
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
                            "run", "[" + Thread.currentThread() +
                            "]:set operation on " + agent.getMibName());
                    }
                    agent.set(createMibRequest(varBind,version,data));
                    break;

                case pduWalkRequest:
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
                            "run", "[" + Thread.currentThread() +
                            "]:check operation on " + agent.getMibName());
                    }
                    agent.check(createMibRequest(varBind,version,data));
                    break;

                default:
                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
                            "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 (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");
        }
    }

    // -------------------------------------------------------------
    //
    // This function does a best-effort to map global error status
    // to SNMP v1 valid global error status.
    //
    // An SnmpStatusException can contain either:
    // <li> v2 local error codes (that should be stored in the varbind)
    // <li> v2 global error codes 
    // <li> v1 global error codes 
    //
    // v2 local error codes (noSuchInstance, noSuchObject) are
    // transformed in a global v1 snmpRspNoSuchName error.
    //
    // v2 global error codes are transformed in the following way:
    //
    //    If the request was a GET/GETNEXT then either
    //         snmpRspNoSuchName or snmpRspGenErr is returned.
    //
    //    Otherwise:
    //      snmpRspNoAccess, snmpRspInconsistentName
    //               => snmpRspNoSuchName
    //      snmpRspAuthorizationError, snmpRspNotWritable, snmpRspNoCreation
    //               => snmpRspReadOnly  (snmpRspNoSuchName for GET/GETNEXT)
    //      snmpRspWrong*
    //               => snmpRspBadValue  (snmpRspNoSuchName for GET/GETNEXT)
    //      snmpRspResourceUnavailable, snmpRspRspCommitFailed,
    //      snmpRspUndoFailed
    //                  => 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;

    }

    // -------------------------------------------------------------
    //
    // This function does a best-effort to map global error status
    // to SNMP v2 valid global error status.
    //
    // An SnmpStatusException can contain either:
    // <li> v2 local error codes (that should be stored in the varbind)
    // <li> v2 global error codes 
    // <li> v1 global error codes 
    //
    // v2 local error codes (noSuchInstance, noSuchObject)
    // should not raise this level: they should have been stored in the
    // varbind earlier. If they, do there is nothing much we can do except
    // to transform them into:
    // <li> a global snmpRspGenErr (if the request is a GET/GETNEXT) 
    // <li> a global snmpRspNoSuchName otherwise. 
    //
    // v2 global error codes are transformed in the following way:
    //
    //    If the request was a GET/GETNEXT then snmpRspGenErr is returned.
    //    (snmpRspGenErr is the only global error that is expected to be
    //     raised by a GET/GETNEXT request).
    //
    //    Otherwise the v2 code itself is returned
    //
    // v1 global error codes are transformed in the following way:
    //
    //      snmpRspNoSuchName
    //               => snmpRspNoAccess  (snmpRspGenErr for GET/GETNEXT)
    //      snmpRspReadOnly
    //               => snmpRspNotWritable (snmpRspGenErr for GET/GETNEXT)
    //      snmpRspBadValue
    //               => snmpRspWrongValue  (snmpRspGenErr for GET/GETNEXT)
    //
    // -------------------------------------------------------------
    //
    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;
    }

    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;
    }

    /**
     * The method returns the error status of the operation.
     * The method takes into account the protocol version.
     */
    protected int getErrorStatus() {
        if (errorStatus == snmpRspNoError)
            return snmpRspNoError;

        return mapErrorStatus(errorStatus,version,type);
    }

    /**
     * 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.
     */
    protected int getErrorIndex() {
        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];
    }

    /**
     * The method updates the varbind list of the subrequest.
     */
    protected  void updateRequest(SnmpVarBind var, int pos) {
        int size= varBind.size();
        translation[size]= pos;
        varBind.addElement(var);
    }

    /**
     * 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) {

        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 {
                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
                        "updateResult","Position `"+pos+"' is out of bound...");
                }
            }
        }
    }

    private void init(SnmpEngine engine,
                      SnmpIncomingRequest incRequest) {
        this.incRequest = incRequest;
        this.engine = engine;
    }

    // PRIVATE VARIABLES
    //------------------

    /**
     * Store the protocol version to handle
     */
    protected int version= snmpVersionOne;

    /**
     * Store the operation type. Remember if the type is Walk, it means
     * that we have to invoke the check method ...
     */
    protected int type= 0;

    /**
     * Agent directly handled by the sub-request handler.
     */
    protected SnmpMibAgent agent;

    /**
     * Error status.
     */
    protected int errorStatus= snmpRspNoError;

    /**
     * Index of error.
     * A value of -1 means no error.
     */
    protected int errorIndex= -1;

    /**
     * The varbind list specific to the current sub request.
     * The vector must contain object of type SnmpVarBind.
     */
    protected Vector<SnmpVarBind> varBind;

    /**
     * The array giving the index translation between the content of
     * <VAR>varBind and the varbind list as specified in the request.
     */
    protected int[] translation;

    /**
     * Contextual object allocated by the SnmpUserDataFactory.
     **/
    protected Object data;

    /**
     * The SnmpMibRequest that will be passed to the agent.
     *
     **/
    private   SnmpMibRequest mibRequest = null;

    /**
     * The SnmpPdu that will be passed to the request.
     *
     **/
    private   SnmpPdu reqPdu = null;

    // All the methods of the Vector class are synchronized.
    // Synchronization is a very expensive operation. In our case it is not always
    // required...
    //
    @SuppressWarnings("serial")  // we never serialize this
    class NonSyncVector<E> extends Vector {

        public NonSyncVector(int size) {
            super(size);
        }

        final void addNonSyncElement(E obj) {
            ensureCapacity(elementCount + 1);
            elementData[elementCount++] = obj;
        }

        @SuppressWarnings("unchecked")  // cast to E
        final E elementAtNonSync(int index) {
            return (E) elementData[index];
        }
    };
}

Other Java examples (source code examples)

Here is a short list of links related to this Java SnmpSubRequestHandler.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.