alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (ConnectorConnectionPoolAdminServiceImpl.java)

This example Glassfish source code file (ConnectorConnectionPoolAdminServiceImpl.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

connectorconnectionpool, connectorruntimeexception, connectorruntimeexception, exception, jdbc, log, logging, managedconnectionfactory, naming, namingexception, namingexception, poolinfo, resourceexception, resourceexception, resourceprincipal, sql, sqlexception, string, string, util

The Glassfish ConnectorConnectionPoolAdminServiceImpl.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. 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_1_1.html
 * or packager/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 packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [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 com.sun.enterprise.connectors.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.logging.Level;
import javax.naming.NamingException;
import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.TransactionSupport;
import javax.security.auth.Subject;

import com.sun.appserv.connectors.internal.api.ConnectorRuntimeException;
import com.sun.appserv.connectors.internal.api.ConnectorsUtil;
import org.glassfish.resource.common.PoolInfo;
import com.sun.appserv.connectors.internal.api.PoolingException;
import org.glassfish.resource.common.ResourceInfo;
import com.sun.enterprise.config.serverbeans.JdbcResource;
import com.sun.enterprise.config.serverbeans.ResourcePool;
import com.sun.enterprise.config.serverbeans.SecurityMap;
import com.sun.enterprise.connectors.ActiveResourceAdapter;
import com.sun.enterprise.connectors.*;
import com.sun.enterprise.connectors.authentication.ConnectorSecurityMap;
import com.sun.enterprise.connectors.authentication.RuntimeSecurityMap;
import com.sun.enterprise.connectors.util.*;
import com.sun.enterprise.deployment.ConnectionDefDescriptor;
import com.sun.enterprise.deployment.ConnectorDescriptor;
import com.sun.enterprise.deployment.ConnectorConfigProperty ;
import com.sun.enterprise.deployment.ResourcePrincipal;
import com.sun.enterprise.resource.listener.UnpooledConnectionEventListener;
import com.sun.enterprise.resource.pool.PoolManager;
import org.glassfish.internal.api.RelativePathResolver;
import com.sun.enterprise.util.i18n.StringManager;
import javax.resource.spi.ConnectionRequestInfo;
import org.jvnet.hk2.config.types.Property;


/**
 * Connector connection pool admin service performs the
 * functionality of creation, deletion, recreation, testing of the pools.
 *
 * @author Srikanth P and Aditya Gore
 */

public class ConnectorConnectionPoolAdminServiceImpl extends ConnectorService {

    private static StringManager localStrings =
            StringManager.getManager(ConnectorConnectionPoolAdminServiceImpl.class);

    /**
     * Default constructor
     */
    public ConnectorConnectionPoolAdminServiceImpl() {
        super();

    }

    /**
     * Creates connector connection pool in the connector container.
     *
     * @param ccp     ConnectorConnectionPool instance to be bound to JNDI. This
     *                object contains the pool properties.
     * @param cdd     ConnectorDescriptor obejct which abstracts the ra.xml
     * @param rarName Name of the resource adapter
     * @throws ConnectorRuntimeException When creation of pool fails.
     */
    public void createConnectorConnectionPool(ConnectorConnectionPool ccp,
                                              ConnectionDefDescriptor cdd, String rarName)
            throws ConnectorRuntimeException {

        if ((ccp == null) || (cdd == null) || (rarName == null)) {

            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Wrong parameters for pool creation ");
            }
            String i18nMsg = localStrings.getString("ccp_adm.wrong_params_for_create");
            throw new ConnectorRuntimeException(i18nMsg);
        }
        ConnectorDescriptorInfo cdi = new ConnectorDescriptorInfo();

        ConnectorDescriptor connectorDescriptor = _registry.getDescriptor(rarName);

        if (connectorDescriptor == null) {
            String i18nMsg = localStrings.getString("ccp_adm.no_conn_pool_obj", rarName);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            _logger.log(Level.SEVERE, "rardeployment.connector_descriptor_notfound_registry", rarName);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }
        cdi.setRarName(rarName);
        cdi.setResourceAdapterClassName(
                connectorDescriptor.getResourceAdapterClass());
        cdi.setConnectionDefinitionName(cdd.getConnectionFactoryIntf());
        cdi.setManagedConnectionFactoryClass(
                cdd.getManagedConnectionFactoryImpl());
        cdi.setConnectionFactoryClass(cdd.getConnectionFactoryImpl());
        cdi.setConnectionFactoryInterface(cdd.getConnectionFactoryIntf());
        cdi.setConnectionClass(cdd.getConnectionImpl());
        cdi.setConnectionInterface(cdd.getConnectionIntf());
        cdi.setMCFConfigProperties(cdd.getConfigProperties());
        cdi.setResourceAdapterConfigProperties(
                connectorDescriptor.getConfigProperties());
        createConnectorConnectionPool(ccp, cdi);
    }

    /**
     * Creates connector connection pool in the connector container.
     *
     * @param connectorPoolObj  ConnectorConnectionPool instance to be bound to JNDI. This
     *                          object contains the pool properties.
     * @param connectorDescInfo ConnectorDescriptorInfo object which
     *                          abstracts the connection definition values
     *                          present in ra.xml
     * @throws ConnectorRuntimeException When creation of pool fails.
     */

    private void createConnectorConnectionPool(
            ConnectorConnectionPool connectorPoolObj,
            ConnectorDescriptorInfo connectorDescInfo)
            throws ConnectorRuntimeException {

        connectorPoolObj.setConnectorDescriptorInfo(connectorDescInfo);
        createConnectorConnectionPool(connectorPoolObj);
    }

    /**
     * Creates connector connection pool in the connector container.
     *
     * @param connectorPoolObj ConnectorConnectionPool instance to be bound to JNDI. This
     *                         object contains the pool properties.
     * @throws ConnectorRuntimeException When creation of pool fails.
     */
    public void createConnectorConnectionPool(ConnectorConnectionPool connectorPoolObj)
            throws ConnectorRuntimeException {

        PoolInfo poolInfo = connectorPoolObj.getPoolInfo();
        if (connectorPoolObj == null || poolInfo == null) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Wrong parameters for pool creation ");
            }
            String i18nMsg = localStrings.getString("ccp_adm.wrong_params_for_create");
            throw new ConnectorRuntimeException(i18nMsg);
        }
        String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
        try {

            _runtime.getResourceNamingService().publishObject(poolInfo, jndiNameForPool, connectorPoolObj, true);
            ManagedConnectionFactory mcf = obtainManagedConnectionFactory(poolInfo);
            if (mcf == null) {
                _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
                String i18nMsg = localStrings.getString("ccp_adm.failed_to_create_mcf", poolInfo);
                ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
                _logger.log(Level.SEVERE, "rardeployment.mcf_creation_failure", poolInfo);
                _logger.log(Level.SEVERE, "", cre);
                throw cre;
            }

        } catch (NamingException ex) {

            String i18nMsg = localStrings.getString("ccp_adm.failed_to_publish_in_jndi", poolInfo);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            cre.initCause(ex);
            _logger.log(Level.SEVERE, "rardeployment.pool_jndi_bind_failure", poolInfo);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        } catch (NullPointerException ex) {
            try {
                _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
            } catch (NamingException ne) {
                if(_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Failed to unbind connection pool object  ", poolInfo);
                }
            }

            String i18nMsg = localStrings.getString("ccp_adm.failed_to_register_mcf", poolInfo);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            cre.initCause(ex);
            _logger.log(Level.SEVERE, "rardeployment.mcf_registration_failure", poolInfo);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }
    }

    /**
     * Creates connector connection pool in the connector container.
     * cannot be used for 1.5 rar cases
     *
     * @param connectorPoolObj ConnectorConnectionPool instance to be bound to JNDI. This
     *                         object contains the pool properties.
     * @param security         unused
     * @param configProperties MCF config properties
     * @throws ConnectorRuntimeException When creation of pool fails.
     */
    public void createConnectorConnectionPool(
            ConnectorConnectionPool connectorPoolObj, String security,
            Set configProperties) throws ConnectorRuntimeException {
        if (connectorPoolObj == null || configProperties == null) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Wrong parameters for pool creation ");
            }
            String i18nMsg = localStrings.getString("ccp_adm.wrong_params_for_create");
            throw new ConnectorRuntimeException(i18nMsg);
        }
        PoolInfo poolInfo = connectorPoolObj.getPoolInfo();
        String moduleName =
                connectorPoolObj.getConnectorDescriptorInfo().getRarName();
        String connectionDefinitionName =
                connectorPoolObj.getConnectorDescriptorInfo().
                        getConnectionDefinitionName();

        ConnectorDescriptor connectorDescriptor =
                _registry.getDescriptor(moduleName);

        if (connectorDescriptor == null) {
            String i18nMsg = localStrings.getString("ccp_adm.null_connector_desc", moduleName);
            ConnectorRuntimeException cre = new
                    ConnectorRuntimeException(i18nMsg);
            _logger.log(Level.SEVERE, "rardeployment.null_mcf_in_registry", moduleName);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }

        Set connectionDefs =
                connectorDescriptor.getOutboundResourceAdapter().getConnectionDefs();

        Iterator iterator = connectionDefs.iterator();

        ConnectionDefDescriptor connectionDefDescriptor = null;

        while (iterator.hasNext()) {
            connectionDefDescriptor =
                    (ConnectionDefDescriptor) iterator.next();
            if (connectionDefinitionName.equals(
                    connectionDefDescriptor.getConnectionFactoryIntf()))
                break;
        }

        ConnectorDescriptorInfo connectorDescInfo =
                ConnectorDDTransformUtils.getConnectorDescriptorInfo(
                        connectionDefDescriptor);
        connectorDescInfo.setMCFConfigProperties(configProperties);
        connectorDescInfo.setRarName(moduleName);
        connectorDescInfo.setResourceAdapterClassName(
                connectorDescriptor.getResourceAdapterClass());

        createConnectorConnectionPool(connectorPoolObj, connectorDescInfo);
    }


    /**
     * Deletes connector Connection pool
     *
     * @param poolInfo Name of the pool to delete
     * @throws ConnectorRuntimeException if pool deletion operation fails
     */

    public void deleteConnectorConnectionPool(PoolInfo poolInfo)
            throws ConnectorRuntimeException {
        deleteConnectorConnectionPool(poolInfo, false );
    }

    /**
     * Deletes connector Connection pool. Here check in made whether resources
     * pertaining to pool are present in domain.xml.
     *
     * @param poolInfo Name of the pool to delete
     * @param cascade  If true all the resources associed with that are also
     *                 deleted from connector container
     *                 If false and if some resources pertaining to pool
     *                 are present deletion operation fails . If no resources
     *                 are present pool is deleted.
     * @throws ConnectorRuntimeException if pool deletion operation fails
     */

    public void deleteConnectorConnectionPool(PoolInfo poolInfo, boolean cascade)
            throws ConnectorRuntimeException {

        if (poolInfo == null) {
            _logger.log(Level.WARNING, "ccp_adm.null_pool_name");
            String i18nMsg = localStrings.getString("ccp_adm.null_pool_name");
            throw new ConnectorRuntimeException(i18nMsg);
        }

        boolean errorOccured = false;

        /*  Not needed as --cascade is handled via v3's application life cycle contracts

                ResourcesUtil resUtil = ResourcesUtil.createInstance();
                Object[] connectorResourcesJndiNames =
                                resUtil.getConnectorResourcesJndiNames(poolName);
                if(cascade==true && connectorResourcesJndiNames != null) {
                   for(int i=0;i<connectorResourcesJndiNames.length;++i) {
                       try {
                           getRuntime().deleteConnectorResource(
                                      (String)connectorResourcesJndiNames[i]);
                       } catch(ConnectorRuntimeException cre) {
                         errorOccured=true;
                       }
                   }

                } else if(connectorResourcesJndiNames != null &&
                              connectorResourcesJndiNames.length != 0) {

                }
        */
        killPool(poolInfo);
        boolean result = _registry.removeManagedConnectionFactory(poolInfo);

        if (!result) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "rardeployment.mcf_removal_failure", poolInfo);
            }
            return;
        }

        try {
            //String originalPoolName = ConnectorAdminServiceUtils.getOriginalResourceName(poolName);
            String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
            _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
        } catch (NamingException ne) {
            _logger.log(Level.SEVERE, "rardeployment.connectionpool_removal_from_jndi_error", poolInfo);
            String i18nMsg = localStrings.getString("ccp_adm.failed_to_remove_from_jndi", poolInfo);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            cre.initCause(ne);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }
        if (errorOccured){
            String i18nMsg = localStrings.getString("ccp_adm.failed_to_delete_conn_res", poolInfo);
            ConnectorRuntimeException cre = new
                    ConnectorRuntimeException(i18nMsg);
            _logger.log(Level.SEVERE, "rardeployment.all_resources_removal_error", poolInfo);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }
    }

    /**
     * Kills a specific pool
     *
     * @param poolInfo poolName to kill
     */
    public void killPool(PoolInfo poolInfo) {
        _runtime.getPoolManager().killPool(poolInfo);
    }

    /**
     * Gets the properties of the Java bean connection definition class that
     * have setter methods defined and the default values as provided by the
     * Connection Definition java bean developer.
     *
     * @param connectionDefinitionClassName The Connection Definition Java bean class for which
     *                                      overrideable properties are required.
     * @return Map<String, Object> String represents property name
     *         and Object is the defaultValue that is a primitive type or String
     */
    public static Map<String, Object> getConnectionDefinitionPropertiesAndDefaults(String connectionDefinitionClassName, String resType) {
        return ConnectionDefinitionUtils
                .getConnectionDefinitionPropertiesAndDefaults(
                        connectionDefinitionClassName, resType);
    }

    /**
     * asadmin test-connection-pool
     * This method is used to provide backend functionality for the
     * test-connection-pool asadmin command. Briefly the design is as
     * follows:<br>
     * 1. obtainManagedConnection for the poolname<br>
     * 2. lookup ConnectorDescriptorInfo from InitialContext using poolname<br>
     * 3. from cdi get username and password<br>
     * 4. create ResourcePrincipal using default username and password<br>
     * 5. create a Subject from this (doPriveleged)<br>
     * 6. createManagedConnection using above subject<br>
     * 7. getConnection from the ManagedConnection with above subject<br>
     *
     * @param poolInfo connection-pool name
     * @return true if the connection pool is healthy. false otherwise
     * @throws ResourceException if pool is not usable
     */
    public boolean testConnectionPool(PoolInfo poolInfo)
            throws ResourceException {
        //dump(poolName); //TODO V3 no way to call dump ?
        ManagedConnection con = null;
        try {
            //Create the ManagedConnection
            con = (ManagedConnection) getUnpooledConnection(poolInfo, null, false);
        } catch (Exception re) {
            //Since we have an exception, the pool is not good
            Object params[] = new Object[]{poolInfo, re.getMessage()};
            _logger.log(Level.WARNING, "test.connection.pool.failed", params);
            ResourceException e = new ResourceException("Ping failed Exception - " +
                    re.getMessage() +
                    " Please check the server.log for more details.");
            e.initCause(re);
            throw e;
        } finally {
            try {
                //destroy the MC
                if (con != null) {
                    con.destroy();
                }
            } catch (Throwable e) {
                //ignore
            }
        }

        //We did not get a ResourceException, so pool must be OK
        return true;
    }

    /**
     * Utility method that is used to get the default subject for the 
     * specified mcf and resource principal.
     * @param poolInfo
     * @param mcf
     * @param prin
     * @return
     * @throws javax.resource.ResourceException
     */
    protected Subject getDefaultSubject(PoolInfo poolInfo, ManagedConnectionFactory mcf, 
            ResourcePrincipal prin) throws ResourceException {
        ResourcePrincipal resourcePrincipal = null;
        if (prin == null) {
            try {
                resourcePrincipal = getDefaultResourcePrincipal(poolInfo, mcf);
            } catch (NamingException ne) {
                _logger.log(Level.WARNING, "jdbc.pool_not_reachable",
                        ne.getMessage());
                String l10nMsg = localStrings.getString(
                        "pingpool.name_not_bound", poolInfo);
                ResourceException e = new ResourceException(l10nMsg + poolInfo);
                e.initCause(ne);
                throw e;
            }
        } else {
            resourcePrincipal = prin;
        }

        final Subject defaultSubject =
                ConnectionPoolObjectsUtils.createSubject(mcf, resourcePrincipal);


        if (_logger.isLoggable(Level.FINE)) {
            _logger.fine("using subject: " + defaultSubject);

        }        
        return defaultSubject;
    }

    /**
     * Utility method to get Managed connection from the supplied mcf and 
     * default subject.
     * @param mcf
     * @param defaultSubject
     * @return
     * @throws javax.resource.ResourceException
     */
    protected ManagedConnection getManagedConnection(ManagedConnectionFactory mcf, 
            Subject defaultSubject, ConnectionRequestInfo cReqInfo) throws ResourceException {
        
        ManagedConnection mc = null;
        
        //Create the ManagedConnection
        mc = mcf.createManagedConnection(defaultSubject, cReqInfo);
        return mc;

    }    

