001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.db.storage.s3; 029 030import org.opencms.util.CmsStringUtil; 031 032import software.amazon.awssdk.regions.Region; 033 034/** 035 * Configuration for the S3 client used by the storage backend.<p> 036 */ 037public class CmsS3ClientConfiguration { 038 039 /** Default complete API call timeout in milliseconds. */ 040 public static final int DEFAULT_API_CALL_TIMEOUT = 60000; 041 042 /** Default single API call attempt timeout in milliseconds. */ 043 public static final int DEFAULT_API_CALL_ATTEMPT_TIMEOUT = 30000; 044 045 /** Default connection timeout in milliseconds. */ 046 public static final int DEFAULT_CONNECTION_TIMEOUT = 5000; 047 048 /** Default timeout for acquiring a pooled connection in milliseconds. */ 049 public static final int DEFAULT_CONNECTION_ACQUISITION_TIMEOUT = 10000; 050 051 /** Default maximum number of pooled connections. */ 052 public static final int DEFAULT_MAX_CONNECTIONS = 50; 053 054 /** Default maximum number of retries. */ 055 public static final int DEFAULT_MAX_RETRIES = 2; 056 057 /** Default AWS region. */ 058 public static final String DEFAULT_REGION = Region.AWS_GLOBAL.id(); 059 060 /** Default socket timeout in milliseconds. */ 061 public static final int DEFAULT_SOCKET_TIMEOUT = 30000; 062 063 /** The S3 access key. */ 064 private final String m_accessKey; 065 066 /** The complete API call timeout in milliseconds. */ 067 private final int m_apiCallTimeout; 068 069 /** The single API call attempt timeout in milliseconds. */ 070 private final int m_apiCallAttemptTimeout; 071 072 /** The bucket name. */ 073 private final String m_bucketName; 074 075 /** The connection timeout in milliseconds. */ 076 private final int m_connectionTimeout; 077 078 /** The timeout for acquiring a pooled connection in milliseconds. */ 079 private final int m_connectionAcquisitionTimeout; 080 081 /** The endpoint. */ 082 private final String m_endpoint; 083 084 /** The maximum number of retries. */ 085 private final int m_maxRetries; 086 087 /** The maximum number of pooled connections. */ 088 private final int m_maxConnections; 089 090 /** Whether path-style access should be used. */ 091 private final boolean m_pathStyle; 092 093 /** The AWS region. */ 094 private final String m_region; 095 096 /** The S3 secret key. */ 097 private final String m_secretKey; 098 099 /** The socket timeout in milliseconds. */ 100 private final int m_socketTimeout; 101 102 /** 103 * Creates a new S3 client configuration.<p> 104 * 105 * @param endpoint the S3 endpoint 106 * @param bucketName the bucket name 107 * @param accessKey the access key 108 * @param secretKey the secret key 109 * @param pathStyle whether path-style access should be used 110 * @param region the AWS region 111 * @param connectionTimeout the connection timeout in milliseconds 112 * @param socketTimeout the socket timeout in milliseconds 113 * @param apiCallAttemptTimeout the timeout for a single API call attempt in milliseconds 114 * @param apiCallTimeout the timeout for the complete API call in milliseconds 115 * @param maxRetries the maximum number of retries 116 */ 117 public CmsS3ClientConfiguration( 118 String endpoint, 119 String bucketName, 120 String accessKey, 121 String secretKey, 122 boolean pathStyle, 123 String region, 124 int connectionTimeout, 125 int socketTimeout, 126 int apiCallAttemptTimeout, 127 int apiCallTimeout, 128 int maxRetries) { 129 130 this( 131 endpoint, 132 bucketName, 133 accessKey, 134 secretKey, 135 pathStyle, 136 region, 137 connectionTimeout, 138 socketTimeout, 139 apiCallAttemptTimeout, 140 apiCallTimeout, 141 maxRetries, 142 DEFAULT_MAX_CONNECTIONS, 143 DEFAULT_CONNECTION_ACQUISITION_TIMEOUT); 144 } 145 146 /** 147 * Creates a new S3 client configuration including connection pool settings.<p> 148 * 149 * @param endpoint the S3 endpoint 150 * @param bucketName the bucket name 151 * @param accessKey the S3 access key 152 * @param secretKey the S3 secret key 153 * @param pathStyle whether path-style access should be used 154 * @param region the AWS region 155 * @param connectionTimeout the connection timeout in milliseconds 156 * @param socketTimeout the socket timeout in milliseconds 157 * @param apiCallAttemptTimeout the timeout for a single API call attempt in milliseconds 158 * @param apiCallTimeout the timeout for the complete API call in milliseconds 159 * @param maxRetries the maximum number of retries 160 * @param maxConnections the maximum number of pooled connections 161 * @param connectionAcquisitionTimeout the timeout for acquiring a pooled connection in milliseconds 162 */ 163 public CmsS3ClientConfiguration( 164 String endpoint, 165 String bucketName, 166 String accessKey, 167 String secretKey, 168 boolean pathStyle, 169 String region, 170 int connectionTimeout, 171 int socketTimeout, 172 int apiCallAttemptTimeout, 173 int apiCallTimeout, 174 int maxRetries, 175 int maxConnections, 176 int connectionAcquisitionTimeout) { 177 178 validateRequired("endpoint", endpoint); 179 validateRequired("bucketName", bucketName); 180 validateRequired("accessKey", accessKey); 181 validateRequired("secretKey", secretKey); 182 validateRequired("region", region); 183 validatePositive("connectionTimeout", connectionTimeout); 184 validatePositive("socketTimeout", socketTimeout); 185 validatePositive("apiCallAttemptTimeout", apiCallAttemptTimeout); 186 validatePositive("apiCallTimeout", apiCallTimeout); 187 validateNonNegative("maxRetries", maxRetries); 188 validatePositive("maxConnections", maxConnections); 189 validatePositive("connectionAcquisitionTimeout", connectionAcquisitionTimeout); 190 m_endpoint = endpoint.trim(); 191 m_bucketName = bucketName.trim(); 192 m_accessKey = accessKey; 193 m_secretKey = secretKey; 194 m_pathStyle = pathStyle; 195 m_region = region.trim(); 196 m_connectionTimeout = connectionTimeout; 197 m_connectionAcquisitionTimeout = connectionAcquisitionTimeout; 198 m_socketTimeout = socketTimeout; 199 m_apiCallAttemptTimeout = apiCallAttemptTimeout; 200 m_apiCallTimeout = apiCallTimeout; 201 m_maxRetries = maxRetries; 202 m_maxConnections = maxConnections; 203 } 204 205 /** 206 * Creates a new S3 client configuration using default client settings.<p> 207 * 208 * @param endpoint the S3 endpoint 209 * @param bucketName the bucket name 210 * @param accessKey the access key 211 * @param secretKey the secret key 212 * @param pathStyle whether path-style access should be used 213 * 214 * @return the configuration 215 */ 216 public static CmsS3ClientConfiguration createDefault( 217 String endpoint, 218 String bucketName, 219 String accessKey, 220 String secretKey, 221 boolean pathStyle) { 222 223 return new CmsS3ClientConfiguration( 224 endpoint, 225 bucketName, 226 accessKey, 227 secretKey, 228 pathStyle, 229 DEFAULT_REGION, 230 DEFAULT_CONNECTION_TIMEOUT, 231 DEFAULT_SOCKET_TIMEOUT, 232 DEFAULT_API_CALL_ATTEMPT_TIMEOUT, 233 DEFAULT_API_CALL_TIMEOUT, 234 DEFAULT_MAX_RETRIES); 235 } 236 237 /** 238 * Validates that a configuration value is not negative.<p> 239 * 240 * @param name the configuration name 241 * @param value the configuration value 242 */ 243 private static void validateNonNegative(String name, int value) { 244 245 if (value < 0) { 246 throw new IllegalArgumentException(name + " must not be negative."); 247 } 248 } 249 250 /** 251 * Validates that a configuration value is positive.<p> 252 * 253 * @param name the configuration name 254 * @param value the configuration value 255 */ 256 private static void validatePositive(String name, int value) { 257 258 if (value <= 0) { 259 throw new IllegalArgumentException(name + " must be positive."); 260 } 261 } 262 263 /** 264 * Validates that a configuration value is not empty.<p> 265 * 266 * @param name the configuration name 267 * @param value the configuration value 268 */ 269 private static void validateRequired(String name, String value) { 270 271 if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) { 272 throw new IllegalArgumentException(name + " must not be empty."); 273 } 274 } 275 276 /** 277 * Returns the access key.<p> 278 * 279 * @return the access key 280 */ 281 public String getAccessKey() { 282 283 return m_accessKey; 284 } 285 286 /** 287 * Returns the single API call attempt timeout.<p> 288 * 289 * @return the timeout in milliseconds 290 */ 291 public int getApiCallAttemptTimeout() { 292 293 return m_apiCallAttemptTimeout; 294 } 295 296 /** 297 * Returns the complete API call timeout.<p> 298 * 299 * @return the timeout in milliseconds 300 */ 301 public int getApiCallTimeout() { 302 303 return m_apiCallTimeout; 304 } 305 306 /** 307 * Returns the bucket name.<p> 308 * 309 * @return the bucket name 310 */ 311 public String getBucketName() { 312 313 return m_bucketName; 314 } 315 316 /** 317 * Returns the timeout for acquiring a pooled connection.<p> 318 * 319 * @return the timeout in milliseconds 320 */ 321 public int getConnectionAcquisitionTimeout() { 322 323 return m_connectionAcquisitionTimeout; 324 } 325 326 /** 327 * Returns the connection timeout.<p> 328 * 329 * @return the timeout in milliseconds 330 */ 331 public int getConnectionTimeout() { 332 333 return m_connectionTimeout; 334 } 335 336 /** 337 * Returns the endpoint.<p> 338 * 339 * @return the endpoint 340 */ 341 public String getEndpoint() { 342 343 return m_endpoint; 344 } 345 346 /** 347 * Returns the maximum number of pooled connections.<p> 348 * 349 * @return the maximum number of pooled connections 350 */ 351 public int getMaxConnections() { 352 353 return m_maxConnections; 354 } 355 356 /** 357 * Returns the maximum number of retries.<p> 358 * 359 * @return the maximum number of retries 360 */ 361 public int getMaxRetries() { 362 363 return m_maxRetries; 364 } 365 366 /** 367 * Returns the configured AWS region.<p> 368 * 369 * @return the AWS region 370 */ 371 public String getRegion() { 372 373 return m_region; 374 } 375 376 /** 377 * Returns the secret key.<p> 378 * 379 * @return the secret key 380 */ 381 public String getSecretKey() { 382 383 return m_secretKey; 384 } 385 386 /** 387 * Returns the socket timeout.<p> 388 * 389 * @return the timeout in milliseconds 390 */ 391 public int getSocketTimeout() { 392 393 return m_socketTimeout; 394 } 395 396 /** 397 * Returns whether path-style access is configured.<p> 398 * 399 * @return true if path-style access is configured 400 */ 401 public boolean isPathStyle() { 402 403 return m_pathStyle; 404 } 405}