Package org.jvnet.glassfish.comms.clb.core.util

Source Code of org.jvnet.glassfish.comms.clb.core.util.LoadbalancerUtil

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. 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.
*/
package org.jvnet.glassfish.comms.clb.core.util;

import com.ericsson.ssa.container.SipBindingCtx;
import com.ericsson.ssa.container.SipBindingResolver;
import com.ericsson.ssa.sip.AddressImpl;
import com.ericsson.ssa.sip.SipServletRequestImpl;
import com.ericsson.ssa.sip.SipURIDecoder;
import com.ericsson.ssa.sip.SipURIEncoder;
import com.ericsson.ssa.sip.ViaImpl;
import com.ericsson.ssa.sip.dns.SipTransports;
import com.ericsson.ssa.sip.dns.TargetTuple;
import com.ericsson.ssa.sip.transaction.Transaction;

import com.sun.enterprise.admin.server.core.AdminService;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.Cluster;
import com.sun.enterprise.config.serverbeans.ClusterHelper;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.config.serverbeans.ConvergedLbClusterRef;
import com.sun.enterprise.config.serverbeans.ConvergedLbConfig;
import com.sun.enterprise.config.serverbeans.ConvergedLbConfigs;
import com.sun.enterprise.config.serverbeans.ConvergedLbPolicy;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
import com.sun.enterprise.config.serverbeans.ServerHelper;
import com.sun.enterprise.config.serverbeans.ServerRef;
import com.sun.enterprise.server.ServerContext;

import java.io.File;
import org.jvnet.glassfish.comms.clb.core.sip.Socket;
import org.jvnet.glassfish.comms.util.LogUtil;

import org.apache.catalina.util.Base64;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jvnet.glassfish.comms.clb.core.CLBConstants;
import org.jvnet.glassfish.comms.clb.core.CLBRuntimeException;
import org.jvnet.glassfish.comms.clb.core.sip.Connection;
import org.jvnet.glassfish.comms.clb.core.sip.ConnectionParseException;


/**
* Misc. utility methods.
*/
public class LoadbalancerUtil {
    private static final Logger logger = LogUtil.CLB_LOGGER.getLogger();
    private static final SipURIDecoder sipURIDecoder = new SipURIDecoder();
    private static final SipURIEncoder sipURIEncoder = new SipURIEncoder();
    private static MessageDigest md;
    private static boolean isAsymmetric = false;
    private static boolean reuseClientFEConnection = false;
   
    public static boolean isAsymmetric() {
        return isAsymmetric;
    }

    public static void setAsymmetric(boolean isasymmetric) {
        isAsymmetric = isasymmetric;
    }

    private LoadbalancerUtil() {
    } // Disable creation

    /**
     * Encodes the specific string to a string that only contains valid
     * characters for a SIP parameter.
     *
     * @param raparamm the parameter to encode
     * @return the encoded parameter
     */
    public static String encodeParameter(String str) {
        return encodeParameter(str.getBytes(), false);
    }

    /**
     * Decodes a parameter that have been encoded using
     * {@link #encodeParameter(String)}.
     *
     * @param encodedParam the encoded parameter
     * @return the decoded parameter
     * @throws UnsupportedEncodingException
     */
    public static String decodeParameter(String encodedParam) throws UnsupportedEncodingException {
        String uriDecoded = sipURIDecoder.decode(encodedParam);

        return uriDecoded;
    }

    /**
     * Encodes the specific byte array to a string that only contains valid
     * characters for a SIP parameter.
     *
     * @param bytes the bytes to encode
     * @param doBase64 TODO
     * @return the encoded string
     */
    public static String encodeParameter(byte[] bytes, boolean doBase64) {
        String str;

        if (doBase64) {
            str = new String(Base64.encode(bytes));
        } else {
            str = new String(bytes);
        }

        return sipURIEncoder.encodeParameter(str);
    }

    /**
     * Decodes a parameter that have been encoded using
     * {@link #encodeParameter(String)}.
     *
     * @param encodedParam the encoded parameter
     * @param doBase64 TODO
     * @return the decoded parameter
     * @throws IOException thrown in case decoding fails
     */
    public static byte[] decodeParameterToBytes(String encodedParam,
        boolean doBase64) throws IOException {
        String uriDecoded = sipURIDecoder.decode(encodedParam);

        if (doBase64) {
            return Base64.decode(uriDecoded.getBytes());
        } else {
            return uriDecoded.getBytes();
        }
    }

