Package com.sun.enterprise.ee.selfmanagement.actions

Source Code of com.sun.enterprise.ee.selfmanagement.actions.CheckListenerHealth

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-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 https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  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 at glassfish/bootstrap/legal/LICENSE.txt.
* 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, 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.
*/

/*
* 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
* glassfish/bootstrap/legal/CDDLv1.0.txt or
* https://glassfish.dev.java.net/public/CDDLv1.0.html.
* 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
* glassfish/bootstrap/legal/CDDLv1.0.txt.  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]
*/
package com.sun.enterprise.ee.selfmanagement.actions;

import com.sun.enterprise.server.ApplicationServer;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.serverbeans.ServerHelper;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.config.serverbeans.HttpListener;
import com.sun.enterprise.admin.util.JMXConnectorConfig;
import com.sun.enterprise.admin.servermgmt.InstanceException;
import com.sun.enterprise.config.serverbeans.PropertyResolver;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.security.SSLUtils;
import com.sun.logging.LogDomains;


import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.net.MalformedURLException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.KeyManager;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import java.util.Hashtable;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.concurrent.Callable;
import java.lang.reflect.Method;

public class CheckListenerHealth implements Callable<Boolean> {

    /** ANY address for server socket to listen to */
    static final String ANY_ADDR = "0.0.0.0" ;
   
    /** Http protocol */
    static final String HTTP_PROTOCOL = "http://";
           
    /** HTTPS protocol */
    static final String HTTPS_PROTOCOL = "https://";
   
    /** Type key name for object name */
    static final String TYPE_KEY_NAME = "type";
   
    /** Name key for name of object name */
    static final String NAME_KEY = "name";
   
    /** Type for selector */
    static final String HTTP_SELECTOR = "Selector";
   
    /** Http selector statistic API */
    static final String BUSY_PTHREADS_NAME = "currentBusyProcessorThreads";
   
    /** Http selector statistic API */
    static final String MAX_THREAD_NAME = "maxThreads";
   
    /** Name of the server whose listener is being checked */
    private Server server = null;
   
    /** Listener to check */
    private HttpListener listener = null;
   
    /** Timeout in seconds */
    private int timeoutInSeconds;
   
    /** Connect timeout */
    private int connectTimeout;
   
    /** Listener port, on which the selector works */
    private int listenerPort;
   
    /** Listeners no. of acceptor threads */
    private int countAcceptorThreads;
 
    /** isHealthy */
    boolean isHealthy = false;
   
    /** Logger for self management service */
    private static Logger _logger = LogDomains.getLogger(LogDomains.SELF_MANAGEMENT_LOGGER);
   
    /**
     * Initializes the instance of CheckListenerHealth
     *
     * @param httpListener Server listener to check
     * @timeout Timeout in seconds, upon elapse of which listener
     *          would be consider non-responsive
     */
    public CheckListenerHealth(Server inst, HttpListener httpListener, int timeout)
               throws ConfigException {
        try {
            server = inst;
            listener = httpListener;
            timeoutInSeconds = timeout;
            String val  = httpListener.getAcceptorThreads();
            countAcceptorThreads = Integer.parseInt(val);
       
            val = httpListener.getPort();           
            PropertyResolver pr = new PropertyResolver(InstanceHangAction.configCtx,
                                                       inst.getName());
            String resolvedPort = pr.resolve(val);
            listenerPort = Integer.parseInt(resolvedPort);
            /* the default value used by LB; which has been factored in from
             *proxy config - 5 seconds
             */
            connectTimeout = 5 * 1000;
        } catch (ConfigException ex) {
            throw ex;
        }
    }
   
