diff --git a/pom.xml b/pom.xml index ae5c57c..233bb51 100644 --- a/pom.xml +++ b/pom.xml @@ -217,7 +217,7 @@ org.mariadb.jdbc mariadb-java-client - 2.7.3 + 3.0.6 com.fasterxml.jackson.core diff --git a/src/main/groovy/life/qbic/DataSource.groovy b/src/main/groovy/life/qbic/DataSource.groovy index 0db5240..76d1927 100644 --- a/src/main/groovy/life/qbic/DataSource.groovy +++ b/src/main/groovy/life/qbic/DataSource.groovy @@ -20,6 +20,7 @@ interface DataSource { * execution of the connection object with a try-with-resource statement or call the * {@link AutoCloseable#close()} method explicitly.

* @return a connection to the datasource + * @throws {@link TimeOutException} when a connection cannot be acquired from the data source */ - Connection getConnection() + Connection getConnection() throws TimeOutException } diff --git a/src/main/groovy/life/qbic/QBiCDataSource.groovy b/src/main/groovy/life/qbic/QBiCDataSource.groovy index c84b502..6eaf084 100644 --- a/src/main/groovy/life/qbic/QBiCDataSource.groovy +++ b/src/main/groovy/life/qbic/QBiCDataSource.groovy @@ -1,8 +1,11 @@ package life.qbic +import groovy.util.logging.Log4j2 + import javax.inject.Inject import javax.inject.Singleton import java.sql.Connection +import java.sql.SQLTimeoutException /** * QBiCDataSource Class @@ -12,11 +15,15 @@ import java.sql.Connection * @since 1.2.1 */ @Singleton +@Log4j2 class QBiCDataSource implements DataSource { - javax.sql.DataSource source + private final static int MAX_RETRY_COUNT = 3 + + private final javax.sql.DataSource source - @Inject QBiCDataSource (javax.sql.DataSource source) { + @Inject + QBiCDataSource(javax.sql.DataSource source) { this.source = source } @@ -24,7 +31,21 @@ class QBiCDataSource implements DataSource { * {@InheritDocs} */ @Override - Connection getConnection() { + Connection getConnection() throws TimeOutException { + Connection connection = null + int turn = 1 + while (!connection) { + if (turn == MAX_RETRY_COUNT) { + throw new TimeOutException("Maximum number of tries reached ($MAX_RETRY_COUNT), connection to database server timed out repeatedly.") + } + try { + connection = this.source.getConnection() + } catch (SQLTimeoutException e) { + log.error("Turn $turn to get connection failed.") + log.error("Connection to database server timed out.", e) + } + turn++; + } return this.source.connection } } diff --git a/src/main/groovy/life/qbic/TimeOutException.java b/src/main/groovy/life/qbic/TimeOutException.java new file mode 100644 index 0000000..4738c38 --- /dev/null +++ b/src/main/groovy/life/qbic/TimeOutException.java @@ -0,0 +1,23 @@ +package life.qbic; + +/** + * Timeout Exception + *

+ * Is thrown when connections to a data source cannot be established. + * + * @since 2.2.3 + */ +public class TimeOutException extends RuntimeException { + + public TimeOutException() { + } + + public TimeOutException(String message) { + super(message); + } + + public TimeOutException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/groovy/life/qbic/db/MariaDBManager.groovy b/src/main/groovy/life/qbic/db/MariaDBManager.groovy index c9f70e3..dab0383 100644 --- a/src/main/groovy/life/qbic/db/MariaDBManager.groovy +++ b/src/main/groovy/life/qbic/db/MariaDBManager.groovy @@ -3,7 +3,9 @@ package life.qbic.db import groovy.sql.GroovyRowResult import groovy.sql.Sql import groovy.util.logging.Log4j2 +import life.qbic.DataSource import life.qbic.QBiCDataSource +import life.qbic.TimeOutException import life.qbic.api.rest.v2.samples.SampleStatusDto import life.qbic.datamodel.identifiers.SampleCodeFunctions import life.qbic.datamodel.people.Address @@ -27,7 +29,6 @@ import org.codehaus.groovy.runtime.DefaultGroovyMethods import javax.inject.Inject import javax.inject.Singleton -import javax.sql.DataSource import java.sql.Connection import java.sql.SQLException import java.sql.Timestamp @@ -49,7 +50,15 @@ class MariaDBManager implements IQueryService, INotificationService, SampleEvent @Inject MariaDBManager(QBiCDataSource dataSource) { - this.dataSource = dataSource.getSource() + this.dataSource = dataSource + } + + private Connection getConnection() throws UnrecoverableException { + try { + return dataSource.getConnection() + } catch (TimeOutException exception) { + throw new UnrecoverableException("Connection to data source timed out", exception) + } } void addNewLocation(String sampleId, Location location) throws IllegalArgumentException {