/*
    */
/**
     * Utility method to get a managed connection factory for the jdbc connection
     * pool name.
     * @param poolName
     * @return
     * @throws javax.resource.ResourceException
     *//*

    protected ManagedConnectionFactory getManagedConnectionFactory(String poolName) 
            throws ResourceException {
        ManagedConnectionFactory mcf = null;
        try {
            mcf = obtainManagedConnectionFactory(poolName);

        } catch (ConnectorRuntimeException cre) {
            logFine("getUnpooledConnection :: obtainManagedConnectionFactory " +
                    "threw exception. Doing checkAndLoadPoolResource");
            if (checkAndLoadPool(poolName)) {
                logFine("getUnpooledConnection:: checkAndLoadPoolResource is true");
                try {
                    */
/* TODO not needed for non-cluster
                 //deploy the pool resource if not already done
                 //The pool resource would get loaded in case we are in DAS
                 //due to the checkAndLoadPoolResource call
                 //but in EE, if the pool we are trying to access is in a
                 //remote instance, the pool will not have been created
                 if ( ! isConnectorConnectionPoolDeployed( poolName ) ) {
                             logFine("getUnpooledConnection :: " +
                     "isConnectorConnectionPoolDeployed is false");
                     try {
                         jdbcPoolToDeploy = getJdbcConnectionPoolServerBean( poolName );
                     if ( jdbcPoolToDeploy != null ) {
                             (new JdbcConnectionPoolDeployer()).deployResource(
                             jdbcPoolToDeploy );
                                     logFine("getUnpooledConnection :: force deployed the " +
                             "JdbcConnectionPool : " + poolName);
                     } else {
                         ccPoolToDeploy = getConnectorConnectionPoolServerBean(
                         poolName );
                         (new ConnectorConnectionPoolDeployer()).deployResource(
                         ccPoolToDeploy);
                                     logFine("getUnpooledConnection :: force deployed the " +
                             "ConnectorConnectionPool :" + poolName);
                     }
                     needToUndeployPool = true;
                     } catch(Exception e ) {
                         _logger.log( Level.SEVERE,
                             "jdbc.could_not_do_actual_deploy for : ", poolName );
                         throw new ResourceException( e );
                     }
                 }*//*

                    logFine("getUnpooledConnection :: " +
                            "Now calling obtainManagedConnectionFactory again");
                    mcf = obtainManagedConnectionFactory(poolName);
                    logFine("getUnpooledConnection:: " +
                            "done obtainManagedConnectionFactory again");
                } catch (ConnectorRuntimeException creAgain) {
                    String l10nMsg = localStrings.getString(
                            "pingpool.cannot_obtain_mcf", poolName);
                    _logger.log(Level.WARNING, "jdbc.pool_not_reachable",
                            l10nMsg);
                    ResourceException e = new ResourceException(l10nMsg);
                    e.initCause(creAgain);
                    throw e;
                }
            } else {
                _logger.log(Level.WARNING, "jdbc.pool_not_reachable",
                        cre.getMessage());
                String l10nMsg = localStrings.getString(
                        "pingpool.cannot_obtain_mcf", poolName);
                ResourceException e = new ResourceException(l10nMsg);
                e.initCause(cre);
                throw e;

            }
        }
        return mcf;
    }
*/

    /**
     * This method is used to provide backend functionality for the
     * ping-connection-pool asadmin command. Briefly the design is as
     * follows:<br>
     * 1. obtainManagedConnectionFactory for the poolname<br>
     * 2. lookup ConnectorDescriptorInfo from InitialContext using poolname<br>
     * 3. from cdi get username and password<br>
     * 4. create ResourcePrincipal using default username and password<br>
     * 5. create a Subject from this (doPriveleged)<br>
     * 6. createManagedConnection using above subject<br>
     * 7. add a dummy ConnectionEventListener to the mc that simply handles connectionClosed
     * 8. getConnection from the ManagedConnection with above subject<br>
     *
     * @param poolInfo               The poolname from whose MCF to obtain the unpooled mc
     * @param principal                   The ResourcePrincipal to use for authenticating the request if not null.
     *                               If null, the pool's default authentication mechanism is used
     * @param returnConnectionHandle If true will return the logical connection handle
     *                               derived from the Managed Connection, else will only return mc
     * @return an unPooled connection
     * @throws ResourceException for various error conditions
     */
    public Object getUnpooledConnection(PoolInfo poolInfo, ResourcePrincipal principal, boolean returnConnectionHandle)
            throws ResourceException {
        ManagedConnectionFactory mcf = null;
        ResourcePool poolToDeploy = null;
        boolean needToUndeployPool = false;
        ConnectorRuntime runtime = ConnectorRuntime.getRuntime();

        try {
            //START CR 6597868
            if (!isPoolReferredByResource(poolInfo)) {
                if (_registry.isMCFCreated(poolInfo)){
                    unloadAndKillPool(poolInfo);
                }
            }
            //END CR 6597868
            mcf = obtainManagedConnectionFactory(poolInfo, new Hashtable());
        } catch (ConnectorRuntimeException re) {
            logFine("getUnpooledConnection :: obtainManagedConnectionFactory " +
                    "threw exception. So doing checkAndLoadPoolResource");
            if (checkAndLoadPool(poolInfo)) {
                logFine("getUnpooledConnection:: checkAndLoadPoolResource is true");
                try {

                    //deploy the pool resource if not already done
                    //The pool resource would get loaded in case we are in DAS
                    //due to the checkAndLoadPoolResource call
                    //but in EE, if the pool we are trying to access is in a
                    //remote instance, the pool will not have been created
                    if (!isConnectorConnectionPoolDeployed(poolInfo)) {
                        logFine("getUnpooledConnection :: isConnectorConnectionPoolDeployed is false");
                        try {
                            poolToDeploy = (ResourcePool)
                                    runtime.getResources(poolInfo).getResourceByName(ResourcePool.class, poolInfo.getName());
                            runtime.getResourceDeployer(poolToDeploy).deployResource(poolToDeploy);
                            logFine("getUnpooledConnection :: force deployed the ConnectionPool : " + poolInfo);
                            needToUndeployPool = true;
                        } catch (Exception e) {
                            _logger.log(Level.SEVERE, "jdbc.could_not_do_actual_deploy for : ", poolInfo);
                            throw new ResourceException(e);
                        }
                    }
                    logFine("getUnpooledConnection :: Now calling obtainManagedConnectionFactory again");
                    mcf = obtainManagedConnectionFactory(poolInfo);
                    logFine("getUnpooledConnection:: done obtainManagedConnectionFactory again");

                } catch (ConnectorRuntimeException creAgain) {
                    String l10nMsg = localStrings.getString(
                            "pingpool.cannot_obtain_mcf", poolInfo);
                    _logger.log(Level.WARNING, "jdbc.pool_not_reachable", l10nMsg);
                    ResourceException e = new ResourceException(l10nMsg);
                    e.initCause(creAgain);
                    throw e;
                }
            } else {
                _logger.log(Level.WARNING, "jdbc.pool_not_reachable", re.getMessage());
                String l10nMsg = localStrings.getString("pingpool.cannot_obtain_mcf", poolInfo);
                ResourceException e = new ResourceException(l10nMsg);
                e.initCause(re);
                throw e;
            }
        }

        ResourcePrincipal resourcePrincipal = null;
        if (principal == null) {
            try {
                resourcePrincipal = getDefaultResourcePrincipal(poolInfo, mcf);
            } catch (NamingException ne) {
                _logger.log(Level.WARNING, "jdbc.pool_not_reachable", ne.getMessage());
                String l10nMsg = localStrings.getString("pingpool.name_not_bound", poolInfo);
                ResourceException e = new ResourceException(l10nMsg + poolInfo);
                e.initCause(ne);
                throw e;
            }
        } else {
            resourcePrincipal = principal;
        }

        final Subject defaultSubject = ConnectionPoolObjectsUtils.createSubject(mcf, resourcePrincipal);

        if (_logger.isLoggable(Level.FINE)) {
            _logger.fine("using subject: " + defaultSubject);
        }

        //Create the ManagedConnection
        ManagedConnection mc = mcf.createManagedConnection(defaultSubject, null);
        //We are done with the pool for now, so undeploy if we deployed
        //it here
        if (needToUndeployPool) {
            if (poolToDeploy != null) {
                logFine("getUnpooledConnection :: need to force undeploy pool");
                try {
                    runtime.getResourceDeployer(poolToDeploy).undeployResource(poolToDeploy);
                } catch (Exception e) {
                    if(_logger.isLoggable(Level.FINE)) {
                        _logger.fine("getUnpooledConnection: error undeploying pool");
                    }
                }
                logFine("getUnpooledConnection :: done.. force undeploy of pool");
            }
        }
        //Add our dummy ConnectionEventListener impl.
        //This impl only knows how to handle connectionClosed events
        mc.addConnectionEventListener(new UnpooledConnectionEventListener());
        return returnConnectionHandle ? mc.getConnection(defaultSubject, null) : mc;
    }

    //START CR 6597868
    /** This method is used to find out if pool is linked to data-source or not
      * if pool is not linked then ping will not take changes to pool
      * dynamically.
      * @param poolInfo pool-name
      * @return boolean indicating whether the pool is referred or not
      */
    private boolean isPoolReferredByResource(PoolInfo poolInfo){
        ResourcesUtil resUtil = ResourcesUtil.createInstance();
        return (resUtil.isPoolReferredInServerInstance(poolInfo) || resUtil.isJdbcPoolReferredInServerInstance(poolInfo));
    }
    //END CR 6597868


    /**
     * Utility method to get property value from ConnectorDescriptorInfo.
     * @param prop
     * @return
     */
    protected String getPropertyValue(String prop, 
            ConnectorConnectionPool connectorConnectionPool) {
        String result = null;
        ConnectorDescriptorInfo cdi = connectorConnectionPool.getConnectorDescriptorInfo();

        Set mcfConfigProperties = cdi.getMCFConfigProperties();
        Iterator mcfConfPropsIter = mcfConfigProperties.iterator();
        while (mcfConfPropsIter.hasNext()) {
            ConnectorConfigProperty  envProp = (ConnectorConfigProperty ) mcfConfPropsIter.next();

            if (envProp.getName().toUpperCase().equals(prop)) {
                result = envProp.getValue();
            } 
        }
        return result;
    }

    private ResourcePrincipal getDefaultResourcePrincipal( PoolInfo poolInfo,
        ManagedConnectionFactory mcf ) throws NamingException {
        return getDefaultResourcePrincipal(poolInfo, mcf, null);
    }
    
    /*
    * Returns a ResourcePrincipal object populated with a pool's
    * default USERNAME and PASSWORD
    *
    * @throws NamingException if poolname lookup fails
    */
    private ResourcePrincipal getDefaultResourcePrincipal(PoolInfo poolInfo,
                                                          ManagedConnectionFactory mcf, Hashtable env)
            throws NamingException {
        String userName = null;
        String password = null;
        // All this to get the default user name and principal
        ConnectorConnectionPool connectorConnectionPool = null;
        try {
            String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
            connectorConnectionPool = (ConnectorConnectionPool)
                    _runtime.getResourceNamingService().lookup(poolInfo, jndiNameForPool, env);
        } catch (NamingException ne) {
            throw ne;
        }

        userName = getPropertyValue("USERNAME", connectorConnectionPool);
        if(userName == null) {
            userName = getPropertyValue("USER", connectorConnectionPool);
        }
        password = getPropertyValue("PASSWORD", connectorConnectionPool);
        try {
            password = RelativePathResolver.getRealPasswordFromAlias(password);
        } catch(Exception e) {
            _logger.log(Level.WARNING, "unable_to_get_password_from_alias", e);
        }

        // To avoid using "", "" as the default username password, try to get
        // the username and password from MCF, to use in subject. MQ adapter
        // cannot use "","" as the username/password.

        if (userName == null || userName.trim().equals("")) {
            userName = ConnectionPoolObjectsUtils.getValueFromMCF("UserName", poolInfo, mcf);
            //It is possible that ResourceAdapter may have getUser() instead of
            //getUserName() property getter
            if (userName.trim().equals("")) {
                userName = ConnectionPoolObjectsUtils.getValueFromMCF("User", poolInfo, mcf);
            }
            password = ConnectionPoolObjectsUtils.getValueFromMCF("Password", poolInfo, mcf);
        }
        //Now return the ResourcePrincipal
        return new ResourcePrincipal(userName, password);
    }

    /**
     * Rebinds the connection pool with matchning flag set.
     *
     * @param poolInfo pool for which matching need to be switched on
     * @throws ConnectorRuntimeException , if a Naming error occurs.
     */
    public void switchOnMatching(PoolInfo poolInfo) throws ConnectorRuntimeException {
        try {
            ConnectorConnectionPool origCcp =
                    getOriginalConnectorConnectionPool(poolInfo);
            origCcp.setMatchConnections(true);

            //now rebind the object in jndi
            String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);


            _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
            _runtime.getResourceNamingService().publishObject(poolInfo, jndiNameForPool, origCcp, true);
        } catch (NamingException e) {
            ConnectorRuntimeException ex =
                    new ConnectorRuntimeException(e.getMessage());
            throw(ConnectorRuntimeException) ex.initCause(e);
        }
    }

   /**
    * Create a ConnectorConnectionPool from information in memory
    */
    private ConnectorConnectionPool getOriginalConnectorConnectionPool(
            PoolInfo poolInfo) throws NamingException {

        ConnectorConnectionPool ccpOrig = null;

        String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
        try {
            ccpOrig = (ConnectorConnectionPool)_runtime.getResourceNamingService().lookup(poolInfo, jndiNameForPool);
        } catch (NamingException ne) {
                throw ne;
        }
        return ccpOrig;
    }

    private ConnectorConnectionPool getConnectorConnectionPool(PoolInfo poolInfo)
        throws ConnectorRuntimeException, NamingException  {
        return getConnectorConnectionPool(poolInfo, null);
    }
    
    /**
     * Returns the connector connection pool object corresponding
     * to the pool name
     *
     * @param poolInfo Name of the pool.MCF pertaining to this pool is
     *                 created/returned.
     * @return Connector connection pool corresponding to this instance
     * @throws ConnectorRuntimeException if creation/retrieval
     *                                   of MCF fails
     */
    private ConnectorConnectionPool getConnectorConnectionPool(PoolInfo poolInfo, Hashtable env)
            throws ConnectorRuntimeException, NamingException {
        String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);

        ConnectorConnectionPool connectorConnectionPool = (ConnectorConnectionPool)
                _runtime.getResourceNamingService().lookup(poolInfo, jndiNameForPool, env);
        if (connectorConnectionPool == null) {
            String i18nMsg = localStrings.getString("ccp_adm.null_pool", poolInfo);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            _logger.log(Level.SEVERE, "rardeployment.connectionpool_object_null", poolInfo);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }
        return connectorConnectionPool;
    }

    /**
     * Returns the resource adapter object corresponding
     * to the pool
     *
     * @param connectorConnectionPool Name of the pool.
     *                                MCF pertaining to this pool is
     *                                created/returned.
     * @return Resource adapter instance corresponding to this pool.
     * @throws ConnectorRuntimeException if creation/retrieval
     *                                   of RA fails
     */
    private ActiveResourceAdapter getResourceAdapter(ConnectorConnectionPool connectorConnectionPool)
            throws ConnectorRuntimeException {

        String rarName = connectorConnectionPool.getConnectorDescriptorInfo().getRarName();
        ActiveResourceAdapter activeResourceAdapter = getActiveResourceAdapter(rarName);
        if (activeResourceAdapter == null) {
            String i18nMsg = localStrings.getString("ccp_adm.active_ra_not_init", rarName);

            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            _logger.log(Level.SEVERE, "rardeployment.resourceadapter_not_initialized", rarName);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }
        return activeResourceAdapter;
    }

    private ActiveResourceAdapter getActiveResourceAdapter(String rarName)
            throws ConnectorRuntimeException {
        ActiveResourceAdapter activeResourceAdapter = _registry.getActiveResourceAdapter(rarName);
        //we dont need this check for normal resources of domain.xml config, but datasource-definition needs it.
        if (activeResourceAdapter == null) {
            ifSystemRarLoad(rarName);
            activeResourceAdapter = _registry.getActiveResourceAdapter(rarName);
        }
        return activeResourceAdapter;
    }

    /** Returns the MCF instances.
     *  @param poolInfo Name of the pool.MCF pertaining to this pool is
     *         created/returned.
     *  @return created/already present MCF instance
     *  @throws ConnectorRuntimeException if creation/retrieval of MCF fails
     */
    public ManagedConnectionFactory[] obtainManagedConnectionFactories(
           PoolInfo poolInfo) throws ConnectorRuntimeException {
	ManagedConnectionFactory[] mcfs = null;
        String raName = null;
        try {
		ConnectorConnectionPool conPool =
				getConnectorConnectionPool(poolInfo);
		ActiveResourceAdapter activeResourceAdapter =
					getResourceAdapter(conPool);
            raName = activeResourceAdapter.getModuleName();
                mcfs =
                     activeResourceAdapter.
                        createManagedConnectionFactories
                                (conPool, null);
        } catch(NamingException ne) {
            String i18nMsg = localStrings.getString(
                "pingpool.name_not_bound", poolInfo);
            ConnectorRuntimeException cre = new
                ConnectorRuntimeException( i18nMsg);
            cre.initCause(ne);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "rardeployment.jndi_lookup_failed",
                        poolInfo);
                _logger.log(Level.FINE, "", cre);
            }
            //_logger.log(Level.SEVERE,"",cre);
            throw cre;
        }
        catch(NullPointerException ne) {
            String i18nMsg = localStrings.getString(
                "ccp_adm.failed_to_register_mcf", poolInfo);
            ConnectorRuntimeException cre = new
                ConnectorRuntimeException( i18nMsg );
            cre.initCause(ne);
            _logger.log(Level.SEVERE,"mcf_add_toregistry_failed",poolInfo);
            if (_logger.isLoggable( Level.FINE ) ) {
                _logger.log(Level.FINE,"",cre);
            }
            //_logger.log(Level.SEVERE,"",cre);
            throw cre;
        }
        for(ManagedConnectionFactory mcf : mcfs){
            validateMCF(mcf, raName);
        }
	return mcfs;
    }

    private void validateMCF(ManagedConnectionFactory mcf, String raName) {
        _runtime.getConnectorBeanValidator().validateJavaBean(mcf, raName);
    }


    public ManagedConnectionFactory obtainManagedConnectionFactory(PoolInfo poolInfo) throws ConnectorRuntimeException{
        return obtainManagedConnectionFactory(poolInfo, null);
    }
    
    /**
     * Returns the MCF instance. If the MCF is already created and
     * present in connectorRegistry that instance is returned. Otherwise it
     * is created explicitly and added to ConnectorRegistry.
     *
     * @param poolInfo Name of the pool.MCF pertaining to this pool is
     *                 created/returned.
     * @return created/already present MCF instance
     * @throws ConnectorRuntimeException if creation/retrieval of MCF fails
     */
    public ManagedConnectionFactory obtainManagedConnectionFactory(PoolInfo poolInfo, Hashtable env)
            throws ConnectorRuntimeException {
        try {
            if (_registry.isMCFCreated(poolInfo)) {
                return _registry.getManagedConnectionFactory(poolInfo);
            } else {

                ConnectorConnectionPool connectorConnectionPool = getConnectorConnectionPool(poolInfo, env);
                ActiveResourceAdapter activeResourceAdapter = getResourceAdapter(connectorConnectionPool);
                ClassLoader loader = activeResourceAdapter.getClassLoader();
                ManagedConnectionFactory mcf = activeResourceAdapter.
                        createManagedConnectionFactory(connectorConnectionPool, loader);
                if (mcf != null) {
                    //validate MCF before it is used or related pooling infrastructure is created.
                    validateMCF(mcf, activeResourceAdapter.getModuleName());

                    ResourcePrincipal prin =
                            getDefaultResourcePrincipal(poolInfo, mcf, env);
                    Subject s = ConnectionPoolObjectsUtils.createSubject(mcf, prin);
                    int txSupport = connectorConnectionPool.getTransactionSupport();

                    //JSR-322 : check the runtime transaction level support of MCF and use appropriately.
                    if (mcf instanceof javax.resource.spi.TransactionSupport) {
                        TransactionSupport.TransactionSupportLevel mcfTS =
                                ((javax.resource.spi.TransactionSupport) mcf).getTransactionSupport();

                        int containerTxSupport = ConnectionPoolObjectsUtils.convertSpecTxSupportToContainerTxSupport(mcfTS);
                        boolean isValidTxSupportLevel = ConnectionPoolObjectsUtils.isTxSupportConfigurationSane(
                                containerTxSupport, activeResourceAdapter.getModuleName());

                        if (isValidTxSupportLevel) {
                            txSupport = containerTxSupport;
                        } else {

                            Object params[] = { mcfTS, activeResourceAdapter.getModuleName() };
                            String i18nMsg = localStrings.getString("ccp_adm_service.incorrect_tx_support", params);
                            ConnectorRuntimeException cre = new
                                    ConnectorRuntimeException(i18nMsg);
                            _logger.log(Level.SEVERE, "rardeployment.incorrect_tx_support",
                                    connectorConnectionPool.getName());
                            throw cre;
                        }
                    }

                    boolean isPM = connectorConnectionPool.isNonComponent();
                    boolean isNonTx = connectorConnectionPool.isNonTransactional();
                    ConnectorSecurityMap[] securityMaps =
                            connectorConnectionPool.getSecurityMaps();
                    RuntimeSecurityMap runtimeSecurityMap =
                            SecurityMapUtils.processSecurityMaps(securityMaps);
                    boolean lazyEnlistable = connectorConnectionPool.isLazyConnectionEnlist();
                    boolean lazyAssoc = connectorConnectionPool.isLazyConnectionAssoc();

                    if (isPM || isNonTx) {
                        /*
                        We should not do lazyEnlistment if we are an __pm
                        resource since we won't have an InvocationContext and
                        the lazy enlistment depends upon an InvocationContext
                        For a nonTx resource enlistment (lazy or otherwise)
                        doesn't come into the picture at all
                        */
                        lazyEnlistable = false;
                    }

                    if (isPM) {
                        //We need to switch off lazy association here because of
                        //the way our Persistence layer behaves. Adding a system
                        //property here to allow other persistence layers to use
                        //lazy association with PM resources
                        if (lazyAssoc) {
                            String str = System.getProperty(
                                    "com.sun.enterprise.resource.AllowLazyAssociationWithPM", "FALSE");
                            if (str.toUpperCase().trim().equals("FALSE")) {
                                lazyAssoc = false;
                            }
                        }
                    }

                    PoolMetaData pmd = new PoolMetaData(poolInfo, mcf, s, txSupport, prin,
                            isPM, isNonTx, lazyEnlistable, runtimeSecurityMap, lazyAssoc);
                    logFine(pmd.toString());
                    _registry.addManagedConnectionFactory(poolInfo, pmd);
                }

                PoolType pt = getPoolType(connectorConnectionPool);

                createAndAddPool(poolInfo, pt, env);
                return mcf;
            }
        } catch (NamingException ne) {
            String i18nMsg = localStrings.getString("pingpool.name_not_bound", poolInfo);
            ConnectorRuntimeException cre = new
                    ConnectorRuntimeException(i18nMsg);
            cre.initCause(ne);
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "rardeployment.jndi_lookup_failed", poolInfo);
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }
        catch (NullPointerException ne) {
            String i18nMsg = localStrings.getString("ccp_adm.failed_to_register_mcf", poolInfo);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            cre.initCause(ne);
            _logger.log(Level.SEVERE, "mcf_add_toregistry_failed", poolInfo);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }
    }


    private PoolType getPoolType(ConnectorConnectionPool connectorConnectionPool) {
        PoolType pt = PoolType.STANDARD_POOL;
        if (!connectorConnectionPool.isPoolingOn()) {
            pt = PoolType.POOLING_DISABLED;
        } else if (connectorConnectionPool.isAssociateWithThread()) {
            pt = PoolType.ASSOCIATE_WITH_THREAD_POOL;
        } else if (connectorConnectionPool.isPartitionedPool()) {
            pt = PoolType.PARTITIONED_POOL;
        }
        return pt;
    }

    public PoolType getPoolType(PoolInfo poolInfo) throws ConnectorRuntimeException {
        ConnectorConnectionPool ccp;
        try {
            ccp = getConnectorConnectionPool(poolInfo);
        } catch (NamingException e) {
            ConnectorRuntimeException cre = new ConnectorRuntimeException(e.getMessage());
            cre.initCause(e);
            throw cre;
        }
        return getPoolType(ccp);
    }


    private void logFine(String msg) {
        if (msg != null) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine(msg);
            }
        }
    }

    /**
     * create an empty connection pool
     *
     * @param poolInfo pool to be created
     * @param pt       type of pool
     * @throws ConnectorRuntimeException
     */
    private void createAndAddPool(PoolInfo poolInfo, PoolType pt, Hashtable env) throws ConnectorRuntimeException {
        PoolManager poolMgr = _runtime.getPoolManager();
        try {
            poolMgr.createEmptyConnectionPool(poolInfo, pt, env);
        } catch (PoolingException pe) {
            String i18nMsg = localStrings.getString("ccp_adm.failed_to_create_pool_object");
            ConnectorRuntimeException cre = new ConnectorRuntimeException(i18nMsg);
            cre.initCause(pe);
            throw cre;
        }
    }

    /**
     * Checks if a conncetor connection pool has been deployed to this server
     * instance
     *
     * @param poolInfo
     * @return
     */
    public boolean isConnectorConnectionPoolDeployed(PoolInfo poolInfo) {
        try {
            String jndiName = ConnectorAdminServiceUtils.
                    getReservePrefixedJNDINameForPool(poolInfo);
            _runtime.getResourceNamingService().lookup(poolInfo, jndiName);
            return true;
        } catch (NamingException e) {
            return false;
        }
    }

    /**
     * Reconfigure a connection pool.
     * This method compares the passed connector connection pool with the one
     * in memory. If the pools are unequal and the MCF properties are changed
     * a pool recreate is required. However if the pools are unequal and the
     * MCF properties are not changed a recreate is not required
     *
     * @param ccp           - the Updated connector connection pool object that admin
     *                      hands over
     * @param excludedProps - A set of excluded property names that we want
     *                      to be excluded in the comparison check while
     *                      comparing MCF properties
     * @return true - if a pool restart is required, false otherwise
     * @throws ConnectorRuntimeException
     */
    public boolean reconfigureConnectorConnectionPool(ConnectorConnectionPool
            ccp, Set excludedProps) throws ConnectorRuntimeException {
        if (ccp == null) {
            throw new ConnectorRuntimeException("No pool to reconfigure, new pool object is null");
        }
        logFine("new ccp :\n" + ccp.toString());

        //see if the new ConnectorConnectionPool is different from
        //the original one and update relevant properties
        PoolInfo poolInfo = ccp.getPoolInfo();
        ConnectorConnectionPool origCcp = null;
        try {
            origCcp = getOriginalConnectorConnectionPool(poolInfo);
        } catch (NamingException ne) {
            throw new ConnectorRuntimeException(ne.getMessage());
        }

        if (origCcp == null) {
            throw new ConnectorRuntimeException("No pool to reconfigure, original pool object is null");
        }
        logFine("original ccp :\n" + origCcp.toString());

        ConnectionPoolReconfigHelper.ReconfigAction action = ConnectionPoolReconfigHelper.compare(origCcp, ccp,
                excludedProps);
        logFine("pool reconfig action == " + action);
        if (action == ConnectionPoolReconfigHelper.ReconfigAction.UPDATE_MCF_AND_ATTRIBUTES) {
            updateMCFAndPoolAttributes(ccp);
        } else if (action == ConnectionPoolReconfigHelper.ReconfigAction.RECREATE_POOL) {
            return true;
        }

        return false;
    }

    private void updateMCFAndPoolAttributes(ConnectorConnectionPool
            ccp) throws ConnectorRuntimeException {
        PoolInfo poolInfo = ccp.getPoolInfo();
        try {
            ConnectorConnectionPool origCcp =
                    getOriginalConnectorConnectionPool(poolInfo);

            //update properties
            origCcp.setSteadyPoolSize(ccp.getSteadyPoolSize());
            origCcp.setMaxPoolSize(ccp.getMaxPoolSize());
            origCcp.setMaxWaitTimeInMillis(ccp.getMaxWaitTimeInMillis());
            origCcp.setPoolResizeQuantity(ccp.getPoolResizeQuantity());
            origCcp.setIdleTimeoutInSeconds(ccp.getIdleTimeoutInSeconds());
            origCcp.setFailAllConnections(ccp.isFailAllConnections());

            //lazyEnlist, lazyAssoc and assocWithThread not required since they result
            //in a pool restart anyways, so they wouldn't have changed if we
            //came here
            origCcp.setMatchConnections(ccp.matchConnections());
            origCcp.setMaxConnectionUsage(ccp.getMaxConnectionUsage());
            origCcp.setNonComponent(ccp.isNonComponent());
            origCcp.setNonTransactional(ccp.isNonTransactional());
            origCcp.setConCreationRetryAttempts(ccp.getConCreationRetryAttempts());
            origCcp.setConCreationRetryInterval
                    (ccp.getConCreationRetryInterval());
            origCcp.setValidateAtmostOncePeriod(ccp.getValidateAtmostOncePeriod());
            origCcp.setConnectionLeakTracingTimeout(ccp.getConnectionLeakTracingTimeout());
            origCcp.setConnectionReclaim(ccp.isConnectionReclaim());

            //now rebind the object in jndi
            String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
            _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
            _runtime.getResourceNamingService().publishObject(poolInfo, jndiNameForPool, origCcp, true);


        } catch (NamingException ne) {
            throw new ConnectorRuntimeException(ne.getMessage());
        }

        //Check if this pool has been brought into memory
        //If its already in memory, just call reconfig on it

        PoolManager poolMgr = _runtime.getPoolManager();
        try {
            poolMgr.reconfigPoolProperties(ccp);
        } catch (PoolingException pe) {
            throw new ConnectorRuntimeException(pe.getMessage());
        }
        //Run setXXX methods on the copy of the MCF that we have
        //this is done to update the MCF to reflect changes in the
        //MCF properties for which we don't really need to recreate
        //the pool
        ConnectorRegistry registry = ConnectorRegistry.getInstance();
        ManagedConnectionFactory mcf = registry.getManagedConnectionFactory(
                poolInfo);
        SetMethodAction sma = new SetMethodAction(mcf,
                ccp.getConnectorDescriptorInfo().getMCFConfigProperties());
        try {
            sma.run();
        } catch (Exception e) {
            _logger.log(Level.WARNING, e.getMessage());
            ConnectorRuntimeException cre = new ConnectorRuntimeException(e.getMessage());
            cre.initCause(e);
            throw cre;
        }

        //update the properties "allow-non-component-callers" and
        //"non-transactional-connections" in the PoolMetaData
        PoolMetaData pmd = registry.getPoolMetaData(poolInfo);
        pmd.setIsPM(ccp.isNonComponent());
        pmd.setIsNonTx(ccp.isNonTransactional());
        pmd.setAuthCredentialsDefinedInPool(ccp.getAuthCredentialsDefinedInPool());

        logFine("Pool properties reconfiguration done");
    }

    /**
     * Recreate a connector connection pool. This method essentially does
     * the following things:
     * 1. Delete the said connector connection pool<br>
     * 2. Bind the pool to JNDI<br>
     * 3. Create an MCF for this pool and register with the connector registry<br>
     *
     * @param ccp - the ConnectorConnectionPool to publish
     */
    public void recreateConnectorConnectionPool(ConnectorConnectionPool ccp)
            throws ConnectorRuntimeException {
        ConnectorRegistry registry = ConnectorRegistry.getInstance();
        if (registry == null) {
            throw new ConnectorRuntimeException(
                    "Cannot get ConnectorRegistry");
        }
        PoolInfo poolInfo = ccp.getPoolInfo();
        //First remove this pool from memory
        try {
            unloadAndKillPool(poolInfo);
        } catch (ConnectorRuntimeException cre) {
            throw cre;
        }
        //kill the pool
        //FIXME: deleteConnectorConnectionPool should do this
        //PoolManager poolManager = Switch.getSwitch().getPoolManager();
        //poolManager.killPool( poolName );

        //Now bind the updated pool and
        //obtain a new managed connection factory for this pool

        String jndiNameForPool = ConnectorAdminServiceUtils.
                getReservePrefixedJNDINameForPool(poolInfo);
        ManagedConnectionFactory mcf = null;
        try {
            _runtime.getResourceNamingService().publishObject(poolInfo, jndiNameForPool, ccp, true);
            mcf = obtainManagedConnectionFactory(poolInfo);

        } catch (NamingException ne) {
            _logger.log(Level.SEVERE,
                    "rardeployment.pool_jndi_bind_failure", poolInfo);
            String i18nMsg = localStrings.getString(
                    "ccp_adm.could_not_recreate_pool", poolInfo);
            ConnectorRuntimeException crex = new ConnectorRuntimeException(i18nMsg);
            crex.initCause(ne);
            throw crex;
        } finally{
            if (mcf == null) {
                try{
                    _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
                }catch(NamingException e){
                    _logger.log(Level.WARNING,"Unable to unbind the pool configuration object " +
                            "of pool [ "+ poolInfo +" ] during MCF creation failure");
                }
                _logger.log(Level.WARNING, "rardeployment.mcf_creation_failure", poolInfo);

                String i18nMsg = localStrings.getString(
                        "ccp_adm.failed_to_create_mcf", poolInfo);
                throw new ConnectorRuntimeException(i18nMsg);
            }
        }

    }

    /**
     * unloads and kills the connector Connection pool without checking for
     * resources in domain.xml.
     *
     * @param poolInfo Name of the pool to delete
     * @throws ConnectorRuntimeException if pool unload or kill operation fails
     */

    private void unloadAndKillPool(PoolInfo poolInfo)
            throws ConnectorRuntimeException {

        killPool(poolInfo);
        boolean result = _registry.removeManagedConnectionFactory(poolInfo);
        if (result == false) {
            _logger.log(Level.SEVERE,
                    "rardeployment.mcf_removal_failure", poolInfo);
            String i18nMsg = localStrings.getString(
                    "ccp_adm.wrong_params_for_create", poolInfo);
            ConnectorRuntimeException cre = new
                    ConnectorRuntimeException(i18nMsg);
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }
        try {
            String jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
            _runtime.getResourceNamingService().unpublishObject(poolInfo, jndiNameForPool);
        } catch (NamingException ne) {
            String i18nMsg = localStrings.getString(
                    "ccp_adm.failed_to_remove_from_jndi", poolInfo);
            ConnectorRuntimeException cre = new
                    ConnectorRuntimeException(i18nMsg);
            cre.initCause(ne);
            _logger.log(Level.SEVERE,
                    "rardeployment.connectionpool_removal_from_jndi_error",
                    poolInfo);
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "", cre);
            }
            throw cre;
        }

    }

    /**
     * Creates connector connection pool in the connector container.
     *
     * @param ccp                      ConnectorConnectionPool instance to be bound to JNDI. This
     *                                 object contains the pool properties.
     * @param connectionDefinitionName Connection definition name against which
     *                                 connection pool is being created
     * @param rarName                  Name of the resource adapter
     * @param props                    Properties of MCF which are present in domain.xml
     *                                 These properties override the ones present in ra.xml
     * @param securityMaps             Array fo security maps.
     * @throws ConnectorRuntimeException When creation of pool fails.
     */

    public void createConnectorConnectionPool(ConnectorConnectionPool ccp,
                                              String connectionDefinitionName, String rarName,
                                              List<Property> props, List securityMaps)
            throws ConnectorRuntimeException {

        if ((ccp == null) || (connectionDefinitionName == null)
                || (rarName == null)) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Wrong parameters for pool creation ");
            }
            String i18nMsg = localStrings.getString(
                    "ccp_adm.wrong_params_for_create");
            throw new ConnectorRuntimeException(i18nMsg);
        }

        ConnectorDescriptor connectorDescriptor =
                _registry.getDescriptor(rarName);
        if(connectorDescriptor == null){
            connectorDescriptor = _runtime.getConnectorDescriptor(rarName);
        }
        if (connectorDescriptor == null) {
            String i18nMsg = localStrings.getString(
                    "ccp_adm.no_conn_pool_obj", rarName);
            ConnectorRuntimeException cre = new ConnectorRuntimeException(
                    i18nMsg);
            _logger.log(Level.SEVERE,
                    "rardeployment.connector_descriptor_notfound_registry", rarName);
            _logger.log(Level.SEVERE, "", cre);
            throw cre;
        }

        Set connectionDefs =
                connectorDescriptor.getOutboundResourceAdapter().getConnectionDefs();
        ConnectionDefDescriptor cdd = null;
        Iterator it = connectionDefs.iterator();
        while (it.hasNext()) {
            cdd = (ConnectionDefDescriptor) it.next();
            if (connectionDefinitionName.equals(cdd.getConnectionFactoryIntf()))
                break;

        }
        ConnectorDescriptorInfo cdi = new ConnectorDescriptorInfo();

        cdi.setRarName(rarName);
        cdi.setResourceAdapterClassName(
                connectorDescriptor.getResourceAdapterClass());
        cdi.setConnectionDefinitionName(cdd.getConnectionFactoryIntf());
        cdi.setManagedConnectionFactoryClass(
                cdd.getManagedConnectionFactoryImpl());
        cdi.setConnectionFactoryClass(cdd.getConnectionFactoryImpl());
        cdi.setConnectionFactoryInterface(cdd.getConnectionFactoryIntf());
        cdi.setConnectionClass(cdd.getConnectionImpl());
        cdi.setConnectionInterface(cdd.getConnectionIntf());
        Set mergedProps = ConnectorDDTransformUtils.mergeProps(props, cdd.getConfigProperties());
        cdi.setMCFConfigProperties(mergedProps);
        cdi.setResourceAdapterConfigProperties(
                connectorDescriptor.getConfigProperties());
        ccp.setSecurityMaps(SecurityMapUtils.getConnectorSecurityMaps(securityMaps));
        createConnectorConnectionPool(ccp, cdi);
    }
    
    /**
     * Flush Connection pool by reinitializing the connections 
     * established in the pool.
     * @param poolInfo
     * @throws com.sun.appserv.connectors.internal.api.ConnectorRuntimeException
     */
    public boolean flushConnectionPool(PoolInfo poolInfo) throws ConnectorRuntimeException {
        PoolManager poolMgr = _runtime.getPoolManager();
        try {
            return poolMgr.flushConnectionPool( poolInfo );
        } catch (PoolingException ex) {
            throw new ConnectorRuntimeException(ex.getMessage());
        }
    }

    /**
     * Get a sql connection from the DataSource specified by the jdbcJndiName.
     * This API is intended to be used in the DAS. The motivation for having this
     * API is to provide the CMP backend a means of acquiring a connection during
     * the codegen phase. If a user is trying to deploy an app on a remote server,
     * without this API, a resource reference has to be present both in the DAS
     * and the server instance. This makes the deployment more complex for the
     * user since a resource needs to be forcibly created in the DAS Too.
     * This API will mitigate this need.
     *
     * @param resourceInfo the jndi name of the resource being used to get Connection from
     *                 This resource can either be a pmf resource or a jdbc resource
     * @param user     the user used to authenticate this request
     * @param password the password used to authenticate this request
     * @return a java.sql.Connection
     * @throws java.sql.SQLException in case of errors
     */
    public Connection getConnection(ResourceInfo resourceInfo, String user, String password)
            throws SQLException {
        java.sql.Connection con = null;
        try {
            //DASResourcesUtil.setAdminConfigContext();
            PoolInfo poolInfo = getPoolNameFromResourceJndiName(resourceInfo);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("ConnectorRuntime.getConnection :: poolName : " + poolInfo);
            }
            //Maintain consitency with the ConnectionManagerImpl change to be checked in later
            String passwd = (password == null) ? "" : password;

            //From what we have seen so far, the user cannot be null
            //but password can be
            //if user is null we will use default authentication
            //TODO: Discuss if this is the right thing to do
            ResourcePrincipal prin = (user == null) ?
                    null : new ResourcePrincipal(user, password);
            con = (java.sql.Connection) getUnpooledConnection(poolInfo, prin, true);
            if (con == null) {
                String i18nMsg = localStrings.getString(
                        "ccp_adm.null_unpooled_connection");
                throw new SQLException(i18nMsg);
            }
        } catch (ResourceException re) {
            SQLException sqle = new SQLException(re.getMessage());
            sqle.initCause(re);
            _logger.log(Level.WARNING, "jdbc.exc_get_conn", re.getMessage());
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine(" getConnection in ConnectorRuntime failed : " + re);
            }
            throw sqle;
        } catch (Exception ex) {
            SQLException sqle = new SQLException(ex.getMessage());
            sqle.initCause(ex);
            _logger.log(Level.WARNING, "jdbc.exc_get_conn", ex.getMessage());
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine(" getConnection in ConnectorRuntime failed : " + ex);
            }
            throw sqle;
        }/* finally {
            try {
                DASResourcesUtil.resetAdminConfigContext();
            } catch (Exception e) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.fine("caught exception while setting " +
                            "getConnectionFromConnectorRuntime to false");
                }
            }

        }*/

        return con;
    }

    /**
     * Get a sql connection from the DataSource specified by the jdbcJndiName.
     * This API is intended to be used in the DAS. The motivation for having this
     * API is to provide the CMP backend a means of acquiring a connection during
     * the codegen phase. If a user is trying to deploy an app on a remote server,
     * without this API, a resource reference has to be present both in the DAS
     * and the server instance. This makes the deployment more complex for the
     * user since a resource needs to be forcibly created in the DAS Too.
     * This API will mitigate this need.
     *
     * @param resourceInfo the jndi name of the resource being used to get Connection from
     *                 This resource can either be a pmf resource or a jdbc resource
     * @return a java.sql.Connection
     * @throws java.sql.SQLException in case of errors
     */
    public Connection getConnection(ResourceInfo resourceInfo)
            throws SQLException {
        java.sql.Connection con = null;
        try {
            //DASResourcesUtil.setAdminConfigContext();
            PoolInfo poolInfo = getPoolNameFromResourceJndiName(resourceInfo);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("ConnectorRuntime.getConnection :: poolName : "
                        + poolInfo);
            }
            con = (java.sql.Connection) getUnpooledConnection(poolInfo, null,
                    true);
            if (con == null) {
                String i18nMsg = localStrings.getString(
                        "ccp_adm.null_unpooled_connection");
                throw new SQLException(i18nMsg);
            }
        } catch (ResourceException re) {
            SQLException sqle = new SQLException(re.getMessage());
            sqle.initCause(re);
            _logger.log(Level.WARNING, "jdbc.exc_get_conn", re.getMessage());
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("Exception : " + re);
            }
            throw sqle;
        } catch (Exception ex) {
            SQLException sqle = new SQLException(ex.getMessage());
            sqle.initCause(ex);
            _logger.log(Level.WARNING, "jdbc.exc_get_conn", ex.getMessage());
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine(" getConnection in ConnectorRuntime failed : " + ex);
            }
            throw sqle;
        } /*finally {
            try {
              //  DASResourcesUtil.resetAdminConfigContext();
            } catch (Exception e) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.fine("caught exception while setting " +
                            "getConnectionFromConnectorRuntime to false");
                }
            }
        }*/

        return con;
    }

    /**
     * Gets the Pool name that this JDBC resource points to. In case of a PMF resource
     * gets the pool name of the pool pointed to by jdbc resource being pointed to by
     * the PMF resource
     *
     * @param jndiName the jndi name of the resource being used to get Connection from
     *                 This resource can either be a pmf resource or a jdbc resource
     * @return poolName of the pool that this resource directly/indirectly points to
     */
    private PoolInfo getPoolNameFromResourceJndiName(ResourceInfo resourceInfo) {
        //String poolName = null;
        PoolInfo poolInfo= null;
        JdbcResource jdbcResource = null;
/*     
        DASResourcesUtil resourcesUtil = (DASResourcesUtil) ResourcesUtil.createInstance();

        //check if the jndi name is that of a pmf resource or a jdbc resource
        PersistenceManagerFactoryResource pmfRes =
                resourcesUtil.getPMFResourceByJndiName(jndiName );
	if (pmfRes != null) {
	    jdbcRes = resourcesUtil.getJdbcResourceByJndiName(
                    pmfRes.getJdbcResourceJndiName());
	} else {

	    jdbcRes = resourcesUtil.getJdbcResourceByJndiName(jndiName);
/*	}*/
        ResourceInfo actualResourceInfo = resourceInfo;
        String jndiName = resourceInfo.getName();
        String suffix = ConnectorsUtil.getValidSuffix(jndiName);
        if(suffix != null){
            jndiName = jndiName.substring(0, jndiName.lastIndexOf(suffix));
            actualResourceInfo =
                    new ResourceInfo(jndiName, resourceInfo.getApplicationName(), resourceInfo.getModuleName());
        }
        ConnectorRuntime runtime = ConnectorRuntime.getRuntime();
        jdbcResource = (JdbcResource) runtime.getResources(actualResourceInfo).getResourceByName
                (JdbcResource.class, actualResourceInfo.getName());

        if (jdbcResource != null) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("jdbcRes is ---: " + jdbcResource.getJndiName());
                _logger.fine("poolName is ---: " + jdbcResource.getPoolName());
            }
        }
        if(jdbcResource != null){
            poolInfo = new PoolInfo(jdbcResource.getPoolName(), actualResourceInfo.getApplicationName(),
                    actualResourceInfo.getModuleName());
        }
        return poolInfo;
    }                          
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish ConnectorConnectionPoolAdminServiceImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.