1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package ch.syabru.nagios.broker.jmx;
17
18 import java.io.IOException;
19
20 import javax.management.ListenerNotFoundException;
21 import javax.management.MBeanServerConnection;
22 import javax.management.Notification;
23 import javax.management.NotificationListener;
24 import javax.management.ObjectName;
25 import javax.management.remote.JMXConnectionNotification;
26 import javax.management.remote.JMXConnector;
27 import javax.management.remote.JMXConnectorFactory;
28 import javax.management.remote.JMXServiceURL;
29
30 import org.apache.commons.lang.Validate;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import ch.syabru.nagios.broker.Message;
35 import ch.syabru.nagios.broker.MessageHandler;
36 import ch.syabru.nagios.broker.MessageListener;
37 import ch.syabru.nagios.broker.MessageListenerManager;
38
39
40
41
42
43
44
45 public class JmxMessageListener
46 implements MessageListener, NotificationListener
47 {
48 private final Logger logger = LoggerFactory.getLogger(this.getClass());
49
50 private MessageListenerManager messageListenerManager;
51 private MessageHandler messageHandler;
52 private JMXServiceURL jmxServiceUrl;
53 private ObjectName objectName;
54
55 private JMXConnector connector;
56 private String id;
57
58
59
60
61
62
63
64
65 public JmxMessageListener(MessageListenerManager messageListenerManager,
66 MessageHandler messageHandler, JMXServiceURL jmxServiceUrl,
67 ObjectName objectName)
68 {
69 Validate.notNull(messageListenerManager,
70 "messageListenerManager must not be null");
71 Validate.notNull(messageHandler, "messageHandler must not be null");
72 Validate.notNull(jmxServiceUrl, "jmxServiceUrl must not be null");
73 Validate.notNull(objectName, "objectName must not be null");
74 this.messageListenerManager = messageListenerManager;
75 this.messageHandler = messageHandler;
76 this.jmxServiceUrl = jmxServiceUrl;
77 this.objectName = objectName;
78 this.id = "JMX listener " + jmxServiceUrl + ", " +
79 objectName.toString();
80 }
81
82 @Override
83 public String getId() {
84 return id;
85 }
86
87 @Override
88 public void registerListener()
89 {
90 try {
91 connector = JMXConnectorFactory.connect(jmxServiceUrl);
92 connector.addConnectionNotificationListener(this, null, null);
93 MBeanServerConnection con = connector.getMBeanServerConnection();
94 con.addNotificationListener(objectName, this, null, null);
95 logger.info("Registered JMX notification listener [{}]", getId());
96 } catch (Exception e) {
97 logger.warn("Failed to register JMX notification listener. " +
98 "Will retry later. [{}] [{}]", new Object[] {getId(),
99 e.getMessage()});
100 messageListenerManager.addForReconnect(this);
101 }
102 }
103
104
105
106
107 @Override
108 public void unregisterListener() {
109 if (connector != null) {
110 try {
111 connector.removeConnectionNotificationListener(this);
112 } catch (ListenerNotFoundException e) {
113 logger.debug("Error removing connection notification " +
114 "listener", e);
115 }
116 try {
117 MBeanServerConnection con =
118 connector.getMBeanServerConnection();
119 con.removeNotificationListener(objectName, this);
120 logger.debug("Unregistered notification listener [{}]",
121 getId());
122 } catch (ListenerNotFoundException e) {
123
124 } catch (Exception e) {
125 logger.debug("Error removing notification listener", e);
126 }
127 try {
128 connector.close();
129 } catch (IOException e) {
130 logger.debug("Error closing JMX connection", e);
131 }
132 }
133 }
134
135 @Override
136 public void handleNotification(Notification notification, Object handback)
137 {
138
139 if (notification instanceof JMXConnectionNotification) {
140 JMXConnectionNotification connNotification =
141 (JMXConnectionNotification) notification;
142 if (connNotification.getType().equals(
143 JMXConnectionNotification.CLOSED))
144 {
145 logger.warn("Connection closed. Will retry later to " +
146 "re-register listener. [{}]", getId());
147 messageListenerManager.addForReconnect(this);
148 } else if (connNotification.getType().equals(
149 JMXConnectionNotification.FAILED))
150 {
151 logger.warn("Connection failed. Will retry later to " +
152 "re-register listener. [{}]", getId());
153 messageListenerManager.addForReconnect(this);
154 }
155 } else {
156 try {
157 Message message = new JmxMessage(notification);
158
159
160 messageHandler.messageReceived(message);
161 } catch (Exception e) {
162 logger.error("Error handling JMX notification", e);
163 }
164 }
165 }
166 }