    /**
     * Create a trust manager that does not validate certificate chains
     *
     * @return Trust Manager trust all certificates
     */
    private TrustManager[] setupAllTrust() {
        TrustManager[] trustAllCerts = null;
        try {
            trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
            };                 
        } catch (Exception ex) {
            //nop
        }
        return trustAllCerts;
    }

    /**
     * Reflects on InstanceRegistry class static method to
     * The method is used for obtaining MBeanServerConnection
     * to a instance JMX service.
     *
     * @return Method to invoke
     */
    private Method reflectInstanceRegistry() {
        Method mthd = null;

        try {
            final String INSTANCEREGISTRYCLASS = "com.sun.enterprise.ee.admin.clientreg.InstanceRegistry";
            final String OPNAME = "getInstanceConnection";

            Class reflec = Class.forName(INSTANCEREGISTRYCLASS);
            Class[] types = new Class[]{Class.forName("java.lang.String")};
            mthd = reflec.getDeclaredMethod(OPNAME,types);
        } catch (Exception ex) {
            //nop, shouldn't be the case - placeholder.
        }

        return mthd;
    }
   
    /**
     * Queries the instance statistic on http listener selector
     * to determine if the selector is unresponsive due to max'd
     * out on the threads in processor pipeline
     *
     * @return true if listener mx'd out, false otherwise.
     */
    boolean checkInstanceStatistics(String listener) {
        MBeanServerConnection mbsConn = null;
        String domain = ApplicationServer.getServerContext().getDefaultDomainName();
        String name = "http"+listenerPort;
        Hashtable<String,String> props = new Hashtable(2);
       
        /* get the MBeanserver connection to instances remote connector
         * Failure to communicate even over rmi path would further point
         * towards hang/unresponsive condition
         */
        try {
            props.put(TYPE_KEY_NAME,HTTP_SELECTOR);
            props.put(NAME_KEY,name);
            ObjectName objName = new ObjectName(domain,props);
           
            //mbsConn = InstanceRegistry.getInstanceConnection(server.getName());
            Method refMethod = reflectInstanceRegistry();
            if (refMethod == null) {

                /* shouldn't be the case, though cannot further verify instance status
                 * let it proceed with first level non-responsive check done -timeout.
                 */
                throw new Exception();
            }

            Object[] params = new Object[]{server.getName()};
            mbsConn = (MBeanServerConnection)refMethod.invoke(null,params);
            Integer val = (Integer)mbsConn.getAttribute(objName,MAX_THREAD_NAME);
            int maxThreads = val;
            val = (Integer) mbsConn.getAttribute(objName,BUSY_PTHREADS_NAME);
            int busyCount = val;
           
            if ( busyCount == countAcceptorThreads * maxThreads) {
                //the listener has max'd out
                _logger.log(Level.INFO,"sgmt.instancehang_listenermaxd",
                            new Object[]{server.getName(),listener,val.toString()});
                return false;
            } else {
                //still scope to process more processor tasks
                _logger.log(Level.INFO,"sgmt.instancehang_listenersnotmaxd",
                            new Object[]{server.getName(),listener,val});
                return true;
            }
        } catch (Exception ex) {
            // IO exception
            return false;
        }
    }
   
    /**
     * Checks for non-responsiveness of the listener
     *
     * @return true If listener is responsive, false otherwise
     */
    public Boolean call() throws Exception {
        boolean isHealthy = true;
       
        String address = listener.getAddress();
        JMXConnectorConfig jmxCfg = null;
        String urlString = null;
        ConfigContext configCtx = InstanceHangAction.configCtx;
       
        try {
            if (address.equals(ANY_ADDR)) {
                jmxCfg = ServerHelper.getJMXConnectorInfo(configCtx,server.getName());
                address = jmxCfg.getHost();
            }
       
            boolean sslEnabled = listener.isSecurityEnabled();
            if (sslEnabled) {
                // ssl connection   
                urlString = HTTPS_PROTOCOL + address + ":" + listenerPort + "/";
                URL url = new URL(urlString);
               
                _logger.log(Level.INFO,"sgmt.instancehang_startlistcheck",
                             new Object[]{server.getName(),urlString});
                            
                TrustManager[] trustAllCerts = setupAllTrust();
                SSLContext sc = SSLContext.getInstance("SSL");
                KeyManager[] keyMgr = SSLUtils.getKeyManagers();
                sc.init(keyMgr, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                HttpsURLConnection urlCon = (HttpsURLConnection)url.openConnection();
                urlCon.setConnectTimeout(connectTimeout);
                urlCon.setReadTimeout(timeoutInSeconds*1000);
                urlCon.connect();
                InputStream buffer = urlCon.getInputStream();
                buffer.read();
            } else {
                //non-ssl connection
                urlString = HTTP_PROTOCOL + address + ":" + listenerPort + "/";
                URL url = new URL(urlString);
               
                _logger.log(Level.INFO,"sgmt.instancehang_startlistcheck",
                             new Object[]{server.getName(),urlString});

                HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
                urlCon.setConnectTimeout(connectTimeout);
                urlCon.setReadTimeout(timeoutInSeconds*1000);
                urlCon.connect();
                InputStream buffer = urlCon.getInputStream();
                buffer.read();
            }
        } catch (MalformedURLException ex) {
            //nop
        } catch (IOException ex) {
            //either connect or read failure. Server not healthy
            _logger.log(Level.WARNING,"sgmt.instancehang_listener_notresponding",
                        new Object[]{server.getName(),urlString,timeoutInSeconds});
            isHealthy = checkInstanceStatistics(urlString);
            return isHealthy;
        } catch (IllegalArgumentException ex) {
            //nop
        } catch (Exception ex) {
            //nop - config, ssl, keymanager
        }
       
        _logger.log(Level.INFO,"sgmt.instancehang_listenerresp",
                    new Object[]{server.getName(),urlString});
        return isHealthy;
    }
}
TOP

Related Classes of com.sun.enterprise.ee.selfmanagement.actions.CheckListenerHealth

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.