feat: add write conflict resolution options#136
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThis PR introduces write conflict resolution options to the SDK, adding Changes
Sequence DiagramsequenceDiagram
participant User as User Code
participant Client as Client
participant Mapper as Mapper Logic
participant API as WriteRequest Body
User->>Client: Write with ClientWriteOptions<br/>(Conflict: OnDuplicateWrites.Ignore)
Client->>Mapper: MapOnDuplicateWrites(Ignore)
Mapper-->>Client: WriteRequestWrites.OnDuplicateEnum.Ignore
Client->>Mapper: MapOnMissingDeletes(null)
Mapper-->>Client: WriteRequestDeletes.OnMissingEnum.Error<br/>(default)
Client->>API: WriteRequest with<br/>Writes.OnDuplicate=Ignore<br/>Deletes.OnMissing=Error
API-->>Client: Response
Client-->>User: Result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The changes introduce straightforward enum mappings and conflict option propagation with consistent patterns across test cases. While the test file is large with extensive scenarios, the logic density is moderate—primarily validation of option threading through request paths and header precedence. The breaking API surface change (optional Possibly related issues
Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
.openapi-generator/FILES(1 hunks)CHANGELOG.md(8 hunks)README.md(2 hunks)src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs(5 hunks)src/OpenFga.Sdk/Api/OpenFgaApi.cs(31 hunks)src/OpenFga.Sdk/ApiClient/ApiClient.cs(3 hunks)src/OpenFga.Sdk/Client/Client.cs(19 hunks)src/OpenFga.Sdk/Client/ClientConfiguration.cs(4 hunks)src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientCreateStoreOptions.cs(1 hunks)src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientListStoresOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientReadAssertionsOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelsOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientReadChangesOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientRequestOptions.cs(1 hunks)src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithStoreId.cs(1 hunks)src/OpenFga.Sdk/Client/Model/ClientWriteAssertionsOptions.cs(2 hunks)src/OpenFga.Sdk/Client/Model/ClientWriteOptions.cs(3 hunks)src/OpenFga.Sdk/Model/RequestOptions.cs(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (22)
src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Model/RequestOptions.cs (1)
src/OpenFga.Sdk/Client/Client.cs (1)
IRequestOptions(74-78)
src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientCreateStoreOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelsOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientReadAssertionsOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientWriteAssertionsOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs (4)
src/OpenFga.Sdk/Client/Client.cs (2)
WriteRequestWrites(239-244)WriteRequestDeletes(246-251)src/OpenFga.Sdk/ApiClient/Utils.cs (1)
Utils(27-63)src/OpenFga.Sdk/Client/ClientConfiguration.cs (3)
ClientConfiguration(31-157)ClientConfiguration(36-45)ClientConfiguration(50-50)src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientReadChangesOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientWriteOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/ClientConfiguration.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientRequestOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Client.cs (7)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (2)
ApiClient(30-231)ApiClient(41-67)src/OpenFga.Sdk/Client/ClientConfiguration.cs (4)
ClientConfiguration(31-157)ClientConfiguration(36-45)ClientConfiguration(50-50)ValidateHeaders(126-156)src/OpenFga.Sdk/Model/RequestOptions.cs (3)
RequestOptions(18-35)RequestOptions(22-23)RequestOptions(29-31)src/OpenFga.Sdk/Model/WriteRequestWrites.cs (2)
WriteRequestWrites(70-78)WriteRequestWrites(107-109)src/OpenFga.Sdk/Model/WriteRequestDeletes.cs (2)
WriteRequestDeletes(70-78)WriteRequestDeletes(107-109)src/OpenFga.Sdk/Api/OpenFgaApi.cs (16)
Task(52-74)Task(85-107)Task(117-133)Task(143-164)Task(175-197)Task(207-228)Task(239-261)Task(273-297)Task(308-330)Task(341-363)Task(374-398)Task(409-433)Task(445-472)Task(486-520)Task(531-553)Task(565-590)src/OpenFga.Sdk/Client/Model/ClientWriteOptions.cs (1)
ClientWriteOptions(118-135)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (2)
src/OpenFga.Sdk/Exceptions/ApiException.cs (5)
ApiException(22-84)ApiException(26-28)ApiException(34-36)ApiException(45-47)ApiException(50-52)src/OpenFga.Sdk/Exceptions/ApiAuthenticationError.cs (3)
FgaApiAuthenticationError(25-48)FgaApiAuthenticationError(34-38)FgaApiAuthenticationError(40-42)
src/OpenFga.Sdk/Client/Model/ClientListStoresOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs (1)
src/OpenFga.Sdk/ApiClient/ApiClient.cs (1)
IDictionary(189-228)
src/OpenFga.Sdk/Api/OpenFgaApi.cs (1)
src/OpenFga.Sdk/Client/Client.cs (17)
Task(81-114)Task(116-139)Task(141-182)Task(184-215)Task(260-262)Task(267-270)Task(275-276)Task(281-282)Task(291-294)Task(299-302)Task(307-316)Task(321-332)Task(341-344)Task(349-363)Task(368-437)Task(442-444)IRequestOptions(74-78)
🪛 LanguageTool
README.md
[grammar] ~210-~210: There might be a mistake here.
Context: ...### Custom Headers #### Default Headers You can set default headers that will be...
(QB_NEW_EN)
CHANGELOG.md
[grammar] ~6-~6: There might be a mistake here.
Context: ...ionfor headers sent with every request - per-request headers support viaHeaders...
(QB_NEW_EN)
[grammar] ~9-~9: There might be a mistake here.
Context: ...s` class for client-level header support - add header validation to prevent overidi...
(QB_NEW_EN)
[grammar] ~10-~10: Ensure spelling is correct
Context: ...rt - add header validation to prevent overiding of reserved headers - feat: add write c...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~10-~10: There might be a mistake here.
Context: ...to prevent overiding of reserved headers - feat: add write conflict resolution opti...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ...norefor handling missing tuple deletes - Available inClientWriteOptions.Conflic...
(QB_NEW_EN)
[grammar] ~17-~17: There might be a mistake here.
Context: ...teOptions.Conflict` property [!WARNING] BREAKING CHANGES: - **OpenFgaApi method...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...d 2.0, .NET 8.0 and .NET 9.0 [!WARNING] BREAKING CHANGES: - While we have dropp...
(QB_NEW_EN)
[grammar] ~62-~62: There might be a mistake here.
Context: ... can still be used in .NET 6.0 projects. - We have updated the underlying OpenAPI g...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ... New Enum Value | Affected Enum | | -------------- | -------------------- ...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ... -------------------- | -------------- | | WRITE | TUPLEOPERATIONWRITE ...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ... TUPLEOPERATIONWRITE | TupleOperation | | DELETE | TUPLEOPERATIONDELETE ...
(QB_NEW_EN)
[grammar] ~109-~109: There might be a mistake here.
Context: ...lag enable-consistency-params enabled. See the [v1.5.7 release notes](https:/...
(QB_NEW_EN)
[grammar] ~176-~176: There might be a mistake here.
Context: ... - OpenFgaApi now requires storeId as first param when needed - `Configuratio...
(QB_NEW_EN)
[grammar] ~178-~178: There might be a mistake here.
Context: ...he following request interfaces changed: - CheckRequest: the TupleKey field is now of interfa...
(QB_NEW_EN)
[grammar] ~200-~200: There might be a mistake here.
Context: ...): read with no filter (read all tuples) - chore(deps): update dependencies ## v0....
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md
194-194: Bare URL used
(MD034, no-bare-urls)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Test netcoreapp3.1 on windows-latest
- GitHub Check: Analyze (csharp)
- GitHub Check: Test net8.0 on windows-latest
- GitHub Check: Test net48 on windows-latest
🔇 Additional comments (28)
src/OpenFga.Sdk/Client/Model/ClientReadChangesOptions.cs (1)
14-14: LGTM! Headers property correctly implements per-request header support.The addition of the
Headersproperty follows the established pattern across client option models. The nullableIDictionary<string, string>?type is appropriate for optional headers, and the/// <inheritdoc />comment correctly indicates interface implementation. Header validation is properly handled at the API client boundary as shown in the relevant code snippets.Also applies to: 35-36
src/OpenFga.Sdk/Client/Model/ClientListUsersOptions.cs (1)
15-15: LGTM!The addition of the
Headersproperty and correspondingusingdirective correctly implements per-request header support. The nullable dictionary type andinheritdoccomment indicate proper alignment with the interface contract.Also applies to: 31-33
src/OpenFga.Sdk/Client/Model/ClientWriteAssertionsOptions.cs (1)
14-15: LGTM!The per-request header support is correctly implemented with the appropriate nullable dictionary type and interface documentation inheritance.
Also applies to: 32-34
src/OpenFga.Sdk/Client/Model/ClientListRelationsOptions.cs (1)
15-15: LGTM!The addition of per-request header support follows the established pattern and correctly uses the nullable dictionary type with interface documentation.
Also applies to: 36-38
CHANGELOG.md (1)
5-51: LGTM!The changelog clearly documents the new per-request header support and breaking changes. The inclusion of before/after code examples helps users understand the migration path.
src/OpenFga.Sdk/Client/Model/ClientReadAssertionsOptions.cs (1)
14-15: LGTM!The per-request header support is correctly implemented following the established pattern across client option classes.
Also applies to: 31-33
src/OpenFga.Sdk/Client/Model/ClientReadOptions.cs (1)
15-15: LGTM!The addition of per-request header support is correctly implemented with the appropriate type and documentation.
Also applies to: 38-40
.openapi-generator/FILES (1)
240-240: LGTM!The addition of
RequestOptions.csto the generated files manifest correctly tracks the new model introduced for per-request header support.src/OpenFga.Sdk/Client/Model/ClientCheckOptions.cs (1)
15-15: LGTM!The per-request header support is correctly implemented, maintaining consistency with the other client option classes in this PR.
Also applies to: 31-33
src/OpenFga.Sdk/Client/Model/ClientExpandOptions.cs (1)
15-15: LGTM! Clean addition of per-request headers support.The
Headersproperty addition follows the consistent pattern established across client option classes and aligns with the per-request headers mechanism described in the PR objectives.Also applies to: 32-33
src/OpenFga.Sdk/Client/Model/ClientBatchCheckOptions.cs (1)
15-15: LGTM! Consistent implementation.The addition of the
Headersproperty is consistent with other client option classes and properly supports per-request header customization.Also applies to: 41-42
src/OpenFga.Sdk/Client/Model/ClientListObjectsOptions.cs (1)
15-15: LGTM! Pattern correctly applied.The
Headersproperty addition follows the established pattern and enables per-request header support for list objects operations.Also applies to: 32-33
src/OpenFga.Sdk/Client/Model/ClientRequestOptsWithStoreId.cs (1)
17-17: LGTM! Interface-based inheritance improves design.The change from
ClientRequestOptionstoIClientRequestOptionsfollows better design principles by depending on abstractions rather than concrete implementations. This aligns with the broader refactoring to introduceIClientRequestOptionsacross the SDK.src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelsOptions.cs (1)
14-15: LGTM with filename typo note.The
Headersproperty addition is correct and consistent. Note: This file also has the same filename typo as ClientReadAuthorizaionModelOptions.cs (missing 't' in "Authorization").Also applies to: 35-36
README.md (2)
208-246: Excellent documentation for Custom Headers.The Custom Headers section is well-structured with clear examples showing both default headers and per-request headers. The code examples are complete and follow C# conventions, making it easy for users to understand the feature.
577-614: Clear documentation for Conflict Options.The Conflict Options section effectively explains the new feature with:
- Clear descriptions of both
OnDuplicateWritesandOnMissingDeletesenums- Explicit listing of possible values and their defaults
- Complete code example demonstrating usage
This will help users understand how to handle write conflicts appropriately.
src/OpenFga.Sdk/Client/Model/ClientCreateStoreOptions.cs (1)
14-15: LGTM! Clean refactoring and Headers support.The changes effectively:
- Update the interface to inherit from
IClientRequestOptions(consistent with the broader refactoring)- Add the
Headersproperty for per-request header support- Simplify the implementation while maintaining proper inheritance
Also applies to: 18-18, 20-22
src/OpenFga.Sdk/Client/Model/ClientReadAuthorizaionModelOptions.cs (1)
14-15: The code changes are correct; the filename typo is pre-existing and out of scope for this PR.The
Headersproperty addition andusing System.Collections.Generic;statement are correct. The filename typo "Authorizaion" is pre-existing in the codebase (also appears inClientReadAuthorizaionModelsOptions.cs), indicating it originates from the generator template. Fixing it would require updating the generator source, not individual generated files—this should be addressed separately.src/OpenFga.Sdk/Client/Model/ClientRequestOptions.cs (1)
14-50: LGTM! Well-designed interface and implementation.The interface-based design provides a clean contract for per-request options, and the implementation correctly handles nullable headers for optional customization. The documentation clearly explains the header merging behavior with DefaultHeaders.
src/OpenFga.Sdk/Client/Client.cs (5)
68-78: LGTM! Centralized header extraction with validation.The
ExtractHeadersmethod correctly extracts headers from options implementingIClientRequestOptions, validates them usingClientConfiguration.ValidateHeaders, and returnsIRequestOptionsor null. This centralized approach ensures consistent header handling across all API calls.
239-251: LGTM! Correct enum mapping with explicit null handling.Both mapping methods correctly convert client-facing enums to API enums, with explicit null handling that defaults to
Errorbehavior. This aligns with the PR objective of explicitly sending default values to the API.
267-270: Breaking change: CreateStore parameter type updated.The parameter type changed from
ClientRequestOptions?toIClientRequestOptions?. While this enables the new header functionality, it's a breaking change that requires callers to update their code if they were explicitly usingClientRequestOptionsas the parameter type.Verify that this breaking change is properly documented in the changelog or release notes, as it may affect existing consumers of the SDK.
382-394: LGTM! Conflict options correctly applied to write requests.The write request construction now properly incorporates conflict options via the mapping methods. When writes or deletes are present, the conflict behavior is explicitly passed to the constructors, ensuring the API receives the intended conflict resolution strategy.
407-412: LGTM! Proper initialization of clientWriteOpts with headers and conflict.When transactions are disabled, the
clientWriteOptsare correctly initialized with extracted headers and conflict options from the input options. This ensures that chunked write operations respect the same conflict resolution and custom headers.src/OpenFga.Sdk/Client/Model/ClientWriteOptions.cs (3)
19-47: LGTM! Well-documented conflict resolution enums.The enums clearly define the behavior for handling duplicate writes and missing deletes, with explicit documentation about the default
Errorbehavior. The enum values start at 1 rather than 0, which is appropriate for distinguishing between "not set" (null) and an explicit value.
49-74: LGTM! Clean interface and implementation for conflict options.The
IConflictOptionsinterface andConflictOptionsclass provide a clear contract for controlling conflict resolution behavior. The nullable properties allow callers to specify only the options they need, with unset values defaulting toErrorin the mapping layer.
113-135: LGTM! Proper extension of write options.The
IClientWriteOptionsinterface andClientWriteOptionsclass are correctly extended to support conflict options and per-request headers. This maintains consistency with the broader pattern of addingHeaderssupport across all client option types.src/OpenFga.Sdk/Api/OpenFgaApi.cs (1)
52-74: LGTM! Consistent per-request options pattern across API methods.All API method signatures have been consistently updated to include an optional
IRequestOptions? optionsparameter inserted before theCancellationToken. The headers are correctly extracted viaoptions?.Headersand passed to the underlying API client. The XML documentation has been properly updated to document the new parameter.This pattern is applied uniformly across all 17 public API methods in this file (BatchCheck, Check, CreateStore, DeleteStore, Expand, GetStore, ListObjects, ListStores, ListUsers, Read, ReadAssertions, ReadAuthorizationModel, ReadAuthorizationModels, ReadChanges, Write, WriteAssertions, WriteAuthorizationModel).
While the optional parameter minimizes breaking changes, verify that existing code using named parameters for
cancellationTokenstill compiles correctly, as the parameter order has changed.Example of potentially affected code:
await api.Check(storeId, body, cancellationToken: token);Also applies to: 85-107, 117-133
There was a problem hiding this comment.
Pull Request Overview
This PR implements support for custom headers and write conflict resolution options for the OpenFGA .NET SDK, bringing it in line with OpenFGA API v1.10.0 capabilities.
- Adds comprehensive custom headers support at both client configuration and per-request levels
- Implements write conflict resolution options for handling duplicate writes and missing deletes
- Introduces proper header validation and security measures to prevent reserved header overrides
Reviewed Changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| RequestOptions.cs | New interface and class for API-level header support |
| ClientWriteOptions.cs | Adds conflict resolution enums, options, and headers support |
| ClientRequestOptions.cs | Refactored to interface-based pattern with headers support |
| ClientConfiguration.cs | Adds default headers support with validation |
| Client.cs | Implements header extraction, conflict option mapping, and API integration |
| ApiClient.cs | Enhances header building and OAuth token management |
| OpenFgaApi.cs | Updates all API methods to accept optional request options |
| OpenFgaClientTests.cs | Comprehensive test coverage for new functionality |
| README.md | Documentation for custom headers and conflict options |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
1adf577 to
5453646
Compare
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
✅ Actions performedReview triggered.
|
The base branch was changed.
a8e05da to
7ada57e
Compare
| "SendAsync", | ||
| ItExpr.Is<HttpRequestMessage>(req => | ||
| req.RequestUri == new Uri($"{_config.BasePath}/stores/{_config.StoreId}/write") && | ||
| req.Method == HttpMethod.Post), |
Check notice
Code scanning / CodeQL
Missed 'using' opportunity Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
The most idiomatic fix is to leverage the using declaration so that HttpResponseMessage (responseMsg) is automatically disposed when it goes out of scope, rather than explicitly disposing it in a finally block. Given responseMsg is only assigned in the lambda executed during the mock handler, and not outside that, and its lifecycle is confined to the test method, we can introduce a new code block scoped via the using statement around the body of the test that consumes responseMsg. After the awaited call, assertions can be made as before. The try-finally block is removed, replaced with the using statement covering the same lifetime as the previous try block. This maintains identical functionality and guaranteed disposal in an idiomatic C# way.
Only the method WriteTuples_WithConflictOptions_ShouldPassOptionToApi requires modification (src/OpenFga.Sdk.Test/Client/OpenFgaClientTests.cs, lines 2581-2632):
- Remove the
try/finallyblock, and wrap the relevant logic (from after creatingtuples) in ausingblock forresponseMsg. - Restructure code so
responseMsgis disposed when out of scope, using the latest C#usingstatement style if possible. - Ensure test setup, invocation, and assertions remain unchanged otherwise.
| @@ -2613,22 +2613,19 @@ | ||
| } | ||
| }; | ||
|
|
||
| try { | ||
| await fgaClient.WriteTuples(tuples, new ClientWriteOptions { | ||
| AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", | ||
| Conflict = new ConflictOptions { | ||
| OnDuplicateWrites = OnDuplicateWrites.Ignore | ||
| } | ||
| }); | ||
| await fgaClient.WriteTuples(tuples, new ClientWriteOptions { | ||
| AuthorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1", | ||
| Conflict = new ConflictOptions { | ||
| OnDuplicateWrites = OnDuplicateWrites.Ignore | ||
| } | ||
| }); | ||
|
|
||
| Assert.NotNull(capturedRequest); | ||
| Assert.NotNull(capturedRequest.Writes); | ||
| Assert.Equal(WriteRequestWrites.OnDuplicateEnum.Ignore, capturedRequest.Writes.OnDuplicate); | ||
| } | ||
| finally { | ||
| if (responseMsg != null) | ||
| responseMsg.Dispose(); | ||
| } | ||
| Assert.NotNull(capturedRequest); | ||
| Assert.NotNull(capturedRequest.Writes); | ||
| Assert.Equal(WriteRequestWrites.OnDuplicateEnum.Ignore, capturedRequest.Writes.OnDuplicate); | ||
|
|
||
| if (responseMsg != null) | ||
| responseMsg.Dispose(); | ||
| } | ||
|
|
||
| /// <summary> |
Description
Implements support for write conflict resolution options introduced in OpenFGA v1.10.0, allowing users to control behavior for duplicate writes and missing deletes.
OnDuplicateWritesenum:Error(default) |Ignore- controls behavior when writing a tuple that already existsOnMissingDeletesenum:Error(default) |Ignore- controls behavior when deleting a non-existent tupleConflictOptionsclass with properties for both enum typesClientWriteOptions.ConflictpropertyError) are explicitly sent to the API when not specified by the userUsage Example:
References
Generated from → openfga/sdk-generator#644
Issue → #121
Review Checklist
mainSummary by CodeRabbit
Release Notes
New Features
Documentation
Bug Fixes