Skip to content

Commit

Permalink
Issue eclipse-ee4j#24900 write a few unit tests to start to understand
Browse files Browse the repository at this point in the history
associateConnection logic which is used by ConnectorXAResource in
connector-runtime
  • Loading branch information
escay committed Oct 8, 2024
1 parent c30ecb4 commit fd51567
Show file tree
Hide file tree
Showing 11 changed files with 816 additions and 79 deletions.
5 changes: 5 additions & 0 deletions appserver/jdbc/jdbc-ra/jdbc-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
<groupId>org.glassfish.gmbal</groupId>
<artifactId>gmbal</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ public abstract class JdbcObjectsFactory implements Serializable {
* @return JdbcObjectsFactory
*/
public static JdbcObjectsFactory getInstance() {
String className = "com.sun.gjc.spi.jdbc40.Jdbc40ObjectsFactory";
try {
return(JdbcObjectsFactory)
Class.forName("com.sun.gjc.spi.jdbc40.Jdbc40ObjectsFactory")
Class.forName(className)
.getDeclaredConstructor()
.newInstance();
} catch (Exception e) {
_logger.log(WARNING, "jdbc.jdbc_factory_class_load_exception", e);
_logger.log(WARNING, "jdbc.jdbc_factory_class_load_exception", className);
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import jakarta.resource.ResourceException;
import jakarta.resource.spi.ConnectionEvent;
import jakarta.resource.spi.ConnectionEventListener;
import jakarta.resource.spi.ConnectionRequestInfo;
import jakarta.resource.spi.DissociatableManagedConnection;
import jakarta.resource.spi.LazyEnlistableManagedConnection;
import jakarta.resource.spi.LocalTransaction;
Expand Down Expand Up @@ -129,32 +130,43 @@ public class ManagedConnectionImpl
private Boolean isClientInfoSupported;

/**
* Constructor for <code>ManagedConnectionImpl</code>. The pooledConn parameter
* is expected to be null and sqlConn parameter is the actual connection in case
* where the actual connection is got from a non pooled datasource object. The
* pooledConn parameter is expected to be non null and sqlConn parameter is
* expected to be null in the case where the datasource object is a connection
* pool datasource or an xa datasource.
* Constructor for <code>ManagedConnectionImpl</code>. The pooledConn parameter is expected to be null and sqlConn
* parameter is the actual connection in case where the actual connection is got from a non pooled datasource object.
* The pooledConn parameter is expected to be non null and sqlConn parameter is expected to be null in the case where
* the datasource object is a connection pool datasource or an xa datasource.
*
* @param pooledConn <code>PooledConnection</code> object in case the physical
* connection is to be obtained from a pooled <code>DataSource</code>; null
* otherwise
* @param sqlConn <code>java.sql.Connection</code> object in case the physical
* connection is to be obtained from a non pooled <code>DataSource</code>; null
* otherwise
* @param passwdCred object conatining the user and password for allocating the
* connection
* @throws ResourceException if the <code>ManagedConnectionFactory</code> object
* that created this <code>ManagedConnectionImpl</code> object is not the same
* as returned by <code>PasswordCredential</code> object passed
* @param pooledConn <code>PooledConnection</code> object in case the physical connection is to be obtained from a
* pooled <code>DataSource</code>; null otherwise
* @param sqlConn <code>java.sql.Connection</code> object in case the physical connection is to be obtained from a non
* pooled <code>DataSource</code>; null otherwise
* @param passwdCred object containing the user and password for allocating the connection, value is allowed to be null.
* @param mcf the reference to the ManagedConnectionFactory instance that created this ManagedConnectionImpl instance.
* @param poolInfo Name of the pool
* @param statementCacheSize Statement caching is usually a feature of the JDBC driver. The GlassFish Server provides
* caching for drivers that do not support caching. To enable this feature, set the Statement Cache Size. By default,
* this attribute is set to zero and the statement caching is turned off. To enable statement caching, you can set any
* positive nonzero value. The built-in cache eviction strategy is LRU-based (Least Recently Used). When a connection
* pool is flushed, the connections in the statement cache are recreated.<br>
* Configured via create-jdbc-connection-pool --statementcachesize
* @param statementCacheType In case statementCacheSize is not 0 this defines the statement cache type to be used. Valid
* values are defined in com.sun.gjc.spi.base.datastructure.CacheFactory. Value null or "" uses an LRU Cache
* implementation. Value FIXED uses FIXED size cache implementation. Any other values are expected to be a className for
* a cache implementation.
* @param delegator optional SqlTraceDelegator, value is allowed to be null.
* @param statementLeakTimeout statement leak timeout in seconds.<br>
* Configured via create-jdbc-connection-pool --statementleaktimeout
* @param statementLeakReclaim true if statements need to be reclaimed.<br>
* Configured via create-jdbc-connection-pool --statementleakreclaim
* @throws ResourceException if the <code>ManagedConnectionFactory</code> object that created this
* <code>ManagedConnectionImpl</code> object is not the same as returned by <code>PasswordCredential</code> object
* passed. And throws ResourceException in case both pooledConn and sqlConn are null.
*/
public ManagedConnectionImpl(PooledConnection pooledConn, Connection sqlConn, PasswordCredential passwdCred,
ManagedConnectionFactory mcf, PoolInfo poolInfo, int statementCacheSize, String statementCacheType,
SQLTraceDelegator delegator, long statementLeakTimeout, boolean statementLeakReclaim)
throws ResourceException {

if (pooledConn == null && sqlConn == null) {

String i18nMsg = localStrings.getString("jdbc.conn_obj_null");
throw new ResourceException(i18nMsg);
}
Expand All @@ -170,7 +182,6 @@ public ManagedConnectionImpl(PooledConnection pooledConn, Connection sqlConn, Pa

this.managedConnectionFactory = mcf;
if (passwdCredential != null && this.managedConnectionFactory.equals(passwdCredential.getManagedConnectionFactory()) == false) {

String i18nMsg = localStrings.getString("jdbc.mc_construct_err");
throw new ResourceException(i18nMsg);
}
Expand Down Expand Up @@ -248,6 +259,7 @@ private void tuneStatementLeakTracing(PoolInfo poolInfo, long statementLeakTimeo
* @param listener <code>ConnectionEventListener</code>
* @see <code>removeConnectionEventListener</code>
*/
@Override
public void addConnectionEventListener(ConnectionEventListener listener) {
this.listener = listener;
}
Expand All @@ -256,11 +268,12 @@ public void addConnectionEventListener(ConnectionEventListener listener) {
* Used by the container to change the association of an application-level
* connection handle with a <code>ManagedConnectionImpl</code> instance.
*
* @param connection <code>ConnectionHolder30</code> to be associated with this
* @param connection <code>ConnectionHolder</code> to be associated with this
* <code>ManagedConnectionImpl</code> instance
* @throws ResourceException if the physical connection is no more valid or the
* connection handle passed is null
*/
@Override
public void associateConnection(Object connection) throws ResourceException {
logFine("In associateConnection");
checkIfValid();
Expand All @@ -282,7 +295,7 @@ public void associateConnection(Object connection) throws ResourceException {
* previous statements and result sets also need to be removed.
*/

connectionHolder.setActive(true);
connectionHolder.setActive();
incrementCount();

// associate the MC to the supplied logical connection similar to associating
Expand All @@ -304,6 +317,7 @@ public void associateConnection(Object connection) throws ResourceException {
*
* @throws ResourceException if the physical connection is no more valid
*/
@Override
public void cleanup() throws ResourceException {
logFine("In cleanup");

Expand Down Expand Up @@ -351,6 +365,7 @@ private void clearStatementCache() {
* @throws ResourceException if there is an error in closing the physical
* connection
*/
@Override
public void destroy() throws ResourceException {
logFine("In destroy");
if (isDestroyed) {
Expand Down Expand Up @@ -400,7 +415,8 @@ public void destroy() throws ResourceException {
* @throws jakarta.resource.spi.SecurityException if there is a mismatch between
* the password credentials or reauthentication is requested
*/
public Object getConnection(Subject sub, jakarta.resource.spi.ConnectionRequestInfo cxReqInfo) throws ResourceException {
@Override
public Object getConnection(Subject sub, ConnectionRequestInfo cxReqInfo) throws ResourceException {
logFine("In getConnection");
checkIfValid();

Expand Down Expand Up @@ -431,7 +447,7 @@ public Object getConnection(Subject sub, jakarta.resource.spi.ConnectionRequestI
incrementCount();
isClean = false;

myLogicalConnection.setActive(true);
myLogicalConnection.setActive();

return myLogicalConnection;
}
Expand Down Expand Up @@ -484,6 +500,7 @@ private void resetAutoCommit() throws ResourceException {
* @return <code>LocalTransactionImpl</code> instance
* @throws ResourceException if the physical connection is not valid
*/
@Override
public LocalTransaction getLocalTransaction() throws ResourceException {
logFine("In getLocalTransaction");
checkIfValid();
Expand All @@ -498,6 +515,7 @@ public LocalTransaction getLocalTransaction() throws ResourceException {
* @throws ResourceException if the physical connection is not valid
* @see <code>setLogWriter</code>
*/
@Override
public PrintWriter getLogWriter() throws ResourceException {
logFine("In getLogWriter");
checkIfValid();
Expand All @@ -512,6 +530,7 @@ public PrintWriter getLogWriter() throws ResourceException {
* @return <code>ManagedConnectionMetaData</code> instance
* @throws ResourceException if the physical connection is not valid
*/
@Override
public ManagedConnectionMetaData getMetaData() throws ResourceException {
logFine("In getMetaData");
checkIfValid();
Expand All @@ -528,6 +547,7 @@ public ManagedConnectionMetaData getMetaData() throws ResourceException {
* @throws NotSupportedException if underlying datasource is not an
* <code>XADataSource</code>
*/
@Override
public XAResource getXAResource() throws ResourceException {
logFine("In getXAResource");
checkIfValid();
Expand Down Expand Up @@ -556,7 +576,11 @@ public XAResource getXAResource() throws ResourceException {
* @param listener <code>ConnectionEventListener</code> to be removed
* @see <code>addConnectionEventListener</code>
*/
@Override
public void removeConnectionEventListener(ConnectionEventListener listener) {
if (this.listener == listener) {
this.listener = null;
}
}

/**
Expand Down Expand Up @@ -709,41 +733,37 @@ void checkIfValid() throws ResourceException {
}

/**
* This method is called by the <code>ConnectionHolder30</code> when its close
* method is called. This <code>ManagedConnection</code> instance invalidates
* the connection handle and sends a CONNECTION_CLOSED event to all the
* registered event listeners.
* This method is called by the <code>ConnectionHolder</code> when its close method is called. This
* <code>ManagedConnection</code> instance invalidates the connection handle and sends a CONNECTION_CLOSED event to all
* the registered event listeners.
*
* @param e Exception that may have occurred while closing the connection handle
* @param connHolder30Object <code>ConnectionHolder30</code> that has been
* closed
* @throws SQLException in case closing the sql connection got out of
* <code>getConnection</code> on the underlying <code>PooledConnection</code>
* throws an exception
* @param connectionHolder <code>ConnectionHolder</code> that has been closed
* @throws SQLException in case closing the sql connection got out of <code>getConnection</code> on the underlying
* <code>PooledConnection</code> throws an exception
*/
public void connectionClosed(Exception e, ConnectionHolder connHolder30Object) throws SQLException {
connHolder30Object.invalidate();
public void connectionClosed(Exception e, ConnectionHolder connectionHolder) throws SQLException {
connectionHolder.invalidate();
decrementCount();
connectionEvent.setConnectionHandle(connHolder30Object);
connectionEvent.setConnectionHandle(connectionHolder);

if (markedForRemoval && !transactionInProgress) {
BadConnectionEventListener badConnectionEventListener = (BadConnectionEventListener) listener;
badConnectionEventListener.badConnectionClosed(connectionEvent);
_logger.log(INFO, "jdbc.markedForRemoval_conClosed");
markedForRemoval = false;
} else {
listener.connectionClosed(connectionEvent);
if (listener != null) {
listener.connectionClosed(connectionEvent);
}
}
}

/**
* This method is called by the <code>ConnectionHolder30</code> when it detects
* a connecion related error.
* This method is called by the <code>ConnectionHolder</code> when it detects a connection related error.
*
* @param e Exception that has occurred during an operation on the physical
* connection
* @param connectionHolder <code>ConnectionHolder</code> that detected the
* physical connection error
* @param e Exception that has occurred during an operation on the physical connection
* @param connectionHolder <code>ConnectionHolder</code> that detected the physical connection error
*/
void connectionErrorOccurred(Exception e, ConnectionHolder connectionHolder) {
ConnectionEventListener connectionEventListener = this.listener;
Expand Down Expand Up @@ -787,19 +807,16 @@ void XAEndOccurred() {
}

/**
* This method is called by a Connection Handle to check if it is the active
* Connection Handle. If it is not the active Connection Handle, this method
* throws an SQLException. Else, it returns setting the active Connection Handle
* to the calling Connection Handle object to this object if the active
* Connection Handle is null.
* This method is called by a Connection Handle to check if it is the active Connection Handle. If it is not the active
* Connection Handle, this method throws an SQLException. Else, it returns setting the active Connection Handle to the
* calling Connection Handle object to this object if the active Connection Handle is null.
*
* @param ch <code>ConnectionHolder30</code> that requests this
* <code>ManagedConnection</code> instance whether it can be active or not
* @throws SQLException in case the physical is not valid or there is already an
* active connection handle
* @param connectionHolder <code>ConnectionHolder</code> that requests this <code>ManagedConnection</code> instance
* whether it can be active or not
* @throws SQLException in case the physical is not valid or there is already an active connection handle
*/

public void checkIfActive(ConnectionHolder ch) throws SQLException {
public void checkIfActive(ConnectionHolder connectionHolder) throws SQLException {
if (isDestroyed || !isUsable) {
throw new SQLException(localStrings.getString("jdbc.conn_not_usable"));
}
Expand All @@ -822,6 +839,7 @@ public void decrementCount() {
connectionCount--;
}

@Override
public void dissociateConnections() {
if (myLogicalConnection != null) {
myLogicalConnection.dissociateConnection();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -58,6 +59,15 @@ public abstract class ConnectionHolder implements Connection {
protected boolean wrappedAlready;
protected boolean isClosed;
protected boolean valid = true;

/**
* The active flag is false when the connection handle is created. When a method
* is invoked on this object, it asks the ManagedConnection if it can be the
* active connection handle out of the multiple connection handles. If the
* ManagedConnection reports that this connection handle can be active by
* setting this flag to true via the setActive function, the above method
* invocation succeeds; otherwise an exception is thrown.
*/
protected boolean active;

private LazyAssociatableConnectionManager lazyAssocCm_;
Expand All @@ -77,17 +87,6 @@ public static enum ConnectionType {

private ConnectionType myType_ = ConnectionType.STANDARD;

/**
* The active flag is false when the connection handle is created. When a method
* is invoked on this object, it asks the ManagedConnection if it can be the
* active connection handle out of the multiple connection handles. If the
* ManagedConnection reports that this connection handle can be active by
* setting this flag to true via the setActive function, the above method
* invocation succeeds; otherwise an exception is thrown.
*/



/**
* Constructs a Connection holder.
*
Expand Down Expand Up @@ -168,6 +167,7 @@ public void dissociateConnection() {
*
* @throws SQLException In case of a database error.
*/
@Override
public void clearWarnings() throws SQLException {
checkValidity();
connection.clearWarnings();
Expand All @@ -178,6 +178,7 @@ public void clearWarnings() throws SQLException {
*
* @throws SQLException In case of a database error.
*/
@Override
public void close() throws SQLException {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "ConnectionHolder.close() START managedConnectionImpl=" + managedConnectionImpl);
Expand Down Expand Up @@ -777,11 +778,9 @@ protected void checkValidity() throws SQLException {

/**
* Sets the active flag to true
*
* @param actv boolean
*/
public void setActive(boolean actv) {
active = actv;
public void setActive() {
active = true;
}

/*
Expand Down
Loading

0 comments on commit fd51567

Please sign in to comment.