573 lines · 21.6 KB · Java
RawDownload
/* * Copyright (c) 2000, 2003, 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.agent;  // java imports//import java.util.Vector;import java.util.Enumeration;import java.util.Iterator; // jmx imports//import javax.management.AttributeList;import javax.management.Attribute;import javax.management.MBeanException;import javax.management.MBeanServer;import javax.management.ObjectName;import javax.management.ReflectionException;import javax.management.InstanceNotFoundException;import javax.management.InvalidAttributeValueException;import javax.management.InstanceAlreadyExistsException;import javax.management.MBeanRegistrationException;import javax.management.NotCompliantMBeanException;import javax.management.RuntimeOperationsException;import com.sun.jmx.snmp.SnmpOid;import com.sun.jmx.snmp.SnmpValue;import com.sun.jmx.snmp.SnmpVarBind;import com.sun.jmx.snmp.SnmpStatusException;  /** * <p> * This class is a utility class that transforms SNMP GET / SET requests * into standard JMX getAttributes() setAttributes() requests. * </p> * * <p> * The transformation relies on the metadata information provided by the * {@link com.sun.jmx.snmp.agent.SnmpGenericMetaServer} object which is * passed as the first parameter to every method. This SnmpGenericMetaServer * object is usually a Metadata object generated by <code>mibgen</code>. * </p> * * <p><b><i> * This class is used internally by mibgen generated metadata objects and * you should never need to use it directly. * </b></i></p> * <p><b>This API is a Sun Microsystems internal API  and is subject * to change without notice.</b></p> **/ public class SnmpGenericObjectServer {     // ----------------------------------------------------------------------    //    //    Protected variables    //    // ----------------------------------------------------------------------     /**     * The MBean server through which the MBeans will be accessed.     **/    protected final MBeanServer server;     // ----------------------------------------------------------------------    //    // Constructors    //    // ----------------------------------------------------------------------     /**     * Builds a new SnmpGenericObjectServer. Usually there will be a single     * object of this type per MIB.     *     * @param server The MBeanServer in which the MBean accessed by this     *               MIB are registered.     **/    public SnmpGenericObjectServer(MBeanServer server) {        this.server = server;    }     /**     * Execute an SNMP GET request.     *     * <p>     * This method first builds the list of attributes that need to be     * retrieved from the MBean and then calls getAttributes() on the     * MBean server. Then it updates the SnmpMibSubRequest with the values     * retrieved from the MBean.     * </p>     *     * <p>     * The SNMP metadata information is obtained through the given     * <code>meta</code> object, which usually is an instance of a     * <code>mibgen</code> generated class.     * </p>     *     * <p><b><i>     * This method is called internally by <code>mibgen</code> generated     * objects and you should never need to call it directly.     * </i></b></p>     *     * @param meta  The metadata object impacted by the subrequest     * @param name  The ObjectName of the MBean impacted by this subrequest     * @param req   The SNMP subrequest to execute on the MBean     * @param depth The depth of the SNMP object in the OID tree.     *     * @exception SnmpStatusException whenever an SNMP exception must be     *      raised. Raising an exception will abort the request.<br>     *      Exceptions should never be raised directly, but only by means of     * <code>     * req.registerGetException(<i>VariableId</i>,<i>SnmpStatusException</i>)     * </code>     **/    public void get(SnmpGenericMetaServer meta, ObjectName name,                    SnmpMibSubRequest req, int depth)        throws SnmpStatusException {         // java.lang.System.out.println(">>>>>>>>> GET " + name);         final int           size     = req.getSize();        final Object        data     = req.getUserData();        final String[]      nameList = new String[size];        final SnmpVarBind[] varList  = new SnmpVarBind[size];        final long[]        idList   = new long[size];        int   i = 0;         for (Enumeration e=req.getElements(); e.hasMoreElements();) {            final SnmpVarBind var= (SnmpVarBind) e.nextElement();            try {                final long id = var.oid.getOidArc(depth);                nameList[i]   = meta.getAttributeName(id);                varList[i]    = var;                idList[i]     = id;                 // Check the access rights according to the MIB.                // The MBean might be less restrictive (have a getter                // while the MIB defines the variable as AFN)                //                meta.checkGetAccess(id,data);                 //java.lang.System.out.println(nameList[i] + " added.");                i++;            } catch(SnmpStatusException x) {                //java.lang.System.out.println("exception for " + nameList[i]);                //x.printStackTrace();                req.registerGetException(var,x);            }        }         AttributeList result = null;        int errorCode = SnmpStatusException.noSuchInstance;         try {            result = server.getAttributes(name,nameList);        } catch (InstanceNotFoundException f) {            //java.lang.System.out.println(name + ": instance not found.");            //f.printStackTrace();            result = new AttributeList();        } catch (ReflectionException r) {            //java.lang.System.out.println(name + ": reflexion error.");            //r.printStackTrace();            result = new AttributeList();        } catch (Exception x) {            result = new AttributeList();        }          final Iterator it = result.iterator();         for (int j=0; j < i; j++) {            if (!it.hasNext()) {                //java.lang.System.out.println(name + "variable[" + j +                //                           "] absent");                final SnmpStatusException x =                    new SnmpStatusException(errorCode);                req.registerGetException(varList[j],x);                continue;            }             final Attribute att = (Attribute) it.next();             while ((j < i) && (! nameList[j].equals(att.getName()))) {                //java.lang.System.out.println(name + "variable[" +j +                //                           "] not found");                final SnmpStatusException x =                    new SnmpStatusException(errorCode);                req.registerGetException(varList[j],x);                j++;            }             if ( j == i) break;             try {                varList[j].value =                    meta.buildSnmpValue(idList[j],att.getValue());            } catch (SnmpStatusException x) {                req.registerGetException(varList[j],x);            }            //java.lang.System.out.println(att.getName() + " retrieved.");        }        //java.lang.System.out.println(">>>>>>>>> END GET");    }     /**     * Get the value of an SNMP variable.     *     * <p><b><i>     * You should never need to use this method directly.     * </i></b></p>     *     * @param meta  The impacted metadata object     * @param name  The ObjectName of the impacted MBean     * @param id    The OID arc identifying the variable we're trying to set.     * @param data  User contextual data allocated through the     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}     *     * @return The value of the variable.     *     * @exception SnmpStatusException whenever an SNMP exception must be     *      raised. Raising an exception will abort the request. <br>     *      Exceptions should never be raised directly, but only by means of     * <code>     * req.registerGetException(<i>VariableId</i>,<i>SnmpStatusException</i>)     * </code>     **/    public SnmpValue get(SnmpGenericMetaServer meta, ObjectName name,                         long id, Object data)        throws SnmpStatusException {        final String attname = meta.getAttributeName(id);        Object result = null;         try {            result = server.getAttribute(name,attname);        } catch (MBeanException m) {            Exception t = m.getTargetException();            if (t instanceof SnmpStatusException)                throw (SnmpStatusException) t;            throw new SnmpStatusException(SnmpStatusException.noSuchInstance);        } catch (Exception e) {            throw new SnmpStatusException(SnmpStatusException.noSuchInstance);        }         return meta.buildSnmpValue(id,result);    }     /**     * Execute an SNMP SET request.     *     * <p>     * This method first builds the list of attributes that need to be     * set on the MBean and then calls setAttributes() on the     * MBean server. Then it updates the SnmpMibSubRequest with the new     * values retrieved from the MBean.     * </p>     *     * <p>     * The SNMP metadata information is obtained through the given     * <code>meta</code> object, which usually is an instance of a     * <code>mibgen</code> generated class.     * </p>     *     * <p><b><i>     * This method is called internally by <code>mibgen</code> generated     * objects and you should never need to call it directly.     * </i></b></p>     *     * @param meta  The metadata object impacted by the subrequest     * @param name  The ObjectName of the MBean impacted by this subrequest     * @param req   The SNMP subrequest to execute on the MBean     * @param depth The depth of the SNMP object in the OID tree.     *     * @exception SnmpStatusException whenever an SNMP exception must be     *      raised. Raising an exception will abort the request. <br>     *      Exceptions should never be raised directly, but only by means of     * <code>     * req.registerGetException(<i>VariableId</i>,<i>SnmpStatusException</i>)     * </code>     **/    public void set(SnmpGenericMetaServer meta, ObjectName name,                    SnmpMibSubRequest req, int depth)        throws SnmpStatusException {         final int size               = req.getSize();        final AttributeList attList  = new AttributeList(size);        final String[]      nameList = new String[size];        final SnmpVarBind[] varList  = new SnmpVarBind[size];        final long[]        idList   = new long[size];        int   i = 0;         for (Enumeration e=req.getElements(); e.hasMoreElements();) {            final SnmpVarBind var= (SnmpVarBind) e.nextElement();            try {                final long id = var.oid.getOidArc(depth);                final String attname = meta.getAttributeName(id);                final Object attvalue=                    meta.buildAttributeValue(id,var.value);                final Attribute att = new Attribute(attname,attvalue);                attList.add(att);                nameList[i]   = attname;                varList[i]    = var;                idList[i]     = id;                i++;            } catch(SnmpStatusException x) {                req.registerSetException(var,x);            }        }         AttributeList result = null;        int errorCode = SnmpStatusException.noAccess;         try {            result = server.setAttributes(name,attList);        } catch (InstanceNotFoundException f) {            result = new AttributeList();            errorCode = SnmpStatusException.snmpRspInconsistentName;        } catch (ReflectionException r) {            errorCode = SnmpStatusException.snmpRspInconsistentName;            result = new AttributeList();        } catch (Exception x) {            result = new AttributeList();        }         final Iterator it = result.iterator();         for (int j=0; j < i; j++) {            if (!it.hasNext()) {                final SnmpStatusException x =                    new SnmpStatusException(errorCode);                req.registerSetException(varList[j],x);                continue;            }             final Attribute att = (Attribute) it.next();             while ((j < i) && (! nameList[j].equals(att.getName()))) {                final SnmpStatusException x =                    new SnmpStatusException(SnmpStatusException.noAccess);                req.registerSetException(varList[j],x);                j++;            }             if ( j == i) break;             try {                varList[j].value =                    meta.buildSnmpValue(idList[j],att.getValue());            } catch (SnmpStatusException x) {                req.registerSetException(varList[j],x);            }         }    }     /**     * Set the value of an SNMP variable.     *     * <p><b><i>     * You should never need to use this method directly.     * </i></b></p>     *     * @param meta  The impacted metadata object     * @param name  The ObjectName of the impacted MBean     * @param x     The new requested SnmpValue     * @param id    The OID arc identifying the variable we're trying to set.     * @param data  User contextual data allocated through the     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}     *     * @return The new value of the variable after the operation.     *     * @exception SnmpStatusException whenever an SNMP exception must be     *      raised. Raising an exception will abort the request. <br>     *      Exceptions should never be raised directly, but only by means of     * <code>     * req.registerSetException(<i>VariableId</i>,<i>SnmpStatusException</i>)     * </code>     **/    public SnmpValue set(SnmpGenericMetaServer meta, ObjectName name,                         SnmpValue x, long id, Object data)        throws SnmpStatusException {        final String attname = meta.getAttributeName(id);        final Object attvalue=            meta.buildAttributeValue(id,x);        final Attribute att = new Attribute(attname,attvalue);         Object result = null;         try {            server.setAttribute(name,att);            result = server.getAttribute(name,attname);        } catch(InvalidAttributeValueException iv) {            throw new                SnmpStatusException(SnmpStatusException.snmpRspWrongValue);        } catch (InstanceNotFoundException f) {            throw new                SnmpStatusException(SnmpStatusException.snmpRspInconsistentName);        } catch (ReflectionException r) {            throw new                SnmpStatusException(SnmpStatusException.snmpRspInconsistentName);        } catch (MBeanException m) {            Exception t = m.getTargetException();            if (t instanceof SnmpStatusException)                throw (SnmpStatusException) t;            throw new                SnmpStatusException(SnmpStatusException.noAccess);        } catch (Exception e) {            throw new                SnmpStatusException(SnmpStatusException.noAccess);        }         return meta.buildSnmpValue(id,result);    }     /**     * Checks whether an SNMP SET request can be successfully performed.     *     * <p>     * For each variable in the subrequest, this method calls     * checkSetAccess() on the meta object, and then tries to invoke the     * check<i>AttributeName</i>() method on the MBean. If this method     * is not defined then it is assumed that the SET won't fail.     * </p>     *     * <p><b><i>     * This method is called internally by <code>mibgen</code> generated     * objects and you should never need to call it directly.     * </i></b></p>     *     * @param meta  The metadata object impacted by the subrequest     * @param name  The ObjectName of the MBean impacted by this subrequest     * @param req   The SNMP subrequest to execute on the MBean     * @param depth The depth of the SNMP object in the OID tree.     *     * @exception SnmpStatusException if the requested SET operation must     *      be rejected. Raising an exception will abort the request. <br>     *      Exceptions should never be raised directly, but only by means of     * <code>     * req.registerCheckException(<i>VariableId</i>,<i>SnmpStatusException</i>)     * </code>     *     **/    public void check(SnmpGenericMetaServer meta, ObjectName name,                      SnmpMibSubRequest req, int depth)        throws SnmpStatusException {         final Object data = req.getUserData();         for (Enumeration e=req.getElements(); e.hasMoreElements();) {            final SnmpVarBind var= (SnmpVarBind) e.nextElement();            try {                final long id = var.oid.getOidArc(depth);                // call meta.check() here, and meta.check will call check()                check(meta,name,var.value,id,data);            } catch(SnmpStatusException x) {                req.registerCheckException(var,x);            }        }    }     /**     * Checks whether a SET operation can be performed on a given SNMP     * variable.     *     * @param meta  The impacted metadata object     * @param name  The ObjectName of the impacted MBean     * @param x     The new requested SnmpValue     * @param id    The OID arc identifying the variable we're trying to set.     * @param data  User contextual data allocated through the     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}     *     * <p>     * This method calls checkSetAccess() on the meta object, and then     * tries to invoke the check<i>AttributeName</i>() method on the MBean.     * If this method is not defined then it is assumed that the SET     * won't fail.     * </p>

Lines 1–500 of 573.