Spring/db

[DynamoDB] software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Pool closed 에러 해결

MOMOBOB 2024. 5. 11. 19:41
반응형

Error

아래와 같이 DynamoDB 접근을 위한 Repository를 JUnit 테스트로 테스트했을 때 아래와 같은 에러가 발생함.

 

Test Code

    @Test
    void saveDontworkingEntity() {
        Dontworking entity1 = Dontworking.builder()
                .id("1000")
                .name("홍길동")
                .data("길동's DATA")
                .build();
        Dontworking entity2 = Dontworking.builder()
                .id("1001")
                .name("김철수")
                .data("철수's DATA")
                .build();

        reactiveDynamoRepository.saveDontworking(entity1)
                .doOnError(throwable -> throwable.printStackTrace())
                .subscribe();
    }

 

Error Log

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Pool closed
    at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:111)
    at software.amazon.awssdk.core.exception.SdkClientException.create(SdkClientException.java:47)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.utils.RetryableStageHelper.setLastException(RetryableStageHelper.java:223)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.utils.RetryableStageHelper.setLastException(RetryableStageHelper.java:218)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.maybeRetryExecute(AsyncRetryableStage.java:182)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.lambda$attemptExecute$1(AsyncRetryableStage.java:159)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
    at software.amazon.awssdk.utils.CompletableFutureUtils.lambda$forwardExceptionTo$0(CompletableFutureUtils.java:79)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$execute$0(MakeAsyncHttpRequestStage.java:108)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.completeResponseFuture(MakeAsyncHttpRequestStage.java:255)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$executeHttpRequest$3(MakeAsyncHttpRequestStage.java:167)
    at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
    at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
    at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.IllegalStateException: Pool closed
    at software.amazon.awssdk.http.nio.netty.internal.http2.HttpOrHttp2ChannelPool.lambda$completeProtocolConfiguration$5(HttpOrHttp2ChannelPool.java:141)
    at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
    at io.netty.util.concurrent.PromiseTask.run(PromiseTask.java:106)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    ... 1 more

 

 

반응형

 

 


 

Solution

아래와 같이 WebFlux와 DynamoDbEnhancedAsyncClient를 사용하였음

@Override
    public Mono<Void> saveDontworking(Dontworking dontworking) {

        DynamoDbAsyncTable<DontworkingEntity> table = enhancedAsyncClient.table("DONTWORKING_TEST", TableSchema.fromBean(DontworkingEntity.class));
        return Mono.fromFuture(table.putItem(DontworkingEntity.toEntity(dontworking)));
    }

 

 

projectreactor 기반의 라이브러리를 사용하기 위해선 reactive test를 위한 별도의 라이브러리인 io.projectreactor.reactor-test를 사용해야함.

 

Reactor Test에는 StepVerifier 와 TestPublisher, 두가지가 존재함.

 

참고 : https://medium.com/@BPandey/writing-unit-test-in-reactive-spring-boot-application-32b8878e2f57

 

Writing Unit Test in Reactive Spring Boot Application

After I described “Building of Reactive Backend Spring Boot Application using WebFlux” I decided to explain how to test different…

medium.com

 

 

아래와 같이 StepVerifier를 이용하여 테스트하면 정상 동작함.

@Test
    void saveDontworkingEntity() {
        Dontworking entity1 = Dontworking.builder()
                .id("1000")
                .name("홍길동")
                .data("길동's DATA")
                .build();
        Dontworking entity2 = Dontworking.builder()
                .id("1001")
                .name("김철수")
                .data("철수's DATA")
                .build();

        Mono<Void> result = reactiveDynamoRepository.saveDontworking(entity1)
                .doOnError(throwable -> throwable.printStackTrace());

        StepVerifier
                .create(result)
                .verifyComplete();
    }

 

 


Thank you!

 

 

반응형