diff --git a/sdk/data/azcosmos/CHANGELOG.md b/sdk/data/azcosmos/CHANGELOG.md index b077831a90c3..4f7a68682806 100644 --- a/sdk/data/azcosmos/CHANGELOG.md +++ b/sdk/data/azcosmos/CHANGELOG.md @@ -10,6 +10,8 @@ ### Breaking Changes +* Removed `ChangeFeedResponse.PopulateCompositeContinuationToken()`. The method is no longer needed: `GetChangeFeed` now populates `ChangeFeedResponse.ContinuationToken` directly with the multi-range composite token. Callers who built single-range tokens manually can use `GetCompositeContinuationToken()` instead. See [PR 26792](https://github.com/Azure/azure-sdk-for-go/pull/26792). + ### Bugs Fixed * Fixed `GetChangeFeed` to survive partition splits: customer-supplied `FeedRange`s are now overlap-matched against the routing map, `410/Gone` triggers a cache refresh and bounded retry, split parents expand into per-child queue entries (inheriting the parent's ETag), and the continuation token persists multi-range state across calls. Continuation tokens are guarded against cross-container reuse. See [PR 26768](https://github.com/Azure/azure-sdk-for-go/pull/26768). diff --git a/sdk/data/azcosmos/cosmos_change_feed_response.go b/sdk/data/azcosmos/cosmos_change_feed_response.go index 8d9f7d2aeef3..f4a300bc6221 100644 --- a/sdk/data/azcosmos/cosmos_change_feed_response.go +++ b/sdk/data/azcosmos/cosmos_change_feed_response.go @@ -59,27 +59,6 @@ func newChangeFeedResponse(resp *http.Response) (ChangeFeedResponse, error) { return response, nil } -// PopulateCompositeContinuationToken generates and sets the composite continuation -// token from response.FeedRange + response.ETag. Retained for back-compat. -// -// In the multi-range queue-driven GetChangeFeed path, response.ContinuationToken -// is already populated with the multi-range composite token by the drain loop -// itself. This method is therefore a no-op when ContinuationToken is non-empty -// — overwriting it with a single-range token rebuilt from the per-head -// FeedRange would lose the multi-range queue state and cause callers that -// resume with the resulting token to skip subsequent ranges after a split. -func (response *ChangeFeedResponse) PopulateCompositeContinuationToken() { - if response.ContinuationToken != "" { - return - } - if response.FeedRange != nil && response.ETag != "" { - compositeToken, err := response.GetCompositeContinuationToken() - if err == nil && compositeToken != "" { - response.ContinuationToken = compositeToken - } - } -} - // GetContinuation from ChangeFeedResponse func (c ChangeFeedResponse) GetContinuation() string { return string(c.ETag) diff --git a/sdk/data/azcosmos/cosmos_change_feed_response_test.go b/sdk/data/azcosmos/cosmos_change_feed_response_test.go index c9e1821b9b14..6a18b0f32c1e 100644 --- a/sdk/data/azcosmos/cosmos_change_feed_response_test.go +++ b/sdk/data/azcosmos/cosmos_change_feed_response_test.go @@ -139,14 +139,16 @@ func TestChangeFeedResponseWithFeedRange(t *testing.T) { MaxExclusive: "FF", } - parsedResponse.PopulateCompositeContinuationToken() - - if parsedResponse.ContinuationToken == "" { - t.Fatal("expected CompositeContinuationToken to be populated, but it was empty") + tokenStr, err := parsedResponse.GetCompositeContinuationToken() + if err != nil { + t.Fatalf("GetCompositeContinuationToken returned error: %v", err) + } + if tokenStr == "" { + t.Fatal("expected GetCompositeContinuationToken to return a non-empty token") } var compositeToken compositeContinuationToken - err = json.Unmarshal([]byte(parsedResponse.ContinuationToken), &compositeToken) + err = json.Unmarshal([]byte(tokenStr), &compositeToken) if err != nil { t.Fatalf("failed to unmarshal composite token: %v", err) } @@ -211,9 +213,11 @@ func TestChangeFeedResponseWithoutFeedRange(t *testing.T) { t.Fatalf("failed to create ChangeFeedResponse: %v", err) } - parsedResponse.PopulateCompositeContinuationToken() - - if parsedResponse.ContinuationToken != "" { - t.Errorf("expected CompositeContinuationToken to be empty, but got: %q", parsedResponse.ContinuationToken) + tokenStr, err := parsedResponse.GetCompositeContinuationToken() + if err != nil { + t.Fatalf("GetCompositeContinuationToken returned error: %v", err) + } + if tokenStr != "" { + t.Errorf("expected GetCompositeContinuationToken to return empty string when FeedRange is nil, got: %q", tokenStr) } } diff --git a/sdk/data/azcosmos/cosmos_container_change_feed.go b/sdk/data/azcosmos/cosmos_container_change_feed.go index c37dd1411a4d..f2514db9a117 100644 --- a/sdk/data/azcosmos/cosmos_container_change_feed.go +++ b/sdk/data/azcosmos/cosmos_container_change_feed.go @@ -383,8 +383,7 @@ func (c *ContainerClient) getChangeFeedForQueue( // Capture the response body's _rid into the token's ResourceID on first // successful response. This keeps the cross-container guard meaningful // across resume — token-issued-by-this-container always carries the - // container's RID — and matches pre-F1 PopulateCompositeContinuationToken - // semantics that downstream tests rely on. + // container's RID. if token.ResourceID == "" && response.ResourceID != "" { token.ResourceID = response.ResourceID }