usr/src/java/rad/org/opensolaris/os/rad/jmx/RadJMXConnector.java
author David Powell <David.Powell@sun.com>
Wed, 16 Dec 2009 19:06:12 -0800
changeset 401 fc1223edbd8d
parent 391 71abce159a62
child 433 e629b84699e3
permissions -rw-r--r--
13421 apache: o.o.o.rad.ContainerException: system error: error talking to slave 13426 TLS transport auto-generates readable private keys 13429 file browsing API hard codes incorrect attributes

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

package org.opensolaris.os.rad.jmx;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanServerConnection;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.remote.JMXConnectionNotification;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXServiceURL;
import javax.security.auth.Subject;
import org.opensolaris.os.rad.Client;
import org.opensolaris.os.rad.ClientFramer;

public class RadJMXConnector implements JMXConnector
{
    private File path_ = null;
    private String host_;
    private int port_;
    private boolean tls_;
    private Map<String, ?> env_;

    private Client client_ = null;
    private boolean closed_ = false;
    private MBeanServerConnection mbsc_ = null;
    private NotificationBroadcasterSupport notify_ =
	new NotificationBroadcasterSupport();
    private int serial_ = 0;

    RadJMXConnector(JMXServiceURL url, Map<String, ?> env, boolean usetls) {
	host_ = url.getHost();
	port_ = url.getPort();
	env_ = env;
	tls_ = usetls;
	if (port_ == 0)
	    port_ = 12302;
    }

    RadJMXConnector(JMXServiceURL url, Map<String, ?> env)
	throws MalformedURLException {

	path_ = new File(url.getURLPath());
	if (!path_.isAbsolute())
	    throw new MalformedURLException("Absolute path required");
	env_ = env;
    }

    private void checkState(boolean connect) throws IOException {
	if (closed_)
	    throw new IOException("Connection was closed.");
	if (!connect && client_ == null)
	    throw new IOException("Connection not established.");
    }

    public void connect() throws IOException {
	connect(env_);
    }

    public void connect(Map<String, ?> env) throws IOException {
	checkState(true);

	if (env == null) {
	    env = env_;
	} else if (env_ != null) {
	    Map<String, Object> t = new HashMap<String, Object>(env_);
	    t.putAll(env);
	    env = t;
	}
	ClientFramer framer = path_ != null ? new ClientFramer(path_) :
	    new ClientFramer(InetAddress.getByName(host_), port_, tls_, env);
	client_ = new Client(framer);
	notify_.sendNotification(new JMXConnectionNotification(
	    JMXConnectionNotification.OPENED, this, getConnectionId(),
	    ++serial_, null, null));
    }

    public MBeanServerConnection getMBeanServerConnection() throws IOException {
	checkState(false);
	if (mbsc_ == null)
	    mbsc_ = new RadMBeanServerConnection(client_);
	return (mbsc_);
    }

    public MBeanServerConnection getMBeanServerConnection(
	Subject delegationSubject) throws IOException {

	if (delegationSubject == null)
	    return getMBeanServerConnection();

	checkState(false);
	throw new IOException("Subject delegation not supported");
    }

    public void close() throws IOException {
	if (client_ == null)
	    return;

	String id = getConnectionId();
	closed_ = true;
	client_.close();
	client_ = null;
	mbsc_ = null;

	notify_.sendNotification(new JMXConnectionNotification(
	    JMXConnectionNotification.CLOSED, this, id, ++serial_, null, null));
    }

    public void addConnectionNotificationListener(NotificationListener listener,
	NotificationFilter filter, Object handback) {

	notify_.addNotificationListener(listener, filter, handback);
    }

    public void removeConnectionNotificationListener(
	NotificationListener listener) throws ListenerNotFoundException {

	notify_.removeNotificationListener(listener);
    }

    public void removeConnectionNotificationListener(NotificationListener l,
	NotificationFilter f, Object handback) throws ListenerNotFoundException
    {
	notify_.removeNotificationListener(l, f, handback);
    }

    public String getConnectionId() throws IOException {
	checkState(false);
	/* XXX */
	return "service:jmx:rad://" + host_ + ":" + port_ + " " + "foo 1";
    }
}