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