This is an automated email from the ASF dual-hosted git repository.

bartmaer pushed a commit to branch 5670
in repository https://gitbox.apache.org/repos/asf/hop.git

commit a435ef3ecae31dfd35a2c7881cfab7a287e82ca2
Author: Bart Maertens <bart.maert...@know.bi>
AuthorDate: Fri Sep 5 14:43:35 2025 +0200

    additional retry options. fixes #5669
---
 .../apache/hop/vfs/gs/GoogleStorageFileSystem.java |  22 ++-
 .../hop/vfs/gs/config/GoogleCloudConfig.java       |  33 +++-
 .../hop/vfs/gs/config/GoogleCloudConfigPlugin.java | 220 +++++++++++++++++++++
 .../gs/config/messages/messages_en_US.properties   |  20 ++
 4 files changed, 288 insertions(+), 7 deletions(-)

diff --git 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/GoogleStorageFileSystem.java
 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/GoogleStorageFileSystem.java
index 711d50f6bb..74a713b781 100644
--- 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/GoogleStorageFileSystem.java
+++ 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/GoogleStorageFileSystem.java
@@ -29,6 +29,8 @@ import org.apache.commons.vfs2.FileSystemException;
 import org.apache.commons.vfs2.FileSystemOptions;
 import org.apache.commons.vfs2.provider.AbstractFileName;
 import org.apache.commons.vfs2.provider.AbstractFileSystem;
