Package org.mc4j.ems.impl.jmx.connection.support.providers.proxy

Source Code of org.mc4j.ems.impl.jmx.connection.support.providers.proxy.GenericMBeanServerProxy

/*
* Copyright 2002-2009 Greg Hinkle
*
* 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.mc4j.ems.impl.jmx.connection.support.providers.proxy;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mc4j.ems.connection.EmsConnectException;
import org.mc4j.ems.connection.EmsUnsupportedTypeException;
import org.mc4j.ems.connection.LoadException;
import org.mc4j.ems.connection.support.ConnectionProvider;
import org.mc4j.ems.impl.jmx.connection.support.providers.JBossConnectionProvider;

import javax.management.MBeanServer;
import java.io.NotSerializableException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.NoSuchObjectException;

/**
*
* @author Greg Hinkle (ghinkle@users.sourceforge.net), January 2002
* @author Ian Springer
* @version $Revision: 597 $($Author: ianpspringer $ / $Date: 2009-06-15 15:52:30 -0400 (Mon, 15 Jun 2009) $)
*/
public class GenericMBeanServerProxy implements InvocationHandler, StatsProxy {
    private static Log log = LogFactory.getLog(GenericMBeanServerProxy.class);

    private Object remoteServer;
    private ConnectionProvider provider;

    private long roundTrips;

    private long failures;

    private boolean reconnecting = false;

    /** Creates a new instance of Proxy */
    public GenericMBeanServerProxy(Object remoteServer) {
        this.remoteServer = remoteServer;
    }

    public GenericMBeanServerProxy() {
    }

    public ConnectionProvider getProvider() {
        return provider;
    }

    public void setProvider(ConnectionProvider provider) {
        this.provider = provider;
    }

    public Object getRemoteServer() {
        return remoteServer;
    }

    public void setRemoteServer(Object remoteServer) {
        this.remoteServer = remoteServer;
    }

    public Object invoke(
        Object proxy, Method m, Object[] args)
    throws Throwable {

//        SwingUtility.eventThreadAlert();
//
//        ConnectionInfoAction.addHit();

        Class serverClass = this.remoteServer.getClass();
        //org.openide.windows.IOProvider.getDefault().getStdOut().println("Looking at object: " + serverClass.getName());

        // TODO GH: This is horribly inefficient
        Method[] ms = serverClass.getMethods();
        Method queryMethod = null;
        for (int i = 0; i < ms.length; i++) {
            //org.openide.windows.IOProvider.getDefault().getStdOut().println("\t" + ms[i].getName() +
            //    Arrays.asList(ms[i].getParameterTypes()));
            if (ms[i].getName().equals("queryMBeans"))
                queryMethod = ms[i];
        }
        Method method;
        if ("queryMBeans".equals(m.getName())) {
            method = queryMethod;
            //method = serverClass.getMethod(m.getName(), new Class[] { ObjectName.class, QueryExp.class });
        } else {
            method = serverClass.getMethod(m.getName(),m.getParameterTypes());
        }

        if (method == null) {
            throw new EmsConnectException("Unsupported operation [" + m.getName() + "]");
        }

        ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
        try {
            roundTrips++;
//            Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
            boolean isJBossConnection = (this.provider instanceof JBossConnectionProvider);
            if (isJBossConnection) {
                JBossConnectionProvider jbossProvider = (JBossConnectionProvider) this.provider;
                // See https://jira.jboss.org/jira/browse/JOPR-9 for an explanation of why we have to re-set the
                // PrincipalInfo prior to every JBoss JMX call.                
                //jbossProvider.resetPrincipalInfo();
                // Login via JAAS before making the call...
                jbossProvider.login();
            }
            Object returnValue;
            try {
                returnValue = method.invoke(this.remoteServer, args);
            } finally {
                if (isJBossConnection) {
                    JBossConnectionProvider jbossProvider = (JBossConnectionProvider) this.provider;
                    // Logout via JAAS before returning...
                    jbossProvider.logout();
                }
            }
            return returnValue;
        } catch(InvocationTargetException e) {
            failures++;
            if (e.getCause() != null) {
                Throwable t = e.getCause();
                if (t instanceof java.rmi.ConnectException) {
                    throw new EmsConnectException(t);
                } else if (t instanceof NoSuchObjectException) {
                    // This happens when the server comes back up and the stub is stale
                    // try to reconnect if this provider supports it (if it told the proxy what the provider was)
                    if (provider != null && !reconnecting) {
                        try {
                            log.info("Reestablishing RMI stub " + this.provider.getConnectionSettings().getServerUrl());
                            reconnecting = true;
                            provider.connect();
                            // Retry the request once
                            return this.invoke(proxy, m, args);
                        } catch(Exception f) {
                            log.warn("Unable to reestablish RMI stub to restarted server.",f);
                        } finally{ reconnecting = false; }
                    }
                    // The reconnect failed, throw the original exception
                    // If the retry fails, it will throw its own exception
                    throw new EmsConnectException(t);
                } else if (t instanceof java.io.IOException) {
                    throw new EmsConnectException(t);
                } else if (t instanceof NotSerializableException) {
                    throw new EmsUnsupportedTypeException("Value was not serializable " + t.getLocalizedMessage(),t);
                } else {
                    throw new EmsConnectException("Connection failure " + t.getLocalizedMessage(), t);
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            failures++;
            //e.printStackTrace();
            throw e;
        } finally {
//            Thread.currentThread().setContextClassLoader(ctxLoader);
        }
    }

    public long getRoundTrips() {
        return roundTrips;
    }

    public long getFailures() {
        return failures;
    }

    public MBeanServer buildServerProxy() {
        try {
            Object proxy = Proxy.newProxyInstance(
                GenericMBeanServerProxy.class.getClassLoader(),
                    new Class<?>[] { Class.forName("javax.management.MBeanServer")},
                this);
            return (MBeanServer) proxy;

        } catch (ClassNotFoundException e) {
            throw new LoadException("Unable to find JMX Classes", e);
        }
    }
}
TOP

Related Classes of org.mc4j.ems.impl.jmx.connection.support.providers.proxy.GenericMBeanServerProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.