-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: backport the pool fix by copying the upstream module
- Loading branch information
Showing
19 changed files
with
1,194 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# SQL Pool Apache Commons Pool | ||
|
||
This extension registers named `javax.sql.DataSource`s to | ||
the `org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry` | ||
capable of pooling `java.sql.Connection`s. The pooling mechanism is backed by | ||
the [Apache Commons Pool library](https://commons.apache.org/proper/commons-pool/). | ||
|
||
## Old Configuration (Deprecated since 0.3.1) | ||
|
||
| Key | Description | Mandatory | | ||
|:--------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------|-----------| | ||
| edc.datasource.<datasource_name>.url | JDBC driver url | X | | ||
| edc.datasource.<datasource_name>.pool.maxIdleConnections | The maximum amount of idling connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.maxTotalConnections | The maximum amount of total connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.minIdleConnections | The minimum amount of idling connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.testConnectionOnBorrow | Flag to define whether connections will be validated when a connection has been obtained from the pool | | | ||
| edc.datasource.<datasource_name>.pool.testConnectionOnCreate | Flag to define whether connections will be validated when a connection has been established | | | ||
| edc.datasource.<datasource_name>.pool.testConnectionOnReturn | Flag to define whether connections will be validated when a connection has been returned to the pool | | | ||
| edc.datasource.<datasource_name>.pool.testConnectionWhileIdle | Flag to define whether idling connections will be validated | | | ||
| edc.datasource.<datasource_name>.pool.testQuery | Test query to validate a connection maintained by the pool | | | ||
| edc.datasource.<datasource_name>.<jdbc_properties> | JDBC driver specific configuration properties | | | ||
|
||
## New Configuration (since 0.3.1) | ||
|
||
| Key | Description | Mandatory | | ||
|:-----------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------|-----------| | ||
| edc.datasource.<datasource_name>.url | JDBC driver url | X | | ||
| edc.datasource.<datasource_name>.pool.connections.max-idle | The maximum amount of idling connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.connections.max-total | The maximum amount of total connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.connections.min-idle | The minimum amount of idling connections maintained by the pool | | | ||
| edc.datasource.<datasource_name>.pool.connection.test.on-borrow | Flag to define whether connections will be validated when a connection has been obtained from the pool | | | ||
| edc.datasource.<datasource_name>.pool.connection.test.on-create | Flag to define whether connections will be validated when a connection has been established | | | ||
| edc.datasource.<datasource_name>.pool.connection.test.on-return | Flag to define whether connections will be validated when a connection has been returned to the pool | | | ||
| edc.datasource.<datasource_name>.pool.connection.test.while-idle | Flag to define whether idling connections will be validated | | | ||
| edc.datasource.<datasource_name>.pool.connection.test.query | Test query to validate a connection maintained by the pool | | | ||
| edc.datasource.<datasource_name>.<jdbc_properties> | JDBC driver specific configuration properties | | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (c) 2021 Daimler TSS GmbH | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Apache License, Version 2.0 which is available at | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Daimler TSS GmbH - Initial build file | ||
* | ||
*/ | ||
|
||
plugins { | ||
`java-library` | ||
`java-test-fixtures` | ||
`maven-publish` | ||
} | ||
|
||
|
||
dependencies { | ||
api(libs.edc.spi.transaction.datasource) | ||
api(libs.edc.sql.core) | ||
implementation(libs.apache.commons.pool) | ||
|
||
testImplementation(libs.edc.junit) | ||
testImplementation(libs.edc.transaction.local) | ||
|
||
} | ||
|
||
|
170 changes: 170 additions & 0 deletions
170
...l-pool/src/main/java/org/eclipse/tractusx/edc/sql/pool/commons/CommonsConnectionPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Apache License, Version 2.0 which is available at | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.tractusx.edc.sql.pool.commons; | ||
|
||
import org.apache.commons.pool2.BasePooledObjectFactory; | ||
import org.apache.commons.pool2.DestroyMode; | ||
import org.apache.commons.pool2.PooledObject; | ||
import org.apache.commons.pool2.impl.DefaultPooledObject; | ||
import org.apache.commons.pool2.impl.GenericObjectPool; | ||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; | ||
import org.eclipse.edc.spi.monitor.Monitor; | ||
import org.eclipse.edc.spi.persistence.EdcPersistenceException; | ||
import org.eclipse.edc.sql.pool.ConnectionPool; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.SQLException; | ||
import java.util.Objects; | ||
import javax.sql.DataSource; | ||
|
||
public final class CommonsConnectionPool implements ConnectionPool, AutoCloseable { | ||
private final GenericObjectPool<Connection> connectionObjectPool; | ||
private final CommonsConnectionPoolConfig poolConfig; | ||
|
||
public CommonsConnectionPool(DataSource dataSource, CommonsConnectionPoolConfig commonsConnectionPoolConfig, Monitor monitor) { | ||
this.poolConfig = commonsConnectionPoolConfig; | ||
Objects.requireNonNull(dataSource, "connectionFactory"); | ||
Objects.requireNonNull(commonsConnectionPoolConfig, "commonsConnectionPoolConfig"); | ||
|
||
this.connectionObjectPool = new GenericObjectPool<>( | ||
new PooledConnectionObjectFactory(dataSource, commonsConnectionPoolConfig.getTestQuery(), monitor), | ||
getGenericObjectPoolConfig(commonsConnectionPoolConfig)); | ||
} | ||
|
||
private static GenericObjectPoolConfig<Connection> getGenericObjectPoolConfig(CommonsConnectionPoolConfig commonsConnectionPoolConfig) { | ||
GenericObjectPoolConfig<Connection> genericObjectPoolConfig = new GenericObjectPoolConfig<>(); | ||
|
||
// no need for JMX | ||
genericObjectPoolConfig.setJmxEnabled(false); | ||
|
||
genericObjectPoolConfig.setMaxIdle(commonsConnectionPoolConfig.getMaxIdleConnections()); | ||
genericObjectPoolConfig.setMaxTotal(commonsConnectionPoolConfig.getMaxTotalConnections()); | ||
genericObjectPoolConfig.setMinIdle(commonsConnectionPoolConfig.getMinIdleConnections()); | ||
|
||
genericObjectPoolConfig.setTestOnBorrow(commonsConnectionPoolConfig.getTestConnectionOnBorrow()); | ||
genericObjectPoolConfig.setTestOnCreate(commonsConnectionPoolConfig.getTestConnectionOnCreate()); | ||
genericObjectPoolConfig.setTestOnReturn(commonsConnectionPoolConfig.getTestConnectionOnReturn()); | ||
genericObjectPoolConfig.setTestWhileIdle(commonsConnectionPoolConfig.getTestConnectionWhileIdle()); | ||
|
||
return genericObjectPoolConfig; | ||
} | ||
|
||
@Override | ||
public Connection getConnection() { | ||
try { | ||
return connectionObjectPool.borrowObject(); | ||
} catch (Exception e) { | ||
throw new EdcPersistenceException(e.getMessage(), e); | ||
} | ||
} | ||
|
||
@Override | ||
public void returnConnection(Connection connection) { | ||
Objects.requireNonNull(connection, "connection"); | ||
|
||
connectionObjectPool.returnObject(connection); | ||
} | ||
|
||
@Override | ||
public void close() { | ||
connectionObjectPool.close(); | ||
} | ||
|
||
public CommonsConnectionPoolConfig getPoolConfig() { | ||
return poolConfig; | ||
} | ||
|
||
private static class PooledConnectionObjectFactory extends BasePooledObjectFactory<Connection> { | ||
private final String testQuery; | ||
private final DataSource dataSource; | ||
|
||
private final Monitor monitor; | ||
|
||
PooledConnectionObjectFactory(@NotNull DataSource dataSource, @NotNull String testQuery, Monitor monitor) { | ||
this.dataSource = Objects.requireNonNull(dataSource); | ||
this.testQuery = Objects.requireNonNull(testQuery); | ||
this.monitor = monitor; | ||
} | ||
|
||
@Override | ||
public Connection create() throws SQLException { | ||
return dataSource.getConnection(); | ||
} | ||
|
||
@Override | ||
public boolean validateObject(PooledObject<Connection> pooledObject) { | ||
if (pooledObject == null) { | ||
return false; | ||
} | ||
|
||
Connection connection = pooledObject.getObject(); | ||
if (connection == null) { | ||
return false; | ||
} | ||
|
||
return isConnectionValid(connection); | ||
} | ||
|
||
@Override | ||
public PooledObject<Connection> wrap(Connection connection) { | ||
return new DefaultPooledObject<>(connection); | ||
} | ||
|
||
@Override | ||
public void destroyObject(PooledObject<Connection> pooledObject, DestroyMode destroyMode) throws Exception { | ||
if (pooledObject == null) { | ||
return; | ||
} | ||
|
||
Connection connection = pooledObject.getObject(); | ||
|
||
if (connection != null && !connection.isClosed()) { | ||
connection.close(); | ||
} | ||
|
||
pooledObject.invalidate(); | ||
} | ||
|
||
private boolean isConnectionValid(Connection connection) { | ||
try { | ||
if (connection.isClosed()) { | ||
return false; | ||
} | ||
|
||
try (PreparedStatement preparedStatement = connection.prepareStatement(testQuery)) { | ||
preparedStatement.execute(); | ||
return rollbackIfNeeded(connection); | ||
} | ||
} catch (Exception e) { // any exception thrown indicates invalidity of the connection | ||
return false; | ||
} | ||
} | ||
|
||
private boolean rollbackIfNeeded(Connection connection) { | ||
try { | ||
if (!connection.getAutoCommit()) { | ||
connection.rollback(); | ||
} | ||
return true; | ||
} catch (SQLException e) { | ||
monitor.debug("Failed to rollback transaction", e); | ||
} | ||
return false; | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.