All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.connectors.ConnectionManagerImpl Maven / Gradle / Ivy

There is a newer version: 10.0-b28
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.connectors;

import com.sun.appserv.connectors.internal.spi.ConnectionManager;
import com.sun.appserv.connectors.internal.api.ConnectorConstants;
import com.sun.appserv.connectors.internal.api.PoolingException;
import com.sun.appserv.connectors.internal.api.ConnectorRuntimeException;
import com.sun.appserv.connectors.internal.api.ConnectorsUtil;
import com.sun.enterprise.connectors.util.ConnectionPoolObjectsUtils;
import com.sun.enterprise.connectors.authentication.AuthenticationService;
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 javax.resource.ResourceException;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.IllegalStateException;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.ResourceAllocationException;
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 String poolName;

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

    //The RAR name
    //This is pushed into the object in the connector runtime during
    //jndi publishing
    protected String rarName;

    protected ResourcePrincipal defaultPrin = null;

    public ConnectionManagerImpl(String poolName) {
        this.poolName = poolName;
    }

    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 setPoolName(String poolName) {
        this.poolName = poolName;
    }

    /**
     * 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.
     * 

* 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 { validatePool(); 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) { 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, poolName); 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, poolName); if (authService != null) { prin = (ResourcePrincipal) authService.mapPrincipal( callerPrincipal, principalSet); } } if (prin == null) { prin = ref.getResourcePrincipal(); if (prin == null) { 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, poolName); } } 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(poolName); ResourceSpec spec = new ResourceSpec(jndiNameToUse, ResourceSpec.JNDI_NAME, pmd); spec.setConnectionPoolName(this.poolName); 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 " + poolName + " txLevel : " + txLevel); } return getResource(txLevel, poolmgr, mcf, spec, subject, cxRequestInfo, info, desc, shareable); } catch (PoolingException ex) { Object[] params = new Object[]{poolName, 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 { 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.getEnvironment() == ConnectorConstants.NON_ACC_CLIENT){ jndiName = ConnectorsUtil.getPMJndiName(jndiName); } //TODO V3 getting mcf not needed ? ManagedConnectionFactory mcf = runtime.obtainManagedConnectionFactory(poolName); ConnectorRegistry registry = ConnectorRegistry.getInstance(); PoolMetaData pmd = registry.getPoolMetaData(poolName); defaultPrin = pmd.getResourcePrincipal(); } private void validatePool() throws ResourceException { ConnectorRegistry registry = ConnectorRegistry.getInstance(); if (registry.getPoolMetaData(poolName) == null) { String msg = getLocalStrings().getString("con_mgr.no_pool_meta_data", poolName); throw new ResourceException(poolName + ": " + 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; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy