From 972cc801e4f1bd86483bfaec0e6d03912e5d8e58 Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Wed, 18 Dec 2024 13:30:48 -0600 Subject: [PATCH] fix: Ensure executor is shutdown --- .../openfga/sdk/api/client/OpenFgaClient.java | 2 + .../sdk/api/client/OpenFgaClientTest.java | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java b/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java index 77cf1d9..2f0453e 100644 --- a/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java +++ b/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java @@ -617,6 +617,8 @@ public CompletableFuture> batchCheck( return CompletableFuture.completedFuture(new ArrayList<>(responses)); } catch (Exception e) { return CompletableFuture.failedFuture(e); + } finally { + executor.shutdown(); } } diff --git a/src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java b/src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java index 189df4e..e02e7ab 100644 --- a/src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java +++ b/src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java @@ -32,6 +32,8 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -41,6 +43,7 @@ import org.hamcrest.Matcher; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; /** * API tests for OpenFgaClient. @@ -1703,6 +1706,41 @@ public void batchCheck() throws Exception { assertEquals(Boolean.TRUE, response.get(0).getAllowed()); } + @Test + public void shouldShutdownExecutorAfterBatchCheck() throws Exception { + // Given + ScheduledExecutorService mockExecutor = mock(ScheduledExecutorService.class); + + try (MockedStatic mockedExecutors = mockStatic(Executors.class)) { + mockedExecutors + .when(() -> Executors.newScheduledThreadPool(anyInt())) + .thenReturn(mockExecutor); + + // mockExecutor needs to handle tasks submitted to it so latch can count down + doAnswer(invocation -> { + Runnable task = invocation.getArgument(0); + task.run(); + return null; + }) + .when(mockExecutor) + .execute(any(Runnable.class)); + + ClientCheckRequest request = new ClientCheckRequest() + ._object(DEFAULT_OBJECT) + .relation(DEFAULT_RELATION) + .user(DEFAULT_USER); + ClientBatchCheckOptions options = new ClientBatchCheckOptions() + .authorizationModelId(DEFAULT_AUTH_MODEL_ID) + .consistency(ConsistencyPreference.MINIMIZE_LATENCY); + + // When + fga.batchCheck(List.of(request), options).get(); + + // Then + verify(mockExecutor).shutdown(); + } + } + @Test public void batchCheck_twentyTimes() throws Exception { // Given