Проблемы с регионом в S3AsyncClient и S3TransferManager при использовании Minio с AWS SDK для Java

Я столкнулся с проблемой при настройке S3AsyncClient с использованием AWS SDK для Java в приложении Spring Boot. Несмотря на установку всех необходимых свойств, я продолжаю получать следующее сообщение об ошибке:

 Unable to load region from software.amazon.awssdk.regions.providers.SystemSettingsRegionProvider@ee630de:Unable to load region from system settings. Region must be specified either via environment variable (AWS_REGION) or  system property (aws.region).
s.a.a.r.p.AwsRegionProviderChain : Unable to load region from software.amazon.awssdk.regions.providers.AwsProfileRegionProvider@22590efb:No region provided in profile: default
s.a.a.r.p.AwsRegionProviderChain: Unable to load region from software.amazon.awssdk.regions.providers.InstanceProfileRegionProvider@6c5be4c6:Unable to contact EC2 metadata service.

Конфигурация класса Minio:

minio.access.url=http://localhost:9000
minio.access.name=minioadmin
minio.access.secret=minioadmin

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;

import java.net.URI;

import static software.amazon.awssdk.transfer.s3.SizeConstant.MB;

@Configuration
public class MinioConfig {

    @Value("${minio.access.url}")
    private String minioUrl;

    @Value("${minio.access.name}")
    private String accessKey;

    @Value("${minio.access.secret}")
    private String accessSecret;


    @Bean
    public S3AsyncClient generateMinioClient(){
        return S3AsyncClient.crtBuilder()
                .endpointOverride(URI.create(minioUrl))
                .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, accessSecret)))
                .region(Region.EU_CENTRAL_2)
                .targetThroughputInGbps(20.0)
                .minimumPartSizeInBytes(8 * MB)
                .build();

    }
}

И Сервис:

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileUpload;
import software.amazon.awssdk.transfer.s3.model.UploadFileRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;

import java.net.URI;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;

@Service
@AllArgsConstructor
public class FileStorageService {
    private final StorageSystem storageSystem;

    public CompletableFuture<CompletedFileUpload> uploadFile(String username, String fileName, URI fileUri) {
        try (S3TransferManager transferManager = S3TransferManager.create()) {
            UploadFileRequest request = UploadFileRequest.builder()
                    .putObjectRequest(req -> req.bucket(username).key("key"))
                    .addTransferListener(LoggingTransferListener.create())
                    .source(Paths.get(fileName))
                    .build();

            return transferManager.uploadFile(request).completionFuture();
        }
    }
}

Контроллер:

import com.wallhack.clouddrive.service.FileStorageService;
import com.wallhack.clouddrive.service.FolderStorageService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.transfer.s3.model.CompletedFileUpload;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Controller
@AllArgsConstructor
public class FileUploadController {
    private FileStorageService fileService; 

    @GetMapping("/upload")
    public String showUploadForm() {
        return "upload";
    }

    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("username") String username,
                                   @RequestParam("file") MultipartFile file,
                                   Model model) {
        try {
           
            Path tempFile = Files.createTempFile("upload-", file.getOriginalFilename());
            Files.copy(file.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);

            URI fileUri = tempFile.toUri(); 

            CompletableFuture<CompletedFileUpload> uploadFuture = fileService.uploadFile(username, file.getOriginalFilename(), fileUri);

            uploadFuture.join();

            model.addAttribute("message", "File uploaded successfully: ");
            
            Files.delete(tempFile);
        } catch (Exception e) {
            model.addAttribute("message", "File upload failed: " + e.getMessage());
        }

        return "home"; 
    }

Что может быть причиной сообщения об ошибке?

Я проверил настройки в application.properties и подтвердил, что переменные установлены правильно. Должен ли я установить что-то еще в application.properties или переменных среды?

Я установил aws.region=us-east-1 в application.properties, но проблема не устранена. Правильно ли использование Region.of("us-east-1") в сборщике S3AsyncClient?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка была в S3AsyncClient, это правильная версия:

@Bean
    public S3AsyncClient generateMinioClient(){
        return S3AsyncClient
                .builder()
                .forcePathStyle(true)  // add this
                .endpointOverride(URI.create(minioUrl))
                .region(Region.AWS_GLOBAL)
                .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, accessSecret)))
                .build();
    } 

Другие вопросы по теме