From 8a9b904339df5674ba2ba1e6cce605ad704291c9 Mon Sep 17 00:00:00 2001 From: Nicolas de Pomereu Date: Mon, 12 Aug 2024 16:06:50 +0200 Subject: [PATCH] Add maxRetries & retryIntervalMs mangement in HTTP calls --- .settings/org.eclipse.jdt.core.prefs | 15 +++++++ .../aceql/jdbc/commons/ConnectionInfo.java | 34 +++++++++++++++- .../jdbc/commons/ConnectionInfoHolder.java | 1 + .../aceql/jdbc/commons/InternalWrapper.java | 8 ++-- .../util/DriverPropertyInfoBuilder.java | 17 +++++++- .../jdbc/commons/driver/util/DriverUtil.java | 39 +++++++++++++++++++ .../jdbc/commons/main/http/HttpManager.java | 8 ++-- .../aceql/jdbc/driver/free/AceQLDriver.java | 8 +++- 8 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 .settings/org.eclipse.jdt.core.prefs diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..0fee6a9c --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/src/main/java/com/aceql/jdbc/commons/ConnectionInfo.java b/src/main/java/com/aceql/jdbc/commons/ConnectionInfo.java index f297fa5f..53e9276f 100644 --- a/src/main/java/com/aceql/jdbc/commons/ConnectionInfo.java +++ b/src/main/java/com/aceql/jdbc/commons/ConnectionInfo.java @@ -67,6 +67,9 @@ public class ConnectionInfo { private Map requestProperties = new HashMap<>(); private String clobReadCharset; private String clobWriteCharset; + + private int maxRetries; + private int retryIntervalMs; /** * Package protected constructor, Driver users can not instantiate the class. @@ -87,6 +90,9 @@ public class ConnectionInfo { this.requestProperties = connectionInfoHolder.getRequestProperties(); this.clobReadCharset = connectionInfoHolder.getClobReadCharset(); this.clobWriteCharset = connectionInfoHolder.getClobWriteCharset(); + + this.maxRetries = connectionInfoHolder.getMaxRetries(); + this.retryIntervalMs = connectionInfoHolder.getRetryIntervalMs(); } // /** @@ -275,8 +281,29 @@ public Instant getCreationDateTime() { return creationDateTime; } - @Override - public String toString() { + + /** + * Gets the maximum number of retries for failed requests. + * @return the maximum number of retries for failed requests. + */ + public int getMaxRetries() { + return maxRetries; + } + + void setMaxRetries(int maxRetries) { + this.maxRetries = maxRetries; + } + + /** + * Gets the interval between retries in milliseconds. + * @return the interval between retries in milliseconds. + */ + public int getRetryIntervalMs() { + return retryIntervalMs; + } + + //@Override + public String _toString() { String username = authentication.getUserName(); String proxyUsername = proxyAuthentication != null ? proxyAuthentication.getUserName() : null; @@ -285,8 +312,11 @@ public String toString() { + ", creationDateTime=" + creationDateTime + ", passwordIsSessionId=" + passwordIsSessionId + ", proxy=" + proxy + ", proxyAuthentication=" + proxyUsername + ", connectTimeout=" + connectTimeout + ", readTimeout=" + readTimeout + ", gzipResult=" + gzipResult + + ", maxRetries=" + maxRetries + ", retryIntervalMs=" + retryIntervalMs + ", resultSetMetaDataPolicy=" + resultSetMetaDataPolicy + ", requestProperties=" + requestProperties + ", clobReadCharset=" + clobReadCharset + ", clobWriteCharset=" + clobWriteCharset + "]"; } + + } diff --git a/src/main/java/com/aceql/jdbc/commons/ConnectionInfoHolder.java b/src/main/java/com/aceql/jdbc/commons/ConnectionInfoHolder.java index d120ad39..8dd30faa 100644 --- a/src/main/java/com/aceql/jdbc/commons/ConnectionInfoHolder.java +++ b/src/main/java/com/aceql/jdbc/commons/ConnectionInfoHolder.java @@ -28,6 +28,7 @@ public class ConnectionInfoHolder { // New 9.4 private int maxRetries = 0; private int retryIntervalMs = 0; + public String getUrl() { return url; } diff --git a/src/main/java/com/aceql/jdbc/commons/InternalWrapper.java b/src/main/java/com/aceql/jdbc/commons/InternalWrapper.java index 9280c00c..b6ae0618 100644 --- a/src/main/java/com/aceql/jdbc/commons/InternalWrapper.java +++ b/src/main/java/com/aceql/jdbc/commons/InternalWrapper.java @@ -21,15 +21,12 @@ import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import java.net.PasswordAuthentication; -import java.net.Proxy; import java.sql.SQLException; -import java.util.Map; +import java.time.Instant; import com.aceql.jdbc.commons.main.http.AceQLHttpApi; import com.aceql.jdbc.commons.main.metadata.dto.DatabaseInfoDto; import com.aceql.jdbc.commons.main.metadata.dto.LimitsInfoDto; -import com.aceql.jdbc.commons.metadata.ResultSetMetaDataPolicy; /** * A internal wrapper for Java package protected calls.
@@ -81,6 +78,9 @@ public static ConnectionInfo connectionInfoBuilder(ConnectionInfoHolder Connecti return new ConnectionInfo(ConnectionInfoHolder); } + public static void setCreationDateTime(ConnectionInfo connectionInfo, Instant instant) { + connectionInfo.setCreationDateTime(instant); + } public static DatabaseInfo databaseInfoBuilder(AceQLHttpApi aceQLHttpApi) throws AceQLException { DatabaseInfoDto databaseInfoDto = aceQLHttpApi.getDatabaseInfoDto(); diff --git a/src/main/java/com/aceql/jdbc/commons/driver/util/DriverPropertyInfoBuilder.java b/src/main/java/com/aceql/jdbc/commons/driver/util/DriverPropertyInfoBuilder.java index e203188c..8191b39b 100644 --- a/src/main/java/com/aceql/jdbc/commons/driver/util/DriverPropertyInfoBuilder.java +++ b/src/main/java/com/aceql/jdbc/commons/driver/util/DriverPropertyInfoBuilder.java @@ -21,10 +21,13 @@ public class DriverPropertyInfoBuilder { public static final String GZIP_RESULT = "Boolean to say if the ResultSet is Gzipped before download. Defaults to true."; public static final String CLOB_CHARSET = "Name of the charset to use when reading a CLOB content with the ResultSet methods. Defaults to null."; - public static final String DEFINES_THE_RESULT_SET_META_DATA_POLICY = "Defines the ResultSet MetaData policy. Says if the ResultSet MetaData is to be downloaded along with the ResultSet. Possible values are \"on\" and \"off\". Defaults to \"on\"."; private static final String CLOB_WRITE_CHARSET = "Name of the charset to use when writing a CLOB content with the PreparedStatement streaming methods. Defaults to \"UTF-8\"."; + public static final String MAX_RETRIES = "Maximum number of retries for connecting to the remote server. Defaults to 3."; + public static final String RETRY_DELAY = "Delay in milliseconds between retries. Defaults to 3000."; + + /** * Build a new DriverPropertyInfo with the passed property * @@ -122,6 +125,18 @@ public List build(Properties info) { driverPropertyInfo.required = false; driverPropertyInfoList.add(driverPropertyInfo); + driverPropertyInfo = getNewDriverPropertyInfo("maxRetries", info); + driverPropertyInfo.description = MAX_RETRIES; + driverPropertyInfo.required = false; + driverPropertyInfo.value = "3"; + driverPropertyInfoList.add(driverPropertyInfo); + + driverPropertyInfo = getNewDriverPropertyInfo("retryIntervalMs", info); + driverPropertyInfo.description = RETRY_DELAY; + driverPropertyInfo.required = false; + driverPropertyInfo.value = "3000"; + driverPropertyInfoList.add(driverPropertyInfo); + List list = new ArrayList<>(); list.add("on"); list.add("off"); diff --git a/src/main/java/com/aceql/jdbc/commons/driver/util/DriverUtil.java b/src/main/java/com/aceql/jdbc/commons/driver/util/DriverUtil.java index d6c713f8..7d23e52e 100644 --- a/src/main/java/com/aceql/jdbc/commons/driver/util/DriverUtil.java +++ b/src/main/java/com/aceql/jdbc/commons/driver/util/DriverUtil.java @@ -211,6 +211,45 @@ public static Map getQueryMap(String query) { return map; } + /** + * Return the value of a property, taking into account the request properties + * @param info the properties + * @return the value of the property or null if not found + * @throws SQLException + */ + public static int getMaxRetries(Properties info) throws SQLException { + String maxRetriesStr = info.getProperty("maxRetries"); + if (maxRetriesStr == null) { + return 0; + } + + int maxRetries = 0; + try { + maxRetries = Integer.parseInt(maxRetriesStr); + } catch (NumberFormatException e) { + throw new SQLException(Tag.PRODUCT + " Invalid maxRetries, is not numeric: " + maxRetries); + } + + return maxRetries; + } + + public static int getIntervalRetryMs(Properties info) throws SQLException { + String intervalRetryMsStr = info.getProperty("intervalRetryMs"); + if (intervalRetryMsStr == null) { + return 0; + } + + int intervalRetryMs = 0; + try { + intervalRetryMs = Integer.parseInt(intervalRetryMsStr); + } catch (NumberFormatException e) { + throw new SQLException(Tag.PRODUCT + " Invalid intervalRetryMs, is not numeric: " + intervalRetryMsStr); + } + + return intervalRetryMs; + + } + /** * Copy a set of properties from one Property to another. *

diff --git a/src/main/java/com/aceql/jdbc/commons/main/http/HttpManager.java b/src/main/java/com/aceql/jdbc/commons/main/http/HttpManager.java index fe2972ba..d1611abe 100644 --- a/src/main/java/com/aceql/jdbc/commons/main/http/HttpManager.java +++ b/src/main/java/com/aceql/jdbc/commons/main/http/HttpManager.java @@ -141,8 +141,8 @@ public PasswordAuthentication getPasswordAuthentication() { public InputStream callWithGetReturnStream(String url) throws MalformedURLException, IOException, UnsupportedEncodingException { - int maxRetries = 3; - int retryIntervalMs = 1000; + int maxRetries = this.connectionInfo.getMaxRetries(); + int retryIntervalMs = this.connectionInfo.getRetryIntervalMs(); /* * if (httpVersion == 1) { return callWithGetInputStreamHttp11(url); } else { @@ -241,8 +241,8 @@ public String callWithGet(String url) public InputStream callWithPost(URL theUrl, Map parameters) throws IOException, ProtocolException, SocketTimeoutException, UnsupportedEncodingException { - int maxRetries = 3; - int retryIntervalMs = 1000; + int maxRetries = this.connectionInfo.getMaxRetries(); + int retryIntervalMs = this.connectionInfo.getRetryIntervalMs(); /* * if (httpVersion == 1) { return callWithGetInputStreamHttp11(url); } else { diff --git a/src/main/java/com/aceql/jdbc/driver/free/AceQLDriver.java b/src/main/java/com/aceql/jdbc/driver/free/AceQLDriver.java index b2b19f91..13e5739f 100644 --- a/src/main/java/com/aceql/jdbc/driver/free/AceQLDriver.java +++ b/src/main/java/com/aceql/jdbc/driver/free/AceQLDriver.java @@ -263,6 +263,8 @@ public Connection connect(String url, Properties info) throws SQLException { passwordIsSessionId = true; } + int maxRetries= DriverUtil.getMaxRetries(info); + int retryIntervalMs = DriverUtil.getIntervalRetryMs(info); ConnectionInfoHolder connectionInfoHolder = new ConnectionInfoHolder(); connectionInfoHolder.setAuthentication(authentication); @@ -271,15 +273,17 @@ public Connection connect(String url, Properties info) throws SQLException { connectionInfoHolder.setConnectTimeout(connectTimeout); connectionInfoHolder.setDatabase(database); connectionInfoHolder.setGzipResult(gzipResult); - connectionInfoHolder.setMaxRetries(3); connectionInfoHolder.setPasswordIsSessionId(passwordIsSessionId); connectionInfoHolder.setProxy(proxy); + connectionInfoHolder.setProxyAuthentication(proxyAuthentication); connectionInfoHolder.setReadTimeout(readTimeout); connectionInfoHolder.setRequestProperties(requestProperties); connectionInfoHolder.setResultSetMetaDataPolicy(resultSetMetaDataPolicy); - connectionInfoHolder.setRetryIntervalMs(1000); connectionInfoHolder.setUrl(url); + connectionInfoHolder.setMaxRetries(maxRetries); + connectionInfoHolder.setRetryIntervalMs(retryIntervalMs); + ConnectionInfo connectionInfo = InternalWrapper.connectionInfoBuilder(connectionInfoHolder); AceQLConnection connection = InternalWrapper.connectionBuilder(connectionInfo);