1 package net.sf.snmpadaptor4j;
2
3 import java.net.URL;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 import javax.management.MBeanAttributeInfo;
10 import javax.management.MBeanConstructorInfo;
11 import javax.management.MBeanInfo;
12 import javax.management.MBeanNotificationInfo;
13 import javax.management.MBeanOperationInfo;
14 import javax.management.MBeanParameterInfo;
15 import javax.management.MBeanServer;
16 import javax.management.ObjectName;
17 import javax.management.StandardMBean;
18 import net.sf.snmpadaptor4j.api.SnmpApiFactory;
19 import net.sf.snmpadaptor4j.api.SnmpDaemon;
20 import net.sf.snmpadaptor4j.api.opennms.OpennmsSnmpApiFactory;
21 import net.sf.snmpadaptor4j.config.XmlConfigParser;
22 import net.sf.snmpadaptor4j.core.JmxListener;
23 import net.sf.snmpadaptor4j.core.JmxNotificationManager;
24 import net.sf.snmpadaptor4j.core.JmxSnmpMib;
25 import net.sf.snmpadaptor4j.core.JvmSnmpMib;
26 import net.sf.snmpadaptor4j.core.SystemSnmpMib;
27 import net.sf.snmpadaptor4j.core.trap.SnmpManagers;
28 import net.sf.snmpadaptor4j.mbean.SystemInfo;
29 import org.apache.log4j.Logger;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public class SnmpAdaptor
138 extends StandardMBean
139 implements SnmpConfiguration, SnmpAppContext, SnmpAdaptorMBean {
140
141
142
143
144 private final Logger logger = Logger.getLogger(SnmpAdaptor.class);
145
146
147
148
149 private final SnmpDaemon daemon;
150
151
152
153
154 private final SystemInfo systemInfo;
155
156
157
158
159 private String listenerAddress = null;
160
161
162
163
164 private Integer listenerPort = null;
165
166
167
168
169 private Integer listenerSnmpVersion = null;
170
171
172
173
174 private String listenerReadCommunity = null;
175
176
177
178
179 private String listenerWriteCommunity = null;
180
181
182
183
184 private final List<SnmpManagerConfiguration> managerList = new ArrayList<SnmpManagerConfiguration>();
185
186
187
188
189 private final String defaultRootOid;
190
191
192
193
194 private final Map<String, String> rootOidMap;
195
196
197
198
199 private final Map<ObjectName, String> mBeanOidMap;
200
201
202
203
204 protected final Map<ClassLoader, SnmpAppContext> appContextMap = new HashMap<ClassLoader, SnmpAppContext>();
205
206
207
208
209 private final SnmpManagers snmpManagers;
210
211
212
213
214 private final SystemSnmpMib systemMib;
215
216
217
218
219 private final JvmSnmpMib jvmMib;
220
221
222
223
224 private final JmxNotificationManager jmxNotificationManager;
225
226
227
228
229 private final JmxListener jmxListener;
230
231
232
233
234
235
236
237
238
239
240 public SnmpAdaptor (final boolean classLoaderScope) throws Exception {
241 this(null, null, null, classLoaderScope);
242 }
243
244
245
246
247
248
249
250
251
252
253
254 public SnmpAdaptor (final SnmpAppContext appContext, final boolean classLoaderScope) throws Exception {
255 this(null, appContext, null, classLoaderScope);
256 }
257
258
259
260
261
262
263
264
265
266
267
268 public SnmpAdaptor (final URL url, final boolean classLoaderScope) throws Exception {
269 this(url, null, classLoaderScope);
270 }
271
272
273
274
275
276
277
278
279
280
281
282
283 public SnmpAdaptor (final URL url, final SystemInfo systemInfo, final boolean classLoaderScope) throws Exception {
284 this(XmlConfigParser.newInstance(url), systemInfo, classLoaderScope);
285 }
286
287
288
289
290
291
292
293
294
295
296
297
298 private SnmpAdaptor (final XmlConfigParser xmlConfigParser, final SystemInfo systemInfo, final boolean classLoaderScope) throws Exception {
299 this(xmlConfigParser, xmlConfigParser, systemInfo, classLoaderScope);
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314 public SnmpAdaptor (final SnmpConfiguration configuration, final SnmpAppContext appContext, final SystemInfo systemInfo, final boolean classLoaderScope)
315 throws Exception {
316 super(SnmpAdaptorMBean.class);
317 initializeMBeanDescriptions();
318 this.defaultRootOid = ((appContext != null) && (appContext.getDefaultRootOid() != null) ? appContext.getDefaultRootOid() : "1.3.6.1.4.1.99.12.8.1");
319 this.rootOidMap = Collections.unmodifiableMap(appContext != null ? appContext.getRootOidMap() : new HashMap<String, String>());
320 this.mBeanOidMap = Collections.unmodifiableMap(appContext != null ? appContext.getMBeanOidMap() : new HashMap<ObjectName, String>());
321 this.systemInfo = (systemInfo != null ? systemInfo : new SystemInfo());
322 this.systemMib = new SystemSnmpMib(this, this.appContextMap, this.systemInfo);
323 this.jvmMib = new JvmSnmpMib(this.systemMib);
324 final JmxSnmpMib jmxSnmpMib = new JmxSnmpMib(this.jvmMib);
325 final SnmpApiFactory apiFactory = new OpennmsSnmpApiFactory();
326 this.snmpManagers = new SnmpManagers(apiFactory);
327 this.jmxNotificationManager = new JmxNotificationManager(this.snmpManagers, this.systemInfo);
328 this.jmxListener = new JmxListener(jmxSnmpMib, this.jmxNotificationManager, this, this.appContextMap, classLoaderScope);
329 this.daemon = apiFactory.newSnmpDaemon(this, jmxSnmpMib);
330 setListenerAddress(configuration != null ? configuration.getListenerAddress() : null);
331 setListenerPort(configuration != null ? configuration.getListenerPort() : null);
332 setListenerSnmpVersion(configuration != null ? configuration.getListenerSnmpVersion() : null);
333 setListenerReadCommunity(configuration != null ? configuration.getListenerReadCommunity() : null);
334 setListenerWriteCommunity(configuration != null ? configuration.getListenerWriteCommunity() : null);
335 if ((configuration != null) && (configuration.getManagerList() != null)) {
336 this.managerList.addAll(configuration.getManagerList());
337 this.snmpManagers.initialize(this.managerList);
338 }
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357 protected SnmpAdaptor (final String defaultRootOid, final SnmpConfiguration configuration, final boolean classLoaderScope, final SystemSnmpMib systemMib,
358 final JvmSnmpMib jvmMib, final JmxListener jmxListener, final JmxNotificationManager jmxNotificationManager, final SnmpDaemon daemon) throws Exception {
359 super(SnmpAdaptorMBean.class);
360 initializeMBeanDescriptions();
361 this.defaultRootOid = defaultRootOid;
362 this.rootOidMap = Collections.unmodifiableMap(new HashMap<String, String>());
363 this.mBeanOidMap = Collections.unmodifiableMap(new HashMap<ObjectName, String>());
364 this.systemInfo = new SystemInfo();
365 this.systemMib = systemMib;
366 this.jvmMib = jvmMib;
367 this.snmpManagers = null;
368 this.jmxNotificationManager = jmxNotificationManager;
369 this.jmxListener = jmxListener;
370 this.daemon = daemon;
371 setListenerAddress(configuration != null ? configuration.getListenerAddress() : null);
372 setListenerPort(configuration != null ? configuration.getListenerPort() : null);
373 setListenerSnmpVersion(configuration != null ? configuration.getListenerSnmpVersion() : null);
374 setListenerReadCommunity(configuration != null ? configuration.getListenerReadCommunity() : null);
375 setListenerWriteCommunity(configuration != null ? configuration.getListenerWriteCommunity() : null);
376 if ((configuration != null) && (configuration.getManagerList() != null)) {
377 this.managerList.addAll(configuration.getManagerList());
378 }
379 }
380
381
382
383
384 private void initializeMBeanDescriptions () {
385
386
387 final String classDescription = "JMX adaptor for SNMP protocol";
388 final String listenerAddressAttributeDescription = "Listening IP address of SNMP daemon";
389 final String listenerPortAttributeDescription = "Listening UDP port of SNMP daemon";
390 final String listenerSnmpVersionAttributeDescription = "Protocol version of SNMP daemon (1 or 2)";
391 final String listenerReadCommunityAttributeDescription = "Read community of SNMP daemon";
392 final String listenerWriteCommunityAttributeDescription = "Write community of SNMP daemon";
393 final String managerListAttributeDescription = "List of managers where to send all notifications (SNMP traps)";
394 final String startedAttributeDescription = "TRUE if the SNMP daemon is started";
395 final String addAppContextDescription = "Adds a new application context";
396 final String removeAppContextDescription = "Removes an application context";
397 final String startDescription = "Starts the SNMP daemon";
398 final String stopDescription = "Stops the SNMP daemon";
399 final String classLoaderParameterDescription = "Class loader of application";
400 final String appContextParameterDescription = "Application context (any class that implements the interface " + SnmpAppContext.class.getName() + ")";
401 final String urlParameterDescription = "URL of SNMP configuration file (XML)";
402 final String configurationParameterDescription = "SNMP configuration settings (any class that implements the interface " + SnmpConfiguration.class.getName()
403 + ")";
404 final String systemInfoParameterDescription = "Informations on the Java application";
405 final String classLoaderScopeParameterDescription = "TRUE for handle only MBeans created by the same ClassLoader that the SNMP adapter - FALSE for handle all MBeans of the JVM (set TRUE to classLoaderScope for web applications: this avoids to publish MBeans of other applications of application server)";
406
407
408 final MBeanParameterInfo classLoaderParameter = new MBeanParameterInfo("classLoader", ClassLoader.class.getName(), classLoaderParameterDescription);
409
410 final MBeanParameterInfo appContextParameter = new MBeanParameterInfo("appContext", SnmpAppContext.class.getName(), appContextParameterDescription);
411 final MBeanParameterInfo urlParameter = new MBeanParameterInfo("url", URL.class.getName(), urlParameterDescription);
412 final MBeanParameterInfo configurationParameter = new MBeanParameterInfo("configuration", SnmpConfiguration.class.getName(),
413 configurationParameterDescription);
414 final MBeanParameterInfo systemInfoParameter = new MBeanParameterInfo("systemInfo", SystemInfo.class.getName(), systemInfoParameterDescription);
415 final MBeanParameterInfo classLoaderScopeParameter = new MBeanParameterInfo("classLoaderScope", boolean.class.getName(),
416 classLoaderScopeParameterDescription);
417
418
419 final MBeanOperationInfo addAppContextOperation = new MBeanOperationInfo("addAppContext", addAppContextDescription, new MBeanParameterInfo[] {
420 classLoaderParameter, appContextParameter }, void.class.getName(), MBeanOperationInfo.ACTION);
421 final MBeanOperationInfo removeAppContextOperation = new MBeanOperationInfo("removeAppContext", removeAppContextDescription,
422 new MBeanParameterInfo[] { classLoaderParameter }, void.class.getName(), MBeanOperationInfo.ACTION);
423 final MBeanOperationInfo startOperation = new MBeanOperationInfo("start", startDescription, new MBeanParameterInfo[] {}, void.class.getName(),
424 MBeanOperationInfo.ACTION);
425 final MBeanOperationInfo stopOperation = new MBeanOperationInfo("stop", stopDescription, new MBeanParameterInfo[] {}, void.class.getName(),
426 MBeanOperationInfo.ACTION);
427 final MBeanOperationInfo[] operations = new MBeanOperationInfo[] { addAppContextOperation, removeAppContextOperation, startOperation, stopOperation };
428
429
430 final MBeanConstructorInfo constructor1 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only classLoaderScope parameter",
431 new MBeanParameterInfo[] { classLoaderScopeParameter });
432 final MBeanConstructorInfo constructor2 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only appContext and classLoaderScope parameters",
433 new MBeanParameterInfo[] { appContextParameter, classLoaderScopeParameter });
434 final MBeanConstructorInfo constructor3 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only url and classLoaderScope parameters",
435 new MBeanParameterInfo[] { urlParameter, classLoaderScopeParameter });
436 final MBeanConstructorInfo constructor4 = new MBeanConstructorInfo(getClass().getName(),
437 "Constructor with only url, systemInfo and classLoaderScope parameters", new MBeanParameterInfo[] { urlParameter, systemInfoParameter,
438 classLoaderScopeParameter });
439 final MBeanConstructorInfo constructor5 = new MBeanConstructorInfo(getClass().getName(),
440 "Constructor with configuration, appContext, systemInfo and classLoaderScope parameters", new MBeanParameterInfo[] { configurationParameter,
441 appContextParameter, systemInfoParameter, classLoaderScopeParameter });
442 final MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[] { constructor1, constructor2, constructor3, constructor4, constructor5 };
443
444
445 final MBeanAttributeInfo listenerAddressAttribute = new MBeanAttributeInfo("ListenerAddress", String.class.getName(), listenerAddressAttributeDescription,
446 true, true, false);
447 final MBeanAttributeInfo listenerPortAttribute = new MBeanAttributeInfo("ListenerPort", Integer.class.getName(), listenerPortAttributeDescription, true,
448 true, false);
449 final MBeanAttributeInfo listenerSnmpVersionAttribute = new MBeanAttributeInfo("ListenerSnmpVersion", Integer.class.getName(),
450 listenerSnmpVersionAttributeDescription, true, true, false);
451 final MBeanAttributeInfo listenerReadCommunityAttribute = new MBeanAttributeInfo("ListenerReadCommunity", String.class.getName(),
452 listenerReadCommunityAttributeDescription, true, true, false);
453 final MBeanAttributeInfo listenerWriteCommunityAttribute = new MBeanAttributeInfo("ListenerWriteCommunity", String.class.getName(),
454 listenerWriteCommunityAttributeDescription, true, true, false);
455 final MBeanAttributeInfo managerListAttribute = new MBeanAttributeInfo("ManagerList", List.class.getName(), managerListAttributeDescription, true, true,
456 false);
457 final MBeanAttributeInfo startedAttribute = new MBeanAttributeInfo("Started", boolean.class.getName(), startedAttributeDescription, true, false, true);
458 final MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[] { listenerAddressAttribute, listenerPortAttribute, listenerSnmpVersionAttribute,
459 listenerReadCommunityAttribute, listenerWriteCommunityAttribute, managerListAttribute, startedAttribute };
460
461
462 final MBeanInfo mBeanInfo = new MBeanInfo(getClass().getName(), classDescription, attributes, constructors, operations, new MBeanNotificationInfo[] {},
463 getMBeanInfo().getDescriptor());
464 cacheMBeanInfo(mBeanInfo);
465
466 }
467
468
469
470
471
472 public void addAppContext (final ClassLoader classLoader, final SnmpAppContext appContext) {
473 synchronized (this.appContextMap) {
474 this.appContextMap.put(classLoader, appContext);
475 this.systemMib.initSysObjectIDSet();
476 }
477 }
478
479
480
481
482
483 public void removeAppContext (final ClassLoader classLoader) {
484 synchronized (this.appContextMap) {
485 this.appContextMap.remove(classLoader);
486 this.systemMib.initSysObjectIDSet();
487 }
488 }
489
490
491
492
493
494 public final String getListenerAddress () {
495 return this.listenerAddress;
496 }
497
498
499
500
501
502 public final void setListenerAddress (final String listenerAddress) {
503 String newListenerAddress = formatAttribute(listenerAddress);
504 if (newListenerAddress == null) {
505 newListenerAddress = "localhost";
506 }
507 if (this.listenerAddress != null ? !this.listenerAddress.equals(newListenerAddress) : true) {
508 try {
509 this.daemon.stop();
510 this.jmxNotificationManager.setEnabled(false);
511 this.listenerAddress = newListenerAddress;
512 }
513 catch (final Throwable e) {
514 this.logger.error(e);
515 }
516 }
517 }
518
519
520
521
522
523 public final Integer getListenerPort () {
524 return this.listenerPort;
525 }
526
527
528
529
530
531 public final void setListenerPort (final Integer listenerPort) {
532 final Integer newListenerPort = (listenerPort != null ? listenerPort : new Integer(161));
533 if (this.listenerPort != null ? !this.listenerPort.equals(newListenerPort) : true) {
534 try {
535 this.daemon.stop();
536 this.jmxNotificationManager.setEnabled(false);
537 this.listenerPort = newListenerPort;
538 }
539 catch (final Throwable e) {
540 this.logger.error(e);
541 }
542 }
543 }
544
545
546
547
548
549 public final Integer getListenerSnmpVersion () {
550 return this.listenerSnmpVersion;
551 }
552
553
554
555
556
557 public final void setListenerSnmpVersion (final Integer listenerSnmpVersion) {
558 Integer newListenerSnmpVersion;
559 if ((listenerSnmpVersion == null) || (listenerSnmpVersion.intValue() < 1) || (listenerSnmpVersion.intValue() > 2)) {
560 newListenerSnmpVersion = new Integer(2);
561 }
562 else {
563 newListenerSnmpVersion = listenerSnmpVersion;
564 }
565 if (this.listenerSnmpVersion != null ? !this.listenerSnmpVersion.equals(newListenerSnmpVersion) : true) {
566 try {
567 this.daemon.stop();
568 this.jmxNotificationManager.setEnabled(false);
569 this.listenerSnmpVersion = newListenerSnmpVersion;
570 }
571 catch (final Throwable e) {
572 this.logger.error(e);
573 }
574 }
575 }
576
577
578
579
580
581 public final String getListenerReadCommunity () {
582 return this.listenerReadCommunity;
583 }
584
585
586
587
588
589 public final void setListenerReadCommunity (final String listenerReadCommunity) {
590 String newListenerReadCommunity = formatAttribute(listenerReadCommunity);
591 if (newListenerReadCommunity == null) {
592 newListenerReadCommunity = "public";
593 }
594 if (this.listenerReadCommunity != null ? !this.listenerReadCommunity.equals(newListenerReadCommunity) : true) {
595 try {
596 this.daemon.stop();
597 this.jmxNotificationManager.setEnabled(false);
598 this.listenerReadCommunity = newListenerReadCommunity;
599 }
600 catch (final Throwable e) {
601 this.logger.error(e);
602 }
603 }
604 }
605
606
607
608
609
610 public final String getListenerWriteCommunity () {
611 return this.listenerWriteCommunity;
612 }
613
614
615
616
617
618 public final void setListenerWriteCommunity (final String listenerWriteCommunity) {
619 String newListenerWriteCommunity = formatAttribute(listenerWriteCommunity);
620 if (newListenerWriteCommunity == null) {
621 newListenerWriteCommunity = "private";
622 }
623 if (this.listenerWriteCommunity != null ? !this.listenerWriteCommunity.equals(newListenerWriteCommunity) : true) {
624 try {
625 this.daemon.stop();
626 this.jmxNotificationManager.setEnabled(false);
627 this.listenerWriteCommunity = newListenerWriteCommunity;
628 }
629 catch (final Throwable e) {
630 this.logger.error(e);
631 }
632 }
633 }
634
635
636
637
638
639 public final List<SnmpManagerConfiguration> getManagerList () {
640 return Collections.unmodifiableList(this.managerList);
641 }
642
643
644
645
646
647 public final String getDefaultRootOid () {
648 return this.defaultRootOid;
649 }
650
651
652
653
654
655 public final Map<String, String> getRootOidMap () {
656 return this.rootOidMap;
657 }
658
659
660
661
662
663 public final Map<ObjectName, String> getMBeanOidMap () {
664 return this.mBeanOidMap;
665 }
666
667
668
669
670
671 public void start () throws Exception {
672 this.daemon.start();
673 if (!this.daemon.isStarted()) {
674 throw new Exception("The SNMP daemon did not start");
675 }
676 this.jmxNotificationManager.setEnabled(true);
677 }
678
679
680
681
682
683 public void stop () throws Exception {
684 this.daemon.stop();
685 if (this.daemon.isStarted()) {
686 throw new Exception("The SNMP daemon has not been stopped");
687 }
688 this.jmxNotificationManager.setEnabled(false);
689 }
690
691
692
693
694
695 public final boolean isStarted () {
696 return this.daemon.isStarted();
697 }
698
699
700
701
702
703
704
705
706 public final SystemInfo getSystemInfo () {
707 return this.systemInfo;
708 }
709
710
711
712
713
714
715 protected static final String formatAttribute (final String value) {
716 String result = value;
717 if (result != null) {
718 result = result.trim();
719 if (result.length() == 0) {
720 result = null;
721 }
722 }
723 return result;
724 }
725
726
727
728
729
730 @Override
731 public ObjectName preRegister (final MBeanServer server, final ObjectName name) throws Exception {
732 final ObjectName result = super.preRegister(server, name);
733 this.jmxListener.open(server);
734 this.jvmMib.open(server);
735 return result;
736 }
737
738
739
740
741
742 @Override
743 public void preDeregister () throws Exception {
744 super.preDeregister();
745 this.jmxListener.close();
746 this.jvmMib.close();
747 }
748
749
750
751
752
753 @Override
754 public String toString () {
755 return "SnmpAdaptor[" + this.listenerAddress + ":" + this.listenerPort + "]";
756 }
757
758 }