Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(java-sdk)!: support server-side batch check endpoint #475

Merged
merged 3 commits into from
Feb 5, 2025
Merged
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
5 changes: 5 additions & 0 deletions config/clients/java/CHANGELOG.md.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

## [Unreleased](https://github.com/openfga/java-sdk/compare/v{{packageVersion}}...HEAD)

- feat!: add support for server-side `BatchCheck` method
- feat: add support for `start_time` parameter in `ReadChanges` endpoint

BREAKING CHANGES:

- Usage of the existing `batchCheck` method should now use the `clientBatchCheck` method.

## v0.7.2

### [0.7.2](https://github.com/openfga/java-sdk/compare/v0.7.1...v0.7.2) (2024-12-18)
Expand Down
24 changes: 24 additions & 0 deletions config/clients/java/config.overrides.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,26 @@
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/ClientAssertion.java",
"templateType": "SupportingFiles"
},
"client-ClientBatchCheckClientResponse.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckClientResponse.java",
"templateType": "SupportingFiles"
},
"client-ClientBatchCheckItem.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckItem.java",
"templateType": "SupportingFiles"
},
"client-ClientBatchCheckRequest.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckRequest.java",
"templateType": "SupportingFiles"
},
"client-ClientBatchCheckResponse.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckResponse.java",
"templateType": "SupportingFiles"
},
"client-ClientBatchCheckSingleResponse.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientBatchCheckSingleResponse.java",
"templateType": "SupportingFiles"
},
"client-ClientCheckRequest.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/client/model/ClientCheckRequest.java",
"templateType": "SupportingFiles"
Expand Down Expand Up @@ -221,6 +237,10 @@
"destinationFilename": "src/main/java/dev/openfga/sdk/api/configuration/BaseConfiguration.java",
"templateType": "SupportingFiles"
},
"config-ClientBatchCheckClientOptions.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/configuration/ClientBatchCheckClientOptions.java",
"templateType": "SupportingFiles"
},
"config-ClientBatchCheckOptions.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/api/configuration/ClientBatchCheckOptions.java",
"templateType": "SupportingFiles"
Expand Down Expand Up @@ -373,6 +393,10 @@
"destinationFilename": "src/main/java/dev/openfga/sdk/errors/FgaInvalidParameterException.java",
"templateType": "SupportingFiles"
},
"errors-FgaValidationError.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/errors/FgaValidationError.java",
"templateType": "SupportingFiles"
},
"errors-HttpStatusCode.java.mustache": {
"destinationFilename": "src/main/java/dev/openfga/sdk/errors/HttpStatusCode.java",
"templateType": "SupportingFiles"
Expand Down
4 changes: 2 additions & 2 deletions config/clients/java/template/README_calling_api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ var response = fgaClient.check(request, options).get();
Run a set of [checks](#check). Batch Check will return `allowed: false` if it encounters an error, and will return the error in the body.
If 429s or 5xxs are encountered, the underlying check will retry up to {{defaultMaxRetry}} times before giving up.

> Passing `ClientBatchCheckOptions` is optional. All fields of `ClientBatchCheckOptions` are optional.
> Passing `ClientBatchCheckClientOptions` is optional. All fields of `ClientBatchCheckClientOptions` are optional.

```java
var request = List.of(
Expand Down Expand Up @@ -392,7 +392,7 @@ var request = List.of(
.relation("deleter")
._object("document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a")
);
var options = new ClientBatchCheckOptions()
var options = new ClientBatchCheckClientOptions()
.additionalHeaders(Map.of("Some-Http-Header", "Some value"))
// You can rely on the model id set in the configuration or override it for this specific request
.authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{{>licenseInfo}}
package {{clientPackage}}.model;

import {{modelPackage}}.CheckResponse;
import {{errorsPackage}}.FgaError;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

public class ClientBatchCheckClientResponse extends CheckResponse {
private final ClientCheckRequest request;
private final Throwable throwable;
private final Integer statusCode;
private final Map<String, List<String>> headers;
private final String rawResponse;

public ClientBatchCheckClientResponse(
ClientCheckRequest request, ClientCheckResponse clientCheckResponse, Throwable throwable) {
this.request = request;
this.throwable = throwable;

if (clientCheckResponse != null) {
this.statusCode = clientCheckResponse.getStatusCode();
this.headers = clientCheckResponse.getHeaders();
this.rawResponse = clientCheckResponse.getRawResponse();
this.setAllowed(clientCheckResponse.getAllowed());
this.setResolution(clientCheckResponse.getResolution());
} else if (throwable instanceof FgaError) {
FgaError error = (FgaError) throwable;
this.statusCode = error.getStatusCode();
this.headers = error.getResponseHeaders().map();
this.rawResponse = error.getResponseData();
} else {
// Should be unreachable, but required for type completion
this.statusCode = null;
this.headers = null;
this.rawResponse = null;
}
}

public ClientCheckRequest getRequest() {
return request;
}

/**
* Returns the result of the check.
* <p>
* If the HTTP request was unsuccessful, this result will be null. If this is the case, you can examine the
* original request with {@link ClientBatchCheckClientResponse#getRequest()} and the exception with
* {@link ClientBatchCheckClientResponse#getThrowable()}.
*
* @return the check result. Is null if the HTTP request was unsuccessful.
*/
@Override
public Boolean getAllowed() {
return super.getAllowed();
}

/**
* Returns the caught exception if the HTTP request was unsuccessful.
* <p>
* If the HTTP request was unsuccessful, this result will be null. If this is the case, you can examine the
* original request with {@link ClientBatchCheckClientResponse#getRequest()} and the exception with
* {@link ClientBatchCheckClientResponse#getThrowable()}.
*
* @return the caught exception. Is null if the HTTP request was successful.
*/
public Throwable getThrowable() {
return throwable;
}

public int getStatusCode() {
return statusCode;
}

public Map<String, List<String>> getHeaders() {
return headers;
}

public String getRawResponse() {
return rawResponse;
}

public String getRelation() {
return request == null ? null : request.getRelation();
}

public static BiFunction<ClientCheckResponse, Throwable, ClientBatchCheckClientResponse> asyncHandler(
ClientCheckRequest request) {
return (response, throwable) -> new ClientBatchCheckClientResponse(request, response, throwable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{{>licenseInfo}}
package {{invokerPackage}}.model;

import java.util.List;

public class ClientBatchCheckItem {
private String user;
private String relation;
private String _object;
private List<ClientTupleKey> contextualTuples;
private Object context;
private String correlationId;

public ClientBatchCheckItem user(String user) {
this.user = user;
return this;
}

public String getUser() {
return user;
}

public ClientBatchCheckItem relation(String relation) {
this.relation = relation;
return this;
}

public String getRelation() {
return relation;
}

public ClientBatchCheckItem _object(String _object) {
this._object = _object;
return this;
}

public String getObject() {
return _object;
}

public ClientBatchCheckItem contextualTuples(List<ClientTupleKey> contextualTuples) {
this.contextualTuples = contextualTuples;
return this;
}

public List<ClientTupleKey> getContextualTuples() {
return contextualTuples;
}

public ClientBatchCheckItem context(Object context) {
this.context = context;
return this;
}

public Object getContext() {
return context;
}

public ClientBatchCheckItem correlationId(String correlationId) {
this.correlationId = correlationId;
return this;
}

public String getCorrelationId() {
return correlationId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{>licenseInfo}}
package {{invokerPackage}}.model;

import java.util.List;

public class ClientBatchCheckRequest {
private List<ClientBatchCheckItem> checks;

public static ClientBatchCheckRequest ofChecks(List<ClientBatchCheckItem> checks) {
return new ClientBatchCheckRequest().checks(checks);
}

public ClientBatchCheckRequest checks(List<ClientBatchCheckItem> checks) {
this.checks = checks;
return this;
}

public List<ClientBatchCheckItem> getChecks() {
return checks;
}
}
Original file line number Diff line number Diff line change
@@ -1,92 +1,16 @@
{{>licenseInfo}}
package {{clientPackage}}.model;

import {{modelPackage}}.CheckResponse;
import {{errorsPackage}}.FgaError;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

public class ClientBatchCheckResponse extends CheckResponse {
private final ClientCheckRequest request;
private final Throwable throwable;
private final Integer statusCode;
private final Map<String, List<String>> headers;
private final String rawResponse;
public class ClientBatchCheckResponse {
private final List<ClientBatchCheckSingleResponse> result;

public ClientBatchCheckResponse(
ClientCheckRequest request, ClientCheckResponse clientCheckResponse, Throwable throwable) {
this.request = request;
this.throwable = throwable;

if (clientCheckResponse != null) {
this.statusCode = clientCheckResponse.getStatusCode();
this.headers = clientCheckResponse.getHeaders();
this.rawResponse = clientCheckResponse.getRawResponse();
this.setAllowed(clientCheckResponse.getAllowed());
this.setResolution(clientCheckResponse.getResolution());
} else if (throwable instanceof FgaError) {
FgaError error = (FgaError) throwable;
this.statusCode = error.getStatusCode();
this.headers = error.getResponseHeaders().map();
this.rawResponse = error.getResponseData();
} else {
// Should be unreachable, but required for type completion
this.statusCode = null;
this.headers = null;
this.rawResponse = null;
}
}

public ClientCheckRequest getRequest() {
return request;
}

/**
* Returns the result of the check.
* <p>
* If the HTTP request was unsuccessful, this result will be null. If this is the case, you can examine the
* original request with {@link ClientBatchCheckResponse#getRequest()} and the exception with
* {@link ClientBatchCheckResponse#getThrowable()}.
*
* @return the check result. Is null if the HTTP request was unsuccessful.
*/
@Override
public Boolean getAllowed() {
return super.getAllowed();
}

/**
* Returns the caught exception if the HTTP request was unsuccessful.
* <p>
* If the HTTP request was unsuccessful, this result will be null. If this is the case, you can examine the
* original request with {@link ClientBatchCheckResponse#getRequest()} and the exception with
* {@link ClientBatchCheckResponse#getThrowable()}.
*
* @return the caught exception. Is null if the HTTP request was successful.
*/
public Throwable getThrowable() {
return throwable;
}

public int getStatusCode() {
return statusCode;
}

public Map<String, List<String>> getHeaders() {
return headers;
}

public String getRawResponse() {
return rawResponse;
}

public String getRelation() {
return request == null ? null : request.getRelation();
public ClientBatchCheckResponse(List<ClientBatchCheckSingleResponse> result) {
this.result = result;
}

public static BiFunction<ClientCheckResponse, Throwable, ClientBatchCheckResponse> asyncHandler(
ClientCheckRequest request) {
return (response, throwable) -> new ClientBatchCheckResponse(request, response, throwable);
public List<ClientBatchCheckSingleResponse> getResult() {
return result;
}
}
}
Loading
Loading