| | |
| | | import io.minio.errors.*; |
| | | import io.minio.http.Method; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import okhttp3.ConnectionPool; |
| | | import okhttp3.ConnectionSpec; |
| | | import okhttp3.OkHttpClient; |
| | | import okhttp3.TlsVersion; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | |
| | | import java.security.ProviderException; |
| | | import java.security.SecureRandom; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.Collections; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import static com.ard.common.config.OssConfiguration.*; |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | public CredentialsDTO getCredentials1111() { |
| | | public CredentialsDTO getCredentials111() { |
| | | try { |
| | | AssumeRoleProvider provider = new AssumeRoleProvider(endpoint, accessKey, |
| | | secretKey, Math.toIntExact(OssConfiguration.expire), |
| | |
| | | public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } |
| | | } |
| | | }; |
| | | SSLContext sslContext = SSLContext.getInstance("TLS"); |
| | | SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); |
| | | sslContext.init(null, trustAllCerts, new SecureRandom()); |
| | | |
| | | ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) |
| | | .tlsVersions(TlsVersion.TLS_1_2) |
| | | .allEnabledCipherSuites() |
| | | .build(); |
| | | |
| | | OkHttpClient httpClient = new OkHttpClient.Builder() |
| | | .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]) |
| | | .sslSocketFactory(sslContext.getSocketFactory(), |
| | | (X509TrustManager) trustAllCerts[0]) |
| | | .hostnameVerifier((hostname, session) -> true) |
| | | .connectionSpecs(Collections.singletonList(spec)) // ⭐关键 |
| | | .connectionPool(new ConnectionPool(0, 1, TimeUnit.SECONDS)) // ⭐禁用复用 |
| | | .build(); |
| | | |
| | | // 构建 AssumeRoleProvider,使用自定义 httpClient |
| | |
| | | @Override |
| | | public Boolean deleteObject(String bucket, String objectKey) { |
| | | try { |
| | | // 检查文件是否存在 |
| | | client.statObject(StatObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .build()); |
| | | |
| | | // 文件存在,执行删除 |
| | | client.removeObject(RemoveObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .build()); |
| | | |
| | | log.info("成功删除文件: {}/{}", bucket, objectKey); |
| | | return true; |
| | | } catch (ErrorResponseException e) { |
| | | // 文件不存在的情况 |
| | | log.warn("文件不存在: {}/{}", bucket, objectKey); |
| | | } catch (MinioException | NoSuchAlgorithmException | IOException | InvalidKeyException e) { |
| | | log.error("Failed to delete file."); |
| | | e.printStackTrace(); |
| | | return false; |
| | | } catch (Exception e) { |
| | | log.error("删除文件失败: {}/{}", bucket, objectKey, e); |
| | | throw new RuntimeException("删除文件失败: " + e.getMessage(), e); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public InputStream getObject(String bucket, String objectKey) { |
| | | try { |
| | | GetObjectResponse object = client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
| | | GetObjectResponse object = client.getObject(GetObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .build()); |
| | | return new ByteArrayInputStream(object.readAllBytes()); |
| | | } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) { |
| | | e.printStackTrace(); |
| | |
| | | @Override |
| | | public void putObject(String bucket, String objectKey, InputStream input) { |
| | | try { |
| | | client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
| | | client.statObject(StatObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .build()); |
| | | throw new RuntimeException("The filename already exists."); |
| | | } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { |
| | | log.info("The file does not exist, start uploading."); |
| | |
| | | // 设置 partSize 为 10MB |
| | | long partSize = 10 * 1024 * 1024; |
| | | ObjectWriteResponse response = client.putObject( |
| | | PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, -1, partSize).build()); |
| | | PutObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .stream(input, -1, partSize) |
| | | .build()); |
| | | log.info("Upload File: {}", response.etag()); |
| | | } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) { |
| | | log.error("Failed to upload File {}.", objectKey); |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void putObject(String bucket, String objectKey, InputStream input, String contentType) { |
| | | try { |
| | | // 检查文件是否已经存在 |
| | | client.statObject(StatObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .build()); |
| | | throw new RuntimeException("The file already exists: " + objectKey); |
| | | } catch (ErrorResponseException e) { |
| | | // 如果文件不存在,则继续上传 |
| | | log.info("The file does not exist, start uploading."); |
| | | try { |
| | | // 设置 partSize 为 10MB |
| | | long partSize = 10 * 1024 * 1024; // 每块 10MB |
| | | PutObjectArgs.Builder putArgsBuilder = PutObjectArgs.builder() |
| | | .bucket(bucket) |
| | | .object(objectKey) |
| | | .stream(input, -1, partSize); |
| | | |
| | | // 如果提供了 Content-Type,则设置该类型 |
| | | if (contentType != null && !contentType.isEmpty()) { |
| | | putArgsBuilder.contentType(contentType); |
| | | } |
| | | |
| | | // 上传文件 |
| | | ObjectWriteResponse response = client.putObject(putArgsBuilder.build()); |
| | | log.info("Uploaded file successfully: {}, ETag: {}", objectKey, response.etag()); |
| | | |
| | | } catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) { |
| | | log.error("Failed to upload file: {}", objectKey, ex); |
| | | throw new RuntimeException("File upload failed: " + objectKey, ex); |
| | | } |
| | | } catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { |
| | | // 如果 statObject 发生错误,说明服务端错误或其他问题 |
| | | log.error("Failed to check if file exists: {}", objectKey, e); |
| | | throw new RuntimeException("Failed to check if file exists: " + objectKey, e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void createClient() { |
| | | if (Objects.nonNull(this.client)) { |
| | |
| | | OkHttpClient httpClient = new OkHttpClient.Builder() |
| | | .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]) |
| | | .hostnameVerifier((hostname, session) -> true) |
| | | .connectionSpecs(Collections.singletonList( |
| | | new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) |
| | | .tlsVersions(TlsVersion.TLS_1_2) // 强制 TLS1.2 |
| | | .build() |
| | | )) |
| | | .build(); |
| | | |
| | | this.client = MinioClient.builder() |