    /**
     * Gets the numeric IP address of the specified InetAddress.
     *
     * @param inetAddress the address
     * @return the numeric IP address of the specified InetAddress.
     */
    public static String getNumericIpAddress(InetAddress inetAddress) {
        byte[] addressBytes = inetAddress.getAddress();

        return unsigned(addressBytes[0]) + "." + unsigned(addressBytes[1]) +
        "." + unsigned(addressBytes[2]) + "." + unsigned(addressBytes[3]);
    }

    private static int unsigned(byte b) {
        if (b >= 0) {
            return b;
        }

        int i = b;

        return i & 0xff;
    }

    /**
     * Gets the local socket on which this instance receives certain traffic for
     * a certain transport.
     *
     * @return the local socket on which this instance receives certain traffic
     *         for a certain transport.
     * @param transport the transport protocol
     * @throws IllegalStateException in case no local socket was found
     */
    public static Socket getLocalSocket(SipTransports transport)
        throws IllegalStateException {
        Socket localAddress = null;

        InetSocketAddress localSAddr = null;

        if (logger.isLoggable(Level.FINER)) {
            logger.log(Level.FINER,
                "Get first suitable local SipBindingCtx for TCP.");
        }

        SipBindingCtx ctx = SipBindingResolver.instance().
                getActiveInternalContext(transport);
                                             

        if (ctx != null) {
            TargetTuple tt = ctx.getTargetTupleForProtocol(transport);

            if (tt != null) {
                localSAddr = tt.getSocketAddress();

                if (logger.isLoggable(Level.FINER)) {
                    logger.log(Level.FINER,
                        "Suitable local SipBindingCtx found, using: " + ctx +
                        ", resolved address: " + localSAddr);
                }
            }
        }

        if (localSAddr != null) {
            String addr = localSAddr.getAddress().getHostAddress();

            if ("0.0.0.0".equals(addr)) {
                try {
                    addr = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException ex) {
                    throw new IllegalStateException("Can't resolve local address.",
                            ex);
                }
            }

            localAddress = new Socket(addr, localSAddr.getPort());

            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER,
                    "Local address resolved to: " + localAddress);
            }
        } else {
            if (System.getProperty("clb.unittest.localsocket") != null) {
                return new Socket("127.0.0.1", 5060);
            }

            throw new IllegalStateException("Can't resolve local address for '" +
                transport +
                "', there exists no listener for that transport; check your sip-listener configuration!");
        }

        return localAddress;
    }

    /**
     * Gets the name of the local instance.
     * @return the name of the local instance
     */
    public static String getLocalInstanceName() {
        ServerContext sc = com.sun.enterprise.server.ondemand.OnDemandServer.getServerContext();

        return sc.getInstanceName();
    }

    /**
     * Gets the name of the local cluster.
     * @return the name of the local cluster or null if not clustered
     * @throws ConfigException in case the configuration could ne be read.
     */
    public static String getLocalClusterName() throws ConfigException {
        ServerContext sc = com.sun.enterprise.server.ondemand.OnDemandServer.getServerContext();
        ConfigContext instanceConfigContext = sc.getConfigContext();
        String instanceName = sc.getInstanceName();

        if (ServerHelper.isServerClustered(instanceConfigContext, instanceName)) {
            Cluster cluster = ClusterHelper.getClusterForInstance(instanceConfigContext,
                    instanceName);

            return cluster.getName();
        }

        return null;
    }

    /**
     * Gets the DCR file from the configuration.
     * @return the DCR file from the configuration
     * @throws ConfigException in case configuration could not be read
     */
    public static String getDcrFileNameFromConfig() throws ConfigException {
        String instanceName = getLocalInstanceName();
        String clusterName = getLocalClusterName();
        boolean isCluster = clusterName != null;

        ConfigContext ctx = AdminService.getAdminService().getAdminContext()
                                        .getAdminConfigContext();
        Domain domain = (Domain) ctx.getRootConfigBean();
        ConvergedLbConfigs clbConfigs = domain.getConvergedLbConfigs();
        // Null in case of a DAS/developer profile. Hence no CLB frontending
        // this instance.Hence no associated DCR file.
        if(clbConfigs == null ) return null;
        boolean matchFound = false;
        ConvergedLbConfig[] clbConfigArray = clbConfigs.getConvergedLbConfig();

        for (int i = 0; i < clbConfigArray.length; i++) {
            if (isCluster) {
                ConvergedLbClusterRef[] clusterRefs = clbConfigArray[i].getConvergedLbClusterRef();

                for (int j = 0; j < clusterRefs.length; j++) {
                    if (clusterRefs[j].getRef().equals(clusterName)) {
                        matchFound = true;

                        break;
                    }
                }
            } else {
                ServerRef[] serverRefs = clbConfigArray[i].getServerRef();

                for (int j = 0; j < serverRefs.length; j++) {
                    if (serverRefs[j].getRef().equals(instanceName)) {
                        matchFound = true;

                        break;
                    }
                }
            }

            if (matchFound) {
                ConvergedLbPolicy clbPolicy = clbConfigArray[i].getConvergedLbPolicy();

                if (clbPolicy.getDcrFile() == null || clbPolicy.getDcrFile().length() == 0) {
                    return clbPolicy.getDcrFile();
                }

                ServerContext sc = com.sun.enterprise.server.ondemand.OnDemandServer.getServerContext();
                ConfigContext instanceConfigContext = sc.getConfigContext();
                Config instanceConfig = ServerBeansFactory.getConfigBean(instanceConfigContext);
               
                return instanceConfig.getName() + File.separator + clbPolicy.getDcrFile();
            }
        }

        return null;
    }

    /**
     * Gets the string to be used for consistent hashing of a server instance.
     * @param clusterName name for cluster in which server is located
     * @param serverInstanceName the name of the server instance
     * @return the string string to be used for consistent hashing of a server instance
     */
    public static String getServerString(String clusterName, String serverInstanceName) {
        return clusterName +"/"+ serverInstanceName;
    }
   
    /**
     * Create a branch ID
     * @param req the request
     * @param via the via to use for creating the branchId
     * @return the brancId
     */
    public static String createBranchId(SipServletRequestImpl req, ViaImpl via) {
        MessageDigest messageDigest = getMessageDigest();
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(req.getRequestURI().toString());
            sb.append(req.getFromImpl().getParameter(AddressImpl.TAG_PARAM));
            sb.append(req.getCallId());
            sb.append(req.getCSeqNumber());
            sb.append(via.toString());

            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER, "Input to generation of branch-ID: " + sb.toString());
            }

            MessageDigest localMD = (MessageDigest) messageDigest.clone();
            byte[] hash = localMD.digest(sb.toString().getBytes());

            sb = new StringBuilder();

            for (int i = 0; i < hash.length; i++) {
                String d = Integer.toHexString(new Byte(hash[i]).intValue() & 0xFF);

                if (d.length() == 1) {
                    sb.append('0');
                }

                sb.append(d);
            }

            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER, "Generated branch ID : " + sb.toString());
            }
            return Transaction.MAGIC_COOKIE + sb.toString();
        } catch (CloneNotSupportedException ex) {
            logger.log(Level.SEVERE,
                    "clb.sip.stack_error_occurred_for_digest_clone",
                    ex.getMessage());
            if(logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE, "clb.caught_an_exception", ex);
            }
        }
        return null;
    }

    private static MessageDigest getMessageDigest() throws Error {
        if (md == null) {
            try {
                md = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                // Should never happen!
                throw new Error(e);
            }
        }
       
        return md;
    }
   
    public static Connection getConnection(ViaImpl via) {
        String connectionIdentity = via.getParameter(CLBConstants.CONNID_PARAM);
        Connection connection = null;

        try {
            connection = (connectionIdentity != null)
                ? Connection.getFromEncoded(connectionIdentity) : null;
        } catch (ConnectionParseException e) {
            // The connection could not be decoded
            logger.log(Level.WARNING,
                "clb.sip.error_parsing_connid", e.getMessage());
            if(logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE, "clb.caught_an_exception", e);
            }
        } catch (IOException e) {
            // The connection could not be decoded
            logger.log(Level.WARNING,
                "clb.sip.error_parsing_connid", e.getMessage());
            if(logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE, "clb.caught_an_exception", e);
            }
        }

        return connection;
    }
   
    public static String generateInstanceID() throws CLBRuntimeException {
        String instanceName = getLocalInstanceName();
        String clusterName = null;
        try{
            clusterName = getLocalClusterName();
        }catch(ConfigException ex){
            throw new CLBRuntimeException("Unable to get cluster name : " +
                    ex, ex);
        }
        String hostName = LoadbalancerUtil.getLocalSocket(SipTransports.TCP_PROT).getHostName();
        return IDGenerator.getId(hostName, clusterName, instanceName);       
    }

    public static boolean isReuseClientFEConnection() {
        return reuseClientFEConnection;
    }

    public static void setReuseClientFEConnection(
            boolean isReuseClientFEConnection) {
        reuseClientFEConnection = isReuseClientFEConnection;
    }
}
TOP

Related Classes of org.jvnet.glassfish.comms.clb.core.util.LoadbalancerUtil

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.