All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.management.remote.generic.ServerIntermediary Maven / Gradle / Ivy

/*
 * @(#)file      ServerIntermediary.java
 * @(#)author    Sun Microsystems, Inc.
 * @(#)version   1.79
 * @(#)lastedit  07/03/08
 * @(#)build     @BUILD_TAG_PLACEHOLDER@
 *
 * 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU General
 * Public License Version 2 only ("GPL") or the Common Development and
 * Distribution License("CDDL")(collectively, the "License"). You may not use
 * this file except in compliance with the License. You can obtain a copy of the
 * License at http://opendmk.dev.java.net/legal_notices/licenses.txt or in the 
 * LEGAL_NOTICES folder that accompanied this code. See the License for the 
 * specific language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file found at
 *     http://opendmk.dev.java.net/legal_notices/licenses.txt
 * or in the LEGAL_NOTICES folder that accompanied this code.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.
 * 
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * 
 *       "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding
 * 
 *       "[Contributor] elects to include this software in this distribution
 *        under the [CDDL or GPL Version 2] license."
 * 
 * If you don't indicate a single choice of license, a recipient has the option
 * to distribute your version of this file under either the CDDL or the GPL
 * Version 2, or to extend the choice of license to its licensees as provided
 * above. However, if you add GPL Version 2 code and therefore, elected the
 * GPL Version 2 license, then the option applies only if the new code is made
 * subject to such option by the copyright holder.
 * 
 */

package javax.management.remote.generic;

import java.io.EOFException;
import java.io.IOException;
import java.io.NotSerializableException;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permission;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import java.rmi.NoSuchObjectException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.loading.ClassLoaderRepository;
import javax.management.remote.JMXConnectionNotification;
import javax.management.remote.JMXServerErrorException;
import javax.management.remote.NotificationResult;
import javax.management.remote.NotificationResult;
import javax.management.remote.SubjectDelegationPermission;
import javax.management.remote.TargetedNotification;
import javax.management.remote.generic.ConnectionClosedException;

import javax.management.remote.message.CloseMessage;
import javax.management.remote.message.MBeanServerRequestMessage;
import javax.management.remote.message.MBeanServerResponseMessage;
import javax.management.remote.message.NotificationRequestMessage;
import javax.management.remote.message.NotificationResponseMessage;
import javax.management.remote.message.Message;
import javax.security.auth.Subject;

import com.sun.jmx.remote.generic.ObjectWrappingImpl;
import com.sun.jmx.remote.generic.SynchroCallback;
import com.sun.jmx.remote.generic.ServerSynchroMessageConnection;

import com.sun.jmx.remote.opt.internal.ServerNotifForwarder;
import com.sun.jmx.remote.opt.internal.ServerCommunicatorAdmin;
import com.sun.jmx.remote.opt.security.JMXSubjectDomainCombiner;
import com.sun.jmx.remote.opt.security.SubjectDelegator;
import com.sun.jmx.remote.opt.util.ClassLoaderWithRepository;
import com.sun.jmx.remote.opt.util.ClassLogger;
import com.sun.jmx.remote.opt.util.EnvHelp;
import com.sun.jmx.remote.opt.util.OrderClassLoaders;
import com.sun.jmx.remote.opt.util.ThreadService;

class ServerIntermediary {

