Skip to content

Commit 8857c36

Browse files
committed
fix: address some more concerns
1 parent dfab5a5 commit 8857c36

5 files changed

Lines changed: 19 additions & 7 deletions

File tree

src/main/java/dev/openfga/sdk/api/BaseStreamingApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ protected HttpRequest buildHttpRequest(String method, String path, Object body,
177177
}
178178

179179
return requestBuilder.build();
180+
} catch (FgaInvalidParameterException e) {
181+
throw e;
180182
} catch (Exception e) {
181183
throw new ApiException(e);
182184
}

src/main/java/dev/openfga/sdk/api/auth/OAuth2Client.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ public CompletableFuture<String> getAccessToken() throws FgaInvalidParameterExce
7676
// after inFlight becomes null immediately sees a valid token.
7777
snapshot.set(new TokenSnapshot(token, Instant.now().plusSeconds(response.getExpiresInSeconds())));
7878

79-
telemetry.metrics().credentialsRequest(1L, new HashMap<>());
80-
8179
// Clear before completing
8280
inFlight.set(null);
8381
promise.complete(token);
82+
83+
// Telemetry fires after the gate is cleared and waiters are unblocked,
84+
// so a slow or throwing metrics call cannot stall the in-flight promise.
85+
telemetry.metrics().credentialsRequest(1L, new HashMap<>());
8486
}
8587
});
8688
} catch (Exception e) {

src/main/java/dev/openfga/sdk/api/client/ApiClient.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public class ApiClient {
5353
private Consumer<HttpRequest.Builder> interceptor;
5454
private Consumer<HttpResponse<InputStream>> responseInterceptor;
5555
private Consumer<HttpResponse<String>> asyncResponseInterceptor;
56+
// NOTE: unbounded — one entry per unique set of client credentials for the lifetime of this ApiClient.
57+
// This is intentional for multi-tenant use cases, but stale entries accumulate if credentials rotate
58+
// frequently (e.g. per-request dynamic credentials). In those cases, callers should reuse the same
59+
// ClientCredentials object or manage ApiClient lifecycle to bound memory growth.
5660
private final ConcurrentMap<CredentialsCacheKey, OAuth2Client> oAuth2Clients = new ConcurrentHashMap<>();
5761

5862
/**

src/test/java/dev/openfga/sdk/api/auth/AccessTokenTest.java renamed to src/test/java/dev/openfga/sdk/api/auth/TokenSnapshotTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.junit.jupiter.params.provider.Arguments;
1010
import org.junit.jupiter.params.provider.MethodSource;
1111

12-
class AccessTokenTest {
12+
class TokenSnapshotTest {
1313

1414
private static Stream<Arguments> expTimeAndResults() {
1515
return Stream.of(

src/test/java/dev/openfga/sdk/api/client/StreamingApiExecutorTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,16 +362,20 @@ public void stream_appliesApiTokenAuthHeader() throws Exception {
362362
// Regression guard for openfga/java-sdk#330: the streaming path must attach
363363
// Authorization: Bearer <token> when the configuration uses API_TOKEN credentials.
364364
String apiToken = "stream-api-token";
365+
366+
// Use a real ApiClient backed by the same mockHttpClient so applyAuthHeader runs for real.
367+
var authBuilder = mock(HttpClient.Builder.class);
368+
when(authBuilder.executor(any())).thenReturn(authBuilder);
369+
when(authBuilder.build()).thenReturn(mockHttpClient);
370+
ApiClient realApiClient = new ApiClient(authBuilder, new ObjectMapper());
371+
365372
ClientConfiguration authConfig = new ClientConfiguration()
366373
.storeId(DEFAULT_STORE_ID)
367374
.authorizationModelId(DEFAULT_AUTH_MODEL_ID)
368375
.apiUrl(FgaConstants.TEST_API_URL)
369376
.credentials(new Credentials(new ApiToken(apiToken)))
370377
.readTimeout(Duration.ofMillis(250));
371-
doCallRealMethod()
372-
.when(mockApiClient)
373-
.applyAuthHeader(any(HttpRequest.Builder.class), any(Configuration.class));
374-
OpenFgaClient authFga = new OpenFgaClient(authConfig, mockApiClient);
378+
OpenFgaClient authFga = new OpenFgaClient(authConfig, realApiClient);
375379

376380
Stream<String> lines = Stream.of("{\"result\":{\"object\":\"document:1\"}}");
377381
HttpResponse<Stream<String>> mockResponse = mockStreamResponse(200, lines);

0 commit comments

Comments
 (0)