Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>
<!-- kotlin std lib (needed for okhttp3)-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/com/google/genai/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

/** Interface for an API client which issues HTTP requests to the GenAI APIs. */
@InternalApi
public abstract class ApiClient {
public abstract class ApiClient implements AutoCloseable {

// {x-version-update-start:google-genai:released}
private static final String SDK_VERSION = "1.40.0";
Expand Down Expand Up @@ -726,4 +726,17 @@ public static void setDefaultBaseUrls(
ApiClient.geminiBaseUrl = geminiBaseUrl;
ApiClient.vertexBaseUrl = vertexBaseUrl;
}

@Override
public void close() {
try {
httpClient().dispatcher().executorService().shutdown();
httpClient().connectionPool().evictAll();
if (httpClient().cache() != null) {
httpClient().cache().close();
}
} catch (IOException e) {
throw new GenAiIOException("Failed to close the client.", e);
}
}
}
10 changes: 1 addition & 9 deletions src/main/java/com/google/genai/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -330,15 +330,7 @@ Optional<String> baseUrl() {
/** Closes the Client instance together with its instantiated http client. */
@Override
public void close() {
try {
apiClient.httpClient().dispatcher().executorService().shutdown();
apiClient.httpClient().connectionPool().evictAll();
if (apiClient.httpClient().cache() != null) {
apiClient.httpClient().cache().close();
}
} catch (IOException e) {
throw new GenAiIOException("Failed to close the client.", e);
}
apiClient.close();
}

/**
Expand Down
20 changes: 0 additions & 20 deletions src/test/java/com/google/genai/ClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,4 @@ public void testSetDefaultBaseUrls() {
// Reset the base URLs after the test.
Client.setDefaultBaseUrls(Optional.empty(), Optional.empty());
}

@Test
public void testCloseClient() throws Exception {
// Arrange
ApiClient apiClient = mock(ApiClient.class);
OkHttpClient httpClient = new OkHttpClient();
when(apiClient.httpClient()).thenReturn(httpClient);

Client client = Client.builder().apiKey(API_KEY).vertexAI(false).build();
Field apiClientField = Client.class.getDeclaredField("apiClient");
apiClientField.setAccessible(true);
apiClientField.set(client, apiClient);

// Act
client.close();

// Assert
assertTrue(httpClient.dispatcher().executorService().isShutdown());
assertEquals(0, httpClient.connectionPool().connectionCount());
}
}
22 changes: 19 additions & 3 deletions src/test/java/com/google/genai/HttpApiClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -46,6 +44,7 @@
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Dispatcher;
Expand Down Expand Up @@ -1483,4 +1482,21 @@ public void testNoDefaultLocationWhenUsingApiKeyOnlyMode(
assertNull(client.location());
assertTrue(client.vertexAI());
}

@Test
public void testCloseClient() {
HttpApiClient client =
new HttpApiClient(
Optional.empty(),
Optional.of(PROJECT),
Optional.of(LOCATION),
Optional.of(CREDENTIALS),
Optional.empty(),
Optional.empty());

client.close();

assertTrue(client.httpClient().dispatcher().executorService().isShutdown());
assertEquals(0, client.httpClient().connectionPool().connectionCount());
}
}