1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.monitor.integration;
20
21 import static java.lang.Integer.parseInt;
22 import static java.lang.System.getProperty;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.net.Socket;
28 import java.net.URL;
29 import java.util.Collection;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.Set;
33
34 import javax.management.MBeanServerConnection;
35 import javax.management.MalformedObjectNameException;
36 import javax.management.ObjectName;
37
38 import org.eclipse.jetty.client.HttpClient;
39 import org.eclipse.jetty.client.api.ContentResponse;
40 import org.eclipse.jetty.client.util.BytesContentProvider;
41 import org.eclipse.jetty.http.HttpStatus;
42 import org.eclipse.jetty.monitor.JMXMonitor;
43 import org.eclipse.jetty.monitor.jmx.EventNotifier;
44 import org.eclipse.jetty.monitor.jmx.EventState;
45 import org.eclipse.jetty.monitor.jmx.EventState.TriggerState;
46 import org.eclipse.jetty.monitor.jmx.EventTrigger;
47 import org.eclipse.jetty.monitor.jmx.MonitorAction;
48 import org.eclipse.jetty.monitor.triggers.AggregateEventTrigger;
49 import org.eclipse.jetty.util.log.Log;
50 import org.eclipse.jetty.util.log.Logger;
51 import org.eclipse.jetty.util.thread.QueuedThreadPool;
52
53 public class JavaMonitorAction extends MonitorAction
54 {
55 private static final Logger LOG = Log.getLogger(JavaMonitorAction.class);
56
57 private final HttpClient _client;
58
59 private final String _url;
60 private final String _uuid;
61 private final String _appid;
62
63 private String _srvip;
64 private String _session;
65
66
67 public JavaMonitorAction(EventNotifier notifier, String url, String uuid, String appid, long pollInterval)
68 throws Exception
69 {
70 super(new AggregateEventTrigger(),notifier,pollInterval);
71
72 _url = url;
73 _uuid = uuid;
74 _appid = appid;
75
76 QueuedThreadPool executor = new QueuedThreadPool();
77 executor.setName(executor.getName() + "-monitor");
78 _client = new HttpClient();
79 _client.setExecutor(executor);
80
81 try
82 {
83 _client.start();
84 _srvip = getServerIP();
85 }
86 catch (Exception ex)
87 {
88 LOG.debug(ex);
89 }
90
91 sendData(new Properties());
92 }
93
94
95
96
97
98 @Override
99 public void execute(EventTrigger trigger, EventState<?> state, long timestamp)
100 {
101 exec(trigger, state, timestamp);
102 }
103
104
105
106
107
108
109
110 private <T> void exec(EventTrigger trigger, EventState<T> state, long timestamp)
111 {
112 Collection<TriggerState<T>> trs = state.values();
113
114 Properties data = new Properties();
115 for (TriggerState<T> ts : trs)
116 {
117 Object value = ts.getValue();
118
119 StringBuffer buffer = new StringBuffer();
120 buffer.append(value == null ? "" : value.toString());
121 buffer.append("|");
122 buffer.append(getClassID(value));
123 buffer.append("||");
124 buffer.append(ts.getDescription());
125
126 data.setProperty(ts.getID(), buffer.toString());
127
128 try
129 {
130 sendData(data);
131 }
132 catch (Exception ex)
133 {
134 LOG.debug(ex);
135 }
136 }
137 }
138
139
140
141
142
143
144 private void sendData(Properties data)
145 throws Exception
146 {
147 data.put("account", _uuid);
148 data.put("appserver", "Jetty");
149 data.put("localIp", _srvip);
150 if (_appid == null)
151 data.put("lowestPort", getHttpPort());
152 else
153 data.put("lowestPort", _appid);
154 if (_session != null)
155 data.put("session", _session);
156
157 Properties response = sendRequest(data);
158
159 parseResponse(response);
160 }
161
162
163
164
165
166
167
168 private Properties sendRequest(Properties request)
169 throws Exception
170 {
171 ByteArrayOutputStream reqStream = null;
172 ByteArrayInputStream resStream = null;
173 Properties response = null;
174
175 try {
176 reqStream = new ByteArrayOutputStream();
177 request.storeToXML(reqStream,null);
178
179 ContentResponse r3sponse = _client.POST(_url)
180 .header("Connection","close")
181 .content(new BytesContentProvider(reqStream.toByteArray()))
182 .send();
183
184
185 if (r3sponse.getStatus() == HttpStatus.OK_200)
186 {
187 response = new Properties();
188 resStream = new ByteArrayInputStream(r3sponse.getContent());
189 response.loadFromXML(resStream);
190 }
191 }
192 finally
193 {
194 try
195 {
196 if (reqStream != null)
197 reqStream.close();
198 }
199 catch (IOException ex)
200 {
201 LOG.ignore(ex);
202 }
203
204 try
205 {
206 if (resStream != null)
207 resStream.close();
208 }
209 catch (IOException ex)
210 {
211 LOG.ignore(ex);
212 }
213 }
214
215 return response;
216 }
217
218
219 private void parseResponse(Properties response)
220 {
221 if (response.get("onhold") != null)
222 throw new Error("Suspended");
223
224
225 if (response.get("session") != null)
226 {
227 _session = (String) response.remove("session");
228
229 AggregateEventTrigger trigger = (AggregateEventTrigger)getTrigger();
230
231 String queryString;
232 ObjectName[] queryResults;
233 for (Map.Entry<Object, Object> entry : response.entrySet())
234 {
235 String[] values = ((String) entry.getValue()).split("\\|");
236
237 queryString = values[0];
238 if (queryString.startsWith("com.javamonitor.openfire"))
239 continue;
240
241 if (queryString.startsWith("com.javamonitor"))
242 {
243 queryString = "org.eclipse.jetty.monitor.integration:type=javamonitortools,id=0";
244 }
245
246 queryResults = null;
247 try
248 {
249 queryResults = queryNames(queryString);
250 }
251 catch (IOException e)
252 {
253 LOG.debug(e);
254 }
255 catch (MalformedObjectNameException e)
256 {
257 LOG.debug(e);
258 }
259
260 if (queryResults != null)
261 {
262 int idx = 0;
263 for(ObjectName objName : queryResults)
264 {
265 String id = entry.getKey().toString()+(idx == 0 ? "" : ":"+idx);
266 String name = queryString.equals(objName.toString()) ? "" : objName.toString();
267 boolean repeat = Boolean.parseBoolean(values[2]);
268 trigger.add(new JavaMonitorTrigger(objName, values[1], id, name, repeat));
269 }
270 }
271 }
272 }
273 }
274
275
276
277
278
279
280 private int getClassID(final Object value)
281 {
282 if (value == null)
283 return 0;
284
285 if (value instanceof Byte ||
286 value instanceof Short ||
287 value instanceof Integer ||
288 value instanceof Long)
289 return 1;
290
291 if (value instanceof Float ||
292 value instanceof Double)
293 return 2;
294
295 if (value instanceof Boolean)
296 return 3;
297
298 return 4;
299 }
300
301
302
303
304
305
306 private String getServerIP()
307 throws Exception
308 {
309 Socket s = null;
310 try {
311 if (getProperty("http.proxyHost") != null)
312 {
313 s = new Socket(getProperty("http.proxyHost"),
314 parseInt(getProperty("http.proxyPort", "80")));
315 }
316 else
317 {
318 int port = 80;
319
320 URL url = new URL(_url);
321 if (url.getPort() != -1) {
322 port = url.getPort();
323 }
324 s = new Socket(url.getHost(), port);
325 }
326 return s.getLocalAddress().getHostAddress();
327 }
328 finally
329 {
330 try
331 {
332 if (s != null)
333 s.close();
334 }
335 catch (IOException ex)
336 {
337 LOG.ignore(ex);
338 }
339 }
340 }
341
342
343 public Integer getHttpPort()
344 {
345 Collection<ObjectName> connectors = null;
346 MBeanServerConnection service;
347 try
348 {
349 service = JMXMonitor.getServiceConnection();
350
351 connectors = service.queryNames(new ObjectName("org.eclipse.jetty.nio:type=selectchannelconnector,*"), null);
352 if (connectors != null && connectors.size() > 0)
353 {
354 Integer lowest = Integer.MAX_VALUE;
355 for (final ObjectName connector : connectors) {
356 lowest = (Integer)service.getAttribute(connector, "port");
357 }
358
359 if (lowest < Integer.MAX_VALUE)
360 return lowest;
361 }
362 }
363 catch (Exception ex)
364 {
365 LOG.debug(ex);
366 }
367
368 return 0;
369 }
370
371
372
373
374
375
376
377
378
379 private ObjectName[] queryNames(ObjectName param)
380 throws IOException, MalformedObjectNameException
381 {
382 ObjectName[] result = null;
383
384 MBeanServerConnection connection = JMXMonitor.getServiceConnection();
385 Set names = connection.queryNames(param, null);
386 if (names != null && names.size() > 0)
387 {
388 result = new ObjectName[names.size()];
389
390 int idx = 0;
391 for(Object name : names)
392 {
393 if (name instanceof ObjectName)
394 result[idx++] = (ObjectName)name;
395 else
396 result[idx++] = new ObjectName(name.toString());
397 }
398 }
399
400 return result;
401 }
402
403 private ObjectName[] queryNames(String param)
404 throws IOException, MalformedObjectNameException
405 {
406 return queryNames(new ObjectName(param));
407 }
408
409 }