Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1244 db pool configuration using environment variables #1295

Merged
merged 6 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/xnwh/pools/DefaultConnectionPoolTypes/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<property name="project.name.local2" value="DefaultConnectionPoolTypes" />

<!--Next release version for the archive file-->
<property name="release.number" value="1.0.0"/>
<property name="release.number" value="1.0.1"/>

<property name="target.dir" value="${basedir}/deploy" />

Expand Down
2 changes: 1 addition & 1 deletion components/xnwh/pools/DefaultConnectionPoolTypes/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gip.xyna</groupId>
<artifactId>DefaultConnectionPoolTypes</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Copyright 2022 Xyna GmbH, Germany
* Copyright 2024 Xyna GmbH, Germany
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,7 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
Expand All @@ -38,11 +39,13 @@
import com.gip.xyna.utils.db.ConnectionPool.NoConnectionAvailableException.Reason;
import com.gip.xyna.utils.db.ConnectionPool.NoConnectionAvailableReasonDetector;
import com.gip.xyna.utils.db.DBConnectionData;
import com.gip.xyna.utils.db.DBConnectionData.DBConnectionDataBuilder;
import com.gip.xyna.utils.db.pool.ConnectionBuildStrategy;
import com.gip.xyna.utils.db.pool.DefaultValidationStrategy;
import com.gip.xyna.utils.db.pool.ValidationStrategy;
import com.gip.xyna.utils.misc.Documentation;
import com.gip.xyna.utils.misc.StringParameter;
import com.gip.xyna.utils.misc.EnvironmentVariable.StringEnvironmentVariable;
import com.gip.xyna.utils.timing.Duration;
import com.gip.xyna.xmcp.PluginDescription;
import com.gip.xyna.xmcp.PluginDescription.ParameterUsage;
Expand Down Expand Up @@ -87,8 +90,29 @@ public class MySQLPoolType extends ConnectionPoolType {
defaultValue(Duration.valueOf("10 s")).
build();

public static final List<StringParameter<?>> additionalParameters =
StringParameter.asList( CONNECT_TIMEOUT, SOCKET_TIMEOUT, VALIDATION_TIMEOUT );
public static final StringParameter<StringEnvironmentVariable> USERNAME_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "usernameEnv")
.label("Username environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db username.")
.de("Name der Umgebungsvariable, die den DB Nutzernamen enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> PASSWORD_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "passwordEnv")
.label("Password environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db password.")
.de("Name der Umgebungsvariable, die das DB Passwort enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> CONNECT_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "connectStringEnv")
.label("Connectstring environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the JDBC connect string.")
.de("Name der Umgebungsvariable mit den JDBC Verbindungsdaten.").build())
.optional().build();

public static final List<StringParameter<?>> additionalParameters = StringParameter.asList(CONNECT_TIMEOUT,
SOCKET_TIMEOUT, VALIDATION_TIMEOUT, USERNAME_ENV, PASSWORD_ENV, CONNECT_ENV);

private PluginDescription pluginDescription;

Expand Down Expand Up @@ -168,16 +192,7 @@ public PluginDescription getPluginDescription() {
public ConnectionBuildStrategy createConnectionBuildStrategy(TypedConnectionPoolParameter cpp) {
Duration connectTimeout = CONNECT_TIMEOUT.getFromMap(cpp.getAdditionalParams());
Duration socketTimeout = SOCKET_TIMEOUT.getFromMap(cpp.getAdditionalParams());
DBConnectionData dbdata =
DBConnectionData.newDBConnectionData().
user(cpp.getUser()).password(cpp.getPassword()).url(cpp.getConnectString())
.connectTimeoutInSeconds((int)connectTimeout.getDuration(TimeUnit.SECONDS))
.socketTimeoutInSeconds((int)socketTimeout.getDuration(TimeUnit.SECONDS))
.classLoaderToLoadDriver(MySQLPoolType.class.getClassLoader()) // enforcing the connector jar to be stored in userlib
.property("rewriteBatchedStatements", "true")
.build();

return new MySQLConnectionBuildStrategy(dbdata, (int)connectTimeout.getDuration(TimeUnit.SECONDS) );
return new MySQLConnectionBuildStrategy(cpp, (int)connectTimeout.getDuration(TimeUnit.SECONDS), (int)socketTimeout.getDuration(TimeUnit.SECONDS) );
}


Expand All @@ -191,16 +206,55 @@ public ValidationStrategy createValidationStrategy(TypedConnectionPoolParameter
public static class MySQLConnectionBuildStrategy implements ConnectionBuildStrategy {

private static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(1, 1000, 10, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
private TypedConnectionPoolParameter tcpp;
private DBConnectionData dbdata;
private int connectTimeout;
private int socketTimeout;
private String poolId;

public MySQLConnectionBuildStrategy(DBConnectionData dbdata, int connectTimeout) {
this.dbdata = dbdata;
private final Optional<StringEnvironmentVariable> userEnv;
private final Optional<StringEnvironmentVariable> pwdEnv;
private final Optional<StringEnvironmentVariable> connectStringEnv;

public MySQLConnectionBuildStrategy(TypedConnectionPoolParameter tcpp, int connectTimeout, int socketTimeout) {
this.tcpp = tcpp;
this.dbdata = null;
this.connectTimeout = connectTimeout;
this.socketTimeout = socketTimeout;

userEnv = Optional
.ofNullable(USERNAME_ENV.getFromMap(tcpp.getAdditionalParams()));
pwdEnv = Optional
.ofNullable(PASSWORD_ENV.getFromMap(tcpp.getAdditionalParams()));
connectStringEnv = Optional
.ofNullable(CONNECT_ENV.getFromMap(tcpp.getAdditionalParams()));
}

private void updateDBConnectData() {
String user = userEnv.flatMap(u -> u.getValue()).filter(s -> !s.isEmpty()).orElse(tcpp.getUser()).trim();
String pwd = pwdEnv.flatMap(p -> p.getValue()).filter(s -> !s.isEmpty()).orElse(tcpp.getPassword()).trim();
String connString = connectStringEnv.flatMap(c -> c.getValue()).filter(s -> !s.isEmpty())
.orElse(tcpp.getConnectString()).trim();

if (dbdata == null) {
dbdata = DBConnectionData.newDBConnectionData().user(user).password(pwd).url(connString)
.connectTimeoutInSeconds(connectTimeout)
.socketTimeoutInSeconds(socketTimeout)
.classLoaderToLoadDriver(MySQLPoolType.class.getClassLoader()) // enforcing the connector jar to be stored
// in userlib
.property("rewriteBatchedStatements", "true")
.build();
} else {
if (dbdata.getUrl().equals(connString) && dbdata.getUser().equals(user) && dbdata.getPassword().equals(pwd))
return;

dbdata = (new DBConnectionDataBuilder(dbdata)).user(user).password(pwd).url(connString).build();
}
}

public Connection createNewConnection() {
updateDBConnectData();

Connection con = createNewConnectionInternal();
if (con == null) {
throw new RuntimeException("Could not create connection but returned null.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
Expand All @@ -30,11 +31,13 @@
import com.gip.xyna.utils.db.ConnectionPool.NoConnectionAvailableException.Reason;
import com.gip.xyna.utils.db.ConnectionPool.NoConnectionAvailableReasonDetector;
import com.gip.xyna.utils.db.DBConnectionData;
import com.gip.xyna.utils.db.DBConnectionData.DBConnectionDataBuilder;
import com.gip.xyna.utils.db.pool.ConnectionBuildStrategy;
import com.gip.xyna.utils.db.pool.FastValidationStrategy;
import com.gip.xyna.utils.db.pool.ValidationStrategy;
import com.gip.xyna.utils.misc.Documentation;
import com.gip.xyna.utils.misc.StringParameter;
import com.gip.xyna.utils.misc.EnvironmentVariable.StringEnvironmentVariable;
import com.gip.xyna.utils.timing.Duration;
import com.gip.xyna.xmcp.PluginDescription;
import com.gip.xyna.xmcp.PluginDescription.ParameterUsage;
Expand Down Expand Up @@ -87,9 +90,30 @@ public class OraclePoolType extends ConnectionPoolType {
build()).
defaultValue(false).
build();

public static final List<StringParameter<?>> additionalParameters =
StringParameter.asList( CONNECT_TIMEOUT, SOCKET_TIMEOUT, VALIDATION_TIMEOUT, DURABLE_STATEMENT_CACHE );

public static final StringParameter<StringEnvironmentVariable> USERNAME_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "usernameEnv")
.label("Username environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db username.")
.de("Name der Umgebungsvariable, die den DB Nutzernamen enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> PASSWORD_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "passwordEnv")
.label("Password environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db password.")
.de("Name der Umgebungsvariable, die das DB Passwort enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> CONNECT_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "connectStringEnv")
.label("Connectstring environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the JDBC connect string.")
.de("Name der Umgebungsvariable mit den JDBC Verbindungsdaten.").build())
.optional().build();

public static final List<StringParameter<?>> additionalParameters = StringParameter.asList(CONNECT_TIMEOUT,
SOCKET_TIMEOUT, VALIDATION_TIMEOUT, DURABLE_STATEMENT_CACHE, USERNAME_ENV, PASSWORD_ENV, CONNECT_ENV);

private PluginDescription pluginDescription;

Expand Down Expand Up @@ -121,32 +145,65 @@ public ConnectionBuildStrategy createConnectionBuildStrategy(TypedConnectionPool
Duration connectTimeout = CONNECT_TIMEOUT.getFromMap(cpp.getAdditionalParams());
Duration socketTimeout = SOCKET_TIMEOUT.getFromMap(cpp.getAdditionalParams());
Boolean useDurableStatementCache = DURABLE_STATEMENT_CACHE.getFromMap(cpp.getAdditionalParams());

DBConnectionData dbdata =
DBConnectionData.newDBConnectionData().
user(cpp.getUser()).password(cpp.getPassword()).url(cpp.getConnectString())
.connectTimeoutInSeconds((int)connectTimeout.getDuration(TimeUnit.SECONDS))
.socketTimeoutInSeconds((int)socketTimeout.getDuration(TimeUnit.SECONDS))
.classLoaderToLoadDriver(OraclePoolType.class.getClassLoader()) // enforcing the connector jar to be stored in userlib
.property("rewriteBatchedStatements", "true")
.build();

return new OracleConnectionBuildStrategy(dbdata, useDurableStatementCache);

return new OracleConnectionBuildStrategy(cpp, useDurableStatementCache,
(int) connectTimeout.getDuration(TimeUnit.SECONDS), (int) socketTimeout.getDuration(TimeUnit.SECONDS));
}


public static class OracleConnectionBuildStrategy implements ConnectionBuildStrategy {

private TypedConnectionPoolParameter tcpp;
private DBConnectionData dbdata;
private int connectTimeout;
private int socketTimeout;
private boolean useDurableStatementCache;
private String poolId;

public OracleConnectionBuildStrategy(DBConnectionData dbdata, boolean useDurableStatementCache) {
this.dbdata = dbdata;
private final Optional<StringEnvironmentVariable> userEnv;
private final Optional<StringEnvironmentVariable> pwdEnv;
private final Optional<StringEnvironmentVariable> connectStringEnv;

public OracleConnectionBuildStrategy(TypedConnectionPoolParameter tcpp, boolean useDurableStatementCache, int connectTimeout, int socketTimeout) {
this.tcpp = tcpp;
this.socketTimeout = socketTimeout;
this.connectTimeout = connectTimeout;
this.dbdata = null;
this.useDurableStatementCache = useDurableStatementCache;

userEnv = Optional
.ofNullable(USERNAME_ENV.getFromMap(tcpp.getAdditionalParams()));
pwdEnv = Optional
.ofNullable(PASSWORD_ENV.getFromMap(tcpp.getAdditionalParams()));
connectStringEnv = Optional
.ofNullable(CONNECT_ENV.getFromMap(tcpp.getAdditionalParams()));
}

private void updateDBConnectData() {
String user = userEnv.flatMap(u -> u.getValue()).filter(s -> !s.isEmpty()).orElse(tcpp.getUser()).trim();
String pwd = pwdEnv.flatMap(p -> p.getValue()).filter(s -> !s.isEmpty()).orElse(tcpp.getPassword()).trim();
String connString = connectStringEnv.flatMap(c -> c.getValue()).filter(s -> !s.isEmpty())
.orElse(tcpp.getConnectString()).trim();

if (dbdata == null) {
dbdata = DBConnectionData.newDBConnectionData().user(user).password(pwd).url(connString)
.connectTimeoutInSeconds(connectTimeout)
.socketTimeoutInSeconds(socketTimeout)
.classLoaderToLoadDriver(OraclePoolType.class.getClassLoader()) // enforcing the connector jar to be stored
// in userlib
.property("rewriteBatchedStatements", "true")
.build();
} else {
if (dbdata.getUrl().equals(connString) && dbdata.getUser().equals(user) && dbdata.getPassword().equals(pwd))
return;

dbdata = (new DBConnectionDataBuilder(dbdata)).user(user).password(pwd).url(connString).build();
}
}

public Connection createNewConnection() {
updateDBConnectData();

try {
Connection con = dbdata.createConnection();
if (useDurableStatementCache) {
Expand Down
2 changes: 1 addition & 1 deletion components/xnwh/pools/MockConnectionPoolTypes/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<property name="project.name.local2" value="MockConnectionPoolTypes" />

<!--Next release version for the archive file-->
<property name="release.number" value="1.0.0"/>
<property name="release.number" value="1.0.1"/>

<property name="target.dir" value="${basedir}/deploy" />

Expand Down
2 changes: 1 addition & 1 deletion components/xnwh/pools/MockConnectionPoolTypes/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gip.xyna</groupId>
<artifactId>MockConnectionPoolTypes</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.gip.xyna.utils.db.pool.ValidationStrategy;
import com.gip.xyna.utils.misc.Documentation;
import com.gip.xyna.utils.misc.StringParameter;
import com.gip.xyna.utils.misc.EnvironmentVariable.StringEnvironmentVariable;
import com.gip.xyna.utils.timing.Duration;
import com.gip.xyna.xmcp.PluginDescription;
import com.gip.xyna.xmcp.PluginDescription.ParameterUsage;
Expand Down Expand Up @@ -70,8 +71,29 @@ public class MockMySQLPoolType extends ConnectionPoolType {
defaultValue(Duration.valueOf("10 s")).
build();

public static final List<StringParameter<?>> additionalParameters =
StringParameter.asList( CONNECT_TIMEOUT, SOCKET_TIMEOUT, VALIDATION_TIMEOUT );
public static final StringParameter<StringEnvironmentVariable> USERNAME_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "usernameEnv")
.label("Username environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db username.")
.de("Name der Umgebungsvariable, die den DB Nutzernamen enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> PASSWORD_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "passwordEnv")
.label("Password environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the db password.")
.de("Name der Umgebungsvariable, die das DB Passwort enthält.").build())
.optional().build();

public static final StringParameter<StringEnvironmentVariable> CONNECT_ENV = StringParameter
.typeEnvironmentVariable(StringEnvironmentVariable.class, "connectStringEnv")
.label("Connectstring environment variable.")
.documentation(Documentation.en("Name of the environment variable containing the JDBC connect string.")
.de("Name der Umgebungsvariable mit den JDBC Verbindungsdaten.").build())
.optional().build();

public static final List<StringParameter<?>> additionalParameters = StringParameter.asList(CONNECT_TIMEOUT,
SOCKET_TIMEOUT, VALIDATION_TIMEOUT, USERNAME_ENV, PASSWORD_ENV, CONNECT_ENV);

private PluginDescription pluginDescription;

Expand Down
2 changes: 1 addition & 1 deletion installation/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ build_conpooltypes() {
echo "building connectionpooltypes..."
cd $SCRIPT_DIR/build
ant -Doracle.home=/tmp conpooltypes
mvn install:install-file -Dfile=../../common/lib/xyna/DefaultConnectionPoolTypes-1.0.0.jar -DpomFile=../../components/xnwh/pools/DefaultConnectionPoolTypes/pom.xml
mvn install:install-file -Dfile=../../common/lib/xyna/DefaultConnectionPoolTypes-1.0.1.jar -DpomFile=../../components/xnwh/pools/DefaultConnectionPoolTypes/pom.xml
}

build_persistencelayers() {
Expand Down
2 changes: 1 addition & 1 deletion installation/build/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<dependency>
<groupId>com.gip.xyna</groupId>
<artifactId>DefaultConnectionPoolTypes</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>com.gip.xyna</groupId>
Expand Down
Loading
Loading