diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES
index 4a6526e..0308880 100644
--- a/.openapi-generator/FILES
+++ b/.openapi-generator/FILES
@@ -82,13 +82,32 @@ src/main/java/dev/openfga/sdk/api/auth/CredentialsFlowResponse.java
src/main/java/dev/openfga/sdk/api/auth/OAuth2Client.java
src/main/java/dev/openfga/sdk/api/client/ApiClient.java
src/main/java/dev/openfga/sdk/api/client/ApiResponse.java
+src/main/java/dev/openfga/sdk/api/client/ClientAssertion.java
+src/main/java/dev/openfga/sdk/api/client/ClientCheckRequest.java
+src/main/java/dev/openfga/sdk/api/client/ClientExpandRequest.java
+src/main/java/dev/openfga/sdk/api/client/ClientListObjectsRequest.java
+src/main/java/dev/openfga/sdk/api/client/ClientListRelationsRequest.java
+src/main/java/dev/openfga/sdk/api/client/ClientReadRequest.java
+src/main/java/dev/openfga/sdk/api/client/ClientTupleKey.java
+src/main/java/dev/openfga/sdk/api/client/ClientWriteRequest.java
+src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java
src/main/java/dev/openfga/sdk/api/configuration/ApiToken.java
src/main/java/dev/openfga/sdk/api/configuration/BaseConfiguration.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientCheckOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientConfiguration.java
src/main/java/dev/openfga/sdk/api/configuration/ClientCredentials.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientExpandOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientListObjectsOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientReadOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ClientWriteOptions.java
src/main/java/dev/openfga/sdk/api/configuration/Configuration.java
src/main/java/dev/openfga/sdk/api/configuration/ConfigurationOverride.java
src/main/java/dev/openfga/sdk/api/configuration/Credentials.java
src/main/java/dev/openfga/sdk/api/configuration/CredentialsMethod.java
+src/main/java/dev/openfga/sdk/api/configuration/ListStoresOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ReadAuthorizationModelOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ReadAuthorizationModelsOptions.java
+src/main/java/dev/openfga/sdk/api/configuration/ReadChangesOptions.java
src/main/java/dev/openfga/sdk/api/model/AbstractOpenApiSchema.java
src/main/java/dev/openfga/sdk/api/model/Any.java
src/main/java/dev/openfga/sdk/api/model/Assertion.java
@@ -149,9 +168,12 @@ src/main/java/dev/openfga/sdk/errors/FgaInvalidParameterException.java
src/main/java/dev/openfga/sdk/util/Pair.java
src/main/java/dev/openfga/sdk/util/StringUtil.java
src/test-integration/java/dev/openfga/sdk/api/OpenFgaApiIntegrationTest.java
+src/test-integration/java/dev/openfga/sdk/api/client/OpenFgaClientIntegrationTest.java
+src/test-integration/java/package-info.java
src/test/java/dev/openfga/sdk/api/OpenFgaApiTest.java
src/test/java/dev/openfga/sdk/api/OpenFgaApiTest.java
src/test/java/dev/openfga/sdk/api/auth/OAuth2ClientTest.java
+src/test/java/dev/openfga/sdk/api/client/OpenFgaClientTest.java
src/test/java/dev/openfga/sdk/api/configuration/ClientCredentialsTest.java
src/test/java/dev/openfga/sdk/api/configuration/ConfigurationTest.java
src/test/java/dev/openfga/sdk/api/model/AnyTest.java
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a06299..f38be19 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## v0.0.5
+
+### [0.0.5](https://github.com/openfga/java-sdk/compare/v0.0.4...v0.0.5) (2023-09-27)
+
+- feat(client): add `OpenFgaClient` wrapping `OpenFgaApi` and exposing a simplified interface.
+ See [docs](https://github.com/openfga/java-sdk?tab=readme-ov-file#initializing-the-api-client)
+- chore(docs): update the README with installation and usage instructions.
+
## v0.0.3, v0.0.4
### [0.0.4](https://github.com/openfga/java-sdk/compare/v0.0.2...v0.0.4) (2023-09-21)
diff --git a/README.md b/README.md
index f2213ba..0e32cc1 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Java SDK for OpenFGA
+[![Maven Central](https://img.shields.io/maven-central/v/dev.openfga/openfga-sdk.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22dev.openfga%22%20AND%20a:%22openfga-sdk%22)
+[![Javadoc](https://javadoc.io/badge2/dev.openfga/openfga-sdk/javadoc.svg)](https://javadoc.io/doc/dev.openfga/openfga-sdk)
[![Release](https://img.shields.io/github/v/release/openfga/java-sdk?sort=semver&color=green)](https://github.com/openfga/java-sdk/releases)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fopenfga%2Fjava-sdk.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fopenfga%2Fjava-sdk?ref=badge_shield)
@@ -65,6 +67,49 @@ OpenFGA is designed to make it easy for application builders to model their perm
## Installation
+The OpenFGA Java SDK is available on [Maven Central](https://central.sonatype.com/).
+
+It can be used with the following:
+
+* Gradle (Groovy)
+
+```groovy
+implementation 'dev.openfga:openfga-sdk:0.0.5'
+```
+
+* Gradle (Kotlin)
+
+```kotlin
+implementation("dev.openfga:openfga-sdk:0.0.5")
+```
+
+* Apache Maven
+
+```xml
+
+ dev.openfga
+ openfga-sdk
+ 0.0.5
+
+```
+
+* Ivy
+
+```xml
+
+```
+
+* SBT
+
+```scala
+libraryDependencies += "dev.openfga" % "openfga-sdk" % "0.0.5"
+```
+
+* Leiningen
+
+```edn
+[dev.openfga/openfga-sdk "0.0.5"]
+```
## Getting Started
@@ -75,17 +120,85 @@ OpenFGA is designed to make it easy for application builders to model their perm
#### No Credentials
-```cjava
+```java
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.openfga.sdk.api.client.ApiClient;
+import dev.openfga.sdk.api.client.OpenFgaClient;
+import dev.openfga.sdk.api.configuration.ClientConfiguration;
+import java.net.http.HttpClient;
+
+public class Example {
+ public static void main(String[] args) throws Exception {
+ var clientConfig = new ClientConfiguration()
+ .apiUrl(System.getenv("OPENFGA_API_URL")) // If not specified, will default to "https://localhost:8080"
+ .storeId(System.getenv("OPENFGA_STORE_ID")) // Not required when calling createStore() or listStores()
+ .authorizationModelId(System.getenv("OPENFGA_AUTHORIZATION_MODEL_ID")); // Optional, can be overridden per request
+ var apiClient = new ApiClient(HttpClient.newBuilder(), new ObjectMapper());
+
+ var fgaClient = new OpenFgaClient(apiClient, clientConfig);
+ var response = fgaClient.readAuthorizationModels().get();
+ }
+}
```
#### API Token
```java
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.openfga.sdk.api.client.ApiClient;
+import dev.openfga.sdk.api.client.OpenFgaClient;
+import dev.openfga.sdk.api.configuration.ApiToken;
+import dev.openfga.sdk.api.configuration.ClientConfiguration;
+import dev.openfga.sdk.api.configuration.Credentials;
+import java.net.http.HttpClient;
+
+public class Example {
+ public static void main(String[] args) throws Exception {
+ var clientConfig = new ClientConfiguration()
+ .apiUrl(System.getenv("OPENFGA_API_URL")) // If not specified, will default to "https://localhost:8080"
+ .storeId(System.getenv("OPENFGA_STORE_ID")) // Not required when calling createStore() or listStores()
+ .authorizationModelId(System.getenv("OPENFGA_AUTHORIZATION_MODEL_ID")) // Optional, can be overridden per request
+ .credentials(new Credentials(
+ new ApiToken(System.getenv("OPENFGA_API_TOKEN")) // will be passed as the "Authorization: Bearer ${ApiToken}" request header
+ ));
+ var apiClient = new ApiClient(HttpClient.newBuilder(), new ObjectMapper());
+
+ var fgaClient = new OpenFgaClient(apiClient, clientConfig);
+ var response = fgaClient.readAuthorizationModels().get();
+ }
+}
```
#### Client Credentials
```java
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.openfga.sdk.api.client.ApiClient;
+import dev.openfga.sdk.api.client.OpenFgaClient;
+import dev.openfga.sdk.api.configuration.ClientConfiguration;
+import dev.openfga.sdk.api.configuration.ClientCredentials;
+import dev.openfga.sdk.api.configuration.Credentials;
+import java.net.http.HttpClient;
+
+public class Example {
+ public static void main(String[] args) throws Exception {
+ var clientConfig = new ClientConfiguration()
+ .apiUrl(System.getenv("OPENFGA_API_URL")) // If not specified, will default to "https://localhost:8080"
+ .storeId(System.getenv("OPENFGA_STORE_ID")) // Not required when calling createStore() or listStores()
+ .authorizationModelId(System.getenv("OPENFGA_AUTHORIZATION_MODEL_ID")) // Optional, can be overridden per request
+ .credentials(new Credentials(
+ new ClientCredentials()
+ .apiTokenIssuer(System.getenv("OPENFGA_API_TOKEN_ISSUER"))
+ .apiAudience(System.getenv("OPENFGA_API_AUDIENCE"))
+ .clientId(System.getenv("OPENFGA_CLIENT_ID"))
+ .clientSecret(System.getenv("OPENFGA_CLIENT_SECRET"))
+ ));
+ var apiClient = new ApiClient(HttpClient.newBuilder(), new ObjectMapper());
+
+ var fgaClient = new OpenFgaClient(apiClient, clientConfig);
+ var response = fgaClient.readAuthorizationModels().get();
+ }
+}
```
@@ -106,6 +219,12 @@ Get a paginated list of stores.
[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/ListStores)
```java
+var options = new ListStoresOptions()
+ .pageSize(10)
+ .continuationToken("...");
+var stores = fgaClient.listStores(options);
+
+// stores = [{ "id": "01FQH7V8BEG3GPQW93KTRFR8JB", "name": "FGA Demo Store", "created_at": "2022-01-01T00:00:00.000Z", "updated_at": "2022-01-01T00:00:00.000Z" }]
```
##### Create Store
@@ -115,6 +234,17 @@ Initialize a store.
[API Documentation](https://openfga.dev/api/service/docs/api#/Stores/CreateStore)
```java
+var request = new CreateStoreRequest().name("FGA Demo");
+var store = fgaClient.createStore(request).get();
+
+// store.getId() = "01FQH7V8BEG3GPQW93KTRFR8JB"
+
+// store the store.getId() in database
+
+// update the storeId of the client instance
+fgaClient.setStoreId(store.getId());
+
+// continue calling the API normally
```
##### Get Store
@@ -126,6 +256,9 @@ Get information about the current store.
> Requires a client initialized with a storeId
```java
+var store = fgaClient.getStore().get();
+
+// store = { "id": "01FQH7V8BEG3GPQW93KTRFR8JB", "name": "FGA Demo Store", "created_at": "2022-01-01T00:00:00.000Z", "updated_at": "2022-01-01T00:00:00.000Z" }
```
##### Delete Store
@@ -137,6 +270,7 @@ Delete a store.
> Requires a client initialized with a storeId
```java
+var store = fgaClient.deleteStore().get();
```
#### Authorization Models
@@ -148,6 +282,14 @@ Read all authorization models in the store.
[API Documentation](https://openfga.dev/api/service#/Authorization%20Models/ReadAuthorizationModels)
```java
+var options = new ReadAuthorizationModelsOptions()
+ .pageSize(10)
+ .continuationToken("...");
+var response = fgaClient.readAuthorizationModels(options).get();
+
+// response.getAuthorizationModels() = [
+// { id: "01GXSA8YR785C4FYS3C0RTG7B1", schemaVersion: "1.1", typeDefinitions: [...] },
+// { id: "01GXSBM5PVYHCJNRNKXMB4QZTW", schemaVersion: "1.1", typeDefinitions: [...] }];
```
##### Write Authorization Model
@@ -163,6 +305,37 @@ Create a new authorization model.
> You can use the OpenFGA [CLI](https://github.com/openfga/cli) or [Syntax Transformer](https://github.com/openfga/syntax-transformer) to convert between the OpenFGA DSL and the JSON authorization model.
```java
+
+var request = new WriteAuthorizationModelRequest()
+ .schemaVersion("1.1")
+ .typeDefinitions(List.of(
+ new TypeDefinition().type("user").relations(Map.of()),
+ new TypeDefinition()
+ .type("document")
+ .relations(Map.of(
+ "writer", new Userset(),
+ "viewer", new Userset().union(new Usersets()
+ .child(List.of(
+ new Userset(),
+ new Userset().computedUserset(new ObjectRelation().relation("writer"))
+ ))
+ )
+ ))
+ .metadata(new Metadata()
+ .relations(Map.of(
+ "writer", new RelationMetadata().directlyRelatedUserTypes(
+ List.of(new RelationReference().type("user"))
+ ),
+ "viewer", new RelationMetadata().directlyRelatedUserTypes(
+ List.of(new RelationReference().type("user"))
+ )
+ ))
+ )
+ ));
+
+var response = fgaClient.writeAuthorizationModel(request).get();
+
+// response.getAuthorizationModelId() = "01GXSA8YR785C4FYS3C0RTG7B1"
```
#### Read a Single Authorization Model
@@ -172,6 +345,15 @@ Read a particular authorization model.
[API Documentation](https://openfga.dev/api/service#/Authorization%20Models/ReadAuthorizationModel)
```java
+var options = new ReadAuthorizationModelOptions()
+ // You can rely on the model id set in the configuration or override it for this specific request
+ .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1");
+
+var response = fgaClient.readAuthorizationModel(options).get();
+
+// response.getAuthorizationModel().getId() = "01GXSA8YR785C4FYS3C0RTG7B1"
+// response.getAuthorizationModel().getSchemaVersion() = "1.1"
+// response.getAuthorizationModel().getTypeDefinitions() = [{ "type": "document", "relations": { ... } }, { "type": "user", "relations": { ... }}]
```
##### Read the Latest Authorization Model
@@ -181,6 +363,11 @@ Reads the latest authorization model (note: this ignores the model id in configu
[API Documentation](https://openfga.dev/api/service#/Authorization%20Models/ReadAuthorizationModel)
```java
+var response = fgaClient.readLatestAuthorizationModel().get();
+
+// response.getAuthorizationModel().getId() = "01GXSA8YR785C4FYS3C0RTG7B1"
+// response.getAuthorizationModel().SchemaVersion() = "1.1"
+// response.getAuthorizationModel().TypeDefinitions() = [{ "type": "document", "relations": { ... } }, { "type": "user", "relations": { ... }}]
```
#### Relationship Tuples
@@ -192,6 +379,18 @@ Reads the list of historical relationship tuple writes and deletes.
[API Documentation](https://openfga.dev/api/service#/Relationship%20Tuples/ReadChanges)
```java
+var options = new ClientReadChangesOptions()
+ .type("document")
+ .pageSize(10)
+ .continuationToken("...");
+
+var response = fgaClient.readChanges(options).get();
+
+// response.getContinuationToken() = ...
+// response.getChanges() = [
+// { tupleKey: { user, relation, object }, operation: TupleOperation.WRITE, timestamp: ... },
+// { tupleKey: { user, relation, object }, operation: TupleOperation.DELETE, timestamp: ... }
+// ]
```
##### Read Relationship Tuples
@@ -201,6 +400,38 @@ Reads the relationship tuples stored in the database. It does not evaluate nor e
[API Documentation](https://openfga.dev/api/service#/Relationship%20Tuples/Read)
```java
+// Find if a relationship tuple stating that a certain user is a viewer of a certain document
+var request = new ClientReadRequest()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ ._object("document:roadmap");
+
+// Find all relationship tuples where a certain user has a relationship as any relation to a certain document
+var request = new ClientReadRequest()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ ._object("document:roadmap");
+
+// Find all relationship tuples where a certain user is a viewer of any document
+var request = new ClientReadRequest()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ ._object("document:");
+
+// Find all relationship tuples where any user has a relationship as any relation with a particular document
+var request = new ClientReadRequest()
+ ._object("document:roadmap");
+
+// Read all stored relationship tuples
+var request = new ClientReadRequest();
+
+var options = new ClientReadOptions()
+ .pageSize(10)
+ .continuationToken("...");
+
+var response = fgaClient.read(request, options).get();
+
+// In all the above situations, the response will be of the form:
+// response = { tuples: [{ key: { user, relation, object }, timestamp }, ...]}
```
##### Write (Create and Delete) Relationship Tuples
@@ -214,6 +445,29 @@ Create and/or delete relationship tuples to update the system state.
By default, write runs in a transaction mode where any invalid operation (deleting a non-existing tuple, creating an existing tuple, one of the tuples was invalid) or a server error will fail the entire operation.
```java
+var request = new ClientWriteRequest()
+ .writes(List.of(
+ new TupleKey()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ ._object("document:roadmap"),
+ new TupleKey()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ ._object("document:budget")
+ ))
+ .deletes(List.of(
+ new TupleKey()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("writer")
+ ._object("document:roadmap")
+ ));
+
+// You can rely on the model id set in the configuration or override it for this specific request
+var options = new ClientWriteOptions()
+ .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1");
+
+var response = fgaClient.write(request, options).get();
```
Convenience `WriteTuples` and `DeleteTuples` methods are also available.
@@ -223,6 +477,7 @@ Convenience `WriteTuples` and `DeleteTuples` methods are also available.
The SDK will split the writes into separate requests and send them sequentially to avoid violating rate limits.
```java
+// Coming soon
```
#### Relationship Queries
@@ -234,6 +489,16 @@ Check if a user has a particular relation with an object.
[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/Check)
```java
+var request = new ClientCheckRequest()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("writer")
+ ._object("document:roadmap");
+var options = new ClientCheckOptions()
+ // You can rely on the model id set in the configuration or override it for this specific request
+ .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1");
+
+var response = fgaClient.check(request, options).get();
+// response.getAllowed() = true
```
##### Batch Check
@@ -242,6 +507,7 @@ Run a set of [checks](#check). Batch Check will return `allowed: false` if it en
If 429s or 5xxs are encountered, the underlying check will retry up to 15 times before giving up.
```java
+// Coming soon
```
##### Expand
@@ -251,6 +517,16 @@ Expands the relationships in userset tree format.
[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/Expand)
```java
+var request = new ClientExpandRequest()
+ .relation("viewer")
+ ._object("document:roadmap");
+var options = new ClientCheckOptions()
+ // You can rely on the model id set in the configuration or override it for this specific request
+ .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1");
+
+var response = fgaClient.expand(request, options).get();
+
+// response.getTree().getRoot() = {"name":"document:roadmap#viewer","leaf":{"users":{"users":["user:81684243-9356-4421-8fbf-a4f8d36aa31b","user:f52a4f7a-054d-47ff-bb6e-3ac81269988f"]}}}
```
##### List Objects
@@ -260,6 +536,23 @@ List the objects of a particular type a user has access to.
[API Documentation](https://openfga.dev/api/service#/Relationship%20Queries/ListObjects)
```java
+var request = new ClientListObjectsRequest()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ .type("document")
+ .contextualTuples(List.of(
+ new ClientTupleKey()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("writer")
+ ._object("document:budget")
+ ));
+var options = new ClientListObjectsOptions()
+ // You can rely on the model id set in the configuration or override it for this specific request
+ .authorizationModelId("01GXSA8YR785C4FYS3C0RTG7B1");
+
+var response = fgaClient.listObjects(request, options).get();
+
+// response.getObjects() = ["document:roadmap"]
```
##### List Relations
@@ -267,6 +560,7 @@ List the objects of a particular type a user has access to.
List the relations a user has on an object.
```java
+// Coming soon.
```
#### Assertions
@@ -278,6 +572,7 @@ Read assertions for a particular authorization model.
[API Documentation](https://openfga.dev/api/service#/Assertions/Read%20Assertions)
```java
+var response = fgaClient.readAssertions().get();
```
##### Write Assertions
@@ -287,11 +582,37 @@ Update the assertions for a particular authorization model.
[API Documentation](https://openfga.dev/api/service#/Assertions/Write%20Assertions)
```java
+var assertions = List.of(
+ new ClientAssertion()
+ .user("user:81684243-9356-4421-8fbf-a4f8d36aa31b")
+ .relation("viewer")
+ ._object("document:roadmap")
+ .expectation(true)
+);
+fgaClient.writeAssertions(assertions).get();
```
### API Endpoints
+| Method | HTTP request | Description |
+| ------------- | ------------- | ------------- |
+| [**check**](docs/OpenFgaApi.md#check) | **POST** /stores/{store_id}/check | Check whether a user is authorized to access an object |
+| [**createStore**](docs/OpenFgaApi.md#createstore) | **POST** /stores | Create a store |
+| [**deleteStore**](docs/OpenFgaApi.md#deletestore) | **DELETE** /stores/{store_id} | Delete a store |
+| [**expand**](docs/OpenFgaApi.md#expand) | **POST** /stores/{store_id}/expand | Expand all relationships in userset tree format, and following userset rewrite rules. Useful to reason about and debug a certain relationship |
+| [**getStore**](docs/OpenFgaApi.md#getstore) | **GET** /stores/{store_id} | Get a store |
+| [**listObjects**](docs/OpenFgaApi.md#listobjects) | **POST** /stores/{store_id}/list-objects | List all objects of the given type that the user has a relation with |
+| [**listStores**](docs/OpenFgaApi.md#liststores) | **GET** /stores | List all stores |
+| [**read**](docs/OpenFgaApi.md#read) | **POST** /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules |
+| [**readAssertions**](docs/OpenFgaApi.md#readassertions) | **GET** /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID |
+| [**readAuthorizationModel**](docs/OpenFgaApi.md#readauthorizationmodel) | **GET** /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model |
+| [**readAuthorizationModels**](docs/OpenFgaApi.md#readauthorizationmodels) | **GET** /stores/{store_id}/authorization-models | Return all the authorization models for a particular store |
+| [**readChanges**](docs/OpenFgaApi.md#readchanges) | **GET** /stores/{store_id}/changes | Return a list of all the tuple changes |
+| [**write**](docs/OpenFgaApi.md#write) | **POST** /stores/{store_id}/write | Add or delete tuples from the store |
+| [**writeAssertions**](docs/OpenFgaApi.md#writeassertions) | **PUT** /stores/{store_id}/assertions/{authorization_model_id} | Upsert assertions for an authorization model ID |
+| [**writeAuthorizationModel**](docs/OpenFgaApi.md#writeauthorizationmodel) | **POST** /stores/{store_id}/authorization-models | Create a new authorization model |
+
### Models
diff --git a/build.gradle b/build.gradle
index 156bc95..291c259 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@ plugins {
id 'java'
// Quality
+ id 'jacoco'
id 'jvm-test-suite'
id 'com.diffplug.spotless' version '6.20.0'
@@ -17,7 +18,7 @@ plugins {
apply from: 'publish.gradle'
group = 'dev.openfga'
-version = '0.0.4'
+version = '0.0.5'
repositories {
mavenCentral()
@@ -36,6 +37,16 @@ javadoc {
options.addStringOption('Xdoclint:none', '-quiet')
}
+test {
+ // JaCoCo coverage report is always generated after tests run.
+ finalizedBy jacocoTestReport
+}
+
+jacocoTestReport {
+ // tests are required to run before generating a JaCoCo coverage report.
+ dependsOn test
+}
+
ext {
jackson_version = "2.14.1"
junit_version = "5.7.1"
diff --git a/publish.gradle b/publish.gradle
index b070679..927ab8c 100644
--- a/publish.gradle
+++ b/publish.gradle
@@ -6,7 +6,7 @@ publishing {
pom {
group = 'dev.openfga'
name = 'openfga-sdk'
- version = '0.0.4'
+ version = '0.0.5'
description = 'This is an autogenerated Java SDK for OpenFGA. It provides a wrapper around the [OpenFGA API definition](https://openfga.dev/api).'
url = 'https://openfga.dev'
licenses {
diff --git a/src/main/java/dev/openfga/sdk/api/OpenFgaApi.java b/src/main/java/dev/openfga/sdk/api/OpenFgaApi.java
index 1b27e63..c4f2e25 100644
--- a/src/main/java/dev/openfga/sdk/api/OpenFgaApi.java
+++ b/src/main/java/dev/openfga/sdk/api/OpenFgaApi.java
@@ -52,6 +52,11 @@
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
+/**
+ * A low-level API representation of an OpenFGA server.
+ *
+ * Most code should favor the simpler and higher-level {@link OpenFgaClient} when calling an OpenFGA server.
+ */
public class OpenFgaApi {
private final HttpClient memberVarHttpClient;
private final ObjectMapper memberVarObjectMapper;
@@ -61,8 +66,6 @@ public class OpenFgaApi {
private final Consumer> memberVarResponseInterceptor;
private final Consumer> memberVarAsyncResponseInterceptor;
- // TODO: In every request, get access token, (Assuming plain access token, or OAuth2 CredentialsMethod)
-
public OpenFgaApi(ApiClient apiClient, Configuration configuration) throws FgaInvalidParameterException {
memberVarHttpClient = apiClient.getHttpClient();
memberVarObjectMapper = apiClient.getObjectMapper();
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientAssertion.java b/src/main/java/dev/openfga/sdk/api/client/ClientAssertion.java
new file mode 100644
index 0000000..d1722a9
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientAssertion.java
@@ -0,0 +1,86 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import dev.openfga.sdk.api.model.Assertion;
+import dev.openfga.sdk.api.model.TupleKey;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ClientAssertion {
+ private String user;
+ private String relation;
+ private String _object;
+ private boolean expectation;
+
+ public ClientAssertion user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+
+ public ClientAssertion relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientAssertion _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ /**
+ * Get _object
+ * @return _object
+ **/
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientAssertion expectation(boolean expectation) {
+ this.expectation = expectation;
+ return this;
+ }
+
+ public boolean getExpectation() {
+ return expectation;
+ }
+
+ public Assertion asAssertion() {
+ TupleKey tupleKey = new TupleKey().user(user).relation(relation)._object(_object);
+ return new Assertion().tupleKey(tupleKey).expectation(expectation);
+ }
+
+ public static List asAssertions(List assertions) {
+ if (assertions == null || assertions.isEmpty()) {
+ return List.of();
+ }
+
+ return assertions.stream().map(ClientAssertion::asAssertion).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientCheckRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientCheckRequest.java
new file mode 100644
index 0000000..a8d4005
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientCheckRequest.java
@@ -0,0 +1,58 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+public class ClientCheckRequest {
+ private String user;
+ private String relation;
+ private String _object;
+
+ public ClientCheckRequest _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ /**
+ * Get _object
+ * @return _object
+ **/
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientCheckRequest relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientCheckRequest user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientExpandRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientExpandRequest.java
new file mode 100644
index 0000000..9394753
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientExpandRequest.java
@@ -0,0 +1,58 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+public class ClientExpandRequest {
+ private String user;
+ private String relation;
+ private String _object;
+
+ public ClientExpandRequest _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ /**
+ * Get _object
+ * @return _object
+ **/
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientExpandRequest relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientExpandRequest user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientListObjectsRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientListObjectsRequest.java
new file mode 100644
index 0000000..9f25b34
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientListObjectsRequest.java
@@ -0,0 +1,66 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import java.util.List;
+
+public class ClientListObjectsRequest {
+ private String user;
+ private String relation;
+ private String type;
+ private List contextualTupleKeys;
+
+ public ClientListObjectsRequest user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+
+ public ClientListObjectsRequest relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientListObjectsRequest type(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public ClientListObjectsRequest contextualTupleKeys(List contextualTupleKeys) {
+ this.contextualTupleKeys = contextualTupleKeys;
+ return this;
+ }
+
+ public List getContextualTupleKeys() {
+ return contextualTupleKeys;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientListRelationsRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientListRelationsRequest.java
new file mode 100644
index 0000000..1f122f5
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientListRelationsRequest.java
@@ -0,0 +1,66 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import java.util.List;
+
+public class ClientListRelationsRequest {
+ private String user;
+ private String _object;
+ private List relations;
+ private List contextualTupleKeys;
+
+ public ClientListRelationsRequest user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+
+ public ClientListRelationsRequest _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientListRelationsRequest relations(List relations) {
+ this.relations = relations;
+ return this;
+ }
+
+ /**
+ * Get relations
+ * @return relations
+ **/
+ public List getRelations() {
+ return relations;
+ }
+
+ public ClientListRelationsRequest contextualTupleKeys(List contextualTupleKeys) {
+ this.contextualTupleKeys = contextualTupleKeys;
+ return this;
+ }
+
+ public List getContextualTupleKeys() {
+ return contextualTupleKeys;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientReadRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientReadRequest.java
new file mode 100644
index 0000000..1b9df66
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientReadRequest.java
@@ -0,0 +1,58 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+public class ClientReadRequest {
+ private String user;
+ private String relation;
+ private String _object;
+
+ public ClientReadRequest _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ /**
+ * Get _object
+ * @return _object
+ **/
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientReadRequest relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientReadRequest user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientTupleKey.java b/src/main/java/dev/openfga/sdk/api/client/ClientTupleKey.java
new file mode 100644
index 0000000..7993519
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientTupleKey.java
@@ -0,0 +1,88 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import dev.openfga.sdk.api.model.ContextualTupleKeys;
+import dev.openfga.sdk.api.model.TupleKey;
+import dev.openfga.sdk.api.model.TupleKeys;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ClientTupleKey {
+ private String user;
+ private String relation;
+ private String _object;
+
+ public ClientTupleKey _object(String _object) {
+ this._object = _object;
+ return this;
+ }
+
+ /**
+ * Get _object
+ * @return _object
+ **/
+ public String getObject() {
+ return _object;
+ }
+
+ public ClientTupleKey relation(String relation) {
+ this.relation = relation;
+ return this;
+ }
+
+ /**
+ * Get relation
+ * @return relation
+ **/
+ public String getRelation() {
+ return relation;
+ }
+
+ public ClientTupleKey user(String user) {
+ this.user = user;
+ return this;
+ }
+
+ /**
+ * Get user
+ * @return user
+ **/
+ public String getUser() {
+ return user;
+ }
+
+ public TupleKey asTupleKey() {
+ return new TupleKey().user(user).relation(relation)._object(_object);
+ }
+
+ public static TupleKeys asTupleKeys(List clientTupleKeys) {
+ if (clientTupleKeys == null || clientTupleKeys.size() == 0) {
+ return new TupleKeys();
+ }
+
+ return new TupleKeys().tupleKeys(asListOfTupleKey(clientTupleKeys));
+ }
+
+ public static ContextualTupleKeys asContextualTupleKeys(List clientTupleKeys) {
+ if (clientTupleKeys == null || clientTupleKeys.size() == 0) {
+ return new ContextualTupleKeys();
+ }
+
+ return new ContextualTupleKeys().tupleKeys(asListOfTupleKey(clientTupleKeys));
+ }
+
+ private static List asListOfTupleKey(List clientTupleKeys) {
+ return clientTupleKeys.stream().map(ClientTupleKey::asTupleKey).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/ClientWriteRequest.java b/src/main/java/dev/openfga/sdk/api/client/ClientWriteRequest.java
new file mode 100644
index 0000000..ecbebbc
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/ClientWriteRequest.java
@@ -0,0 +1,38 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import java.util.List;
+
+public class ClientWriteRequest {
+ private List writes;
+ private List deletes;
+
+ public ClientWriteRequest writes(List writes) {
+ this.writes = writes;
+ return this;
+ }
+
+ public List getWrites() {
+ return writes;
+ }
+
+ public ClientWriteRequest deletes(List deletes) {
+ this.deletes = deletes;
+ return this;
+ }
+
+ public List getDeletes() {
+ return deletes;
+ }
+}
diff --git a/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java b/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java
new file mode 100644
index 0000000..34517d6
--- /dev/null
+++ b/src/main/java/dev/openfga/sdk/api/client/OpenFgaClient.java
@@ -0,0 +1,509 @@
+/*
+ * OpenFGA
+ * A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.
+ *
+ * The version of the OpenAPI document: 0.1
+ * Contact: community@openfga.dev
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+package dev.openfga.sdk.api.client;
+
+import static dev.openfga.sdk.util.StringUtil.isNullOrWhitespace;
+
+import dev.openfga.sdk.api.*;
+import dev.openfga.sdk.api.configuration.*;
+import dev.openfga.sdk.api.model.*;
+import dev.openfga.sdk.errors.*;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+public class OpenFgaClient {
+ private ApiClient apiClient;
+ private ClientConfiguration configuration;
+ private OpenFgaApi api;
+
+ private static final String CLIENT_BULK_REQUEST_ID_HEADER = "X-OpenFGA-Client-Bulk-Request-Id";
+ private static final String CLIENT_METHOD_HEADER = "X-OpenFGA-Client-Method";
+ private static final int DEFAULT_MAX_METHOD_PARALLEL_REQS = 10;
+
+ public OpenFgaClient(ApiClient apiClient, ClientConfiguration configuration) throws FgaInvalidParameterException {
+ this.apiClient = apiClient;
+ this.configuration = configuration;
+ this.api = new OpenFgaApi(apiClient, configuration);
+ }
+
+ /* ***********
+ * Utilities *
+ *************/
+
+ public void setStoreId(String storeId) {
+ configuration.storeId(storeId);
+ }
+
+ public void setAuthorizationModelId(String authorizationModelId) {
+ configuration.authorizationModelId(authorizationModelId);
+ }
+
+ public void setConfiguration(ClientConfiguration configuration) throws FgaInvalidParameterException {
+ this.configuration = configuration;
+ this.api = new OpenFgaApi(apiClient, configuration);
+ }
+
+ /* ********
+ * Stores *
+ **********/
+
+ /**
+ * ListStores - Get a paginated list of stores.
+ */
+ public CompletableFuture listStores() throws FgaInvalidParameterException {
+ configuration.assertValid();
+ return call(() -> api.listStores(null, null));
+ }
+
+ public CompletableFuture listStores(ListStoresOptions options)
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ return call(() -> api.listStores(options.getPageSize(), options.getContinuationToken()));
+ }
+
+ /**
+ * CreateStore - Initialize a store
+ */
+ public CompletableFuture createStore(CreateStoreRequest request)
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ return call(() -> api.createStore(request));
+ }
+
+ /**
+ * GetStore - Get information about the current store.
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture getStore() throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ return call(() -> api.getStore(storeId));
+ }
+
+ /**
+ * DeleteStore - Delete a store
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture deleteStore() throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ return call(() -> api.deleteStore(storeId));
+ }
+
+ /* **********************
+ * Authorization Models *
+ ************************/
+
+ /**
+ * ReadAuthorizationModels - Read all authorization models
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture readAuthorizationModels()
+ throws FgaInvalidParameterException {
+ return readAuthorizationModels(null);
+ }
+
+ /**
+ * ReadAuthorizationModels - Read all authorization models
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture readAuthorizationModels(
+ ReadAuthorizationModelsOptions options) throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+
+ Integer pageSize;
+ String continuationToken;
+
+ if (options != null) {
+ pageSize = options.getPageSize();
+ continuationToken = options.getContinuationToken();
+ } else {
+ // null are valid for these values
+ continuationToken = null;
+ pageSize = null;
+ }
+
+ return call(() -> api.readAuthorizationModels(storeId, pageSize, continuationToken));
+ }
+
+ /**
+ * WriteAuthorizationModel - Create a new version of the authorization model
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture writeAuthorizationModel(
+ WriteAuthorizationModelRequest request) throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ return call(() -> api.writeAuthorizationModel(storeId, request));
+ }
+
+ /**
+ * ReadAuthorizationModel - Read the current authorization model
+ *
+ * @throws FgaInvalidParameterException When either the Store ID or Authorization Model ID are null, empty, or whitespace
+ */
+ public CompletableFuture readAuthorizationModel()
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ String authorizationModelId = configuration.getAuthorizationModelIdChecked();
+ return call(() -> api.readAuthorizationModel(storeId, authorizationModelId));
+ }
+
+ /**
+ * ReadAuthorizationModel - Read the current authorization model
+ *
+ * @throws FgaInvalidParameterException When either the Store ID or Authorization Model ID are null, empty, or whitespace
+ */
+ public CompletableFuture readAuthorizationModel(
+ ReadAuthorizationModelOptions options) throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ String authorizationModelId = options.getAuthorizationModelIdChecked();
+ return call(() -> api.readAuthorizationModel(storeId, authorizationModelId));
+ }
+
+ /**
+ * ReadLatestAuthorizationModel - Read the latest authorization model for the current store
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture readLatestAuthorizationModel()
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ return call(() -> api.readAuthorizationModels(storeId, 1, null))
+ .thenApply(response -> new ReadAuthorizationModelResponse()
+ .authorizationModel(response.getAuthorizationModels().get(0)));
+ }
+
+ /* *********************
+ * Relationship Tuples *
+ ***********************/
+
+ /**
+ * Read Changes - Read the list of historical relationship tuple writes and deletes
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture readChanges(ReadChangesOptions options)
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+ return call(() ->
+ api.readChanges(storeId, options.getType(), options.getPageSize(), options.getContinuationToken()));
+ }
+
+ /**
+ * Read - Read tuples previously written to the store (does not evaluate)
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture read(ClientReadRequest request) throws FgaInvalidParameterException {
+ return read(request, null);
+ }
+
+ /**
+ * Read - Read tuples previously written to the store (does not evaluate)
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture read(ClientReadRequest request, ClientReadOptions options)
+ throws FgaInvalidParameterException {
+ configuration.assertValid();
+ String storeId = configuration.getStoreIdChecked();
+
+ ReadRequest body = new ReadRequest();
+ TupleKey tupleKey = new TupleKey();
+
+ if (request != null) {
+ tupleKey.user(request.getUser()).relation(request.getRelation())._object(request.getObject());
+ }
+
+ if (options != null) {
+ body.pageSize(options.getPageSize()).continuationToken(options.getContinuationToken());
+ }
+
+ body.tupleKey(tupleKey);
+
+ return call(() -> api.read(storeId, body));
+ }
+
+ /**
+ * Write - Create or delete relationship tuples
+ *
+ * @throws FgaInvalidParameterException When the Store ID is null, empty, or whitespace
+ */
+ public CompletableFuture