1 package net.sf.snmpadaptor4j.core;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Map.Entry;
8 import javax.management.MBeanServer;
9 import javax.management.Notification;
10 import javax.management.NotificationListener;
11 import javax.management.ObjectName;
12 import org.apache.log4j.Logger;
13 import net.sf.snmpadaptor4j.core.mapping.SnmpTrapMapping;
14 import net.sf.snmpadaptor4j.core.trap.SnmpManagers;
15 import net.sf.snmpadaptor4j.core.trap.SnmpTrapBuilder;
16 import net.sf.snmpadaptor4j.mbean.SystemInfo;
17 import net.sf.snmpadaptor4j.object.SnmpTrap;
18
19
20
21
22
23
24
25
26
27 public class JmxNotificationManager {
28
29
30
31
32 protected final class Listener
33 implements NotificationListener {
34
35
36
37
38 protected final SnmpTrapBuilder trapBuilder;
39
40
41
42
43
44 protected Listener (final SnmpTrapBuilder trapBuilder) {
45 super();
46 this.trapBuilder = trapBuilder;
47 }
48
49
50
51
52
53 public void handleNotification (final Notification notification, final Object handback) {
54 JmxNotificationManager.this.handleNotification(this.trapBuilder, notification);
55 }
56
57
58
59
60
61 @Override
62 public String toString () {
63 return "Listener[trapBuilder=" + this.trapBuilder + "]";
64 }
65
66 }
67
68
69
70
71 protected final Logger logger = Logger.getLogger(JmxNotificationManager.class);
72
73
74
75
76 private final SnmpManagers managers;
77
78
79
80
81 private final SystemInfo systemInfo;
82
83
84
85
86 protected final Map<ObjectName, Listener> listenerMap = new HashMap<ObjectName, Listener>();
87
88
89
90
91 private boolean enabled = false;
92
93
94
95
96
97
98 public JmxNotificationManager (final SnmpManagers managers, final SystemInfo systemInfo) {
99 super();
100 this.managers = managers;
101 this.systemInfo = systemInfo;
102 }
103
104
105
106
107
108
109
110 synchronized void register (final MBeanServer server, final ObjectName mBeanName, final Map<String, SnmpTrapMapping> trapMappingMap) {
111 if (trapMappingMap.isEmpty()) {
112 if (this.logger.isDebugEnabled()) {
113 this.logger.debug("None SNMP trap mapped for [" + mBeanName + "]");
114 }
115 }
116 else {
117 if (this.logger.isInfoEnabled()) {
118 for (final Entry<String, SnmpTrapMapping> trapMappingEntry : trapMappingMap.entrySet()) {
119 this.logger.info("MBean notification registered at [" + mBeanName + "].[" + trapMappingEntry.getKey() + "] = " + trapMappingEntry.getValue());
120 }
121 }
122 final Listener listener = new Listener(new SnmpTrapBuilder(trapMappingMap, this.systemInfo));
123 try {
124 server.addNotificationListener(mBeanName, listener, null, null);
125 this.listenerMap.put(mBeanName, listener);
126 }
127 catch (final Throwable e) {
128 this.logger.warn("Notifications issued in on [" + mBeanName + "] will not cause any SNMP trap sending", e);
129 }
130 }
131 }
132
133
134
135
136
137 synchronized void unregisterAll (final MBeanServer server) {
138 final List<ObjectName> mBeanNameList = new ArrayList<ObjectName>(this.listenerMap.keySet());
139 for (final ObjectName mBeanName : mBeanNameList) {
140 unregister(server, mBeanName);
141 }
142 }
143
144
145
146
147
148
149 synchronized void unregister (final MBeanServer server, final ObjectName mBeanName) {
150 final Listener listener = this.listenerMap.get(mBeanName);
151 if (listener != null) {
152 if (this.logger.isInfoEnabled()) {
153 for (final String notificationType : listener.trapBuilder.getMappingMap().keySet()) {
154 this.logger.info("MBean notification unregistered at [" + mBeanName + "].[" + notificationType + "]");
155 }
156 }
157 try {
158 if (server.isRegistered(mBeanName)) {
159 server.removeNotificationListener(mBeanName, listener);
160 }
161 else {
162 if (this.logger.isTraceEnabled()) {
163 this.logger.trace("[" + mBeanName + "] already unregistered from JMX");
164 }
165 }
166 this.listenerMap.remove(mBeanName);
167 }
168 catch (final Throwable e) {
169 this.logger.warn("An error occurred when unloading of [" + mBeanName + "] to support notifications", e);
170 }
171 }
172 }
173
174
175
176
177
178 public final boolean isEnabled () {
179 return this.enabled;
180 }
181
182
183
184
185
186 public void setEnabled (boolean enabled) {
187 this.enabled = enabled;
188 }
189
190
191
192
193
194
195 protected final void handleNotification (final SnmpTrapBuilder trapBuilder, final Notification notification) {
196 if (this.enabled) {
197 if (this.logger.isTraceEnabled()) {
198 this.logger.trace("JMX notification [" + notification.getSource() + "].[" + notification.getType() + "] received");
199 this.logger.trace("source = " + notification.getSource());
200 this.logger.trace("sequenceNumber = " + notification.getSequenceNumber());
201 this.logger.trace("timeStamp = " + notification.getTimeStamp());
202 this.logger.trace("type = " + notification.getType());
203 this.logger.trace("message = " + notification.getMessage());
204 if (notification.getUserData() instanceof Map) {
205 for (final Entry<?, ?> entry : ((Map<?, ?>) (notification.getUserData())).entrySet()) {
206 this.logger.trace("userData: " + entry.getKey() + " = " + entry.getValue());
207 }
208 }
209 else {
210 this.logger.trace("userData = "
211 + (notification.getUserData() != null ? "(" + notification.getUserData().getClass().getName() + ")" : "") + notification.getUserData());
212 }
213 }
214 try {
215 final SnmpTrap trap = trapBuilder.newTrap(notification);
216 if (trap == null) {
217 if (this.logger.isDebugEnabled()) {
218 this.logger.debug("None SNMP trap to send for the JMX notification [" + notification.getSource() + "].[" + notification.getType() + "]");
219 }
220 }
221 else {
222 if (this.logger.isDebugEnabled()) {
223 this.logger.debug("Notification [" + notification.getSource() + "].[" + notification.getType() + "] = " + trap);
224 }
225 this.managers.send(trap);
226 }
227 }
228 catch (final Throwable e) {
229 this.logger.error("Unable to handle the notification " + notification + " for send a SNMP trap", e);
230 }
231 }
232 }
233
234
235
236
237
238 @Override
239 public final String toString () {
240 return "JmxNotificationManager[managers=" + this.managers + "; systemInfo=" + this.systemInfo + "; listenerMap=" + this.listenerMap + "]";
241 }
242
243 }