feat(Storage): Add x-goog-gcs-idempotency-token idempotency header - #18
mahendra-google wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds an idempotency token (x-goog-gcs-idempotency-token) to the retry handler and updates the corresponding tests. The reviewer notes that the token must be sent as a standalone HTTP header rather than being embedded within the x-goog-api-client header. Consequently, the implementation should be updated to add the header directly to the request, the tests should assert on the standalone headers, and the constant should be renamed to reflect this change.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (!gotIdempotencyToken) | ||
| { | ||
| parts.Add(IdempotencyTokenPrefix + Guid.NewGuid()); | ||
| } |
There was a problem hiding this comment.
The x-goog-gcs-idempotency-token is a standalone HTTP header used by Google Cloud Storage for request deduplication. It should not be embedded as a parameter inside the x-goog-api-client header (which is what parts represents here). Doing so will cause the GCS backend to ignore the token. Instead, add it directly to the request headers. This also means you can remove IdempotencyTokenPrefix, gotIdempotencyToken, and the corresponding else if block that parses it from parts.
if (!request.Headers.Contains(IdempotencyTokenHeader))
{
request.Headers.TryAddWithoutValidation(IdempotencyTokenHeader, Guid.NewGuid().ToString());
}| var idempotencyToken = request1Parts[idempotencyTokenName]; | ||
| // Just validate that it's a real GUID... | ||
| Guid.Parse(idempotencyToken); |
| { | ||
| // For testing | ||
| internal const string InvocationIdHeaderPart = "gccl-invocation-id"; | ||
| internal const string IdempotencyTokenHeaderPart = "x-goog-gcs-idempotency-token"; |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces an idempotency token (x-goog-gcs-idempotency-token) to the retry handler and updates the tests to verify its presence. However, the test implementation contains a compilation error because it references a non-existent constant RetryHandler.IdempotencyTokenHeaderPart instead of RetryHandler.IdempotencyTokenHeader. Additionally, there is a logic error in the test because the idempotency token is added as a standalone HTTP header, but the test attempts to parse it from the x-goog-api-client header parts, which will cause a runtime exception.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| Assert.Equal(3, actualHeaders.Count); | ||
|
|
||
| string invocationIdName = RetryHandler.InvocationIdHeaderPart; | ||
| string idempotencyTokenName = RetryHandler.IdempotencyTokenHeaderPart; |
There was a problem hiding this comment.
There are two major issues with this test implementation:\n\n1. Compilation Error: RetryHandler.IdempotencyTokenHeaderPart does not exist. The constant defined in RetryHandler.cs is IdempotencyTokenHeader.\n2. Logic Error / Test Failure: x-goog-gcs-idempotency-token is added as a standalone HTTP header, whereas gccl-invocation-id and gccl-attempt-count are parts of the x-goog-api-client header. Since ReplayingMessageHandler is initialized with VersionHeaderBuilder.HeaderName (x-goog-api-client), actualHeaders only contains the values of the x-goog-api-client header. Because the idempotency token is a separate header, it will not be present in actualHeaders, and attempting to look it up via request1Parts[idempotencyTokenName] will throw a KeyNotFoundException at runtime.\n\nYou will need to reference RetryHandler.IdempotencyTokenHeader and update the test assertion logic to inspect the standalone x-goog-gcs-idempotency-token header directly from the requests.
string idempotencyTokenName = RetryHandler.IdempotencyTokenHeader;|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds support for an idempotency token header (x-goog-gcs-idempotency-token) in the RetryHandler class of Google.Cloud.Storage.V1. If the header is missing from the outgoing request, a new GUID is generated and added. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces an IdempotencyTokenInterceptor to automatically attach a unique idempotency token (x-goog-gcs-idempotency-token) to retriable Google Cloud Storage requests, and adds a unit test to verify this behavior. The review feedback suggests strengthening the unit test by asserting that the idempotency token is present and consistent across all retry attempts, rather than filtering out empty headers which could mask missing tokens.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| var validTokens = actualHeaders | ||
| .Where(token => !string.IsNullOrEmpty(token)) | ||
| .Where(guidStr => guidStr != null) | ||
| .ToList(); | ||
|
|
||
| Assert.NotEmpty(validTokens); | ||
|
|
||
| var firstToken = validTokens.First(); | ||
| // Just validate that it's a real GUID... | ||
| Guid.Parse(firstToken); | ||
| Assert.All(validTokens, token => Assert.Equal(firstToken, token)); |
There was a problem hiding this comment.
The test currently filters out null or empty tokens using .Where(token => !string.IsNullOrEmpty(token)). This means if the idempotency header is missing on any of the retried requests, the test will still pass as long as at least one request has the header.
To ensure that the idempotency token is correctly set on every attempt (including all retries), we should assert that the number of captured headers matches the expected number of requests (3), and that none of them are null or empty.
Assert.Equal(3, actualHeaders.Count);
Assert.All(actualHeaders, token => Assert.False(string.IsNullOrEmpty(token)));
var firstToken = actualHeaders.First();
// Just validate that it's a real GUID...
Guid.Parse(firstToken);
Assert.All(actualHeaders, token => Assert.Equal(firstToken, token));|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces an automatic idempotency token header (x-goog-gcs-idempotency-token) for retriable requests. This is achieved by adding a new IdempotencyTokenInterceptor that injects a unique GUID into the request headers if it is not already present. Additionally, a unit test has been added to verify that the idempotency header is correctly set and preserved across retried requests. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
c05d8a6 to
c5d20aa
Compare
d3d3b80 to
d720432
Compare
This PR implements automatic injection of the
x-goog-gcs-idempotency-tokenheader for retriable requests. This ensures that retries of the same request are recognized as identical by the server, preventing duplicate operations.