    // Note: it is necessary to pass the defaultClassLoader - because
    // the defaultClassLoader is determined from the Map + context
    // class loader of the thread that calls GenericConnectorServer.start()
    public ServerIntermediary(MBeanServer mbeanServer,
			      GenericConnectorServer myServer,
			      ServerSynchroMessageConnection connection,
			      ObjectWrapping wrapper,
			      Subject subject,
			      ClassLoader defaultClassLoader,
			      Map env) {

	if (logger.traceOn()) {
	    logger.trace("constructor", "Create a ServerIntermediary object.");
	}

	if (mbeanServer == null) {
	    throw new NullPointerException("Null mbean server.");
	}

	if (connection == null) {
	    throw new NullPointerException("Null connection.");
	}

	this.mbeanServer = mbeanServer;
	this.myServer = myServer;
	this.connection = connection;

	this.clientId = connection.getConnectionId();
	this.serialization = wrapper;

	this.subjectDelegator = new SubjectDelegator();
	this.subject = subject;
	if (subject == null) {
	    this.acc = null;
	} else {
	    this.acc =
		new AccessControlContext(AccessController.getContext(),
				       new JMXSubjectDomainCombiner(subject));
	}

	this.defaultClassLoader = defaultClassLoader;

	final ClassLoader dcl = defaultClassLoader;
	this.clr = (ClassLoaderWithRepository)
	    AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			return new ClassLoaderWithRepository(
					      getClassLoaderRepository(),
					      dcl);
		    }
		});

	this.env = env;

	final long timeout = EnvHelp.getServerConnectionTimeout(this.env);

	// compatible to RI 1.0: bug 4948444
        String s = (String)this.env.get("com.sun.jmx.remote.bug.compatible");
	if (s == null) {
	    s = (String)AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			return System.getProperty("com.sun.jmx.remote.bug.compatible");
		    }
		});
	}
	isRI10 = "RI1.0.0".equals(s);

	serverCommunicatorAdmin = new GenericServerCommunicatorAdmin(timeout);
    }

    private synchronized ServerNotifForwarder getServerNotifFwd() {
	// Lazily created when first use. Mainly when
	// addNotificationListener is first called.
	if(serverNotifForwarder == null)
	    serverNotifForwarder =
		new ServerNotifForwarder(mbeanServer,
					 env,
					 myServer.getNotifBuffer());

	return serverNotifForwarder;
    }

    public Object handleRequest(MBeanServerRequestMessage req)
	throws Exception {

	if (logger.traceOn()) {
	    logger.trace("handleRequest", "Handle a request: " + req);
	}

	if (req == null) {
	    return null;
	}

	final Object[] params = req.getParams();
	switch (req.getMethodId()) {
	case MBeanServerRequestMessage.CREATE_MBEAN:

	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a CREATE_MBEAN request.");
	    }

	    return mbeanServer.createMBean((String)params[0],
					   (ObjectName)params[1]);

	case MBeanServerRequestMessage.CREATE_MBEAN_LOADER:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a CREATE_MBEAN_LOADER request.");
	    }

	    return mbeanServer.createMBean((String)params[0],
					   (ObjectName)params[1],
					   (ObjectName)params[2]);

	case MBeanServerRequestMessage.CREATE_MBEAN_PARAMS:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a CREATE_MBEAN_PARAMS request.");
	    }

	    return mbeanServer.createMBean(
			       (String)params[0],
			       (ObjectName)params[1],
			       (Object[])serialization.unwrap(params[2], clr),
			       (String[])params[3]);

	case MBeanServerRequestMessage.CREATE_MBEAN_LOADER_PARAMS:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a CREATE_MBEAN_LOADER_PARAMS request.");
	    }

	    return mbeanServer.createMBean(
		(String)params[0],
		(ObjectName)params[1],
		(ObjectName)params[2],
		(Object[])unwrapWithDefault(
				    params[3],
				    getClassLoader((ObjectName)params[2])),
		(String[])params[4]);

	case MBeanServerRequestMessage.GET_ATTRIBUTE:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_ATTRIBUTE request.");
	    }

	    return mbeanServer.getAttribute((ObjectName)params[0],
					    (String)params[1]);

	case MBeanServerRequestMessage.GET_ATTRIBUTES:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_ATTRIBUTES request.");
	    }

	    return mbeanServer.getAttributes((ObjectName)params[0],
					     (String[])params[1]);

	case MBeanServerRequestMessage.GET_DEFAULT_DOMAIN:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_DEFAULT_DOMAIN request.");
	    }

	    return mbeanServer.getDefaultDomain();

	case MBeanServerRequestMessage.GET_DOMAINS:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_DOMAINS request.");
	    }

	    return mbeanServer.getDomains();

	case MBeanServerRequestMessage.GET_MBEAN_COUNT:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_MBEAN_COUNT request.");
	    }

	    return mbeanServer.getMBeanCount();

	case MBeanServerRequestMessage.GET_MBEAN_INFO:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_MBEAN_INFO request.");
	    }

	    return mbeanServer.getMBeanInfo((ObjectName)params[0]);

	case MBeanServerRequestMessage.GET_OBJECT_INSTANCE:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a GET_OBJECT_INSTANCE request.");
	    }

	    return mbeanServer.getObjectInstance((ObjectName)params[0]);

	case MBeanServerRequestMessage.INVOKE:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a INVOKE request.");
	    }

	    return mbeanServer.invoke(
		(ObjectName)params[0],
		(String)params[1],
		(Object[])unwrapWithDefault(
				    params[2],
				    getClassLoaderFor((ObjectName)params[0])),
		(String[])params[3]);

	case MBeanServerRequestMessage.IS_INSTANCE_OF:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a IS_INSTANCE_OF request.");
	    }

	    return mbeanServer.isInstanceOf((ObjectName)params[0],
					    (String)params[1])
		? Boolean.TRUE : Boolean.FALSE;

	case MBeanServerRequestMessage.IS_REGISTERED:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a IS_REGISTERED request.");
	    }

	    return mbeanServer.isRegistered((ObjectName)params[0])
		? Boolean.TRUE : Boolean.FALSE;

	case MBeanServerRequestMessage.QUERY_MBEANS:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a QUERY_MBEANS request.");
	    }

	    return mbeanServer.queryMBeans(
		(ObjectName)params[0],
		(QueryExp)serialization.unwrap(params[1], defaultClassLoader));

	case MBeanServerRequestMessage.QUERY_NAMES:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a QUERY_NAMES request.");
	    }

	    return mbeanServer.queryNames(
		(ObjectName)params[0],
		(QueryExp)serialization.unwrap(params[1], defaultClassLoader));

	case MBeanServerRequestMessage.SET_ATTRIBUTE:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a SET_ATTRIBUTE request.");
	    }

	    mbeanServer.setAttribute(
		(ObjectName)params[0],
		(Attribute)unwrapWithDefault(
		      params[1],getClassLoaderFor((ObjectName)params[0])));
	    return null;

	case MBeanServerRequestMessage.SET_ATTRIBUTES:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a SET_ATTRIBUTES request.");
	    }

	    return mbeanServer.setAttributes(
		(ObjectName)params[0],
		(AttributeList)unwrapWithDefault(
		      params[1],getClassLoaderFor((ObjectName)params[0])));

	case MBeanServerRequestMessage.UNREGISTER_MBEAN:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			     "Handle a UNREGISTER_MBEAN request.");
	    }

	    mbeanServer.unregisterMBean((ObjectName)params[0]);
	    return null;

	case MBeanServerRequestMessage.ADD_NOTIFICATION_LISTENER_OBJECTNAME:
	    if (logger.traceOn()) {
		final String reqname =
		    "ADD_NOTIFICATION_LISTENER_OBJECTNAME";
		logger.trace("handleRequest",
			     "Handle a " + reqname +" request.");
	    }

	    final ClassLoader cl1 = getClassLoaderFor((ObjectName)params[0]);
	    mbeanServer.addNotificationListener(
		(ObjectName)params[0],
		(ObjectName)params[1],
		(NotificationFilter)unwrapWithDefault(params[2], cl1),
		(Object)unwrapWithDefault(params[3], cl1));
	    return null;

	case MBeanServerRequestMessage.
	    REMOVE_NOTIFICATION_LISTENER_OBJECTNAME:
	    if (logger.traceOn()) {
		final String reqname =
		    "REMOVE_NOTIFICATION_LISTENER_OBJECTNAME";
		logger.trace("handleRequest",
			     "Handle a " + reqname +" request.");
	    }

	    mbeanServer.removeNotificationListener((ObjectName)params[0],
						   (ObjectName)params[1]);
	    return null;

	case MBeanServerRequestMessage.
	    REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK:
	    if (logger.traceOn()) {
		final String reqname =
		    "REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK";
		logger.trace("handleRequest",
			     "Handle a " + reqname + " request.");
	    }

	    final ClassLoader cl2 = getClassLoaderFor((ObjectName)params[0]);
	    mbeanServer.removeNotificationListener(
		(ObjectName)params[0],
		(ObjectName)params[1],
		(NotificationFilter)unwrapWithDefault(params[2], cl2),
		(Object)unwrapWithDefault(params[3], cl2));
	    return null;

	case MBeanServerRequestMessage.ADD_NOTIFICATION_LISTENERS:
	    if (logger.traceOn()) {
		logger.trace("handleRequest",
			   "Handle a ADD_NOTIFICATION_LISTENERS request.");
	    }

	    if (isRI10) { // compatible to RI 10: bug 4948444
		final ObjectName name = ((ObjectName[])params[0])[0];
		final ClassLoader cl3 = getClassLoaderFor(name);
		final Object wrappedFilter = ((Object[])params[1])[0];
		return getServerNotifFwd().addNotificationListener(name,
			       (NotificationFilter)unwrapWithDefault(wrappedFilter, cl3));
	    }

	    if (params[0] == null || params[1] == null) {
		throw new IllegalArgumentException("Got null arguments.");
	    }

	    ObjectName[] names = (ObjectName[])params[0];
	    Object[] wrappedFilters = (Object[])params[1];

	    if (names.length != wrappedFilters.length) {

		throw new IllegalArgumentException(
			  "The value lengths of 2 parameters are not same.");
	    }

	    for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy