Skip to content

Commit

Permalink
feat(tuple): support consistency in the tuple read command
Browse files Browse the repository at this point in the history
  • Loading branch information
ewanharris committed Sep 2, 2024
1 parent fc22d9c commit 12ba9f5
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 10 deletions.
2 changes: 1 addition & 1 deletion cmd/store/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func buildStoreData(config fga.ClientConfig, fgaClient client.SdkClient, maxTupl
// get the tuples
maxPages := int(math.Ceil(float64(maxTupleCount) / float64(tuple.DefaultReadPageSize)))

rawTuples, err := tuple.Read(fgaClient, &client.ClientReadRequest{}, maxPages)
rawTuples, err := tuple.Read(fgaClient, &client.ClientReadRequest{}, maxPages, nil)
if err != nil {
return nil, fmt.Errorf("unable to read tuples: %w", err)
}
Expand Down
24 changes: 21 additions & 3 deletions cmd/tuple/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,14 @@ func (r readResponse) toCsvDTO() ([]readResponseCSVDTO, error) {
return readResponseDTO, nil
}

func read(fgaClient client.SdkClient, user string, relation string, object string, maxPages int) (
func read(
fgaClient client.SdkClient,
user string,
relation string,
object string,
maxPages int,
consistency *openfga.ConsistencyPreference,
) (
*readResponse, error,
) {
body := &client.ClientReadRequest{}
Expand All @@ -104,7 +111,7 @@ func read(fgaClient client.SdkClient, user string, relation string, object strin
body.Object = &object
}

response, err := tuple.Read(fgaClient, body, maxPages)
response, err := tuple.Read(fgaClient, body, maxPages, consistency)
if err != nil {
return nil, err //nolint:wrapcheck
}
Expand Down Expand Up @@ -142,7 +149,12 @@ var readCmd = &cobra.Command{
return fmt.Errorf("failed to parse max pages due to %w", err)
}

response, err := read(fgaClient, user, relation, object, maxPages)
consistency, err := cmdutils.ParseConsistencyFromCmd(cmd)
if err != nil {
return fmt.Errorf("error parsing consistency for check: %w", err)
}

response, err := read(fgaClient, user, relation, object, maxPages, consistency)
if err != nil {
return err
}
Expand Down Expand Up @@ -180,6 +192,12 @@ func init() {
readCmd.Flags().String("output-format", "json", "Specifies the format for data presentation. Valid options: "+
"json, simple-json, csv, and yaml.")
readCmd.Flags().Bool("simple-output", false, "Output data in simpler version. (It can be used by write and delete commands)") //nolint:lll
readCmd.Flags().String(
"consistency",
"",
"Consistency preference for the request. Valid options are HIGHER_CONSISTENCY and MINIMIZE_LATENCY.",
)

_ = readCmd.Flags().MarkDeprecated("simple-output", "the flag \"simple-output\" is deprecated and will be removed"+
" in future releases.\nPlease use the \"--output-format=simple-json\" flag instead.")
}
45 changes: 40 additions & 5 deletions cmd/tuple/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ func TestReadError(t *testing.T) {

mockFgaClient.EXPECT().Read(context.Background()).Return(mockBody)

_, err := read(mockFgaClient, "user:user1", "reader", "document:doc1", 5)
_, err := read(
mockFgaClient,
"user:user1",
"reader",
"document:doc1",
5,
openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(),
)
if err == nil {
t.Error("Expect error but there is none")
}
Expand Down Expand Up @@ -91,7 +98,14 @@ func TestReadEmpty(t *testing.T) {

mockFgaClient.EXPECT().Read(context.Background()).Return(mockBody)

output, err := read(mockFgaClient, "user:user1", "reader", "document:doc1", 5)
output, err := read(
mockFgaClient,
"user:user1",
"reader",
"document:doc1",
5,
openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(),
)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -166,7 +180,14 @@ func TestReadSinglePage(t *testing.T) {

mockFgaClient.EXPECT().Read(context.Background()).Return(mockBody)

output, err := read(mockFgaClient, "user:user1", "reader", "document:doc1", 5)
output, err := read(
mockFgaClient,
"user:user1",
"reader",
"document:doc1",
5,
openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(),
)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -281,7 +302,14 @@ func TestReadMultiPages(t *testing.T) {
mockFgaClient.EXPECT().Read(context.Background()).Return(mockBody2),
)

output, err := read(mockFgaClient, "user:user1", "reader", "document:doc1", 5)
output, err := read(
mockFgaClient,
"user:user1",
"reader",
"document:doc1",
5,
openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(),
)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -356,7 +384,14 @@ func TestReadMultiPagesMaxLimit(t *testing.T) {

mockFgaClient.EXPECT().Read(context.Background()).Return(mockBody)

output, err := read(mockFgaClient, "user:user1", "reader", "document:doc1", 1)
output, err := read(
mockFgaClient,
"user:user1",
"reader",
"document:doc1",
1,
openfga.CONSISTENCYPREFERENCE_UNSPECIFIED.Ptr(),
)
if err != nil {
t.Error(err)
}
Expand Down
11 changes: 10 additions & 1 deletion internal/tuple/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import (

const DefaultReadPageSize int32 = 50

func Read(fgaClient client.SdkClient, body *client.ClientReadRequest, maxPages int) (
func Read(
fgaClient client.SdkClient,
body *client.ClientReadRequest,
maxPages int,
consistency *openfga.ConsistencyPreference,
) (
*openfga.ReadResponse, error,
) {
tuples := make([]openfga.Tuple, 0)
Expand All @@ -20,6 +25,10 @@ func Read(fgaClient client.SdkClient, body *client.ClientReadRequest, maxPages i
PageSize: openfga.PtrInt32(DefaultReadPageSize),
}

if consistency != nil && *consistency != openfga.CONSISTENCYPREFERENCE_UNSPECIFIED {
options.Consistency = consistency
}

for {
options.ContinuationToken = &continuationToken

Expand Down

0 comments on commit 12ba9f5

Please sign in to comment.