20
20
import java .math .BigInteger ;
21
21
import java .net .InetSocketAddress ;
22
22
import java .net .MalformedURLException ;
23
+ import java .net .UnknownHostException ;
23
24
import java .rmi .server .RMIClientSocketFactory ;
24
25
import java .rmi .server .RMISocketFactory ;
25
26
import java .util .AbstractMap ;
31
32
import java .util .Map ;
32
33
import java .util .Set ;
33
34
import javax .rmi .ssl .SslRMIClientSocketFactory ;
34
- import java .util .concurrent .Callable ;
35
35
import java .util .concurrent .ExecutionException ;
36
36
import java .util .concurrent .ExecutorService ;
37
37
import java .util .concurrent .Executors ;
57
57
import org .apache .cassandra .db .compaction .CompactionManagerMBean ;
58
58
import org .apache .cassandra .gms .FailureDetector ;
59
59
import org .apache .cassandra .gms .FailureDetectorMBean ;
60
+ import org .apache .cassandra .locator .EndpointSnitchInfoMBean ;
60
61
import org .apache .cassandra .repair .RepairParallelism ;
61
62
import org .apache .cassandra .repair .messages .RepairOption ;
62
63
import org .apache .cassandra .service .ActiveRepairService ;
66
67
import org .slf4j .Logger ;
67
68
import org .slf4j .LoggerFactory ;
68
69
69
- import com .google .common .base .Function ;
70
70
import com .google .common .base .Optional ;
71
71
import com .google .common .collect .Lists ;
72
72
import com .google .common .collect .Maps ;
@@ -100,6 +100,7 @@ public class JmxProxy implements NotificationListener, AutoCloseable {
100
100
private final ObjectName ssMbeanName ;
101
101
private final MBeanServerConnection mbeanServer ;
102
102
private final CompactionManagerMBean cmProxy ;
103
+ private final EndpointSnitchInfoMBean endpointSnitchMbean ;
103
104
private final Object ssProxy ;
104
105
private final Object fdProxy ;
105
106
private final Optional <RepairStatusHandler > repairStatusHandler ;
@@ -110,9 +111,18 @@ public class JmxProxy implements NotificationListener, AutoCloseable {
110
111
public static final Integer JMX_CONNECTION_TIMEOUT = 5 ;
111
112
public static final TimeUnit JMX_CONNECTION_TIMEOUT_UNIT = TimeUnit .SECONDS ;
112
113
113
- private JmxProxy (Optional <RepairStatusHandler > handler , String host , JMXServiceURL jmxUrl ,
114
- JMXConnector jmxConnector , Object ssProxy , ObjectName ssMbeanName ,
115
- MBeanServerConnection mbeanServer , CompactionManagerMBean cmProxy , FailureDetectorMBean fdProxy ) {
114
+ private JmxProxy (
115
+ Optional <RepairStatusHandler > handler ,
116
+ String host ,
117
+ JMXServiceURL jmxUrl ,
118
+ JMXConnector jmxConnector ,
119
+ Object ssProxy ,
120
+ ObjectName ssMbeanName ,
121
+ MBeanServerConnection mbeanServer ,
122
+ CompactionManagerMBean cmProxy ,
123
+ EndpointSnitchInfoMBean endpointSnitchMbean ,
124
+ FailureDetectorMBean fdProxy ) {
125
+
116
126
this .host = host ;
117
127
this .jmxUrl = jmxUrl ;
118
128
this .jmxConnector = jmxConnector ;
@@ -121,6 +131,7 @@ private JmxProxy(Optional<RepairStatusHandler> handler, String host, JMXServiceU
121
131
this .ssProxy = ssProxy ;
122
132
this .repairStatusHandler = handler ;
123
133
this .cmProxy = cmProxy ;
134
+ this .endpointSnitchMbean = endpointSnitchMbean ;
124
135
this .clusterName = Cluster .toSymbolicName (((StorageServiceMBean ) ssProxy ).getClusterName ());
125
136
this .fdProxy = fdProxy ;
126
137
}
@@ -157,12 +168,19 @@ static JmxProxy connect(Optional<RepairStatusHandler> handler, String host, Stri
157
168
* @param password password to use for JMX authentication
158
169
* @param addressTranslator if EC2MultiRegionAddressTranslator isn't null it will be used to translate addresses
159
170
*/
160
- static JmxProxy connect (Optional <RepairStatusHandler > handler , String originalHost , int port ,
161
- String username , String password , final EC2MultiRegionAddressTranslator addressTranslator , int connectionTimeout )
162
- throws ReaperException {
171
+ static JmxProxy connect (
172
+ Optional <RepairStatusHandler > handler ,
173
+ String originalHost ,
174
+ int port ,
175
+ String username ,
176
+ String password ,
177
+ final EC2MultiRegionAddressTranslator addressTranslator ,
178
+ int connectionTimeout ) throws ReaperException {
179
+
163
180
ObjectName ssMbeanName ;
164
181
ObjectName cmMbeanName ;
165
182
ObjectName fdMbeanName ;
183
+ ObjectName endpointSnitchMbeanName ;
166
184
JMXServiceURL jmxUrl ;
167
185
String host = originalHost ;
168
186
@@ -177,35 +195,44 @@ static JmxProxy connect(Optional<RepairStatusHandler> handler, String originalHo
177
195
ssMbeanName = new ObjectName (SS_OBJECT_NAME );
178
196
cmMbeanName = new ObjectName (CompactionManager .MBEAN_OBJECT_NAME );
179
197
fdMbeanName = new ObjectName (FailureDetector .MBEAN_NAME );
198
+ endpointSnitchMbeanName = new ObjectName ("org.apache.cassandra.db:type=EndpointSnitchInfo" );
180
199
} catch (MalformedURLException | MalformedObjectNameException e ) {
181
200
LOG .error (String .format ("Failed to prepare the JMX connection to %s:%s" , host , port ));
182
201
throw new ReaperException ("Failure during preparations for JMX connection" , e );
183
202
}
184
203
try {
185
- Map <String , Object > env = new HashMap <String , Object >();
204
+ Map <String , Object > env = new HashMap <>();
186
205
if (username != null && password != null ) {
187
206
String [] creds = {username , password };
188
207
env .put (JMXConnector .CREDENTIALS , creds );
189
208
}
190
209
env .put ("com.sun.jndi.rmi.factory.socket" , getRMIClientSocketFactory ());
191
210
JMXConnector jmxConn = connectWithTimeout (jmxUrl , connectionTimeout , TimeUnit .SECONDS , env );
192
211
MBeanServerConnection mbeanServerConn = jmxConn .getMBeanServerConnection ();
193
- Object ssProxy =
194
- JMX .newMBeanProxy (mbeanServerConn , ssMbeanName , StorageServiceMBean .class );
212
+ Object ssProxy = JMX .newMBeanProxy (mbeanServerConn , ssMbeanName , StorageServiceMBean .class );
195
213
String cassandraVersion = ((StorageServiceMBean ) ssProxy ).getReleaseVersion ();
196
214
if (cassandraVersion .startsWith ("2.0" ) || cassandraVersion .startsWith ("1." )){
197
- ssProxy = JMX .newMBeanProxy (mbeanServerConn , ssMbeanName , StorageServiceMBean20 .class );
215
+ ssProxy = JMX .newMBeanProxy (mbeanServerConn , ssMbeanName , StorageServiceMBean20 .class );
198
216
}
199
217
200
- CompactionManagerMBean cmProxy =
201
- JMX .newMBeanProxy (mbeanServerConn , cmMbeanName , CompactionManagerMBean .class );
218
+ CompactionManagerMBean cmProxy = JMX . newMBeanProxy ( mbeanServerConn , cmMbeanName , CompactionManagerMBean . class );
219
+ FailureDetectorMBean fdProxy = JMX .newMBeanProxy (mbeanServerConn , fdMbeanName , FailureDetectorMBean .class );
202
220
221
+ EndpointSnitchInfoMBean endpointSnitchProxy
222
+ = JMX .newMBeanProxy (mbeanServerConn , endpointSnitchMbeanName , EndpointSnitchInfoMBean .class );
203
223
204
- FailureDetectorMBean fdProxy =
205
- JMX .newMBeanProxy (mbeanServerConn , fdMbeanName , FailureDetectorMBean .class );
224
+ JmxProxy proxy = new JmxProxy (
225
+ handler ,
226
+ host ,
227
+ jmxUrl ,
228
+ jmxConn ,
229
+ ssProxy ,
230
+ ssMbeanName ,
231
+ mbeanServerConn ,
232
+ cmProxy ,
233
+ endpointSnitchProxy ,
234
+ fdProxy );
206
235
207
- JmxProxy proxy = new JmxProxy (handler , host , jmxUrl , jmxConn , ssProxy , ssMbeanName ,
208
- mbeanServerConn , cmProxy , fdProxy );
209
236
// registering a listener throws bunch of exceptions, so we do it here rather than in the
210
237
// constructor
211
238
mbeanServerConn .addNotificationListener (ssMbeanName , proxy , null , null );
@@ -233,23 +260,30 @@ public String getHost() {
233
260
return host ;
234
261
}
235
262
263
+ public String getDataCenter () {
264
+ // return endpointSnitchMbean.getDatacenter(); // not available until Cassandra-3.0
265
+ return getDataCenter (host );
266
+ }
267
+
268
+ public String getDataCenter (String host ) {
269
+ try {
270
+ return endpointSnitchMbean .getDatacenter (host );
271
+ } catch (UnknownHostException ex ) {
272
+ throw new IllegalArgumentException (ex );
273
+ }
274
+ }
275
+
236
276
/**
237
277
* @return list of tokens in the cluster
238
278
*/
239
279
public List <BigInteger > getTokens () {
240
280
checkNotNull (ssProxy , "Looks like the proxy is not connected" );
281
+
241
282
return Lists .transform (
242
- Lists .newArrayList (((StorageServiceMBean ) ssProxy ).getTokenToEndpointMap ().keySet ()),
243
- new Function <String , BigInteger >() {
244
- @ Override
245
- public BigInteger apply (String s ) {
246
- return new BigInteger (s );
247
- }
248
- });
283
+ Lists .newArrayList (((StorageServiceMBean ) ssProxy ).getTokenToEndpointMap ().keySet ()), s -> new BigInteger (s ));
249
284
}
250
285
251
- public Map <List <String >, List <String >> getRangeToEndpointMap (String keyspace )
252
- throws ReaperException {
286
+ public Map <List <String >, List <String >> getRangeToEndpointMap (String keyspace ) throws ReaperException {
253
287
checkNotNull (ssProxy , "Looks like the proxy is not connected" );
254
288
try {
255
289
return ((StorageServiceMBean ) ssProxy ).getRangeToEndpointMap (keyspace );
@@ -259,8 +293,7 @@ public Map<List<String>, List<String>> getRangeToEndpointMap(String keyspace)
259
293
}
260
294
}
261
295
262
- public List <RingRange > getRangesForLocalEndpoint (String keyspace )
263
- throws ReaperException {
296
+ public List <RingRange > getRangesForLocalEndpoint (String keyspace ) throws ReaperException {
264
297
checkNotNull (ssProxy , "Looks like the proxy is not connected" );
265
298
List <RingRange > localRanges = Lists .newArrayList ();
266
299
try {
@@ -274,7 +307,6 @@ public List<RingRange> getRangesForLocalEndpoint(String keyspace)
274
307
}
275
308
});
276
309
277
-
278
310
LOG .info ("LOCAL RANGES {}" , localRanges );
279
311
return localRanges ;
280
312
} catch (Exception e ) {
@@ -294,8 +326,7 @@ public String getLocalEndpoint() {
294
326
@ NotNull
295
327
public List <String > tokenRangeToEndpoint (String keyspace , RingRange tokenRange ) {
296
328
checkNotNull (ssProxy , "Looks like the proxy is not connected" );
297
- Set <Map .Entry <List <String >, List <String >>> entries =
298
- ((StorageServiceMBean ) ssProxy ).getRangeToEndpointMap (keyspace ).entrySet ();
329
+ Set <Map .Entry <List <String >, List <String >>> entries = ((StorageServiceMBean ) ssProxy ).getRangeToEndpointMap (keyspace ).entrySet ();
299
330
for (Map .Entry <List <String >, List <String >> entry : entries ) {
300
331
BigInteger rangeStart = new BigInteger (entry .getKey ().get (0 ));
301
332
BigInteger rangeEnd = new BigInteger (entry .getKey ().get (1 ));
@@ -396,7 +427,6 @@ public boolean isRepairRunning() {
396
427
return isRepairRunningPre22 () || isRepairRunningPost22 () || isValidationCompactionRunning ();
397
428
}
398
429
399
-
400
430
/**
401
431
* @return true if any repairs are running on the node.
402
432
*/
0 commit comments