+import org.apache.hop.vfs.gs.config.GoogleCloudConfig;
+import org.apache.hop.vfs.gs.config.GoogleCloudConfigSingleton;
 import org.threeten.bp.Duration;
 
 public class GoogleStorageFileSystem extends AbstractFileSystem {
@@ -60,14 +62,22 @@ public class GoogleStorageFileSystem extends 
AbstractFileSystem {
     if (storage != null) {
       return storage;
     }
+
+    GoogleCloudConfig config = GoogleCloudConfigSingleton.getConfig();
+
     RetrySettings retrySettings =
         StorageOptions.getDefaultRetrySettings().toBuilder()
-            // Set the max number of attempts to 10 (initial attempt plus 9 
retries)
-            .setMaxAttempts(10)
-            // Set the backoff multiplier to 3.0
-            .setRetryDelayMultiplier(3.0)
-            // Set the max duration of all attempts to 5 minutes
-            .setTotalTimeout(Duration.ofMinutes(5))
+            .setMaxAttempts(Integer.parseInt(config.getMaxAttempts()))
+            .setInitialRetryDelay(
+                
Duration.ofSeconds(Integer.parseInt(config.getInitialRetryDelay())))
+            
.setRetryDelayMultiplier(Double.parseDouble(config.getRetryDelayMultiplier()))
+            
.setMaxRetryDelay(Duration.ofSeconds(Integer.parseInt(config.getMaxRetryDelay())))
+            
.setTotalTimeout(Duration.ofMinutes(Integer.parseInt(config.getTotalTimeout())))
+            .setInitialRpcTimeout(
+                
Duration.ofSeconds(Integer.parseInt(config.getInitialRpcTimeout())))
+            
.setRpcTimeoutMultiplier(Double.parseDouble(config.getRpcTimeoutMultiplier()))
+            // max RPC Timeout setting causes problems,  disabled for now
+            // 
.setMaxRpcTimeout(Duration.ofSeconds(Integer.parseInt(config.getMaxRpcTimeout())))
             .build();
 
     StorageOptions.Builder optionsBuilder = StorageOptions.newBuilder();
diff --git 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfig.java
 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfig.java
index 98b77be0c6..c4a0023b3d 100644
--- 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfig.java
+++ 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfig.java
@@ -27,11 +27,42 @@ public class GoogleCloudConfig {
   public static final String HOP_CONFIG_GOOGLE_CLOUD_CONFIG_KEY = 
"googleCloud";
 
   private String serviceAccountKeyFile;
+  private String maxAttempts;
+  private String initialRetryDelay;
+  private String retryDelayMultiplier;
+  private String maxRetryDelay;
+  private String totalTimeout;
+  private String initialRpcTimeout;
+  private String rpcTimeoutMultiplier;
+  private String maxRpcTimeout;
+  private String connectionTimeout;
+  private String readTimeout;
 
-  public GoogleCloudConfig() {}
+  public GoogleCloudConfig() {
+    maxAttempts = "6";
+    initialRetryDelay = "1";
+    retryDelayMultiplier = "2.0";
+    maxRetryDelay = "32";
+    totalTimeout = "50";
+    initialRpcTimeout = "50";
+    rpcTimeoutMultiplier = "1.0";
+    maxRpcTimeout = "50";
+    connectionTimeout = "20";
+    readTimeout = "20";
+  }
 
   public GoogleCloudConfig(GoogleCloudConfig config) {
     this();
     serviceAccountKeyFile = config.serviceAccountKeyFile;
+    maxAttempts = config.maxAttempts;
+    initialRetryDelay = config.initialRetryDelay;
+    retryDelayMultiplier = config.retryDelayMultiplier;
+    maxRetryDelay = config.maxRetryDelay;
+    totalTimeout = config.totalTimeout;
+    initialRpcTimeout = config.initialRpcTimeout;
+    rpcTimeoutMultiplier = config.rpcTimeoutMultiplier;
+    maxRpcTimeout = config.maxRpcTimeout;
+    connectionTimeout = config.connectionTimeout;
+    readTimeout = config.readTimeout;
   }
 }
diff --git 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfigPlugin.java
 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfigPlugin.java
index cbe425622e..5780006a3a 100644
--- 
a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfigPlugin.java
+++ 
b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/config/GoogleCloudConfigPlugin.java
@@ -51,6 +51,26 @@ public class GoogleCloudConfigPlugin implements 
IConfigOptions, IGuiPluginCompos
 
   private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_ACCOUNT_KEY_FILE =
       "10000-google-cloud-service-account-key-file";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_ATTEMPTS =
+      "10100-google-cloud-service-max-attempts";
+  private static final String 
WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RETRY_DELAY =
+      "10200-google-cloud-service-initial-retry-delay";
+  private static final String 
WIDGET_ID_GOOGLE_CLOUD_SERVICE_RETRY_DELAY_MULTIPLIER =
+      "10300-google-cloud-service-retry-delay-multiplier";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RETRY_DELAY =
+      "10400-google-cloud-service-max-retry-delay";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_TOTAL_TIMEOUT =
+      "10500-google-cloud-service-total-timeout";
+  private static final String 
WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RPC_TIMEOUT =
+      "10600-google-cloud-service-inital-rpc-timeout";
+  private static final String 
WIDGET_ID_GOOGLE_CLOUD_SERVICE_RPC_TIMEOUT_MULTIPLIER =
+      "10700-google-cloud-service-rpc-timeout-multiplier";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RPC_TIMEOUT =
+      "10800-google-cloud-service-max-rpc-timeout";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_CONNECT_TIMEOUT =
+      "10900-google-cloud-service-connect-timeout";
+  private static final String WIDGET_ID_GOOGLE_CLOUD_SERVICE_READ_TIMEOUT =
+      "1100-google-cloud-service-read-timeout";
 
   @GuiWidgetElement(
       id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_ACCOUNT_KEY_FILE,
@@ -64,6 +84,96 @@ public class GoogleCloudConfigPlugin implements 
IConfigOptions, IGuiPluginCompos
       description = "Configure the path to a Google Cloud service account JSON 
key file")
   private String serviceAccountKeyFile;
 
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_ATTEMPTS,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.MaxAttempts.Label",
+      toolTip = "i18n::GoogleCloudPlugin.MaxAttempts.Description")
+  private String maxAttempts;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RETRY_DELAY,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.InitialRetryDelay.Label",
+      toolTip = "i18n::GoogleCloudPlugin.InitialRetryDelay.Description")
+  private String initialRetryDelay;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_RETRY_DELAY_MULTIPLIER,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.RetryDelayMultiplier.Label",
+      toolTip = "i18n::GoogleCloudPlugin.RetryDelayMultiplier.Description")
+  private String retryDelayMultiplier;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RETRY_DELAY,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.MaxRetryDelay.Label",
+      toolTip = "i18n::GoogleCloudPlugin.MaxRetryDelay.Description")
+  private String maxRetryDelay;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_TOTAL_TIMEOUT,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.TotalTimeout.Label",
+      toolTip = "i18n::GoogleCloudPlugin.TotalTimeout.Description")
+  private String totalTimeout;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RPC_TIMEOUT,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.InitialRpcTimeout.Label",
+      toolTip = "i18n::GoogleCloudPlugin.InitialRpcTimeout.Description")
+  private String initialRpcTimeout;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_RPC_TIMEOUT_MULTIPLIER,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.RpcTimeoutMultiplier.Label",
+      toolTip = "i18n::GoogleCloudPlugin.RpcTimeoutMultiplier.Description")
+  private String rpcTimeoutMultiplier;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RPC_TIMEOUT,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.MaxRpcTimeout.Label",
+      toolTip = "i18n::GoogleCloudPlugin.MaxRpcTimeout.Description")
+  private String maxRpcTimeout;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_CONNECT_TIMEOUT,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.ConnectTimeout.Label",
+      toolTip = "i18n::GoogleCloudPlugin.ConnectTimeout.Description")
+  private String connectTimeout;
+
+  @GuiWidgetElement(
+      id = WIDGET_ID_GOOGLE_CLOUD_SERVICE_READ_TIMEOUT,
+      parentId = ConfigPluginOptionsTab.GUI_WIDGETS_PARENT_ID,
+      type = GuiElementType.TEXT,
+      variables = true,
+      label = "i18n::GoogleCloudPlugin.ReadTimeout.Label",
+      toolTip = "i18n::GoogleCloudPlugin.ReadTimeout.Description")
+  private String readTimeout;
+
   /**
    * Gets instance
    *
@@ -74,6 +184,16 @@ public class GoogleCloudConfigPlugin implements 
IConfigOptions, IGuiPluginCompos
 
     GoogleCloudConfig config = GoogleCloudConfigSingleton.getConfig();
     instance.serviceAccountKeyFile = config.getServiceAccountKeyFile();
+    instance.maxAttempts = config.getMaxAttempts();
+    instance.initialRetryDelay = config.getInitialRetryDelay();
+    instance.retryDelayMultiplier = config.getRetryDelayMultiplier();
+    instance.maxRetryDelay = config.getMaxRetryDelay();
+    instance.totalTimeout = config.getTotalTimeout();
+    instance.initialRpcTimeout = config.getInitialRpcTimeout();
+    instance.rpcTimeoutMultiplier = config.getRpcTimeoutMultiplier();
+    instance.maxRpcTimeout = config.getMaxRpcTimeout();
+    instance.connectTimeout = config.getConnectionTimeout();
+    instance.readTimeout = config.getReadTimeout();
 
     return instance;
   }
@@ -92,6 +212,67 @@ public class GoogleCloudConfigPlugin implements 
IConfigOptions, IGuiPluginCompos
             "The Google Cloud service account JSON jey file is set to '"
                 + serviceAccountKeyFile
                 + "'");
+
+        changed = true;
+      }
+
+      if (maxAttempts != null) {
+        config.setMaxAttempts(maxAttempts);
+        log.logBasic("Google Cloud service max attempts set to " + 
maxAttempts);
+        changed = true;
+      }
+
+      if (initialRetryDelay != null) {
+        config.setInitialRetryDelay(initialRetryDelay);
+        log.logBasic("Google Cloud service initialRetryDelay set to " + 
initialRetryDelay);
+        changed = true;
+      }
+
+      if (retryDelayMultiplier != null) {
+        config.setRetryDelayMultiplier(retryDelayMultiplier);
+        log.logBasic("Google Cloud service retryDelayMultiplier set to " + 
retryDelayMultiplier);
+        changed = true;
+      }
+
+      if (maxRetryDelay != null) {
+        config.setMaxRetryDelay(maxRetryDelay);
+        log.logBasic("Google Cloud service maxRetryDelay set to " + 
maxRetryDelay);
+        changed = true;
+      }
+
+      if (totalTimeout != null) {
+        config.setTotalTimeout(totalTimeout);
+        log.logBasic("Google Cloud service totalTimeout set to " + 
totalTimeout);
+        changed = true;
+      }
+
+      if (initialRpcTimeout != null) {
+        config.setInitialRpcTimeout(initialRpcTimeout);
+        log.logBasic("Google Cloud service initialRpcTimeout set to " + 
initialRpcTimeout);
+        changed = true;
+      }
+
+      if (rpcTimeoutMultiplier != null) {
+        config.setRpcTimeoutMultiplier(rpcTimeoutMultiplier);
+        log.logBasic("Google Cloud service rpcTimeoutMultiplier set to " + 
rpcTimeoutMultiplier);
+        changed = true;
+      }
+
+      if (maxRpcTimeout != null) {
+        config.setMaxRpcTimeout(maxRpcTimeout);
+        log.logBasic("Google Cloud service maxRpcTimeout set to " + 
maxRpcTimeout);
+        changed = true;
+      }
+
+      if (connectTimeout != null) {
+        config.setConnectionTimeout(connectTimeout);
+        log.logBasic("Google Cloud service connectTimeout set to " + 
connectTimeout);
+        changed = true;
+      }
+
+      if (readTimeout != null) {
+        config.setReadTimeout(readTimeout);
+        log.logBasic("Google Cloud service readTimeout set to " + readTimeout);
         changed = true;
       }
 
@@ -131,6 +312,45 @@ public class GoogleCloudConfigPlugin implements 
IConfigOptions, IGuiPluginCompos
           serviceAccountKeyFile = ((TextVar) control).getText();
           
GoogleCloudConfigSingleton.getConfig().setServiceAccountKeyFile(serviceAccountKeyFile);
           break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_ATTEMPTS:
+          maxAttempts = ((TextVar) control).getText();
+          GoogleCloudConfigSingleton.getConfig().setMaxAttempts(maxAttempts);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RETRY_DELAY:
+          initialRetryDelay = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setInitialRetryDelay(initialRetryDelay);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_RETRY_DELAY_MULTIPLIER:
+          retryDelayMultiplier = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setRetryDelayMultiplier(retryDelayMultiplier);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RETRY_DELAY:
+          maxRetryDelay = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setMaxRetryDelay(maxRetryDelay);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_TOTAL_TIMEOUT:
+          totalTimeout = ((TextVar) control).getText();
+          GoogleCloudConfigSingleton.getConfig().setTotalTimeout(totalTimeout);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_INITIAL_RPC_TIMEOUT:
+          initialRpcTimeout = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setInitialRpcTimeout(initialRpcTimeout);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_RPC_TIMEOUT_MULTIPLIER:
+          rpcTimeoutMultiplier = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setRpcTimeoutMultiplier(rpcTimeoutMultiplier);
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_MAX_RPC_TIMEOUT:
+          maxRpcTimeout = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setMaxRpcTimeout(maxRpcTimeout);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_CONNECT_TIMEOUT:
+          connectTimeout = ((TextVar) control).getText();
+          
GoogleCloudConfigSingleton.getConfig().setConnectionTimeout(connectTimeout);
+          break;
+        case WIDGET_ID_GOOGLE_CLOUD_SERVICE_READ_TIMEOUT:
+          readTimeout = ((TextVar) control).getText();
+          GoogleCloudConfigSingleton.getConfig().setReadTimeout(readTimeout);
+          break;
       }
     }
     // Save the project...
diff --git 
a/plugins/tech/google/src/main/resources/org/apache/hop/vfs/gs/config/messages/messages_en_US.properties
 
b/plugins/tech/google/src/main/resources/org/apache/hop/vfs/gs/config/messages/messages_en_US.properties
index 4469d8b7be..99813db674 100644
--- 
a/plugins/tech/google/src/main/resources/org/apache/hop/vfs/gs/config/messages/messages_en_US.properties
+++ 
b/plugins/tech/google/src/main/resources/org/apache/hop/vfs/gs/config/messages/messages_en_US.properties
@@ -20,3 +20,23 @@
 GoogleCloudPlugin.AccountKeyFile.Description=The path to a Google Cloud 
service account JSON key file
 GoogleCloudPlugin.AccountKeyFile.Label=Account key file
 GoogleCloudPlugin.GuiPlugin.Description=Google Cloud
+GoogleCloudPlugin.MaxAttempts.Label=Max number of attempts
+GoogleCloudPlugin.MaxAttempts.Description=Max number of attempts
+GoogleCloudPlugin.InitialRetryDelay.Label=Initial retry delay
+GoogleCloudPlugin.InitialRetryDelay.Description=Initial retry delay
+GoogleCloudPlugin.RetryDelayMultiplier.Label=Retry delay multiplier
+GoogleCloudPlugin.RetryDelayMultiplier.Description=Retry delay multiplier
+GoogleCloudPlugin.MaxRetryDelay.Label=Maximum retry delay
+GoogleCloudPlugin.MaxRetryDelay.Description=Maximum retry delay
+GoogleCloudPlugin.TotalTimeout.Label=Total Timeout
+GoogleCloudPlugin.TotalTimeout.Description=Total Timeout
+GoogleCloudPlugin.InitialRpcTimeout.Label=Initial RPC Timeout
+GoogleCloudPlugin.InitialRpcTimeout.Description=Initial RPC Timeout
+GoogleCloudPlugin.RpcTimeoutMultiplier.Label=RPC Timeout Multiplier
+GoogleCloudPlugin.RpcTimeoutMultiplier.Description=RPC Timeout Multiplier
+GoogleCloudPlugin.MaxRpcTimeout.Label=Max RPC Timeout
+GoogleCloudPlugin.MaxRpcTimeout.Description=Max RPC Timeout
+GoogleCloudPlugin.ConnectTimeout.Label=Connect Timeout
+GoogleCloudPlugin.ConnectTimeout.Description=Connect Timeout
+GoogleCloudPlugin.ReadTimeout.Label=Read Timeout
+GoogleCloudPlugin.ReadTimeout.Description=Read Timeout
\ No newline at end of file

Reply via email to