1 | |
package net.sf.snmpadaptor4j.api.opennms; |
2 | |
|
3 | |
import java.math.BigInteger; |
4 | |
import java.net.InetAddress; |
5 | |
import java.net.UnknownHostException; |
6 | |
import net.sf.snmpadaptor4j.api.SnmpException; |
7 | |
import net.sf.snmpadaptor4j.object.SnmpDataType; |
8 | |
import net.sf.snmpadaptor4j.object.SnmpOid; |
9 | |
import org.apache.log4j.Logger; |
10 | |
import org.opennms.protocols.snmp.SnmpCounter32; |
11 | |
import org.opennms.protocols.snmp.SnmpCounter64; |
12 | |
import org.opennms.protocols.snmp.SnmpGauge32; |
13 | |
import org.opennms.protocols.snmp.SnmpIPAddress; |
14 | |
import org.opennms.protocols.snmp.SnmpInt32; |
15 | |
import org.opennms.protocols.snmp.SnmpNull; |
16 | |
import org.opennms.protocols.snmp.SnmpObjectId; |
17 | |
import org.opennms.protocols.snmp.SnmpOctetString; |
18 | |
import org.opennms.protocols.snmp.SnmpOpaque; |
19 | |
import org.opennms.protocols.snmp.SnmpPduPacket; |
20 | |
import org.opennms.protocols.snmp.SnmpSyntax; |
21 | |
import org.opennms.protocols.snmp.SnmpTimeTicks; |
22 | |
import org.opennms.protocols.snmp.SnmpUInt32; |
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
public abstract class OpennmsSupport { |
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | 84 | protected final Logger logger = Logger.getLogger(getClass()); |
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
protected OpennmsSupport () { |
39 | 84 | super(); |
40 | 84 | } |
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
protected static final SnmpSyntax newSnmpValue (final SnmpDataType snmpDataType, final Object value) throws Exception { |
50 | |
SnmpSyntax snmpValue; |
51 | 220 | if (snmpDataType == SnmpDataType.integer32) { |
52 | 29 | snmpValue = new SnmpInt32(toInteger32(value)); |
53 | |
} |
54 | 191 | else if (snmpDataType == SnmpDataType.unsigned32) { |
55 | 14 | snmpValue = new SnmpUInt32(toUnsigned32(value)); |
56 | |
} |
57 | 177 | else if (snmpDataType == SnmpDataType.gauge32) { |
58 | 14 | snmpValue = new SnmpGauge32(toUnsigned32(value)); |
59 | |
} |
60 | 163 | else if (snmpDataType == SnmpDataType.counter32) { |
61 | 14 | snmpValue = new SnmpCounter32(toUnsigned32(value)); |
62 | |
} |
63 | 149 | else if (snmpDataType == SnmpDataType.counter64) { |
64 | 14 | snmpValue = new SnmpCounter64(toUnsigned64(value)); |
65 | |
} |
66 | 135 | else if (snmpDataType == SnmpDataType.timeTicks) { |
67 | 25 | snmpValue = new SnmpTimeTicks(toTimeTicks(value)); |
68 | |
} |
69 | 110 | else if (snmpDataType == SnmpDataType.octetString) { |
70 | 48 | snmpValue = new SnmpOctetString(toOctetString(value)); |
71 | |
} |
72 | 62 | else if (snmpDataType == SnmpDataType.ipAddress) { |
73 | 21 | snmpValue = new SnmpIPAddress(toIpAddress(value)); |
74 | |
} |
75 | 41 | else if (snmpDataType == SnmpDataType.objectIdentifier) { |
76 | 28 | snmpValue = new SnmpObjectId(toObjectIdentifier(value)); |
77 | |
} |
78 | 13 | else if (snmpDataType == SnmpDataType.opaque) { |
79 | 12 | snmpValue = new SnmpOpaque(toOctetString(value)); |
80 | |
} |
81 | |
else { |
82 | 1 | throw new SnmpException(snmpDataType + " unhandled", SnmpPduPacket.ErrWrongType); |
83 | |
} |
84 | 144 | return snmpValue; |
85 | |
} |
86 | |
|
87 | |
|
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
protected static Object newJmxValue (final Class<?> jmxDataType, final SnmpDataType snmpDataType, final SnmpSyntax newValue) throws Exception { |
95 | |
Object value; |
96 | 241 | if (newValue instanceof SnmpNull) { |
97 | 1 | value = null; |
98 | |
} |
99 | 240 | else if (snmpDataType == SnmpDataType.integer32) { |
100 | 33 | if (!(newValue instanceof SnmpInt32)) { |
101 | 9 | throw new SnmpException("New value is not an integer32", SnmpPduPacket.ErrBadValue); |
102 | |
} |
103 | 24 | value = fromInteger32(jmxDataType, ((SnmpInt32) newValue).getValue()); |
104 | |
} |
105 | 207 | else if (snmpDataType == SnmpDataType.unsigned32) { |
106 | 32 | if (!(newValue instanceof SnmpUInt32) || (newValue instanceof SnmpCounter32) || (newValue instanceof SnmpGauge32) || (newValue instanceof SnmpTimeTicks)) { |
107 | 9 | throw new SnmpException("New value is not an unsigned32", SnmpPduPacket.ErrBadValue); |
108 | |
} |
109 | 23 | value = fromUnsigned32("unsigned32", jmxDataType, ((SnmpUInt32) newValue).getValue()); |
110 | |
} |
111 | 175 | else if (snmpDataType == SnmpDataType.gauge32) { |
112 | 32 | if (!(newValue instanceof SnmpGauge32)) { |
113 | 9 | throw new SnmpException("New value is not a gauge32", SnmpPduPacket.ErrBadValue); |
114 | |
} |
115 | 23 | value = fromUnsigned32("gauge32", jmxDataType, ((SnmpGauge32) newValue).getValue()); |
116 | |
} |
117 | 143 | else if (snmpDataType == SnmpDataType.counter32) { |
118 | 10 | throw new SnmpException("counter32 are not writable", SnmpPduPacket.ErrNotWritable); |
119 | |
} |
120 | 133 | else if (snmpDataType == SnmpDataType.counter64) { |
121 | 10 | throw new SnmpException("counter64 are not writable", SnmpPduPacket.ErrNotWritable); |
122 | |
} |
123 | 123 | else if (snmpDataType == SnmpDataType.timeTicks) { |
124 | 26 | if (!(newValue instanceof SnmpTimeTicks)) { |
125 | 9 | throw new SnmpException("New value is not a timeTicks", SnmpPduPacket.ErrBadValue); |
126 | |
} |
127 | 17 | value = fromTimeTicks(jmxDataType, ((SnmpTimeTicks) newValue).getValue()); |
128 | |
} |
129 | 97 | else if (snmpDataType == SnmpDataType.octetString) { |
130 | 24 | if (!(newValue instanceof SnmpOctetString) || (newValue instanceof SnmpIPAddress) || (newValue instanceof SnmpOpaque)) { |
131 | 9 | throw new SnmpException("New value is not an octetString", SnmpPduPacket.ErrBadValue); |
132 | |
} |
133 | 15 | value = fromOctetString("octetString", jmxDataType, ((SnmpOctetString) newValue).getString()); |
134 | |
} |
135 | 73 | else if (snmpDataType == SnmpDataType.ipAddress) { |
136 | 24 | if (!(newValue instanceof SnmpIPAddress)) { |
137 | 9 | throw new SnmpException("New value is not an ipAddress", SnmpPduPacket.ErrBadValue); |
138 | |
} |
139 | 15 | value = fromIpAddress(jmxDataType, ((SnmpIPAddress) newValue).convertToIpAddress()); |
140 | |
} |
141 | 49 | else if (snmpDataType == SnmpDataType.objectIdentifier) { |
142 | 24 | if (!(newValue instanceof SnmpObjectId)) { |
143 | 9 | throw new SnmpException("New value is not an objectIdentifier", SnmpPduPacket.ErrBadValue); |
144 | |
} |
145 | 15 | value = fromObjectIdentifier(jmxDataType, ((SnmpObjectId) newValue).getIdentifiers()); |
146 | |
} |
147 | 25 | else if (snmpDataType == SnmpDataType.opaque) { |
148 | 24 | if (!(newValue instanceof SnmpOpaque)) { |
149 | 9 | throw new SnmpException("New value is not an opaque", SnmpPduPacket.ErrBadValue); |
150 | |
} |
151 | 15 | value = fromOctetString("opaque", jmxDataType, ((SnmpOpaque) newValue).getString()); |
152 | |
} |
153 | |
else { |
154 | 1 | throw new SnmpException(snmpDataType + " unhandled", SnmpPduPacket.ErrWrongType); |
155 | |
} |
156 | 39 | return value; |
157 | |
} |
158 | |
|
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
private static Integer toInteger32 (final Object value) { |
165 | |
Integer result; |
166 | 29 | if (value instanceof Integer) { |
167 | 4 | result = (Integer) value; |
168 | |
} |
169 | 25 | else if (value instanceof Byte) { |
170 | 1 | result = new Integer(((Byte) value).intValue()); |
171 | |
} |
172 | 24 | else if (value instanceof Short) { |
173 | 1 | result = new Integer(((Short) value).intValue()); |
174 | |
} |
175 | 23 | else if (value instanceof Boolean) { |
176 | 2 | result = new Integer(((Boolean) value).booleanValue() ? 1 : 2); |
177 | |
} |
178 | 21 | else if (value == null) { |
179 | 15 | result = new Integer(0); |
180 | |
} |
181 | |
else { |
182 | 6 | throw new SnmpException(value.getClass() + " is inconsistent with integer32", SnmpPduPacket.ErrWrongType); |
183 | |
} |
184 | 23 | return result; |
185 | |
} |
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
private static Object fromInteger32 (final Class<?> type, final int value) { |
194 | |
Object result; |
195 | 24 | if (Integer.class.equals(type) || int.class.equals(type)) { |
196 | 6 | result = new Integer(value); |
197 | |
} |
198 | 18 | else if (Byte.class.equals(type) || byte.class.equals(type)) { |
199 | 4 | if ((value < Byte.MIN_VALUE) || (value > Byte.MAX_VALUE)) { |
200 | 2 | throw new SnmpException("the value must be between " + Byte.MIN_VALUE + " and " + Byte.MAX_VALUE, SnmpPduPacket.ErrBadValue); |
201 | |
} |
202 | 2 | result = new Byte((byte) value); |
203 | |
} |
204 | 14 | else if (Short.class.equals(type) || short.class.equals(type)) { |
205 | 4 | if ((value < Short.MIN_VALUE) || (value > Short.MAX_VALUE)) { |
206 | 2 | throw new SnmpException("the value must be between " + Short.MIN_VALUE + " and " + Short.MAX_VALUE, SnmpPduPacket.ErrBadValue); |
207 | |
} |
208 | 2 | result = new Short((short) value); |
209 | |
} |
210 | 10 | else if (Boolean.class.equals(type) || boolean.class.equals(type)) { |
211 | 4 | if (value == 1) { |
212 | 1 | result = Boolean.TRUE; |
213 | |
} |
214 | 3 | else if (value == 2) { |
215 | 1 | result = Boolean.FALSE; |
216 | |
} |
217 | |
else { |
218 | 2 | throw new SnmpException("the value must be between true(1) and false(2)", SnmpPduPacket.ErrBadValue); |
219 | |
} |
220 | |
} |
221 | |
else { |
222 | 6 | throw new SnmpException(type + " is inconsistent with integer32", SnmpPduPacket.ErrWrongType); |
223 | |
} |
224 | 12 | return result; |
225 | |
} |
226 | |
|
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
|
232 | |
private static Long toUnsigned32 (final Object value) { |
233 | |
Long result; |
234 | 42 | if (value instanceof Long) { |
235 | 9 | result = (Long) value; |
236 | |
} |
237 | 33 | else if (value instanceof Integer) { |
238 | 3 | result = new Long(((Integer) value).longValue()); |
239 | |
} |
240 | 30 | else if (value instanceof Byte) { |
241 | 3 | result = new Long(((Byte) value).longValue()); |
242 | |
} |
243 | 27 | else if (value instanceof Short) { |
244 | 3 | result = new Long(((Short) value).longValue()); |
245 | |
} |
246 | 24 | else if (value == null) { |
247 | 3 | result = new Long(0L); |
248 | |
} |
249 | |
else { |
250 | 21 | throw new SnmpException(value.getClass() + " is inconsistent with unsigned32", SnmpPduPacket.ErrWrongType); |
251 | |
} |
252 | |
final long maxValue = 2 * (long) Integer.MAX_VALUE + 1; |
253 | 21 | if ((result.longValue() < 0) || (result.longValue() > maxValue)) { |
254 | 6 | throw new SnmpException("the value must be between 0 and " + maxValue, SnmpPduPacket.ErrWrongType); |
255 | |
} |
256 | 15 | return result; |
257 | |
} |
258 | |
|
259 | |
|
260 | |
|
261 | |
|
262 | |
|
263 | |
|
264 | |
|
265 | |
|
266 | |
private static Object fromUnsigned32 (final String snmpDataTypeName, final Class<?> type, final long value) { |
267 | |
Object result; |
268 | 46 | if (Long.class.equals(type) || long.class.equals(type)) { |
269 | 4 | result = new Long(value); |
270 | |
} |
271 | 42 | else if (Integer.class.equals(type) || int.class.equals(type)) { |
272 | 8 | if (value > Integer.MAX_VALUE) { |
273 | 4 | throw new SnmpException("the value must be between 0 and " + Integer.MAX_VALUE, SnmpPduPacket.ErrBadValue); |
274 | |
} |
275 | 4 | result = new Integer((int) value); |
276 | |
} |
277 | 34 | else if (Byte.class.equals(type) || byte.class.equals(type)) { |
278 | 8 | if (value > Byte.MAX_VALUE) { |
279 | 4 | throw new SnmpException("the value must be between 0 and " + Byte.MAX_VALUE, SnmpPduPacket.ErrBadValue); |
280 | |
} |
281 | 4 | result = new Byte((byte) value); |
282 | |
} |
283 | 26 | else if (Short.class.equals(type) || short.class.equals(type)) { |
284 | 8 | if (value > Short.MAX_VALUE) { |
285 | 4 | throw new SnmpException("the value must be between 0 and " + Short.MAX_VALUE, SnmpPduPacket.ErrBadValue); |
286 | |
} |
287 | 4 | result = new Short((short) value); |
288 | |
} |
289 | |
else { |
290 | 18 | throw new SnmpException(type + " is inconsistent with " + snmpDataTypeName, SnmpPduPacket.ErrWrongType); |
291 | |
} |
292 | 16 | return result; |
293 | |
} |
294 | |
|
295 | |
|
296 | |
|
297 | |
|
298 | |
|
299 | |
|
300 | |
private static BigInteger toUnsigned64 (final Object value) { |
301 | |
BigInteger result; |
302 | 14 | if (value instanceof BigInteger) { |
303 | 2 | result = (BigInteger) value; |
304 | |
} |
305 | 12 | else if (value instanceof Long) { |
306 | 2 | result = BigInteger.valueOf(((Long) value).longValue()); |
307 | |
} |
308 | 10 | else if (value == null) { |
309 | 1 | result = BigInteger.valueOf(0L); |
310 | |
} |
311 | |
else { |
312 | 9 | throw new SnmpException(value.getClass() + " is inconsistent with unsigned64", SnmpPduPacket.ErrWrongType); |
313 | |
} |
314 | 5 | final BigInteger minValue = BigInteger.valueOf(0); |
315 | 5 | final BigInteger maxValue = BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(2)).add(BigInteger.valueOf(1)); |
316 | 5 | if ((result.compareTo(minValue) < 0) || (result.compareTo(maxValue) > 0)) { |
317 | 2 | throw new SnmpException("the value must be between " + minValue + " and " + maxValue, SnmpPduPacket.ErrWrongType); |
318 | |
} |
319 | 3 | return result; |
320 | |
} |
321 | |
|
322 | |
|
323 | |
|
324 | |
|
325 | |
|
326 | |
|
327 | |
private static Long toTimeTicks (final Object value) { |
328 | |
Long result; |
329 | 25 | if (value instanceof Long) { |
330 | 14 | result = new Long(((Long) value).longValue() / 10); |
331 | |
} |
332 | 11 | else if (value == null) { |
333 | 1 | result = new Long(0L); |
334 | |
} |
335 | |
else { |
336 | 10 | throw new SnmpException(value.getClass() + " is inconsistent with timeTicks", SnmpPduPacket.ErrWrongType); |
337 | |
} |
338 | |
final long maxValue = 2 * (long) Integer.MAX_VALUE + 1; |
339 | 15 | if ((result.longValue() < 0) || (result.longValue() > maxValue)) { |
340 | 2 | throw new SnmpException("the value must be between 0 and " + maxValue, SnmpPduPacket.ErrWrongType); |
341 | |
} |
342 | 13 | return result; |
343 | |
} |
344 | |
|
345 | |
|
346 | |
|
347 | |
|
348 | |
|
349 | |
|
350 | |
|
351 | |
private static Object fromTimeTicks (final Class<?> type, final long value) { |
352 | |
Object result; |
353 | 17 | if (Long.class.equals(type) || long.class.equals(type)) { |
354 | 2 | result = new Long(10 * value); |
355 | |
} |
356 | |
else { |
357 | 15 | throw new SnmpException(type + " is inconsistent with timeTicks", SnmpPduPacket.ErrWrongType); |
358 | |
} |
359 | 2 | return result; |
360 | |
} |
361 | |
|
362 | |
|
363 | |
|
364 | |
|
365 | |
|
366 | |
|
367 | |
private static byte[] toOctetString (final Object value) { |
368 | |
byte[] result; |
369 | 60 | if (value instanceof String) { |
370 | 38 | result = ((String) value).getBytes(); |
371 | |
} |
372 | 22 | else if (value instanceof byte[]) { |
373 | 2 | result = (byte[]) value; |
374 | |
} |
375 | 20 | else if (value == null) { |
376 | 2 | result = "".getBytes(); |
377 | |
} |
378 | |
else { |
379 | 18 | result = value.toString().getBytes(); |
380 | |
} |
381 | 60 | return result; |
382 | |
} |
383 | |
|
384 | |
|
385 | |
|
386 | |
|
387 | |
|
388 | |
|
389 | |
|
390 | |
|
391 | |
private static Object fromOctetString (final String snmpDataTypeName, final Class<?> type, final byte[] value) { |
392 | |
Object result; |
393 | 30 | if (String.class.equals(type)) { |
394 | 2 | result = new String(value); |
395 | |
} |
396 | 28 | else if (byte[].class.equals(type)) { |
397 | 2 | result = value; |
398 | |
} |
399 | |
else { |
400 | 26 | throw new SnmpException(type + " is inconsistent with " + snmpDataTypeName, SnmpPduPacket.ErrWrongType); |
401 | |
} |
402 | 4 | return result; |
403 | |
} |
404 | |
|
405 | |
|
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
|
411 | |
private static InetAddress toIpAddress (final Object value) throws Exception { |
412 | |
InetAddress result; |
413 | 21 | if (value instanceof InetAddress) { |
414 | 9 | result = (InetAddress) value; |
415 | |
} |
416 | 12 | else if (value instanceof String) { |
417 | |
try { |
418 | 2 | result = InetAddress.getByName((String) value); |
419 | |
} |
420 | 1 | catch (final UnknownHostException e) { |
421 | 1 | throw new SnmpException("IP address is malformed", SnmpPduPacket.ErrWrongValue); |
422 | 1 | } |
423 | |
} |
424 | 10 | else if (value == null) { |
425 | 1 | result = InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 }); |
426 | |
} |
427 | |
else { |
428 | 9 | throw new SnmpException(value.getClass() + " is inconsistent with ipAddress", SnmpPduPacket.ErrWrongType); |
429 | |
} |
430 | 11 | return result; |
431 | |
} |
432 | |
|
433 | |
|
434 | |
|
435 | |
|
436 | |
|
437 | |
|
438 | |
|
439 | |
private static Object fromIpAddress (final Class<?> type, final InetAddress value) { |
440 | |
Object result; |
441 | 15 | if (InetAddress.class.equals(type)) { |
442 | 1 | result = value; |
443 | |
} |
444 | 14 | else if (String.class.equals(type)) { |
445 | 1 | result = value.getHostAddress(); |
446 | |
} |
447 | |
else { |
448 | 13 | throw new SnmpException(type + " is inconsistent with ipAddress", SnmpPduPacket.ErrWrongType); |
449 | |
} |
450 | 2 | return result; |
451 | |
} |
452 | |
|
453 | |
|
454 | |
|
455 | |
|
456 | |
|
457 | |
|
458 | |
private static int[] toObjectIdentifier (final Object value) { |
459 | |
int[] result; |
460 | 28 | if (value instanceof SnmpOid) { |
461 | 17 | result = ((SnmpOid) value).getOid(); |
462 | |
} |
463 | 11 | else if (value instanceof String) { |
464 | 1 | result = SnmpOid.newInstance((String) value).getOid(); |
465 | |
} |
466 | 10 | else if (value == null) { |
467 | 1 | result = new int[] { 1 }; |
468 | |
} |
469 | |
else { |
470 | 9 | throw new SnmpException(value.getClass() + " is inconsistent with objectIdentifier", SnmpPduPacket.ErrWrongType); |
471 | |
} |
472 | 19 | return result; |
473 | |
} |
474 | |
|
475 | |
|
476 | |
|
477 | |
|
478 | |
|
479 | |
|
480 | |
|
481 | |
private static Object fromObjectIdentifier (final Class<?> type, final int[] value) { |
482 | |
Object result; |
483 | 15 | if (SnmpOid.class.equals(type)) { |
484 | 1 | result = SnmpOid.newInstance(value); |
485 | |
} |
486 | 14 | else if (String.class.equals(type)) { |
487 | 1 | result = SnmpOid.newInstance(value).toString(); |
488 | |
} |
489 | |
else { |
490 | 13 | throw new SnmpException(type + " is inconsistent with objectIdentifier", SnmpPduPacket.ErrWrongType); |
491 | |
} |
492 | 2 | return result; |
493 | |
} |
494 | |
|
495 | |
} |