-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathConnection.java
146 lines (130 loc) · 5.11 KB
/
Connection.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package org.datadog.jmxfetch;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.apache.log4j.Logger;
public class Connection {
private static final long CONNECTION_TIMEOUT = 10000;
private static final long JMX_TIMEOUT = 20;
private final static Logger LOGGER = Logger.getLogger(Connection.class.getName());
private static final ThreadFactory daemonThreadFactory = new DaemonThreadFactory();
private JMXConnector connector;
private MBeanServerConnection mbs;
protected HashMap<String, Object> env;
protected JMXServiceURL address;
private static <T extends Throwable> T initCause(T wrapper, Throwable wrapped) {
wrapper.initCause(wrapped);
return wrapper;
}
public MBeanAttributeInfo[] getAttributesForBean(ObjectName bean_name)
throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException {
return mbs.getMBeanInfo(bean_name).getAttributes();
}
public Set<ObjectName> queryNames(ObjectName name) throws IOException {
String scope = (name != null) ? name.toString() : "*:*";
LOGGER.debug("Querying bean names on scope: " + scope);
return mbs.queryNames(name, null);
}
protected void createConnection() throws IOException {
this.env.put("attribute.remote.x.request.waiting.timeout", CONNECTION_TIMEOUT);
closeConnector();
LOGGER.info("Connecting to: " + this.address);
connector = connectWithTimeout(this.address, this.env);
mbs = connector.getMBeanServerConnection();
}
public Object getAttribute(ObjectName objectName, String attributeName) throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException {
return mbs.getAttribute(objectName, attributeName);
}
/**
* Connect to a MBean Server with a timeout
* This code comes from this blog post:
* https://weblogs.java.net/blog/emcmanus/archive/2007/05/making_a_jmx_co.html
*/
JMXConnector connectWithTimeout(final JMXServiceURL url, final Map<String, Object> env) throws IOException {
final BlockingQueue<Object> mailbox = new ArrayBlockingQueue<Object>(1);
ExecutorService executor = Executors.newSingleThreadExecutor(daemonThreadFactory);
executor.submit(new Runnable() {
public void run() {
try {
JMXConnector connector = JMXConnectorFactory.connect(url, env);
if (!mailbox.offer(connector)) {
connector.close();
}
} catch (Throwable t) {
mailbox.offer(t);
}
}
});
Object result;
try {
result = mailbox.poll(JMX_TIMEOUT, TimeUnit.SECONDS);
if (result == null) {
if (!mailbox.offer(""))
result = mailbox.take();
}
} catch (InterruptedException e) {
throw initCause(new InterruptedIOException(e.getMessage()), e);
} finally {
executor.shutdown();
}
if (result == null) {
LOGGER.warn("Connection timed out: " + url);
throw new SocketTimeoutException("Connection timed out: " + url);
}
if (result instanceof JMXConnector) {
return (JMXConnector) result;
}
try {
throw (Throwable) result;
} catch (Throwable e) {
throw new IOException(e.toString(), e);
}
}
public void closeConnector() {
if (connector != null) {
try {
connector.close();
} catch (IOException e) {
// ignore
}
}
}
public boolean isAlive() {
if (connector == null) {
return false;
}
try {
connector.getConnectionId();
} catch (IOException e) { // the connection is closed or broken
return false;
}
return true;
}
private static class DaemonThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
}
}