This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 9da2d23406496d77344a1fad18112f35ac2c9565 Author: Benoit Tellier <[email protected]> AuthorDate: Sun Nov 28 15:13:38 2021 +0700 JAMES-3676 Allow configuring S3 driver read, write and connection timeout --- .../modules/ROOT/pages/configure/blobstore.adoc | 9 ++++ .../aws/S3BlobStoreConfiguration.java | 56 ++++++++++++++++++++-- .../S3BlobStoreConfigurationReader.java | 15 ++++++ src/site/xdoc/server/config-blobstore.xml | 9 ++++ 4 files changed, 86 insertions(+), 3 deletions(-) diff --git a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/blobstore.adoc b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/blobstore.adoc index d8e58c2..66bdd4f 100644 --- a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/blobstore.adoc +++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/blobstore.adoc @@ -139,6 +139,15 @@ Maximum size of stored objects expressed in bytes. | objectstorage.s3.truststore.algorithm | optional: Use this specific trust store algorithm; default SunX509 + +| objectstorage.s3.read.timeout +| optional: HTTP read timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults. + +| objectstorage.s3.write.timeout +| optional: HTTP write timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults. + +| objectstorage.s3.connection.timeout +| optional: HTTP connection timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults. |=== ==== Buckets Configuration diff --git a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreConfiguration.java b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreConfiguration.java index a456d4a..7af3064 100644 --- a/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreConfiguration.java +++ b/server/blob/blob-s3/src/main/java/org/apache/james/blob/objectstorage/aws/S3BlobStoreConfiguration.java @@ -19,6 +19,7 @@ package org.apache.james.blob.objectstorage.aws; +import java.time.Duration; import java.util.Objects; import java.util.Optional; @@ -52,6 +53,9 @@ public class S3BlobStoreConfiguration { private Optional<BucketName> defaultBucketName; private Optional<String> bucketPrefix; private Optional<Integer> httpConcurrency; + private Optional<Duration> readTimeout; + private Optional<Duration> writeTimeout; + private Optional<Duration> connectionTimeout; private Region region; public ReadyToBuild(AwsS3AuthConfiguration specificAuthConfiguration, Region region) { @@ -60,6 +64,9 @@ public class S3BlobStoreConfiguration { this.defaultBucketName = Optional.empty(); this.bucketPrefix = Optional.empty(); this.httpConcurrency = Optional.empty(); + this.readTimeout = Optional.empty(); + this.writeTimeout = Optional.empty(); + this.connectionTimeout = Optional.empty(); } public ReadyToBuild defaultBucketName(Optional<BucketName> defaultBucketName) { @@ -77,6 +84,21 @@ public class S3BlobStoreConfiguration { return this; } + public ReadyToBuild writeTimeout(Optional<Duration> writeTimeout) { + this.writeTimeout = writeTimeout; + return this; + } + + public ReadyToBuild connectionTimeout(Optional<Duration> connectionTimeout) { + this.connectionTimeout = connectionTimeout; + return this; + } + + public ReadyToBuild readTimeout(Optional<Duration> readTimeout) { + this.readTimeout = readTimeout; + return this; + } + public ReadyToBuild bucketPrefix(String bucketPrefix) { this.bucketPrefix = Optional.ofNullable(bucketPrefix); return this; @@ -88,7 +110,7 @@ public class S3BlobStoreConfiguration { } public S3BlobStoreConfiguration build() { - return new S3BlobStoreConfiguration(bucketPrefix, defaultBucketName, region, specificAuthConfiguration, httpConcurrency.orElse(DEFAULT_HTTP_CONCURRENCY)); + return new S3BlobStoreConfiguration(bucketPrefix, defaultBucketName, region, specificAuthConfiguration, httpConcurrency.orElse(DEFAULT_HTTP_CONCURRENCY), readTimeout, writeTimeout, connectionTimeout); } } @@ -101,18 +123,27 @@ public class S3BlobStoreConfiguration { private final Optional<BucketName> namespace; private final Optional<String> bucketPrefix; private final int httpConcurrency; + private Optional<Duration> readTimeout; + private Optional<Duration> writeTimeout; + private Optional<Duration> connectionTimeout; @VisibleForTesting S3BlobStoreConfiguration(Optional<String> bucketPrefix, Optional<BucketName> namespace, Region region, AwsS3AuthConfiguration specificAuthConfiguration, - int httpConcurrency) { + int httpConcurrency, + Optional<Duration> readTimeout, + Optional<Duration> writeTimeout, + Optional<Duration> connectionTimeout) { this.bucketPrefix = bucketPrefix; this.namespace = namespace; this.region = region; this.specificAuthConfiguration = specificAuthConfiguration; this.httpConcurrency = httpConcurrency; + this.readTimeout = readTimeout; + this.writeTimeout = writeTimeout; + this.connectionTimeout = connectionTimeout; } public Optional<BucketName> getNamespace() { @@ -135,6 +166,18 @@ public class S3BlobStoreConfiguration { return region; } + public Optional<Duration> getReadTimeout() { + return readTimeout; + } + + public Optional<Duration> getWriteTimeout() { + return writeTimeout; + } + + public Optional<Duration> getConnectionTimeout() { + return connectionTimeout; + } + @Override public final boolean equals(Object o) { if (o instanceof S3BlobStoreConfiguration) { @@ -144,6 +187,9 @@ public class S3BlobStoreConfiguration { && Objects.equals(this.bucketPrefix, that.bucketPrefix) && Objects.equals(this.region, that.region) && Objects.equals(this.httpConcurrency, that.httpConcurrency) + && Objects.equals(this.readTimeout, that.readTimeout) + && Objects.equals(this.writeTimeout, that.writeTimeout) + && Objects.equals(this.connectionTimeout, that.connectionTimeout) && Objects.equals(this.specificAuthConfiguration, that.specificAuthConfiguration); } return false; @@ -151,7 +197,8 @@ public class S3BlobStoreConfiguration { @Override public final int hashCode() { - return Objects.hash(namespace, bucketPrefix, httpConcurrency, specificAuthConfiguration); + return Objects.hash(namespace, bucketPrefix, httpConcurrency, specificAuthConfiguration, + readTimeout, writeTimeout, connectionTimeout); } @Override @@ -162,6 +209,9 @@ public class S3BlobStoreConfiguration { .add("bucketPrefix", bucketPrefix) .add("region", region) .add("specificAuthConfiguration", specificAuthConfiguration) + .add("readTimeout", readTimeout) + .add("writeTimeout", writeTimeout) + .add("connectionTimeout", connectionTimeout) .toString(); } } diff --git a/server/container/guice/blob/s3/src/main/java/org/apache/james/modules/objectstorage/S3BlobStoreConfigurationReader.java b/server/container/guice/blob/s3/src/main/java/org/apache/james/modules/objectstorage/S3BlobStoreConfigurationReader.java index 44b74f6..9a3bded 100644 --- a/server/container/guice/blob/s3/src/main/java/org/apache/james/modules/objectstorage/S3BlobStoreConfigurationReader.java +++ b/server/container/guice/blob/s3/src/main/java/org/apache/james/modules/objectstorage/S3BlobStoreConfigurationReader.java @@ -19,6 +19,8 @@ package org.apache.james.modules.objectstorage; +import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.Optional; import org.apache.commons.configuration2.Configuration; @@ -27,6 +29,7 @@ import org.apache.james.blob.api.BucketName; import org.apache.james.blob.objectstorage.aws.Region; import org.apache.james.blob.objectstorage.aws.S3BlobStoreConfiguration; import org.apache.james.modules.objectstorage.aws.s3.AwsS3ConfigurationReader; +import org.apache.james.util.DurationParser; public class S3BlobStoreConfigurationReader { @@ -34,6 +37,9 @@ public class S3BlobStoreConfigurationReader { private static final String OBJECTSTORAGE_BUCKET_PREFIX = "objectstorage.bucketPrefix"; private static final String OBJECTSTORAGE_S3_REGION = "objectstorage.s3.region"; private static final String OBJECTSTORAGE_S3_HTTP_CONCURRENCY = "objectstorage.s3.http.concurrency"; + private static final String OBJECTSTORAGE_S3_READ_TIMEOUT = "objectstorage.s3.read.timeout"; + private static final String OBJECTSTORAGE_S3_WRITE_TIMEOUT = "objectstorage.s3.write.timeout"; + private static final String OBJECTSTORAGE_S3_CONNECTION_TIMEOUT = "objectstorage.s3.connection.timeout"; public static S3BlobStoreConfiguration from(Configuration configuration) throws ConfigurationException { Optional<Integer> httpConcurrency = Optional.ofNullable(configuration.getInteger(OBJECTSTORAGE_S3_HTTP_CONCURRENCY, null)); @@ -42,6 +48,12 @@ public class S3BlobStoreConfigurationReader { Region region = Optional.ofNullable(configuration.getString(OBJECTSTORAGE_S3_REGION, null)) .map(Region::of) .orElseThrow(() -> new ConfigurationException("require a region (" + OBJECTSTORAGE_S3_REGION + " key)")); + Optional<Duration> readTimeout = Optional.ofNullable(configuration.getString(OBJECTSTORAGE_S3_READ_TIMEOUT, null)) + .map(s -> DurationParser.parse(s, ChronoUnit.SECONDS)); + Optional<Duration> writeTimeout = Optional.ofNullable(configuration.getString(OBJECTSTORAGE_S3_WRITE_TIMEOUT, null)) + .map(s -> DurationParser.parse(s, ChronoUnit.SECONDS)); + Optional<Duration> connectionTimeout = Optional.ofNullable(configuration.getString(OBJECTSTORAGE_S3_CONNECTION_TIMEOUT, null)) + .map(s -> DurationParser.parse(s, ChronoUnit.SECONDS)); return S3BlobStoreConfiguration.builder() .authConfiguration(AwsS3ConfigurationReader.from(configuration)) @@ -49,6 +61,9 @@ public class S3BlobStoreConfigurationReader { .defaultBucketName(namespace.map(BucketName::of)) .bucketPrefix(bucketPrefix) .httpConcurrency(httpConcurrency) + .readTimeout(readTimeout) + .writeTimeout(writeTimeout) + .connectionTimeout(connectionTimeout) .build(); } diff --git a/src/site/xdoc/server/config-blobstore.xml b/src/site/xdoc/server/config-blobstore.xml index c4f12c1..4f25e2e 100644 --- a/src/site/xdoc/server/config-blobstore.xml +++ b/src/site/xdoc/server/config-blobstore.xml @@ -179,6 +179,15 @@ generate salt with : openssl rand -hex 16 <dt><strong>objectstorage.s3.truststore.algorithm</strong></dt> <dd><i>optional:</i> Use this specific trust store algorithm; default SunX509</dd> + + <dt><strong>objectstorage.s3.read.timeout</strong></dt> + <dd><i>optional:</i> HTTP read timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults.</dd> + + <dt><strong>objectstorage.s3.write.timeout</strong></dt> + <dd><i>optional:</i> HTTP write timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults.</dd> + + <dt><strong>objectstorage.s3.connection.timeout</strong></dt> + <dd><i>optional:</i> HTTP connection timeout. duration, default value being second. Leaving it empty relies on S3 driver defaults.</dd> </dl> </subsection> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
