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

Glassfish example source code file (ConnectionManagerImpl.java)

This example Glassfish source code file (ConnectionManagerImpl.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

bindableresource, clientsecurityinfo, connectionrequestinfo, connectionrequestinfo, io, log, logging, object, object, poolmanager, resourceallocationexception, resourceexception, resourceexception, resourceinfo, resourceprincipal, security, string, string, util

The Glassfish ConnectionManagerImpl.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;

import com.sun.appserv.connectors.internal.api.*;
import com.sun.appserv.connectors.internal.spi.ConnectionManager;
import com.sun.enterprise.config.serverbeans.BindableResource;
import com.sun.enterprise.connectors.util.ConnectionPoolObjectsUtils;
import com.sun.enterprise.connectors.authentication.AuthenticationService;
import com.sun.enterprise.connectors.util.ResourcesUtil;
import com.sun.enterprise.deployment.ConnectorDescriptor;
import com.sun.enterprise.deployment.ResourcePrincipal;
import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
import com.sun.enterprise.resource.ClientSecurityInfo;
import com.sun.enterprise.resource.ResourceSpec;
import com.sun.enterprise.resource.allocator.NoTxConnectorAllocator;
import com.sun.enterprise.resource.allocator.ResourceAllocator;
import com.sun.enterprise.resource.allocator.LocalTxConnectorAllocator;
import com.sun.enterprise.resource.allocator.ConnectorAllocator;
import com.sun.enterprise.resource.pool.PoolManager;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.enterprise.security.SecurityContext;
import com.sun.logging.LogDomains;
import org.glassfish.resource.common.PoolInfo;
import org.glassfish.resource.common.ResourceInfo;

import javax.resource.ResourceException;
import javax.resource.spi.*;
import javax.resource.spi.IllegalStateException;
import javax.security.auth.Subject;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Set;
import java.security.Principal;


/**
 * @author Tony Ng
 */
public class ConnectionManagerImpl implements ConnectionManager, Serializable {

    protected String jndiName;
    protected String logicalName;
    protected PoolInfo poolInfo;
    protected ResourceInfo resourceInfo;

    private static Logger logger = LogDomains.getLogger(ConnectionManagerImpl.class,LogDomains.RSR_LOGGER);
    private static StringManager localStrings = StringManager.getManager(ConnectionManagerImpl.class);

    protected String rarName;

    private transient BindableResource resourceConfiguration;

    protected ResourcePrincipal defaultPrin = null;

    public ConnectionManagerImpl(PoolInfo poolInfo, ResourceInfo resourceInfo) {
        this.poolInfo = poolInfo;
        this.resourceInfo = resourceInfo;
    }

    public void setJndiName(String jndiName) {
        this.jndiName = jndiName;
    }

    public String getJndiName() {
        return jndiName;
    }

    public void setLogicalName(String logicalName) {
        this.logicalName = logicalName;
    }

    public String getLogicalName() {
        return logicalName;
    }


/*
    public void setPoolInfo(PoolInfo poolInfo) {
        this.poolInfo = poolInfo;
    }
*/

    /**
     * Allocate a non transactional connection. This connection, even if
     * acquired in the context of an existing transaction, will never
     * be associated with a transaction
     * The typical use case may be to check the original contents of an EIS
     * when a transacted connection is changing the contents, and the tx
     * is yet to be committed.
     * <p/>
     * We create a ResourceSpec for a non tx connection with a name ending
     * in __nontx. This is to maintain uniformity with the scheme of having
     * __pm connections.
     * If one were to create a resource with a jndiName ending with __nontx
     * the same functionality might be achieved.
     */
    public Object allocateNonTxConnection(ManagedConnectionFactory mcf,
                                          ConnectionRequestInfo cxRequestInfo) throws ResourceException {
        String localJndiName = jndiName;

        logFine("Allocating NonTxConnection");

        //If a resource has been created with __nontx, we don't want to
        //add it again.
        //Otherwise we need to add __nontx at the end to ensure that the
        //mechanism to check for the correct resource manager still works
        //We do the addition if and only if we are getting this call
        //from a normal datasource and not a __nontx datasource.
        if (!jndiName.endsWith(ConnectorConstants.NON_TX_JNDI_SUFFIX)) {
            localJndiName = jndiName + ConnectorConstants.NON_TX_JNDI_SUFFIX;
            logFine("Adding __nontx to jndiname");
        } else {
            logFine("lookup happened from a __nontx datasource directly");
        }
        return allocateConnection(mcf, cxRequestInfo, localJndiName);
    }

    public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cxRequestInfo)
            throws ResourceException {
        return this.allocateConnection(mcf, cxRequestInfo, jndiName);
    }

    public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cxRequestInfo,
                                     String jndiNameToUse) throws ResourceException {
        return this.allocateConnection(mcf, cxRequestInfo, jndiNameToUse, null);
    }

    public Object allocateConnection(ManagedConnectionFactory mcf,
                                     ConnectionRequestInfo cxRequestInfo, String jndiNameToUse, Object conn)
            throws ResourceException {
        validateResourceAndPool();
        PoolManager poolmgr = ConnectorRuntime.getRuntime().getPoolManager();
        boolean resourceShareable = true;

        ResourceReferenceDescriptor ref =  poolmgr.getResourceReference(jndiNameToUse, logicalName);

        if (ref != null) {
            String shareableStr = ref.getSharingScope();

            if (shareableStr.equals(ref.RESOURCE_UNSHAREABLE)) {
                resourceShareable = false;
            }
        }

        //TODO V3 refactor all the 3 cases viz, no res-ref, app-auth, cont-auth.
        if (ref == null) {
            if(getLogger().isLoggable(Level.FINE)) {
                getLogger().log(Level.FINE, "poolmgr.no_resource_reference", jndiNameToUse);
            }
            return internalGetConnection(mcf, defaultPrin, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, true);
        }
        String auth = ref.getAuthorization();

        if (auth.equals(ResourceReferenceDescriptor.APPLICATION_AUTHORIZATION)) {
            if (cxRequestInfo == null) {

                String msg = getLocalStrings().getString("con_mgr.null_userpass");
                throw new ResourceException(msg);
            }
            ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolInfo);
            return internalGetConnection(mcf, null, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, false);
        } else {
            ResourcePrincipal prin = null;
            Set principalSet = null;
            Principal callerPrincipal = null;
            SecurityContext securityContext = null;
            ConnectorRuntime connectorRuntime = ConnectorRuntime.getRuntime();
            //TODO V3 is SecurityContext.getCurrent() the right way ? Does it need to be injected ?
            if (connectorRuntime.isServer() &&
                    (securityContext = SecurityContext.getCurrent()) != null &&
                    (callerPrincipal = securityContext.getCallerPrincipal()) != null &&
                    (principalSet = securityContext.getPrincipalSet()) != null) {
                AuthenticationService authService =
                        connectorRuntime.getAuthenticationService(rarName, poolInfo);
                if (authService != null) {
                    prin = (ResourcePrincipal) authService.mapPrincipal(
                            callerPrincipal, principalSet);
                }
            }

            if (prin == null) {
                prin = ref.getResourcePrincipal();
                if (prin == null) {
                    if (getLogger().isLoggable(Level.FINE)) {
                        getLogger().log(Level.FINE, "default-resource-principal not"
                                + "specified for " + jndiNameToUse + ". Defaulting to"
                                + " user/password specified in the pool");
                    }
                    prin = defaultPrin;
                } else if (!prin.equals(defaultPrin)) {
                    ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolInfo);
                }
            }
            return internalGetConnection(mcf, prin, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, false);
        }
    }

    protected Object internalGetConnection(ManagedConnectionFactory mcf,
                                           final ResourcePrincipal prin, ConnectionRequestInfo cxRequestInfo,
                                           boolean shareable, String jndiNameToUse, Object conn, boolean isUnknownAuth)
            throws ResourceException {
        try {
            PoolManager poolmgr = ConnectorRuntime.getRuntime().getPoolManager();
            ConnectorRegistry registry = ConnectorRegistry.getInstance();
            PoolMetaData pmd = registry.getPoolMetaData(poolInfo);

            ResourceSpec spec = new ResourceSpec(jndiNameToUse,
                    ResourceSpec.JNDI_NAME, pmd);
            spec.setPoolInfo(this.poolInfo);
            ManagedConnectionFactory freshMCF = pmd.getMCF();

            if (getLogger().isLoggable(Level.INFO)) {
                if (!freshMCF.equals(mcf)) {
                    getLogger().info("conmgr.mcf_not_equal");
                }
            }
            ConnectorDescriptor desc = registry.getDescriptor(rarName);

            Subject subject = null;
            ClientSecurityInfo info = null;
            boolean subjectDefined = false;
            if (isUnknownAuth && rarName.equals(ConnectorConstants.DEFAULT_JMS_ADAPTER)
                    && !(pmd.isAuthCredentialsDefinedInPool())) {
                //System.out.println("Unkown Auth - pobably nonACC client");
                //Unknown authorization. This is the case for standalone java clients,
                //where the authorization is neither container nor component
                //managed. In this case we associate an non-null Subject with no
                //credentials, so that the RA can either use its own custom logic
                //for figuring out the credentials. Relevant connector spec section
                //is 9.1.8.2.
                //create non-null Subject associated with no credentials
                //System.out.println("RAR name "+ rarName);
                subject = ConnectionPoolObjectsUtils.createSubject(mcf, null);
            } else {
                if (prin == null) {
                    info = new ClientSecurityInfo(cxRequestInfo);
                } else {
                    info = new ClientSecurityInfo(prin);
                    //If subject is defined, don't attempt to redefine it
                    if (subject == null) {
                        if (prin.equals(defaultPrin)) {
                            subject = pmd.getSubject();
                        } else {
                            subject = ConnectionPoolObjectsUtils.createSubject(mcf, prin);
                        }
                    }
                }
            }

            int txLevel = pmd.getTransactionSupport();
            if (getLogger().isLoggable(Level.FINE)) {
                logFine("ConnectionMgr: poolName " + poolInfo +
                        "  txLevel : " + txLevel);
            }

             if ( conn != null ) {
                 spec.setConnectionToAssociate( conn );
             }


            return getResource(txLevel, poolmgr, mcf, spec, subject, cxRequestInfo, info, desc, shareable);

        } catch (PoolingException ex) {
            Object[] params = new Object[]{poolInfo, ex};
            getLogger().log(Level.WARNING, "poolmgr.get_connection_failure", params);
            String i18nMsg = getLocalStrings().getString("con_mgr.error_creating_connection", ex.getMessage());
            ResourceAllocationException rae = new ResourceAllocationException(i18nMsg);
            rae.initCause(ex);
            throw rae;
        }
    }

    private Object getResource(int txLevel, PoolManager poolmgr, ManagedConnectionFactory mcf, ResourceSpec spec,
                               Subject subject, ConnectionRequestInfo cxRequestInfo, ClientSecurityInfo info,
                               ConnectorDescriptor desc, boolean shareable)
            throws PoolingException, ResourceAllocationException, IllegalStateException, RetryableUnavailableException {
        ResourceAllocator alloc;

        switch (txLevel) {
            case ConnectorConstants.NO_TRANSACTION_INT:
                alloc = new NoTxConnectorAllocator(poolmgr, mcf, spec, subject, cxRequestInfo, info, desc);
                break;
            case ConnectorConstants.LOCAL_TRANSACTION_INT:
                alloc = new LocalTxConnectorAllocator(poolmgr, mcf, spec, subject, cxRequestInfo, info, desc, shareable);
                break;
            case ConnectorConstants.XA_TRANSACTION_INT:
                if (rarName.equals(ConnectorRuntime.DEFAULT_JMS_ADAPTER)) {
                    shareable = false;
                }
                spec.markAsXA();
                alloc = new ConnectorAllocator(poolmgr, mcf, spec, subject, cxRequestInfo, info, desc, shareable);
                return poolmgr.getResource(spec, alloc, info);
            
            default:
                String i18nMsg = getLocalStrings().getString("con_mgr.illegal_tx_level", txLevel + " ");
                throw new IllegalStateException(i18nMsg);
        }
        return poolmgr.getResource(spec, alloc, info);
    }


    public void setRarName(String _rarName) {
        rarName = _rarName;
    }

    public String getRarName() {
        return rarName;
    }

    /*
    * This method is called from the ConnectorObjectFactory lookup
    * With this we move all the housekeeping work in allocateConnection
    * up-front 
    */
    public void initialize() throws ConnectorRuntimeException {

        ConnectorRuntime runtime = ConnectorRuntime.getRuntime();

        if(runtime.isNonACCRuntime()){
            jndiName = ConnectorsUtil.getPMJndiName(jndiName);
        }
        ConnectorRegistry registry = ConnectorRegistry.getInstance();
        PoolMetaData pmd = registry.getPoolMetaData(poolInfo);
        defaultPrin = pmd.getResourcePrincipal();
    }

    private void validateResourceAndPool() throws ResourceException {
        ResourceInfo resourceInfo = this.resourceInfo;
        ResourcesUtil resourcesUtil = ResourcesUtil.createInstance();

        ConnectorRuntime runtime = ConnectorRuntime.getRuntime();
        ConnectorRegistry registry = ConnectorRegistry.getInstance();
        // adding a perf. optimization check so that "config-bean" is not accessed at all for
        // cases where the resource is enabled (deployed). Only for cases where resource
        // is not available, we look further and determine whether resource/resource-ref
        // are disabled.
        if (!registry.isResourceDeployed(resourceInfo)) {
            if(logger.isLoggable(Level.FINEST)){
                logger.log(Level.FINEST,"resourceInfo not found in connector-registry : " + resourceInfo);
            }
            boolean isDefaultResource = false;
            boolean isSunRAResource = false;
            ConnectorDescriptor descriptor = registry.getDescriptor(rarName);
            if (descriptor != null) {
                isDefaultResource = descriptor.getDefaultResourcesNames().contains(resourceInfo.getName());
                if (descriptor.getSunDescriptor() != null) {
                    com.sun.enterprise.deployment.runtime.connector.ResourceAdapter rar =
                            descriptor.getSunDescriptor().getResourceAdapter();
                    if (rar != null) {
                        String sunRAJndiName = (String)
                                rar.getValue(com.sun.enterprise.deployment.runtime.connector.ResourceAdapter.JNDI_NAME);
                        isSunRAResource = resourceInfo.getName().equals(sunRAJndiName);
                    }
                }
            }

            if ((runtime.isServer() || runtime.isEmbedded()) &&
                    (!resourceInfo.getName().contains(ConnectorConstants.DATASOURCE_DEFINITION_JNDINAME_PREFIX) &&
                            (!isDefaultResource) && (!isSunRAResource))) {
                // performance optimization so that resource configuration is not retrieved from
                // resources config bean each time.
                if (resourceConfiguration == null) {
                    resourceConfiguration =
                            (BindableResource) resourcesUtil.getResource(resourceInfo, BindableResource.class);
                    if (resourceConfiguration == null) {
                        String suffix = ConnectorsUtil.getValidSuffix(resourceInfo.getName());
                        // it is possible that the resource is a __PM or __NONTX suffixed resource used by JPA/EJB Container
                        // check for the enabled status and existence using non-prefixed resource-name
                        if (suffix != null) {
                            String nonPrefixedName = resourceInfo.getName().substring(0, resourceInfo.getName().lastIndexOf(suffix));
                            resourceInfo = new ResourceInfo(nonPrefixedName, resourceInfo.getApplicationName(),
                                    resourceInfo.getModuleName());
                            resourceConfiguration = (BindableResource)
                                    resourcesUtil.getResource(resourceInfo, BindableResource.class);
                        }
                    }
                } else {
                    // we cache the resourceConfiguration for performance optimization.
                    // make sure that appropriate (actual) resourceInfo is used for validation.
                    String suffix = ConnectorsUtil.getValidSuffix(resourceInfo.getName());
                    // it is possible that the resource is a __PM or __NONTX suffixed resource used by JPA/EJB Container
                    // check for the enabled status and existence using non-prefixed resource-name
                    if (suffix != null) {
                        String nonPrefixedName = resourceInfo.getName().substring(0, resourceInfo.getName().lastIndexOf(suffix));
                        resourceInfo = new ResourceInfo(nonPrefixedName, resourceInfo.getApplicationName(),
                                resourceInfo.getModuleName());
                    }
                }
                if (resourceConfiguration == null) {
                    throw new ResourceException("No such resource : " + resourceInfo);
                }
                if (!resourcesUtil.isEnabled(resourceConfiguration, resourceInfo)) {
                    throw new ResourceException(resourceInfo + " is not enabled");
                }
            }
        }

        if (registry.getPoolMetaData(poolInfo) == null) {
            String msg = getLocalStrings().getString("con_mgr.no_pool_meta_data", poolInfo);
            throw new ResourceException(poolInfo + ": " + msg);
        }
    }

    public void logFine(String message) {
        if (getLogger().isLoggable(Level.FINE)) {
            getLogger().fine(message);
        }
    }

    private static StringManager getLocalStrings() {
        if(localStrings == null){
            localStrings = StringManager.getManager(ConnectionManagerImpl.class);
        }
        return localStrings;
    }

    protected static Logger getLogger() {
        if (logger == null){
            logger = LogDomains.getLogger(ConnectionManagerImpl.class,LogDomains.RSR_LOGGER);
        }
        return logger;
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish ConnectionManagerImpl.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.