com.sun.enterprise.connectors.service.ConnectorConnectionPoolAdminServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 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.
*/
// Portions Copyright [2016-2021] [Payara Foundation and/or its affiliates]
package com.sun.enterprise.connectors.service;
import com.sun.appserv.connectors.internal.api.ConnectorRuntimeException;
import com.sun.appserv.connectors.internal.api.ConnectorsUtil;
import com.sun.appserv.connectors.internal.api.PoolingException;
import com.sun.enterprise.config.serverbeans.ResourcePool;
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.ConnectorConfigProperty;
import com.sun.enterprise.deployment.ResourcePrincipal;
import com.sun.enterprise.resource.listener.UnpooledConnectionEventListener;
import com.sun.enterprise.resource.pool.PoolManager;
import com.sun.enterprise.util.i18n.StringManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.logging.Level;
import javax.naming.NamingException;
import jakarta.resource.ResourceException;
import jakarta.resource.spi.ConnectionRequestInfo;
import jakarta.resource.spi.ManagedConnection;
import jakarta.resource.spi.ManagedConnectionFactory;
import jakarta.resource.spi.TransactionSupport;
import javax.security.auth.Subject;
import org.glassfish.config.support.TranslatedConfigView;
import org.glassfish.connectors.config.SecurityMap;
import org.glassfish.internal.api.Globals;
import org.glassfish.internal.api.RelativePathResolver;
import org.glassfish.resourcebase.resources.api.PoolInfo;
import org.glassfish.resourcebase.resources.api.ResourceInfo;
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 {
if(connectorPoolObj == 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 jndiNameForPool = ConnectorAdminServiceUtils.getReservePrefixedJNDINameForPool(poolInfo);
try {
_runtime.getResourceNamingService().publishObject(poolInfo, jndiNameForPool, connectorPoolObj, true);
ManagedConnectionFactory mcf = createManagedConnectionFactory(connectorPoolObj);
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);
}
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 String represents property name
* and Object is the defaultValue that is a primitive type or String
*/
public static Map 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:
* 1. obtainManagedConnection for the poolname
* 2. lookup ConnectorDescriptorInfo from InitialContext using poolname
* 3. from cdi get username and password
* 4. create ResourcePrincipal using default username and password
* 5. create a Subject from this (doPriveleged)
* 6. createManagedConnection using above subject
* 7. getConnection from the ManagedConnection with above subject
*
* @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(re.getLocalizedMessage() +
" 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 jakarta.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 jakarta.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;
}
/**
* This method is used to provide backend functionality for the
* ping-connection-pool asadmin command. Briefly the design is as
* follows:
* 1. obtainManagedConnectionFactory for the poolname
* 2. lookup ConnectorDescriptorInfo from InitialContext using poolname
* 3. from cdi get username and password
* 4. create ResourcePrincipal using default username and password
* 5. create a Subject from this (doPriveleged)
* 6. createManagedConnection using above subject
* 7. add a dummy ConnectionEventListener to the mc that simply handles connectionClosed
* 8. getConnection from the ManagedConnection with above subject
*
* @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)
ConnectorsUtil.getResourceByName(runtime.getResources(poolInfo), 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();
boolean isJdbcPoolReferredInServerInstance = false;
Collection extensions =
Globals.getDefaultHabitat().getAllServices(ConnectorRuntimeExtension.class);
for(ConnectorRuntimeExtension extension : extensions) {
isJdbcPoolReferredInServerInstance = extension.isConnectionPoolReferredInServerInstance(poolInfo);
}
return (resUtil.isPoolReferredInServerInstance(poolInfo) || isJdbcPoolReferredInServerInstance);
}
//END CR 6597868
/**
* Utility method to get property value from ConnectorDescriptorInfo.
* @param prop
* @return
*/
public 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(Locale.getDefault()).equals(prop)) {
result = envProp.getValue();
}
}
return TranslatedConfigView.expandValue(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);
}
private ManagedConnectionFactory createManagedConnectionFactory(ConnectorConnectionPool connectorPoolObj) throws ConnectorRuntimeException {
if(_registry.isMCFCreated(connectorPoolObj.getPoolInfo())) {
recreateConnectorConnectionPool(connectorPoolObj);
}
return obtainManagedConnectionFactory(connectorPoolObj.getPoolInfo());
}
/**
* 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 jakarta.resource.spi.TransactionSupport) {
TransactionSupport.TransactionSupportLevel mcfTS =
((jakarta.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(Locale.getDefault()).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
* 2. Bind the pool to JNDI
* 3. Create an MCF for this pool and register with the connector registry
*
* @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 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);
*/
createConnectorConnectionPool(ccp);
}
/**
* 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) {
ConnectorRuntimeException e = new ConnectorRuntimeException(
ex.getLocalizedMessage() +
". Please check the server.log for more details.");
e.initCause(ex);
throw e;
}
}
/**
* 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(poolInfo == null){
throw new SQLException("No pool by name exists ");
}
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, passwd);
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(poolInfo == null){
throw new SQLException("No pool by name exists ");
}
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) {
PoolInfo poolInfo= null;
Collection extensions =
Globals.getDefaultHabitat().getAllServices(ConnectorRuntimeExtension.class);
for(ConnectorRuntimeExtension extension : extensions) {
poolInfo = extension.getPoolNameFromResourceJndiName(resourceInfo);
}
return poolInfo;
}
}