org.gridkit.jvmtool.JmxConnectionInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sjk-core Show documentation
Show all versions of sjk-core Show documentation
Core classes for Swiss Java Knife tool
/**
* Copyright 2013 Alexey Ragozin
*
* Licensed 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.
*/
package org.gridkit.jvmtool;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.gridkit.jvmtool.cli.CommandLauncher;
import org.gridkit.lab.jvm.attach.AttachManager;
import com.beust.jcommander.Parameter;
/**
* Configurable connection for JMX based commands.
*
* @author Alexey Ragozin ([email protected])
*/
public class JmxConnectionInfo {
private CommandLauncher commandHost;
@Parameter(names = {"-p", "--pid"}, description = "JVM process PID")
private Long pid;
@Parameter(names = {"-s", "--socket"}, description = "Socket address for JMX port (host:port)")
private String sockAddr;
@Parameter(names = {"--user"}, description="User for JMX authentication (only for socket connection)")
private String user = null;
@Parameter(names = {"--password"}, description="Password for JMX authentication (only for socket connection)")
private String password = null;
public JmxConnectionInfo(CommandLauncher host) {
this.commandHost = host;
}
public Long getPID() {
return pid;
}
public MBeanServerConnection getMServer() {
if (pid == null && sockAddr == null) {
commandHost.failAndPrintUsage("JVM process is not specified");
}
if (pid != null && sockAddr != null) {
commandHost.failAndPrintUsage("You can specify eigther PID or JMX socket connection");
}
if (pid != null) {
MBeanServerConnection mserver = AttachManager.getDetails(pid).getMBeans();
if (mserver == null) {
commandHost.fail("Failed to access MBean server: " + pid);
}
return mserver;
}
else if (sockAddr != null) {
String host = host(sockAddr);
int port = port(sockAddr);
Map env = null;
if (user != null || password != null) {
if (user == null || password == null) {
commandHost.failAndPrintUsage("Both user and password required for authentication");
}
env = Collections.singletonMap(JMXConnector.CREDENTIALS, (Object)new String[]{user, password});
}
MBeanServerConnection mserver = connectJmx(host, port, env);
if (mserver == null) {
commandHost.fail("Failed to access MBean server: " + host + ":" + port);
}
return mserver;
}
else {
throw new UnsupportedOperationException();
}
}
@SuppressWarnings("resource")
private MBeanServerConnection connectJmx(String host, int port, Map props) {
try {
String proto = System.getProperty("jmx.service.protocol", "rmi");
final String uri = "rmi".equals(proto) ?
"service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi" :
"service:jmx:" + proto + "://" + host + ":" + port;
JMXServiceURL jmxurl = new JMXServiceURL(uri);
JMXConnector conn = props == null ? JMXConnectorFactory.connect(jmxurl) : JMXConnectorFactory.connect(jmxurl, props);
// TODO credentials
MBeanServerConnection mserver = conn.getMBeanServerConnection();
return mserver;
} catch (MalformedURLException e) {
commandHost.fail("JMX Connection failed: " + e.toString(), e);
} catch (IOException e) {
commandHost.fail("JMX Connection failed: " + e.toString(), e);
}
return null;
}
private String host(String sockAddr) {
int c = sockAddr.indexOf(':');
if (c <= 0) {
commandHost.fail("Invalid socket address: " + sockAddr);
}
return sockAddr.substring(0, c);
}
private int port(String sockAddr) {
int c = sockAddr.indexOf(':');
if (c <= 0) {
commandHost.fail("Invalid socket address: " + sockAddr);
}
try {
return Integer.valueOf(sockAddr.substring(c + 1));
} catch (NumberFormatException e) {
commandHost.fail("Invalid socket address: " + sockAddr);
return 0;
}
}
}