diff --git a/config/clients/java/template/libraries/native/api.mustache b/config/clients/java/template/libraries/native/api.mustache index eed5a2590..07ca1e837 100644 --- a/config/clients/java/template/libraries/native/api.mustache +++ b/config/clients/java/template/libraries/native/api.mustache @@ -265,6 +265,12 @@ public class OpenFgaApi { if (body instanceof BatchCheckRequest) { BatchCheckRequest batchCheckRequest = (BatchCheckRequest) body; + if (!isNullOrWhitespace(batchCheckRequest.getAuthorizationModelId())) { + telemetryAttributes.put( + Attributes.FGA_CLIENT_REQUEST_MODEL_ID, + batchCheckRequest.getAuthorizationModelId()); + } + if (batchCheckRequest.getChecks() != null) { telemetryAttributes.put( Attributes.FGA_CLIENT_REQUEST_BATCH_CHECK_SIZE, diff --git a/config/clients/java/template/src/main/api/client/OpenFgaClient.java.mustache b/config/clients/java/template/src/main/api/client/OpenFgaClient.java.mustache index 47b97ed25..876fb6fbe 100644 --- a/config/clients/java/template/src/main/api/client/OpenFgaClient.java.mustache +++ b/config/clients/java/template/src/main/api/client/OpenFgaClient.java.mustache @@ -695,8 +695,23 @@ public class OpenFgaClient { var override = new ConfigurationOverride().addHeaders(options); - Consumer> singleBatchCheckRequest = request -> call(() -> - api.batchCheck(configuration.getStoreId(), new BatchCheckRequest().checks(request), override)) + Consumer> singleBatchCheckRequest = request -> call(() -> { + BatchCheckRequest body = new BatchCheckRequest().checks(request); + if (options.getConsistency() != null) { + body.consistency(options.getConsistency()); + } + + // Set authorizationModelId from options if available; otherwise, use the default from configuration + String authorizationModelId = !isNullOrWhitespace(options.getAuthorizationModelId()) + ? options.getAuthorizationModelId() + : configuration.getAuthorizationModelId(); + + if (!isNullOrWhitespace(authorizationModelId)) { + body.authorizationModelId(authorizationModelId); + } + + return api.batchCheck(configuration.getStoreId(), body, override); + }) .handleAsync((batchCheckResponseApiResponse, throwable) -> { Map response = batchCheckResponseApiResponse.getData().getResult(); diff --git a/config/clients/java/template/src/test/api/client/OpenFgaClientTest.java.mustache b/config/clients/java/template/src/test/api/client/OpenFgaClientTest.java.mustache index 1eef27382..3a29deb1d 100644 --- a/config/clients/java/template/src/test/api/client/OpenFgaClientTest.java.mustache +++ b/config/clients/java/template/src/test/api/client/OpenFgaClientTest.java.mustache @@ -2025,6 +2025,38 @@ public class OpenFgaClientTest { assertEquals("relation not found", response3.getError().getMessage()); } + @Test + public void batchCheck_withOptions() throws Exception { + // Given + String postUrl = String.format("https://api.fga.example/stores/%s/batch-check", DEFAULT_STORE_ID); + String expectedBody = String.format( + "{\"checks\":[{\"tuple_key\":{\"user\":\"%s\",\"relation\":\"%s\",\"object\":\"%s\"},\"contextual_tuples\":null,\"context\":null,\"correlation_id\":\"cor-1\"}],\"authorization_model_id\":\"%s\",\"consistency\":\"%s\"}", + DEFAULT_USER, + DEFAULT_RELATION, + DEFAULT_OBJECT, + DEFAULT_AUTH_MODEL_ID, + ConsistencyPreference.MINIMIZE_LATENCY); + mockHttpClient.onPost(postUrl).withBody(is(expectedBody)).doReturn(200, "{\"result\":{}}"); + + ClientBatchCheckItem item = new ClientBatchCheckItem() + .user(DEFAULT_USER) + .relation(DEFAULT_RELATION) + ._object(DEFAULT_OBJECT) + .correlationId("cor-1"); + ClientBatchCheckRequest request = new ClientBatchCheckRequest().checks(List.of(item)); + ClientBatchCheckOptions options = new ClientBatchCheckOptions() + .authorizationModelId(DEFAULT_AUTH_MODEL_ID) + .consistency(ConsistencyPreference.MINIMIZE_LATENCY); + + // When + ClientBatchCheckResponse response = fga.batchCheck(request, options).join(); + + // Then + mockHttpClient.verify().post(postUrl).withBody(is(expectedBody)).called(1); + assertNotNull(response); + assertTrue(response.getResult().isEmpty()); + } + /** * Expand all relationships in userset tree format, and following userset rewrite rules. Useful to reason * about and debug a certain relationship.