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