Падают интеграционные тесты Minio с ошибкой The Access Key Id you provided does not exist in our records

Я начал знакомиться с Minio и столкнулся с проблемой при написании интеграционных тестов. Все тесты падают с ошибкой

The Access Key Id you provided does not exist in our records. 

Помогите разобраться, пожалуйста

Ошибка

Абстрактный класс, от которого наследуются все интеграционные тесты:

public abstract class AbstractIntegrationTest {

private static final String MINIO_ACCESS_KEY = "minio_access_key-test";
private static final String MINIO_SECRET_KEY = "minio_secret_key-test";
private static final String MINIO_URL = "http://127.0.0.1:9000";
private static final String MINIO_BUCKET = "minio-bucket-test";

    @ClassRule
    public static GenericContainer<?> minioContainer = new GenericContainer<>("minio/minio")
            .withCommand("server /export")
            .withEnv("MINIO_ACCESS_KEY", MINIO_ACCESS_KEY)
            .withEnv("MINIO_SECRET_KEY", MINIO_SECRET_KEY);

    @DynamicPropertySource
    public static void properties(DynamicPropertyRegistry registry) {
        registry.add("minio.bucket", () -> MINIO_BUCKET);
        registry.add("minio.url", () -> MINIO_URL);
        registry.add("minio.access-key", () -> MINIO_ACCESS_KEY);
        registry.add("minio.secret-key", () -> MINIO_SECRET_KEY);
    }
}

Сервис Minio:

@Service
public class MinioServiceImpl implements MinioService {

    @Value("${minio.bucket}")
    private String bucket;

    @Resource
    private MinioClient minioClient;

    @Override
    public void uploadFile(MultipartFile file, String name) {
        try {
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            }
            minioClient.putObject(PutObjectArgs.builder().object(name)
                    .bucket(bucket)
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), -1).build());
        } catch (Exception e) {
            e.printStackTrace();
            throw new MinioException("Не удалось загрузить файл с именем " + name);
        }
    }

    @Override
    public byte[] getFile(String name) {
        byte[] file;
        try {
            InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucket)
                    .object(name).build());
            file = stream.readAllBytes();
        } catch (Exception e) {
            throw new MinioException("Не удалось получить файл с именем" + name);
        }
        return file;
    }

    @Override
    public void deleteFile(String name) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucket)
                    .object(name).build());
        } catch (Exception e) {
            throw new MinioException("Не удалось удалить файл с именем " + name);
        }
    }
}

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

@Configuration
public class MinioConfiguration {

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

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

    @Value("${minio.secret-key}")
    private String secretKey;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }
}

Ответы (1 шт):

Автор решения: Покормите котика

Итак, мне удалось запустить minio в тестовом контейнере. Прикрепляю решение:

Абстрактный класс, от которого наследуются все интеграционные тесты:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
@Testcontainers
public abstract class AbstractIntegrationTest {

    @Autowired
    protected WebTestClient webTestClient;

    private static final String MINIO_ACCESS_KEY = "admin";
    private static final String MINIO_SECRET_KEY = "password";
    private static final int MINIO_PORT = 9999;
    private static final String MINIO_BUCKET = "minio-bucket-test";

    @Container
    private static final GenericContainer<?> minioContainer =
            new GenericContainer<>("minio/minio")
                    .withExposedPorts(9000)
                    .withEnv("MINIO_ROOT_USER", MINIO_ACCESS_KEY)
                    .withEnv("MINIO_ROOT_PASSWORD", MINIO_SECRET_KEY)
                    .withCommand("server", "/data")
                    .withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(
                            new HostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(MINIO_PORT),
                                    new ExposedPort(9000)))));

    @DynamicPropertySource
    public static void properties(DynamicPropertyRegistry registry) {
        registry.add("spring.minio.bucket", () -> MINIO_BUCKET);
        registry.add("spring.minio.url", () -> "http://localhost:" + MINIO_PORT);
        registry.add("spring.minio.access-key", () -> MINIO_ACCESS_KEY);
        registry.add("spring.minio.secret-key", () -> MINIO_SECRET_KEY);
    }
}

Дополнительно (может кому пригодится):

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

@Configuration
@Getter
@NoArgsConstructor
public class MinIOConfig {

    @Value("${spring.minio.url}")
    private String endpoint;

    @Value("${spring.minio.access-key}")
    private String accessKey;

    @Value("${spring.minio.secret-key}")
    private String secretKey;

    @Value("${spring.minio.bucket}")
    private String bucketName;

    @Value("${spring.minio.lifecycleExpirationDays}")
    private int lifecycleExpirationDays;

    @Value("${spring.minio.linkExpirationSeconds}")
    private int expirationValue;

    @Bean
    public MinioClient minioClient() throws Exception {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
        List<LifecycleRule> lifecycleRules = List.of(getLifeCycleRule());
        minioClient.setBucketLifecycle(SetBucketLifecycleArgs.builder()
                .bucket(bucketName)
                .config(new LifecycleConfiguration(lifecycleRules))
                .build());
        return minioClient;
    }

    private LifecycleRule getLifeCycleRule() {
        return new LifecycleRule(
                Status.ENABLED,
                null,
                new Expiration((ZonedDateTime) null, lifecycleExpirationDays, null),
                new RuleFilter(StringUtils.EMPTY),
                Constants.MINIO_RULE_NAME,
                null,
                null,
                null);
    }
}

Использовалась библиотека:

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>${minio.version}</version>
</dependency>

Minio разворачивалась в докере с помощью docker-compose файла:

version: '3.8'
services:
  minio:
    container_name: minio
    image: minio/minio:latest
    environment:
      MINIO_ROOT_USER: "admin"
      MINIO_ROOT_PASSWORD: "password"
    volumes:
      - ./data:/data
    ports:
      - 9000:9000
      - 9001:9001
    command: server /data --console-address :9001
→ Ссылка