1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 6 package software.amazon.awssdk.crt.s3; 7 8 import software.amazon.awssdk.crt.http.HttpMonitoringOptions; 9 import software.amazon.awssdk.crt.http.HttpProxyEnvironmentVariableSetting; 10 import software.amazon.awssdk.crt.http.HttpProxyOptions; 11 import software.amazon.awssdk.crt.io.ClientBootstrap; 12 import software.amazon.awssdk.crt.io.TlsContext; 13 import software.amazon.awssdk.crt.io.StandardRetryOptions; 14 import software.amazon.awssdk.crt.auth.credentials.CredentialsProvider; 15 import software.amazon.awssdk.crt.auth.signing.AwsSigningConfig; 16 import software.amazon.awssdk.crt.auth.signing.AwsSigningConfig.AwsSigningAlgorithm; 17 18 public class S3ClientOptions { 19 20 private String endpoint; 21 private String region; 22 private ClientBootstrap clientBootstrap; 23 private TlsContext tlsContext; 24 private CredentialsProvider credentialsProvider; 25 private AwsSigningConfig signingConfig; 26 private long partSize; 27 private long multipartUploadThreshold; 28 private double throughputTargetGbps; 29 private boolean readBackpressureEnabled; 30 private long initialReadWindowSize; 31 private int maxConnections; 32 private boolean enableS3Express; 33 private long memoryLimitInBytes; 34 private S3ExpressCredentialsProviderFactory s3expressCredentialsProviderFactory; 35 /** 36 * For multi-part upload, content-md5 will be calculated if the 37 * computeContentMd5 is set to true. 38 * 39 * For single-part upload, leave the md5 header as-is if it was specified. If 40 * the header is not set by in the initial request, it will calculated, when the 41 * computeContentMd5 is set to true. 42 * 43 * Default is false; 44 */ 45 private Boolean computeContentMd5; 46 private StandardRetryOptions standardRetryOptions; 47 48 /** 49 * Optional. 50 * Proxy configuration for http connection. 51 */ 52 private HttpProxyOptions proxyOptions; 53 54 /** 55 * Optional. 56 * Configuration for fetching proxy configuration from environment. 57 * By Default read proxy configuration from environment is enabled. 58 * Only works when proxyOptions is not set. If both are set, configuration from 59 * proxy_options is used. 60 */ 61 private HttpProxyEnvironmentVariableSetting httpProxyEnvironmentVariableSetting; 62 63 /** 64 * Optional. 65 * If set to 0, default value is used. 66 */ 67 private int connectTimeoutMs; 68 69 /** 70 * Optional. 71 * Set keepalive to periodically transmit messages for detecting a disconnected 72 * peer. 73 */ 74 private S3TcpKeepAliveOptions tcpKeepAliveOptions; 75 76 private HttpMonitoringOptions monitoringOptions; 77 S3ClientOptions()78 public S3ClientOptions() { 79 this.computeContentMd5 = false; 80 } 81 withRegion(String region)82 public S3ClientOptions withRegion(String region) { 83 this.region = region; 84 return this; 85 } 86 getRegion()87 public String getRegion() { 88 return region; 89 } 90 withClientBootstrap(ClientBootstrap clientBootstrap)91 public S3ClientOptions withClientBootstrap(ClientBootstrap clientBootstrap) { 92 this.clientBootstrap = clientBootstrap; 93 return this; 94 } 95 getClientBootstrap()96 public ClientBootstrap getClientBootstrap() { 97 return clientBootstrap; 98 } 99 100 /** 101 * @deprecated Please use {@link #withSigningConfig(AwsSigningConfig)} instead. 102 * The credentials provider will be used to create the signing Config when the client was created. 103 * Client will use `AwsSigningConfig.getDefaultS3SigningConfig(region, credentialsProvider);` to create the signing config. 104 * 105 * @param credentialsProvider provide credentials for signing. 106 * @return this 107 */ withCredentialsProvider(CredentialsProvider credentialsProvider)108 public S3ClientOptions withCredentialsProvider(CredentialsProvider credentialsProvider) { 109 this.credentialsProvider = credentialsProvider; 110 return this; 111 } 112 getCredentialsProvider()113 public CredentialsProvider getCredentialsProvider() { 114 return credentialsProvider; 115 } 116 117 /** 118 * The configuration related to signing used by S3 client. 119 * `AwsSigningConfig.getDefaultS3SigningConfig(region, credentialsProvider);` can be used as helper to create the default configuration to be used for S3. 120 * In case of public object, or the http message already has a presigned URL, signing can be skipped. 121 * 122 * If not set, a default config will be used with anonymous credentials and skip signing the request. 123 * If set: 124 * - Credentials provider is required. Other configs are all optional, and will be default to what 125 * needs to sign the request for S3, only overrides when Non-zero/Not-empty is set. 126 * - S3 Client will derive the right config for signing process based on this. 127 * 128 * Notes: 129 * - For SIGV4_S3EXPRESS, S3 client will use the credentials in the config to derive the S3 Express 130 * credentials that are used in the signing process. 131 * - Client may make modifications to signing config before passing it on to signer. 132 * 133 * @param signingConfig configuration related to signing via an AWS signing process. 134 * @return this 135 */ withSigningConfig(AwsSigningConfig signingConfig)136 public S3ClientOptions withSigningConfig(AwsSigningConfig signingConfig) { 137 this.signingConfig = signingConfig; 138 return this; 139 } 140 getSigningConfig()141 public AwsSigningConfig getSigningConfig() { 142 return signingConfig; 143 } 144 withPartSize(long partSize)145 public S3ClientOptions withPartSize(long partSize) { 146 this.partSize = partSize; 147 return this; 148 } 149 getPartSize()150 public long getPartSize() { 151 return partSize; 152 } 153 withMultipartUploadThreshold(long multipartUploadThreshold)154 public S3ClientOptions withMultipartUploadThreshold(long multipartUploadThreshold) { 155 this.multipartUploadThreshold = multipartUploadThreshold; 156 return this; 157 } 158 getMultiPartUploadThreshold()159 public long getMultiPartUploadThreshold() { 160 return multipartUploadThreshold; 161 } 162 withThroughputTargetGbps(double throughputTargetGbps)163 public S3ClientOptions withThroughputTargetGbps(double throughputTargetGbps) { 164 this.throughputTargetGbps = throughputTargetGbps; 165 return this; 166 } 167 getThroughputTargetGbps()168 public double getThroughputTargetGbps() { 169 return throughputTargetGbps; 170 } 171 172 /** 173 * Set whether backpressure is enabled (false by default), to prevent response data downloading faster than you can handle it. 174 * <p> 175 * If false, no backpressure is applied and data will download as fast as possible. 176 * <p> 177 * If true, each S3MetaRequest has a flow-control window that shrinks as 178 * response body data is downloaded (headers do not affect the window). 179 * {@link #withInitialReadWindowSize} determines the starting size of each S3MetaRequest's window, in bytes. 180 * Data stops downloading data whenever the window reaches zero. 181 * Increment the window to keep data flowing by calling {@link S3MetaRequest#incrementReadWindow}, 182 * or by returning a size from {@link S3MetaRequestResponseHandler#onResponseBody}. 183 * Maintain a larger window to keep up a high download throughput, 184 * parts cannot download in parallel unless the window is large enough to hold multiple parts. 185 * Maintain a smaller window to limit the amount of data buffered in memory. 186 * <p> 187 * WARNING: This feature is experimental. 188 * Currently, backpressure is only applied to GetObject requests which are split into multiple parts, 189 * and you may still receive some data after the window reaches zero. 190 * 191 * @param enable whether to enable or disable backpressure 192 * @return this 193 */ withReadBackpressureEnabled(boolean enable)194 public S3ClientOptions withReadBackpressureEnabled(boolean enable) { 195 this.readBackpressureEnabled = enable; 196 return this; 197 } 198 getReadBackpressureEnabled()199 public boolean getReadBackpressureEnabled() { 200 return this.readBackpressureEnabled; 201 } 202 203 /** 204 * The starting size of each S3MetaRequest's flow-control window (if backpressure is enabled). 205 * 206 * @see #withReadBackpressureEnabled 207 * 208 * @param bytes size in bytes 209 * @return this 210 */ withInitialReadWindowSize(long bytes)211 public S3ClientOptions withInitialReadWindowSize(long bytes) { 212 initialReadWindowSize = bytes; 213 return this; 214 } 215 getInitialReadWindowSize()216 public long getInitialReadWindowSize() { 217 return this.initialReadWindowSize; 218 } 219 220 /* 221 * @deprecated does not have any effect. Use endpoint option or add Host 222 * header to meta request in order to specify endpoint. 223 */ 224 @Deprecated withEndpoint(String endpoint)225 public S3ClientOptions withEndpoint(String endpoint) { 226 this.endpoint = endpoint; 227 return this; 228 } 229 getEndpoint()230 public String getEndpoint() { 231 return endpoint; 232 } 233 withTlsContext(TlsContext tlsContext)234 public S3ClientOptions withTlsContext(TlsContext tlsContext) { 235 this.tlsContext = tlsContext; 236 return this; 237 } 238 getTlsContext()239 public TlsContext getTlsContext() { 240 return tlsContext; 241 } 242 withMaxConnections(int maxConnections)243 public S3ClientOptions withMaxConnections(int maxConnections) { 244 this.maxConnections = maxConnections; 245 return this; 246 } 247 getMaxConnections()248 public int getMaxConnections() { 249 return maxConnections; 250 } 251 withComputeContentMd5(Boolean computeContentMd5)252 public S3ClientOptions withComputeContentMd5(Boolean computeContentMd5) { 253 this.computeContentMd5 = computeContentMd5; 254 return this; 255 } 256 getComputeContentMd5()257 public Boolean getComputeContentMd5() { 258 return computeContentMd5; 259 } 260 withStandardRetryOptions(StandardRetryOptions standardRetryOptions)261 public S3ClientOptions withStandardRetryOptions(StandardRetryOptions standardRetryOptions) { 262 this.standardRetryOptions = standardRetryOptions; 263 return this; 264 } 265 getStandardRetryOptions()266 public StandardRetryOptions getStandardRetryOptions() { 267 return this.standardRetryOptions; 268 } 269 withProxyOptions(HttpProxyOptions proxyOptions)270 public S3ClientOptions withProxyOptions(HttpProxyOptions proxyOptions) { 271 this.proxyOptions = proxyOptions; 272 return this; 273 } 274 getProxyOptions()275 public HttpProxyOptions getProxyOptions() { 276 return proxyOptions; 277 } 278 withProxyEnvironmentVariableSetting( HttpProxyEnvironmentVariableSetting httpProxyEnvironmentVariableSetting)279 public S3ClientOptions withProxyEnvironmentVariableSetting( 280 HttpProxyEnvironmentVariableSetting httpProxyEnvironmentVariableSetting) { 281 this.httpProxyEnvironmentVariableSetting = httpProxyEnvironmentVariableSetting; 282 return this; 283 } 284 getHttpProxyEnvironmentVariableSetting()285 public HttpProxyEnvironmentVariableSetting getHttpProxyEnvironmentVariableSetting() { 286 return httpProxyEnvironmentVariableSetting; 287 } 288 withConnectTimeoutMs(int connectTimeoutMs)289 public S3ClientOptions withConnectTimeoutMs(int connectTimeoutMs) { 290 this.connectTimeoutMs = connectTimeoutMs; 291 return this; 292 } 293 getConnectTimeoutMs()294 public int getConnectTimeoutMs() { 295 return connectTimeoutMs; 296 } 297 withS3TcpKeepAliveOptions(S3TcpKeepAliveOptions tcpKeepAliveOptions)298 public S3ClientOptions withS3TcpKeepAliveOptions(S3TcpKeepAliveOptions tcpKeepAliveOptions) { 299 this.tcpKeepAliveOptions = tcpKeepAliveOptions; 300 return this; 301 } 302 getTcpKeepAliveOptions()303 public S3TcpKeepAliveOptions getTcpKeepAliveOptions() { 304 return tcpKeepAliveOptions; 305 } 306 307 /** 308 * Options for detecting bad HTTP connections. 309 * If the transfer throughput falls below the specified thresholds 310 * for long enough, the operation is retried on a new connection. 311 * If left unset, default values are used. 312 * 313 * @param monitoringOptions monitoring options 314 * @return this 315 */ withHttpMonitoringOptions(HttpMonitoringOptions monitoringOptions)316 public S3ClientOptions withHttpMonitoringOptions(HttpMonitoringOptions monitoringOptions) { 317 this.monitoringOptions = monitoringOptions; 318 return this; 319 } 320 getMonitoringOptions()321 public HttpMonitoringOptions getMonitoringOptions() { 322 return monitoringOptions; 323 } 324 325 /** 326 * To enable S3 Express support for client 327 * The typical usage for a S3 Express request is to set this to true and let the request to be signed with 328 * {@link AwsSigningAlgorithm#SIGV4_S3EXPRESS}, either from the client level signingConfig or override from request. 329 * 330 * @param enableS3Express To enable S3 Express support for client 331 * @return this 332 */ withEnableS3Express(boolean enableS3Express)333 public S3ClientOptions withEnableS3Express(boolean enableS3Express) { 334 this.enableS3Express = enableS3Express; 335 return this; 336 } 337 getEnableS3Express()338 public boolean getEnableS3Express() { 339 return enableS3Express; 340 } 341 withS3ExpressCredentialsProviderFactory(S3ExpressCredentialsProviderFactory s3expressCredentialsProviderFactory)342 public S3ClientOptions withS3ExpressCredentialsProviderFactory(S3ExpressCredentialsProviderFactory s3expressCredentialsProviderFactory) { 343 this.s3expressCredentialsProviderFactory = s3expressCredentialsProviderFactory; 344 return this; 345 } 346 getS3ExpressCredentialsProviderFactory()347 public S3ExpressCredentialsProviderFactory getS3ExpressCredentialsProviderFactory() { 348 return s3expressCredentialsProviderFactory; 349 } 350 351 /** 352 * The amount of memory the CRT client is allowed to use. 353 * The client makes a best-effort attempt at memory limiting but might exceed this limit in some cases. 354 * If not provided, the client calculates this optimally from other settings, such as targetThroughput. 355 * On a 64-bit system, the default is between 2Gib-8Gib. 356 * It must be at least 1GiB and will be capped to SIZE_MAX of the system. 357 * @param memoryLimitBytes Memory limit in bytes. 358 * @return this 359 */ withMemoryLimitInBytes(long memoryLimitBytes)360 public S3ClientOptions withMemoryLimitInBytes(long memoryLimitBytes) { 361 this.memoryLimitInBytes = memoryLimitBytes; 362 return this; 363 } 364 365 /** 366 * Retrieves the memory limit set for the CRT client in bytes. 367 * If not set, this will return 0. 368 * @return long memory limit in bytes 369 */ getMemoryLimitInBytes()370 public long getMemoryLimitInBytes() { 371 return memoryLimitInBytes; 372 } 373 } 374