Макет S3 для интеграционного тестирования

Хотя мы можем использовать библиотеку S3 mock (например, adobe/S3Mock), иногда мы просто хотим сделать все проще.

Полный исходный код находится в конце этой страницы.

Добавление сторонних зависимостей

Undertow используется в качестве S3 mock-сервера. AWS SDK v2 используется для клиента S3.

<dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-core</artifactId>
    <version>2.2.17.Final</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>s3</artifactId>
    <version>2.17.247</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>url-connection-client</artifactId>
    <version>2.17.247</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.0</version>
    <scope>test</scope>
</dependency>
Войти в полноэкранный режим Выход из полноэкранного режима

Создание имитационного сервера S3

Сначала мы создадим HttpHandler. Он будет возвращать содержимое объекта S3.

static class S3HttpHandler implements HttpHandler {

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        if (exchange.isInIoThread()) {
            exchange.dispatch(this);
            return;
        }

        System.out.printf("Request method: %s%n", exchange.getRequestMethod());
        System.out.printf("Request path: %s%n", exchange.getRequestPath());

        try (BlockingHttpExchange blockingExchange = exchange.startBlocking();
             OutputStream outputStream = exchange.getOutputStream();
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
             BufferedWriter writer = new BufferedWriter(outputStreamWriter)) {

            writer.write("Hello world");
        }
    }

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем мы запускаем имитатор сервера с нашим HttpHandler.

final int S3_MOCK_SERVER_PORT = 9999;

Undertow s3Server = Undertow.builder()
    .addHttpListener(S3_MOCK_SERVER_PORT, "0.0.0.0")
    .setHandler(new S3HttpHandler())
    .build();
s3Server.start();
Вход в полноэкранный режим Выход из полноэкранного режима

Не забудьте остановить наш сервер в конце.

s3Server.stop();
Вход в полноэкранный режим Выход из полноэкранного режима

Настройка S3 клиента

Нам нужно создать S3Client с конечной точкой службы, указывающей на наш S3 mock-сервер.

String serviceEndpoint = String.format("http://localhost:%d", S3_MOCK_SERVER_PORT);

try (S3Client s3Client = S3Client.builder()
    .endpointOverride(URI.create(serviceEndpoint))
    .httpClient(UrlConnectionHttpClient.builder().build())
    .build()) {

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Отправьте запрос на макет сервера.

GetObjectRequest request = GetObjectRequest.builder()
    .bucket("my-bucket")
    .key("my-object")
    .build();

Path targetPath = tempDir.resolve("result");

s3Client.getObject(request, targetPath);

String objectContent = Files.readString(targetPath);
System.out.printf("Object content: %s%n", objectContent);
assertEquals("Hello world", objectContent);
Войти в полноэкранный режим Выход из полноэкранного режима

Полный исходный код

public class S3IntegrationTest {

    @Test
    public void shouldReturnS3Object(@TempDir Path tempDir) throws Exception {
        final int S3_MOCK_SERVER_PORT = 9999;

        Undertow s3Server = Undertow.builder()
            .addHttpListener(S3_MOCK_SERVER_PORT, "0.0.0.0")
            .setHandler(new S3HttpHandler())
            .build();

        s3Server.start();

        String serviceEndpoint = String.format("http://localhost:%d", S3_MOCK_SERVER_PORT);

        try (S3Client s3Client = S3Client.builder()
            .endpointOverride(URI.create(serviceEndpoint))
            .httpClient(UrlConnectionHttpClient.builder().build())
            .build()) {

            GetObjectRequest request = GetObjectRequest.builder()
                .bucket("my-bucket")
                .key("my-object")
                .build();

            Path targetPath = tempDir.resolve("result");

            s3Client.getObject(request, targetPath);

            String objectContent = Files.readString(targetPath);
            System.out.printf("Object content: %s%n", objectContent);
            assertEquals("Hello world", objectContent);
        }

        s3Server.stop();
    }

    static class S3HttpHandler implements HttpHandler {

        @Override
        public void handleRequest(HttpServerExchange exchange) throws Exception {
            if (exchange.isInIoThread()) {
                exchange.dispatch(this);
                return;
            }

            System.out.printf("Request method: %s%n", exchange.getRequestMethod());
            System.out.printf("Request path: %s%n", exchange.getRequestPath());

            try (BlockingHttpExchange blockingExchange = exchange.startBlocking();
                 OutputStream outputStream = exchange.getOutputStream();
                 OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
                 BufferedWriter writer = new BufferedWriter(outputStreamWriter)) {

                writer.write("Hello world");
            }
        }

    }

}
Войти в полноэкранный режим Выход из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий