com.sun.enterprise.connectors.util.ConnectionPoolObjectsUtils 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-2012 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 [2019-2021] Payara Foundation and/or affiliates
package com.sun.enterprise.connectors.util;
import com.sun.appserv.connectors.internal.api.ConnectorConstants;
import com.sun.appserv.connectors.internal.api.ConnectorRuntimeException;
import com.sun.appserv.connectors.spi.TransactionSupport;
import com.sun.enterprise.connectors.ConnectorConnectionPool;
import com.sun.enterprise.connectors.ConnectorRuntime;
import com.sun.enterprise.deployment.ConnectorDescriptor;
import com.sun.enterprise.deployment.ResourcePrincipal;
import com.sun.enterprise.deployment.runtime.connector.ResourceAdapter;
import com.sun.enterprise.deployment.runtime.connector.SunConnector;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.logging.LogDomains;
import org.glassfish.resourcebase.resources.api.PoolInfo;
import org.jvnet.hk2.config.types.Property;
import jakarta.resource.spi.ManagedConnectionFactory;
import jakarta.resource.spi.security.PasswordCredential;
import javax.security.auth.Subject;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This is an util class for creating poolObjects of the type
* ConnectorConnectionPool from ConnectorDescriptor and also using the
* default values.
*
* @author Srikanth P
*/
public final class ConnectionPoolObjectsUtils {
private ConnectionPoolObjectsUtils() { /* disallow instantiation */ }
public static final String ELEMENT_PROPERTY = "ElementProperty";
private static final Logger _logger = LogDomains.getLogger(ConnectionPoolObjectsUtils.class,LogDomains.RSR_LOGGER);
private static final String VALIDATE_ATMOST_EVERY_IDLE_SECS =
"com.sun.enterprise.connectors.ValidateAtmostEveryIdleSecs";
private static final String validateAtmostEveryIdleSecsProperty = System.getProperty(VALIDATE_ATMOST_EVERY_IDLE_SECS);
private static final StringManager localStrings =
StringManager.getManager(ConnectionPoolObjectsUtils.class);
/**
* Creates default ConnectorConnectionPool consisting of default
* pool values.
*
* @param poolInfo Name of the pool
* @return ConnectorConnectionPool created ConnectorConnectionPool instance
*/
public static ConnectorConnectionPool createDefaultConnectorPoolObject(
PoolInfo poolInfo, String rarName) {
ConnectorConnectionPool connectorPoolObj =
new ConnectorConnectionPool(poolInfo);
connectorPoolObj.setMaxPoolSize("20");
connectorPoolObj.setSteadyPoolSize("10");
connectorPoolObj.setMaxWaitTimeInMillis("7889");
connectorPoolObj.setIdleTimeoutInSeconds("789");
connectorPoolObj.setPoolResizeQuantity("2");
connectorPoolObj.setFailAllConnections(false);
connectorPoolObj.setMatchConnections(true); //always
setDefaultAdvancedPoolAttributes(connectorPoolObj);
try {
connectorPoolObj.setTransactionSupport(getTransactionSupportFromRaXml(rarName));
} catch (Exception ex) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("error in setting txSupport");
}
}
return connectorPoolObj;
}
/**
* Sets default values for advanced pool properties
*
* @param connectorPoolObj Connector Connection Pool
*/
private static void setDefaultAdvancedPoolAttributes(ConnectorConnectionPool connectorPoolObj) {
//Other advanced attributes like connection-leak-reclaim, lazy-connection-enlistment,
//lazy-connection-association, associate-with-thread are boolean values which are not required
//to be explicitly initialized to default values.
connectorPoolObj.setMaxConnectionUsage(ConnectorConnectionPool.DEFAULT_MAX_CONNECTION_USAGE);
connectorPoolObj.setConnectionLeakTracingTimeout(ConnectorConnectionPool.DEFAULT_LEAK_TIMEOUT);
connectorPoolObj.setConCreationRetryAttempts(ConnectorConnectionPool.DEFAULT_CON_CREATION_RETRY_ATTEMPTS);
connectorPoolObj.setConCreationRetryInterval(ConnectorConnectionPool.DEFAULT_CON_CREATION_RETRY_INTERVAL);
connectorPoolObj.setValidateAtmostOncePeriod(ConnectorConnectionPool.DEFAULT_VALIDATE_ATMOST_ONCE_PERIOD);
}
/**
* Creates ConnectorConnectionPool object pertaining to the pool props
* mentioned in the sun-ra/xml i.e it represents the pool mentioned in the
* sun-ra.xm.
*
* @param poolInfo Name of the pool
* @param desc ConnectorDescriptor which represent ra.xml and sun-ra.xml.
* @return ConnectorConnectionPool created ConnectorConnectionPool instance
*/
public static ConnectorConnectionPool createSunRaConnectorPoolObject(
PoolInfo poolInfo, ConnectorDescriptor desc, String rarName) {
ConnectorConnectionPool connectorPoolObj =
new ConnectorConnectionPool(poolInfo);
SunConnector sundesc = desc.getSunDescriptor();
ResourceAdapter sunRAXML = sundesc.getResourceAdapter();
connectorPoolObj.setMaxPoolSize(
(String) sunRAXML.getValue(ResourceAdapter.MAX_POOL_SIZE));
connectorPoolObj.setSteadyPoolSize(
(String) sunRAXML.getValue(ResourceAdapter.STEADY_POOL_SIZE));
connectorPoolObj.setMaxWaitTimeInMillis((String) sunRAXML.getValue(
ResourceAdapter.MAX_WAIT_TIME_IN_MILLIS));
connectorPoolObj.setIdleTimeoutInSeconds((String) sunRAXML.getValue(
ResourceAdapter.IDLE_TIMEOUT_IN_SECONDS));
connectorPoolObj.setPoolResizeQuantity("2");
connectorPoolObj.setFailAllConnections(false);
connectorPoolObj.setMatchConnections(true); //always
setDefaultAdvancedPoolAttributes(connectorPoolObj);
try {
connectorPoolObj.setTransactionSupport(getTransactionSupportFromRaXml(rarName));
} catch (Exception ex) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("error in setting txSupport");
}
}
boolean validateAtmostEveryIdleSecs = false;
//For SunRAPool, get the value of system property VALIDATE_ATMOST_EVERY_IDLE_SECS.
if (validateAtmostEveryIdleSecsProperty != null && validateAtmostEveryIdleSecsProperty.equalsIgnoreCase("TRUE")) {
validateAtmostEveryIdleSecs = true;
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "CCP.ValidateAtmostEveryIdleSecs.Set", poolInfo);
}
}
connectorPoolObj.setValidateAtmostEveryIdleSecs(validateAtmostEveryIdleSecs);
return connectorPoolObj;
}
/**
* Return the interger representation container transaction support value equivalent to
* the jakarta.resource.spi.TransactionSupport enum value.
*
* @param mcfTS jakarta.resource.spi.TransactionSupport
* @return container equivalent value
*/
public static int convertSpecTxSupportToContainerTxSupport(
jakarta.resource.spi.TransactionSupport.TransactionSupportLevel mcfTS) {
int containerEquivalentValue ;
switch (mcfTS) {
case LocalTransaction:
containerEquivalentValue = ConnectorConstants.LOCAL_TRANSACTION_INT;
break;
case NoTransaction:
containerEquivalentValue = ConnectorConstants.NO_TRANSACTION_INT;
break;
case XATransaction:
containerEquivalentValue = ConnectorConstants.XA_TRANSACTION_INT;
break;
default :
containerEquivalentValue = ConnectorConstants.UNDEFINED_TRANSACTION_INT;
break;
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("convertSpecTxSupportToContainerTxSupport: passed in mcfTransactionSupport =>" + mcfTS + ", " +
"converted container equivalent value: " + containerEquivalentValue);
}
return containerEquivalentValue;
}
/**
* Return the integer representation of the transaction-support attribure
*
* @param txSupport one of
*
* - NoTransaction
* - LocalTransaction
* - XATransaction
*
* @return one of
*
* - ConnectorConstants.UNDEFINED_TRANSACTION_INT
* - ConnectorConstants.NO_TRANSACTION_INT
* - ConnectorConstants.LOCAL_TRANSACTION_INT
* - ConnectorConstants.XA_TRANSACTION_INT
*
*/
public static int parseTransactionSupportString(String txSupport) {
int txSupportIntVal = ConnectorConstants.UNDEFINED_TRANSACTION_INT;
if (txSupport == null) {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("txSupport is null");
}
return txSupportIntVal;
}
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("parseTransactionSupportString: passed in txSupport =>" + txSupport);
}
if (ConnectorConstants.NO_TRANSACTION_TX_SUPPORT_STRING.equals(txSupport)) {
txSupportIntVal = ConnectorConstants.NO_TRANSACTION_INT;
} else if (ConnectorConstants.LOCAL_TRANSACTION_TX_SUPPORT_STRING.equals(txSupport)) {
txSupportIntVal = ConnectorConstants.LOCAL_TRANSACTION_INT;
} else if (ConnectorConstants.XA_TRANSACTION_TX_SUPPORT_STRING.equals(txSupport)) {
txSupportIntVal = ConnectorConstants.XA_TRANSACTION_INT;
}
return txSupportIntVal;
}
public static boolean isTxSupportConfigurationSane(int txSupport, String raName) {
int raXmlTxSupport = ConnectorConstants.UNDEFINED_TRANSACTION_INT;
try {
raXmlTxSupport = ConnectionPoolObjectsUtils.getTransactionSupportFromRaXml(raName);
} catch (Exception e) {
_logger.log(Level.WARNING,
(e.getMessage() != null ? e.getMessage() : " "));
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "isTxSupportConfigSane:: txSupport => "
+ txSupport + " raXmlTxSupport => " + raXmlTxSupport);
}
return (txSupport <= raXmlTxSupport);
}
/**
* A utility method to map TransactionSupport ints as represented
* in ConnectorConstants to the new TransactionSupport enum
*/
public static TransactionSupport getTransactionSupport(int ts) {
switch (ts) {
case ConnectorConstants.NO_TRANSACTION_INT:
return TransactionSupport.NO_TRANSACTION;
case ConnectorConstants.LOCAL_TRANSACTION_INT:
return TransactionSupport.LOCAL_TRANSACTION;
case ConnectorConstants.XA_TRANSACTION_INT:
return TransactionSupport.XA_TRANSACTION;
default:
return null;
}
}
public static String getValueFromMCF(String prop, PoolInfo poolInfo,
ManagedConnectionFactory mcf) {
String result = null;
try {
Method m = mcf.getClass().getMethod("get" + prop, (java.lang.Class[]) null);
result = (String) m.invoke(mcf, (java.lang.Object[]) null);
} catch (Throwable t) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, t.getMessage(), t);
}
}
return result == null ? "" : result;
}
public static Subject createSubject(ManagedConnectionFactory mcf,
final ResourcePrincipal prin) {
final Subject tempSubject = new Subject();
if (prin != null) {
String password = prin.getPassword();
if (password != null) {
final PasswordCredential pc =
new PasswordCredential(prin.getName(),
password.toCharArray());
pc.setManagedConnectionFactory(mcf);
PrivilegedAction action = () -> {
tempSubject.getPrincipals().add(prin);
tempSubject.getPrivateCredentials().add(pc);
return null;
};
AccessController.doPrivileged(action);
}
}
return tempSubject;
}
public static boolean isPoolSystemPool(org.glassfish.connectors.config.ConnectorConnectionPool
domainCcp) {
String poolName = domainCcp.getName();
return isPoolSystemPool(poolName);
}
public static boolean isPoolSystemPool(String poolName) {
Pattern pattern = Pattern.compile("#");
Matcher matcher = pattern.matcher(poolName);
// If the pool name does not contain #, return false
if (!matcher.find()) {
return false;
}
matcher.reset();
String moduleNameFromPoolName = null;
int matchCount = 0;
while (matcher.find()) {
matchCount++;
int patternStart = matcher.start();
moduleNameFromPoolName = poolName.substring(0, patternStart);
}
// If pool name contains more than 2 #, return false as the
// default system pool will have exactly one # for a standalone rar
// and exactly two #s for an embedded rar
return matchCount == 1 && ResourcesUtil.createInstance().belongToStandAloneRar(moduleNameFromPoolName);
}
/**
* Validates and sets the values for LazyConnectionEnlistment and LazyConnectionAssociation.
* @param lazyAssocString Property value
* @param adminPool Config Bean
* @param conConnPool Connector Connection Pool
*/
public static void setLazyEnlistAndLazyAssocProperties(String lazyAssocString, List properties,
ConnectorConnectionPool conConnPool){
//Get LazyEnlistment value.
//To set LazyAssoc to true, LazyEnlist also need to be true.
//If LazyAssoc is true and LazyEnlist is not set, set it to true.
//If LazyAssoc is true and LazyEnlist is false, throw exception.
if (properties == null) return ;
Property lazyEnlistElement = null;
for(Property property : properties){
if(property.getName().equalsIgnoreCase("LAZYCONNECTIONENLISTMENT")){
lazyEnlistElement = property;
}
}
boolean lazyAssoc = toBoolean( lazyAssocString, false );
if(lazyEnlistElement != null){
boolean lazyEnlist = toBoolean(lazyEnlistElement.getValue(),false);
if(lazyAssoc){
if(lazyEnlist){
conConnPool.setLazyConnectionAssoc( true) ;
conConnPool.setLazyConnectionEnlist( true);
}else{
_logger.log(Level.SEVERE,"conn_pool_obj_utils.lazy_enlist-lazy_assoc-invalid-combination",conConnPool.getName());
String i18nMsg = localStrings.getString(
"cpou.lazy_enlist-lazy_assoc-invalid-combination");
throw new RuntimeException(i18nMsg + conConnPool.getName());
}
}else{
conConnPool.setLazyConnectionAssoc(false);
}
}else{
if(lazyAssoc){
conConnPool.setLazyConnectionAssoc( true) ;
conConnPool.setLazyConnectionEnlist( true);
}else{
conConnPool.setLazyConnectionAssoc( false) ;
}
}
}
private static boolean toBoolean( Object prop, boolean defaultVal ) {
if ( prop == null ) {
return defaultVal;
}
return Boolean.valueOf(((String) prop).toLowerCase(Locale.getDefault()));
}
public static int getTransactionSupportFromRaXml(String rarName) throws
ConnectorRuntimeException {
String txSupport =
ConnectorRuntime.getRuntime().getConnectorDescriptor(rarName).
getOutboundResourceAdapter().getTransSupport();
return parseTransactionSupportString(txSupport);
}
}