Package org.jvnet.glassfish.comms.clb.core.common.chr

Source Code of org.jvnet.glassfish.comms.clb.core.common.chr.StickyHashKeyExtractor

/*
* 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.common.chr;

import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.sip.Address;
import javax.servlet.sip.ServletParseException;
import javax.servlet.sip.SipServletRequest;

import org.jvnet.glassfish.comms.clb.core.CLBConstants;
import org.jvnet.glassfish.comms.clb.core.ConsistentHashRequest;
import org.jvnet.glassfish.comms.clb.proxy.http.util.HttpRequest;
import org.jvnet.glassfish.comms.util.LogUtil;

import com.ericsson.ssa.sip.Header;
import com.ericsson.ssa.sip.SipServletMessageImpl;
import com.ericsson.ssa.sip.SipServletRequestImpl;
import com.ericsson.ssa.sip.URIImpl;
import com.sun.grizzly.util.buf.MessageBytes;


/**
* This hash key extractor extracts hash key encoded in the BEkey cookie of a
* request.
*/
public class StickyHashKeyExtractor implements HashKeyExtractor {
    private static Logger logger = LogUtil.CLB_LOGGER.getLogger();

    /**
     * @see org.jvnet.glassfish.comms.clb.core.common.chr.HashKeyExtractor#getHashKey(javax.servlet.http.HttpServletRequest)
     */
    public String getHashKey(HttpRequest request) {
        String value = null;
        MessageBytes uriMB = request.requestURI();
        String requestURI = uriMB.toString();

        //search URI for encoding
        value = extractBEKeyFromURI(requestURI);

        if (value != null) {
            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER, "clb.found_route_encodedURL",
                           new Object[] {CLBConstants.BEKEY_KEY_NAME,
                                         value, requestURI
                                        });
            }
            return value;
        }

        //search the cookies
        String cookieString = request.getHeader(CLBConstants.COOKIE_HEADER);

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

        int index = cookieString.indexOf(CLBConstants.BEKEY_KEY_NAME);

        if (index == -1) {
            return null;
        }

        int valueStartIndex = cookieString.indexOf("=", index + 1);

        if (valueStartIndex == -1) {
            return null;
        }

        int valueEndIndex = cookieString.indexOf(";", valueStartIndex + 1);

        if (valueEndIndex == -1) {
            valueEndIndex = cookieString.indexOf(",", valueStartIndex + 1);
        }

        if (valueEndIndex == -1) {
            return cookieString.substring(valueStartIndex + 1);
        }

        return cookieString.substring(valueStartIndex + 1, valueEndIndex);
    }

    /**
     * @see org.jvnet.glassfish.comms.clb.core.common.chr.HashKeyExtractor#getHashKey(javax.servlet.sip.SipServletRequest)
     */
    public String getHashKey(SipServletRequest req) {
        return extractHashKey(req);
    }

    private String extractHashKey(SipServletRequest request) {
     
        String bekey = null;
       
        // is there a bekey in topmost Route?
        Header routeHeader = ((SipServletMessageImpl) request).getRawHeader(Header.ROUTE);

        if (routeHeader != null) {
            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER,
                    "The request contains a Route header: " + routeHeader);
            }

            ListIterator<Address> routeIterator;

            try {
                routeIterator = routeHeader.getAddressValues();
            } catch (ServletParseException e) {
                logger.log(Level.WARNING,
                    "clb.sip.address_parse_error", e.getMessage());
                if(logger.isLoggable(Level.FINE)){
                    logger.log(Level.FINE, "clb.caught_an_exception", e);
                }

                return null;
            }

            if (routeIterator.hasNext()) {
                Address topRoute = routeIterator.next();
                URIImpl uriImpl = (URIImpl) topRoute.getURI();
                if (uriImpl != null) {
                    bekey = uriImpl.decodeBeKey();
                }
               
                if (bekey == null) {
                  return null;
                }
                else {
                    if (logger.isLoggable(Level.FINER)) {
                        logger.log(Level.FINER,
                            "The bekey: " + bekey +
                            " was found in the topmost Route: " + topRoute);
                    }
                  return bekey;
                }
            }
        }

       
        // is there a bekey in request-URI?
        URIImpl uriImpl = (URIImpl) request.getRequestURI();
        if (uriImpl != null) {
            bekey = uriImpl.decodeBeKey();
        }

        if (bekey != null) {
            if (logger.isLoggable(Level.FINER)) {
                    logger.log(Level.FINER,
                        "bekey: " + bekey + " was found in the request-URI");
            }
            return bekey;
        }

        // last resort:
        // is there a bekey in to Header? (may only happen on ACK's)
        if ("ACK".equalsIgnoreCase(request.getMethod())) {
          // (Only) if the request is an ACK there may exist an bekey on the To header
            // Try to extract BEKey To-header
            Address toHeader;
            try {
               
                // Use getAddressHeaderImpl to retrieve the AddressImpl.
                // getAddressHeader returns a wrapper around the Address.               
                SipServletRequestImpl requestImpl = (SipServletRequestImpl) request;

                toHeader = requestImpl.getAddressHeaderImpl(Header.TO);
            } catch (ServletParseException e) {
                if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE, "Exception when extracting the To-header", e);
                }
               
                toHeader = null;
            }
           
            if (toHeader != null) {
                URIImpl toUriImpl = (URIImpl) toHeader.getURI();
                if (toUriImpl != null) {
                    bekey = toUriImpl.decodeBeKey();
                }
        if (bekey != null) {
          if (logger.isLoggable(Level.FINER)) {
            logger.log(Level.FINER, "bekey: " + bekey
                + " was found in the To-header");
          }

          return bekey;
        }
      }
        }

    if (logger.isLoggable(Level.FINER)) {
      logger.log(Level.FINER, "no bekey found, it must be a new request: ");
    }
        // this must be a new request, --> return null --> apply dcr rules
        return null;
    }

    /**
     * Extract the encoded BEKey from the requestURI.
     * @param requestURI The Http request URI
     *
     * @return BEKey value if found or null
     */
    private String extractBEKeyFromURI(String requestURI) {
        String extractedBEKey = null;

        try {
            int startIndexForBEKey = requestURI.indexOf(
                                              CLBConstants.BEKEY_URI_IDENTIFIER);
            if (startIndexForBEKey != -1) {
                //Found BEKey URL encoded.
                if (logger.isLoggable(Level.FINER)) {
                    logger.log(Level.FINER,
                               "clb.retrieving_URLencoded_route",
                                new Object[] {CLBConstants.BEKEY_KEY_NAME,
                                              requestURI
                                             });
                }

                int startIndexForBEKeyValue = startIndexForBEKey
                                     + CLBConstants.BEKEY_URI_IDENTIFIER.length();
                int startIndexForNextID = requestURI.indexOf(
                                                CLBConstants.COMMA_DELIMITER,
                                                startIndexForBEKeyValue);

                if (startIndexForNextID != -1) {
                    //There are more id's encoded; extract BEKey
                    if (logger.isLoggable(Level.FINER)) {
                        logger.log(Level.FINER,
                                   "clb.multiple_URLencoded_IDs",
                                    new Object[]{CLBConstants.BEKEY_KEY_NAME,
                                                 requestURI
                                                });
                    }
                    extractedBEKey = requestURI.substring(
                                                      startIndexForBEKeyValue,
                                                      startIndexForNextID);
                } else {
                    if (logger.isLoggable(Level.FINER)) {
                        logger.log(Level.FINER,
                                   "clb.zero_URLencoded_IDs_after_route",
                                    new Object[] {CLBConstants.BEKEY_KEY_NAME,
                                                  requestURI
                                                 });

                    }
                    extractedBEKey = requestURI.substring(
                                                     startIndexForBEKeyValue);
                }

                return (extractedBEKey.trim());
            }        
        } catch (IndexOutOfBoundsException ex) {
                  logger.log(Level.WARNING,
                             "clb.error_extract_route_encodedURL",
                             new Object[]{ CLBConstants.BEKEY_KEY_NAME,
                                           requestURI
                                         });
                  if(logger.isLoggable(Level.FINE)){
                    logger.log(Level.FINE, "clb.caught_an_exception", ex);
                  }
        }
        return extractedBEKey;
    }

    public String getHashKey(ConsistentHashRequest request) {
        String hashKey = null;
        if (request.isHttp()) {
            hashKey = getHashKey(request.getHttpRequest());
        } else {
            hashKey = getHashKey(request.getSipRequest());
        }
        if(hashKey != null){
            request.setSticky(true);
        }
        return hashKey;
    }
   
}
TOP

Related Classes of org.jvnet.glassfish.comms.clb.core.common.chr.StickyHashKeyExtractor

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.