Clean up and simplify Main startup
This commit is contained in:
parent
1709ff2d02
commit
824638594b
@ -3,38 +3,128 @@
|
|||||||
*/
|
*/
|
||||||
package com.scylladb.jmx.main;
|
package com.scylladb.jmx.main;
|
||||||
|
|
||||||
import com.scylladb.jmx.api.APIConfig;
|
import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
|
||||||
import com.scylladb.jmx.utils.RMIServerSocketFactoryImpl;
|
import static java.rmi.registry.LocateRegistry.createRegistry;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static javax.net.ServerSocketFactory.getDefault;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.rmi.server.RMIServerSocketFactory;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.remote.JMXConnectorServer;
|
||||||
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
import javax.management.remote.rmi.RMIConnectorServer;
|
||||||
|
|
||||||
import org.apache.cassandra.db.commitlog.CommitLog;
|
import org.apache.cassandra.db.commitlog.CommitLog;
|
||||||
import org.apache.cassandra.db.compaction.CompactionManager;
|
import org.apache.cassandra.db.compaction.CompactionManager;
|
||||||
import org.apache.cassandra.gms.Gossiper;
|
|
||||||
import org.apache.cassandra.gms.FailureDetector;
|
import org.apache.cassandra.gms.FailureDetector;
|
||||||
|
import org.apache.cassandra.gms.Gossiper;
|
||||||
import org.apache.cassandra.locator.EndpointSnitchInfo;
|
import org.apache.cassandra.locator.EndpointSnitchInfo;
|
||||||
import org.apache.cassandra.net.MessagingService;
|
import org.apache.cassandra.net.MessagingService;
|
||||||
import org.apache.cassandra.service.CacheService;
|
import org.apache.cassandra.service.CacheService;
|
||||||
import org.apache.cassandra.service.GCInspector;
|
import org.apache.cassandra.service.GCInspector;
|
||||||
import org.apache.cassandra.service.StorageProxy;
|
import org.apache.cassandra.service.StorageProxy;
|
||||||
import org.apache.cassandra.service.StorageService;
|
import org.apache.cassandra.service.StorageService;
|
||||||
|
import org.apache.cassandra.streaming.StreamManager;
|
||||||
|
|
||||||
|
import com.scylladb.jmx.api.APIClient;
|
||||||
|
import com.scylladb.jmx.api.APIConfig;
|
||||||
|
import com.scylladb.jmx.metrics.APIMBean;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
// todo: command line options. Make us an agent class (also)
|
||||||
|
private static final APIConfig config = new APIConfig();
|
||||||
|
public static final APIClient client = new APIClient(config);
|
||||||
|
|
||||||
|
private static JMXConnectorServer jmxServer = null;
|
||||||
|
|
||||||
|
private static void setupJmx() {
|
||||||
|
System.setProperty("javax.management.builder.initial", "com.scylladb.jmx.utils.APIBuilder");
|
||||||
|
String jmxPort = System.getProperty("com.sun.management.jmxremote.port");
|
||||||
|
|
||||||
|
if (jmxPort == null) {
|
||||||
|
System.out.println("JMX is not enabled to receive remote connections.");
|
||||||
|
|
||||||
|
jmxPort = System.getProperty("cassandra.jmx.local.port", "7199");
|
||||||
|
String address = System.getProperty("jmx.address", "localhost");
|
||||||
|
if (address.equals("localhost")) {
|
||||||
|
System.setProperty("java.rmi.server.hostname", InetAddress.getLoopbackAddress().getHostAddress());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
System.setProperty("java.rmi.server.hostname", InetAddress.getByName(address).getHostAddress());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RMIServerSocketFactory serverFactory = pPort -> getDefault().createServerSocket(pPort, 0,
|
||||||
|
InetAddress.getLoopbackAddress());
|
||||||
|
createRegistry(Integer.valueOf(jmxPort), null, serverFactory);
|
||||||
|
|
||||||
|
StringBuffer url = new StringBuffer();
|
||||||
|
url.append("service:jmx:");
|
||||||
|
url.append("rmi://").append(address).append("/jndi/");
|
||||||
|
url.append("rmi://").append(address).append(":").append(jmxPort).append("/jmxrmi");
|
||||||
|
System.out.println(url);
|
||||||
|
Map<String, Object> env = new HashMap<>();
|
||||||
|
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
|
||||||
|
|
||||||
|
jmxServer = new RMIConnectorServer(new JMXServiceURL(url.toString()), env, getPlatformMBeanServer());
|
||||||
|
|
||||||
|
jmxServer.start();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error starting local jmx server: " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("JMX is enabled to receive remote connections on port: " + jmxPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
APIConfig.setConfig();
|
System.out.println("Connecting to " + config.getBaseUrl());
|
||||||
System.out.println("Connecting to " + APIConfig.getBaseUrl());
|
|
||||||
System.out.println("Starting the JMX server");
|
System.out.println("Starting the JMX server");
|
||||||
RMIServerSocketFactoryImpl.maybeInitJmx();
|
|
||||||
StorageService.getInstance();
|
setupJmx();
|
||||||
StorageProxy.getInstance();
|
|
||||||
MessagingService.getInstance();
|
try {
|
||||||
CommitLog.getInstance();
|
MBeanServer server = getPlatformMBeanServer();
|
||||||
Gossiper.getInstance();
|
for (Class<? extends APIMBean> clazz : asList(StorageService.class, StorageProxy.class,
|
||||||
EndpointSnitchInfo.getInstance();
|
MessagingService.class, CommitLog.class, Gossiper.class, EndpointSnitchInfo.class,
|
||||||
FailureDetector.getInstance();
|
FailureDetector.class, CacheService.class, CompactionManager.class, GCInspector.class,
|
||||||
CacheService.getInstance();
|
StreamManager.class)) {
|
||||||
CompactionManager.getInstance();
|
Constructor<? extends APIMBean> c = clazz.getDeclaredConstructor(APIClient.class);
|
||||||
GCInspector.register();
|
APIMBean m = c.newInstance(client);
|
||||||
|
server.registerMBean(m, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// forces check for dynamically created mbeans
|
||||||
|
server.queryNames(null, null);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// ignore this. Just means we started before scylla.
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
Thread.sleep(Long.MAX_VALUE);
|
Thread.sleep(Long.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
// make sure to kill the server otherwise we can hang. Not an issue
|
||||||
|
// when killed perhaps, but any exception above etc would leave a
|
||||||
|
// zombie.
|
||||||
|
if (jmxServer != null) {
|
||||||
|
jmxServer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
package com.scylladb.jmx.utils;
|
|
||||||
/**
|
|
||||||
* Copyright (C) The MX4J Contributors.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This software is distributed under the terms of the MX4J License version 1.0.
|
|
||||||
* See the terms of the MX4J License in the documentation provided with this software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modified by ScyllaDB
|
|
||||||
* Copyright 2016 ScyllaDB
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of Scylla.
|
|
||||||
*
|
|
||||||
* Scylla is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Scylla is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import javax.management.MBeanInfo;
|
|
||||||
|
|
||||||
import mx4j.server.MBeanIntrospector;
|
|
||||||
import mx4j.server.MBeanMetaData;
|
|
||||||
|
|
||||||
public class APIMBeanIntrospector extends MBeanIntrospector {
|
|
||||||
private static final java.util.logging.Logger logger = java.util.logging.Logger
|
|
||||||
.getLogger(APIMBeanIntrospector.class.getName());
|
|
||||||
|
|
||||||
public boolean isMBeanCompliant(MBeanMetaData metadata) {
|
|
||||||
Class info = metadata.getMBeanInterface();
|
|
||||||
if (info != null) {
|
|
||||||
String cn = info.getName();
|
|
||||||
if (cn != null) {
|
|
||||||
if (cn.endsWith("MXBean")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.isMBeanCompliant(metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apiIntrospectStandardMBean(MBeanMetaData metadata) {
|
|
||||||
try {
|
|
||||||
Class[] cArg = new Class[1];
|
|
||||||
cArg[0] = MBeanMetaData.class;
|
|
||||||
Method met = MBeanIntrospector.class
|
|
||||||
.getDeclaredMethod("introspectStandardMBean", cArg);
|
|
||||||
met.setAccessible(true);
|
|
||||||
met.invoke((MBeanIntrospector) this, metadata);
|
|
||||||
} catch (NoSuchMethodException | SecurityException
|
|
||||||
| IllegalAccessException | IllegalArgumentException
|
|
||||||
| InvocationTargetException e) {
|
|
||||||
logger.warning("Failed setting mbean info " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apiIntrospect(MBeanMetaData metadata) {
|
|
||||||
apiIntrospectStandardMBean(metadata);
|
|
||||||
Class[] cArg = new Class[1];
|
|
||||||
cArg[0] = MBeanMetaData.class;
|
|
||||||
try {
|
|
||||||
Method met = MBeanIntrospector.class
|
|
||||||
.getDeclaredMethod("createStandardMBeanInfo", cArg);
|
|
||||||
met.setAccessible(true);
|
|
||||||
Object info = met.invoke((MBeanIntrospector) this, metadata);
|
|
||||||
metadata.setMBeanInfo((MBeanInfo) info);
|
|
||||||
} catch (IllegalAccessException | NoSuchMethodException
|
|
||||||
| SecurityException | IllegalArgumentException
|
|
||||||
| InvocationTargetException e) {
|
|
||||||
logger.warning("Failed setting mbean info" + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void introspect(MBeanMetaData metadata) {
|
|
||||||
Class<?> mx_mbean = null;
|
|
||||||
for (Class<?> it : metadata.getMBean().getClass().getInterfaces()) {
|
|
||||||
if (it.getName().endsWith("MXBean")) {
|
|
||||||
mx_mbean = it;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mx_mbean != null) {
|
|
||||||
metadata.setMBeanInterface(mx_mbean);
|
|
||||||
apiIntrospect(metadata);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
super.introspect(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2016 ScyllaDB
|
|
||||||
*
|
|
||||||
* Modified by ScyllaDB
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.scylladb.jmx.utils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.net.*;
|
|
||||||
import java.rmi.registry.LocateRegistry;
|
|
||||||
import java.rmi.server.RMIServerSocketFactory;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.management.remote.JMXConnectorServer;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import javax.management.remote.rmi.RMIConnectorServer;
|
|
||||||
import javax.net.ServerSocketFactory;
|
|
||||||
|
|
||||||
public class RMIServerSocketFactoryImpl implements RMIServerSocketFactory {
|
|
||||||
public static JMXConnectorServer jmxServer = null;
|
|
||||||
|
|
||||||
public static void maybeInitJmx() {
|
|
||||||
System.setProperty("javax.management.builder.initial", "com.scylladb.jmx.utils.APIBuilder");
|
|
||||||
System.setProperty("mx4j.strict.mbean.interface", "no");
|
|
||||||
|
|
||||||
String jmxPort = System
|
|
||||||
.getProperty("com.sun.management.jmxremote.port");
|
|
||||||
|
|
||||||
if (jmxPort == null) {
|
|
||||||
System.out.println(
|
|
||||||
"JMX is not enabled to receive remote connections.");
|
|
||||||
|
|
||||||
jmxPort = System.getProperty("cassandra.jmx.local.port", "7199");
|
|
||||||
String address = System.getProperty("jmx.address", "localhost");
|
|
||||||
if (address.equals("localhost")) {
|
|
||||||
System.setProperty("java.rmi.server.hostname",
|
|
||||||
InetAddress.getLoopbackAddress().getHostAddress());
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
System.setProperty("java.rmi.server.hostname",
|
|
||||||
InetAddress.getByName(address).getHostAddress());
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RMIServerSocketFactory serverFactory = new RMIServerSocketFactoryImpl();
|
|
||||||
LocateRegistry.createRegistry(Integer.valueOf(jmxPort), null,
|
|
||||||
serverFactory);
|
|
||||||
|
|
||||||
StringBuffer url = new StringBuffer();
|
|
||||||
url.append("service:jmx:");
|
|
||||||
url.append("rmi://").append(address).append("/jndi/");
|
|
||||||
url.append("rmi://").append(address).append(":").append(jmxPort)
|
|
||||||
.append("/jmxrmi");
|
|
||||||
System.out.println(url);
|
|
||||||
Map env = new HashMap();
|
|
||||||
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
|
|
||||||
serverFactory);
|
|
||||||
|
|
||||||
jmxServer = new RMIConnectorServer(
|
|
||||||
new JMXServiceURL(url.toString()), env,
|
|
||||||
ManagementFactory.getPlatformMBeanServer());
|
|
||||||
|
|
||||||
jmxServer.start();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println(
|
|
||||||
"Error starting local jmx server: " + e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
System.out.println(
|
|
||||||
"JMX is enabled to receive remote connections on port: "
|
|
||||||
+ jmxPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerSocket createServerSocket(final int pPort) throws IOException {
|
|
||||||
return ServerSocketFactory.getDefault().createServerSocket(pPort, 0,
|
|
||||||
InetAddress.getLoopbackAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj.getClass().equals(getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return RMIServerSocketFactoryImpl.class.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user