Skip to content
Draft
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
25 changes: 22 additions & 3 deletions cmd/tuple/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,23 @@ var deleteCmd = &cobra.Command{
}
if fileName != "" {
startTime := time.Now()
successPath, _ := cmd.Flags().GetString("success-log")
failurePath, _ := cmd.Flags().GetString("failure-log")
var successLogger, failureLogger *tuple.TupleLogger
if successPath != "" {
successLogger, err = tuple.NewTupleLogger(successPath)
if err != nil {
return err
}
defer successLogger.Close()
}
if failurePath != "" {
failureLogger, err = tuple.NewTupleLogger(failurePath)
if err != nil {
return err
}
defer failureLogger.Close()
}

clientTupleKeys, err := tuplefile.ReadTupleFile(fileName)
if err != nil {
Expand All @@ -70,8 +87,10 @@ var deleteCmd = &cobra.Command{
Deletes: clientTupleKeyWithoutCondition,
}

newCtx := tuple.WithSuccessLogger(cmd.Context(), successLogger)
newCtx = tuple.WithFailureLogger(newCtx, failureLogger)
response, err := tuple.ImportTuplesWithoutRampUp(
cmd.Context(), fgaClient,
newCtx, fgaClient,
maxTuplesPerWrite, maxParallelRequests,
writeRequest)
if err != nil {
Expand All @@ -83,11 +102,11 @@ var deleteCmd = &cobra.Command{

outputResponse := make(map[string]interface{})

if !hideImportedTuples && len(response.Successful) > 0 {
if !hideImportedTuples && successPath == "" && len(response.Successful) > 0 {
outputResponse["successful"] = response.Successful
}

if len(response.Failed) > 0 {
if failurePath == "" && len(response.Failed) > 0 {
outputResponse["failed"] = response.Failed
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/tuple/tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func init() {
TupleCmd.AddCommand(deleteCmd)

TupleCmd.PersistentFlags().String("store-id", "", "Store ID")
TupleCmd.PersistentFlags().String("success-log", "", "Filepath to log successful writes")
TupleCmd.PersistentFlags().String("failure-log", "", "Filepath to log failed writes")

err := TupleCmd.MarkPersistentFlagRequired("store-id")
if err != nil { //nolint:wsl
Expand Down
26 changes: 24 additions & 2 deletions cmd/tuple/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,26 @@ func writeTuplesFromFile(ctx context.Context, flags *flag.FlagSet, fgaClient *cl
return fmt.Errorf("failed to parse debug flag due to %w", err)
}

successPath, _ := flags.GetString("success-log")
failurePath, _ := flags.GetString("failure-log")

var successLogger, failureLogger *tuple.TupleLogger
if successPath != "" {
successLogger, err = tuple.NewTupleLogger(successPath)
if err != nil {
return err
}
defer successLogger.Close()
}

if failurePath != "" {
failureLogger, err = tuple.NewTupleLogger(failurePath)
if err != nil {
return err
}
defer failureLogger.Close()
}

tuples, err := tuplefile.ReadTupleFile(fileName)
if err != nil {
return err //nolint:wrapcheck
Expand All @@ -243,6 +263,8 @@ func writeTuplesFromFile(ctx context.Context, flags *flag.FlagSet, fgaClient *cl
}

newCtx := utils.WithDebugContext(ctx, debug)
newCtx = tuple.WithSuccessLogger(newCtx, successLogger)
newCtx = tuple.WithFailureLogger(newCtx, failureLogger)

response, err := tuple.ImportTuples(
newCtx, fgaClient,
Expand All @@ -257,11 +279,11 @@ func writeTuplesFromFile(ctx context.Context, flags *flag.FlagSet, fgaClient *cl

outputResponse := make(map[string]interface{})

if !hideImportedTuples && len(response.Successful) > 0 {
if !hideImportedTuples && successPath == "" && len(response.Successful) > 0 {
outputResponse["successful"] = response.Successful
}

if len(response.Failed) > 0 {
if failurePath == "" && len(response.Failed) > 0 {
outputResponse["failed"] = response.Failed
}

Expand Down
41 changes: 32 additions & 9 deletions internal/tuple/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func importTuplesWithoutRampUp(
return nil, fmt.Errorf("failed to import tuples due to %w", err)
}

successful, failed := processWritesAndDeletes(response)
successful, failed := processWritesAndDeletes(ctx, response)
result := ImportResponse{
Successful: successful,
Failed: failed,
Expand Down Expand Up @@ -215,8 +215,8 @@ func importTuplesWithRampUp(ctx context.Context, fgaClient client.SdkClient,
return err //nolint:wrapcheck
}

successfulWrites, failedWrites := processWrites(response.Writes)
successfulDeletes, failedDeletes := processDeletes(response.Deletes)
successfulWrites, failedWrites := processWrites(ctx, response.Writes)
successfulDeletes, failedDeletes := processDeletes(ctx, response.Deletes)

mutex.Lock()

Expand Down Expand Up @@ -298,45 +298,61 @@ func extractErrMsg(err error) string {
}

func processWritesAndDeletes(
ctx context.Context,
response *client.ClientWriteResponse,
) ([]client.ClientTupleKey, []failedWriteResponse) {
successfulWrites, failedWrites := processWrites(response.Writes)
successfulDeletes, failedDeletes := processDeletes(response.Deletes)
successfulWrites, failedWrites := processWrites(ctx, response.Writes)
successfulDeletes, failedDeletes := processDeletes(ctx, response.Deletes)

return append(successfulWrites, successfulDeletes...), append(failedWrites, failedDeletes...)
}

func processWrites(
ctx context.Context,
writes []client.ClientWriteRequestWriteResponse,
) ([]client.ClientTupleKey, []failedWriteResponse) {
var (
successfulWrites []client.ClientTupleKey
failedWrites []failedWriteResponse
)

successLogger := getSuccessLogger(ctx)
failureLogger := getFailureLogger(ctx)

for _, write := range writes {
if write.Status == client.SUCCESS {
successfulWrites = append(successfulWrites, write.TupleKey)
if successLogger != nil {
successLogger.LogSuccess(write.TupleKey)
}
} else {
reason := extractErrMsg(write.Error)
failedWrites = append(failedWrites, failedWriteResponse{
failed := failedWriteResponse{
TupleKey: write.TupleKey,
Reason: reason,
})
}
failedWrites = append(failedWrites, failed)
if failureLogger != nil {
failureLogger.LogFailure(write.TupleKey)
}
}
}

return successfulWrites, failedWrites
}

func processDeletes(
ctx context.Context,
deletes []client.ClientWriteRequestDeleteResponse,
) ([]client.ClientTupleKey, []failedWriteResponse) {
var (
successfulDeletes []client.ClientTupleKey
failedDeletes []failedWriteResponse
)

successLogger := getSuccessLogger(ctx)
failureLogger := getFailureLogger(ctx)

for _, del := range deletes {
deletedTupleKey := openfga.TupleKey{
Object: del.TupleKey.Object,
Expand All @@ -346,12 +362,19 @@ func processDeletes(

if del.Status == client.SUCCESS {
successfulDeletes = append(successfulDeletes, deletedTupleKey)
if successLogger != nil {
successLogger.LogSuccess(deletedTupleKey)
}
} else {
reason := extractErrMsg(del.Error)
failedDeletes = append(failedDeletes, failedWriteResponse{
failed := failedWriteResponse{
TupleKey: deletedTupleKey,
Reason: reason,
})
}
failedDeletes = append(failedDeletes, failed)
if failureLogger != nil {
failureLogger.LogFailure(deletedTupleKey)
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions internal/tuple/import_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tuple

import (
"context"
"errors"
"testing"

Expand All @@ -23,7 +24,7 @@ func TestProcessWrites(t *testing.T) {
},
}

successful, failed := processWrites(writes)
successful, failed := processWrites(context.Background(), writes)

assert.Len(t, successful, 1)
assert.Len(t, failed, 1)
Expand All @@ -45,7 +46,7 @@ func TestProcessDeletes(t *testing.T) {
},
}

successful, failed := processDeletes(deletes)
successful, failed := processDeletes(context.Background(), deletes)

assert.Len(t, successful, 1)
assert.Len(t, failed, 1)
Expand Down
Loading
Loading