View Javadoc

1   package net.sf.snmpadaptor4j.core;
2   
3   import java.math.BigInteger;
4   import java.net.InetAddress;
5   import java.util.Iterator;
6   import java.util.List;
7   import java.util.Set;
8   import java.util.SortedMap;
9   import java.util.TreeMap;
10  import java.util.TreeSet;
11  import java.util.Map.Entry;
12  import javax.management.MBeanServer;
13  import javax.management.ObjectName;
14  import net.sf.snmpadaptor4j.api.SnmpMib;
15  import net.sf.snmpadaptor4j.api.AttributeAccessor;
16  import net.sf.snmpadaptor4j.core.accessor.MBeanAttributeAccessor;
17  import net.sf.snmpadaptor4j.core.mapping.MBeanAttributeMapping;
18  import net.sf.snmpadaptor4j.object.SnmpDataType;
19  import net.sf.snmpadaptor4j.object.SnmpOid;
20  import org.apache.log4j.Logger;
21  
22  /**
23   * Object representing the <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB) for access to JMX attributes.
24   * @author <a href="http://fr.linkedin.com/in/jpminetti/">Jean-Philippe MINETTI</a>
25   */
26  public class JmxSnmpMib
27  		implements SnmpMib {
28  
29  	/**
30  	 * Logger.
31  	 */
32  	protected final Logger logger = Logger.getLogger(JmxSnmpMib.class);
33  
34  	/**
35  	 * Other object representing the MIB.
36  	 */
37  	private final SnmpMib other;
38  
39  	/**
40  	 * <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
41  	 */
42  	private final SortedMap<SnmpOid, AttributeAccessor> mib = new TreeMap<SnmpOid, AttributeAccessor>();
43  
44  	/**
45  	 * Constructor.
46  	 * @param other Other object representing the MIB.
47  	 */
48  	public JmxSnmpMib (final SnmpMib other) {
49  		super();
50  		this.other = other;
51  	}
52  
53  	/**
54  	 * Returns the <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
55  	 * @return <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
56  	 */
57  	protected final SortedMap<SnmpOid, AttributeAccessor> getMib () {
58  		return this.mib;
59  	}
60  
61  	/**
62  	 * Unregister all attributes.
63  	 */
64  	void unregisterAllAttributes () {
65  		MBeanAttributeAccessor accessor;
66  		synchronized (this.mib) {
67  			while (!this.mib.isEmpty()) {
68  				accessor = (MBeanAttributeAccessor) this.mib.get(this.mib.firstKey());
69  				unregisterAttributes(accessor.getMBeanName(), accessor.getOid());
70  			}
71  		}
72  	}
73  
74  	/**
75  	 * Registers a MBean to SNMP <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
76  	 * @param server JMX agent.
77  	 * @param mBeanName MBean name.
78  	 * @param mBeanAttributeMappingList List of mapping for access to each attribute of an MBean (must not be <code>NULL</code>).
79  	 * @throws Exception Exception if an error occurred.
80  	 */
81  	void registerAttributes (final MBeanServer server, final ObjectName mBeanName, final List<MBeanAttributeMapping> mBeanAttributeMappingList) throws Exception {
82  		for (final MBeanAttributeMapping mapping : mBeanAttributeMappingList) {
83  			if (this.logger.isInfoEnabled()) {
84  				this.logger.info("SNMP attribute registering at " + mapping.getOid() + " (" + mapping.getSnmpDataType() + ") = [" + mBeanName + "]."
85  						+ mapping.getAttributeName() + " (" + mapping.getJmxDataType().getSimpleName() + ")");
86  			}
87  			checkDataType(mapping.getSnmpDataType(), mapping.getJmxDataType());
88  			synchronized (this.mib) {
89  				this.mib.put(mapping.getOid(), new MBeanAttributeAccessor(server, mBeanName, mapping));
90  			}
91  		}
92  	}
93  
94  	/**
95  	 * Unregisters a MBean of SNMP <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
96  	 * @param server JMX agent.
97  	 * @param mBeanName MBean name.
98  	 */
99  	void unregisterAttributes (final MBeanServer server, final ObjectName mBeanName) {
100 		final Set<SnmpOid> oidSet = new TreeSet<SnmpOid>();
101 		synchronized (this.mib) {
102 			for (final AttributeAccessor node : this.mib.values()) {
103 				if (mBeanName.equals(((MBeanAttributeAccessor) node).getMBeanName())) {
104 					oidSet.add(node.getOid());
105 				}
106 			}
107 			for (final SnmpOid oid : oidSet) {
108 				unregisterAttributes(mBeanName, oid);
109 			}
110 		}
111 	}
112 
113 	/**
114 	 * Unregisters a MBean of SNMP <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB).
115 	 * @param mBeanName MBean name.
116 	 * @param oid OID of parameter to unregister.
117 	 */
118 	private void unregisterAttributes (final ObjectName mBeanName, final SnmpOid oid) {
119 		if (this.logger.isInfoEnabled()) {
120 			this.logger.info("SNMP attribute unregistering at " + oid + " for [" + mBeanName + "]");
121 		}
122 		this.mib.remove(oid);
123 	}
124 
125 	/**
126 	 * Checks the consistency between the data types SNMP and Java.
127 	 * @param snmpDataType SNMP data type of MIB node.
128 	 * @param jmxDataType Data type of JMX attribute.
129 	 * @throws Exception Exception if an error occurred.
130 	 */
131 	protected static final void checkDataType (final SnmpDataType snmpDataType, final Class<?> jmxDataType) throws Exception {
132 		if (snmpDataType == SnmpDataType.integer32) {
133 			if (!int.class.equals(jmxDataType) && !Integer.class.equals(jmxDataType) && !byte.class.equals(jmxDataType) && !Byte.class.equals(jmxDataType)
134 					&& !short.class.equals(jmxDataType) && !Short.class.equals(jmxDataType) && !boolean.class.equals(jmxDataType)
135 					&& !Boolean.class.equals(jmxDataType)) {
136 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
137 			}
138 		}
139 		else if ((snmpDataType == SnmpDataType.unsigned32) || (snmpDataType == SnmpDataType.gauge32) || (snmpDataType == SnmpDataType.counter32)) {
140 			if (!long.class.equals(jmxDataType) && !Long.class.equals(jmxDataType) && !int.class.equals(jmxDataType) && !Integer.class.equals(jmxDataType)
141 					&& !byte.class.equals(jmxDataType) && !Byte.class.equals(jmxDataType) && !short.class.equals(jmxDataType) && !Short.class.equals(jmxDataType)) {
142 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
143 			}
144 		}
145 		else if (snmpDataType == SnmpDataType.counter64) {
146 			if (!BigInteger.class.equals(jmxDataType) && !long.class.equals(jmxDataType) && !Long.class.equals(jmxDataType)) {
147 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
148 			}
149 		}
150 		else if (snmpDataType == SnmpDataType.timeTicks) {
151 			if (!long.class.equals(jmxDataType) && !Long.class.equals(jmxDataType)) {
152 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
153 			}
154 		}
155 		else if (snmpDataType == SnmpDataType.ipAddress) {
156 			if (!String.class.equals(jmxDataType) && !InetAddress.class.equals(jmxDataType)) {
157 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
158 			}
159 		}
160 		else if (snmpDataType == SnmpDataType.objectIdentifier) {
161 			if (!String.class.equals(jmxDataType) && !SnmpOid.class.equals(jmxDataType)) {
162 				throw new Exception(snmpDataType + " is inconsistent with " + jmxDataType.getName());
163 			}
164 		}
165 	}
166 
167 	/*
168 	 * {@inheritDoc}
169 	 * @see net.sf.snmpadaptor4j.api.SnmpMib#find(net.sf.snmpadaptor4j.object.SnmpOid)
170 	 */
171 	public final AttributeAccessor find (final SnmpOid oid) {
172 		AttributeAccessor node;
173 		synchronized (this.mib) {
174 			node = this.mib.get(oid);
175 		}
176 		if (node == null) {
177 			node = this.other.find(oid);
178 		}
179 		return node;
180 	}
181 
182 	/*
183 	 * {@inheritDoc}
184 	 * @see net.sf.snmpadaptor4j.api.SnmpMib#next(net.sf.snmpadaptor4j.object.SnmpOid)
185 	 */
186 	public final AttributeAccessor next (final SnmpOid oid) {
187 		AttributeAccessor node;
188 		final Iterator<Entry<SnmpOid, AttributeAccessor>> entryIterator = nextSet(oid).entrySet().iterator();
189 		if (entryIterator.hasNext()) {
190 			node = entryIterator.next().getValue();
191 		}
192 		else {
193 			node = null;
194 		}
195 		return node;
196 	}
197 
198 	/*
199 	 * {@inheritDoc}
200 	 * @see net.sf.snmpadaptor4j.api.SnmpMib#nextSet(net.sf.snmpadaptor4j.object.SnmpOid)
201 	 */
202 	public final SortedMap<SnmpOid, AttributeAccessor> nextSet (final SnmpOid oid) {
203 		final SortedMap<SnmpOid, AttributeAccessor> nodeMap = new TreeMap<SnmpOid, AttributeAccessor>();
204 		synchronized (this.mib) {
205 			nodeMap.putAll(this.mib.tailMap(SnmpOid.newInstance(oid.getOid(), 0)));
206 		}
207 		nodeMap.putAll(this.other.nextSet(oid));
208 		return nodeMap;
209 	}
210 
211 	/*
212 	 * {@inheritDoc}
213 	 * @see java.lang.Object#toString()
214 	 */
215 	@Override
216 	public final String toString () {
217 		return "JmxSnmpMib" + this.mib.values();
218 	}
219 
220 }