Хотя мы можем использовать библиотеку 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");
}
}
}
}