Skip to content

CF-4076 : Add stable sort to paginated CMF list commands - #3413

Open
Paras Negi (paras-negi-flink) wants to merge 1 commit into
mainfrom
CF-4076-cmf-list-stable-sort
Open

CF-4076 : Add stable sort to paginated CMF list commands#3413
Paras Negi (paras-negi-flink) wants to merge 1 commit into
mainfrom
CF-4076-cmf-list-stable-sort

Conversation

@paras-negi-flink

@paras-negi-flink Paras Negi (paras-negi-flink) commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Release Notes

Breaking Changes

  • PLACEHOLDER

New Features

  • PLACEHOLDER

Bug Fixes

  • Fixed Confluent Platform confluent flink ... list commands silently omitting or duplicating items when a resource has more than 100 items.

Checklist

  • I have successfully built and used a custom CLI binary, without linter issues from this PR.
  • I have clearly specified in the What section below whether this PR applies to Confluent Cloud, Confluent Platform, or both.
  • I have attached manual CLI verification results or screenshots in the Test & Review section below.
  • I have added appropriate CLI integration or unit tests for any new or updated commands and functionality.
  • I confirm that this PR introduces no breaking changes or backward compatibility issues.
  • I have indicated the potential customer impact if something goes wrong in the Blast Radius section below.
  • I have put checkmarks below confirming that the feature associated with this PR is enabled in:
    • Confluent Cloud prod
    • Confluent Cloud stag
    • Confluent Platform
    • Check this box if the feature is enabled for certain organizations only

What

This PR fixes CF-4076 for Confluent Platform / CP Flink (CMF on-prem).

The on-prem (CMF) confluent flink ... list commands page through results with offset pagination (.Page(n).Size(100)) but requested no sort order. CMF applies no default ORDER BY, so each page is a separate LIMIT/OFFSET query with no ordering. PostgreSQL does not guarantee a stable row order across separate queries, so once a (filtered) result set exceeds the page size of 100, rows near a page boundary can be silently skipped or duplicated between page requests — with no error. The most-frequently-updated row (e.g. an actively RUNNING statement) is the most likely to shift and disappear.

Fix: request a unique, stable sort on every paginated CMF list call in pkg/flink/cmf_rest_client.go, so offset paging is deterministic. "name" maps server-side (via each resource's SortPropertyMapper) to that resource's unique id column.

Per-resource sort keys:

  • Most list commands → ["name"]
  • secret-mapping list["name", "uid"]name has no unique constraint; uid (the PK) is the tiebreaker
  • application event list["creationTimestamp,desc", "name"] — CMF applies no ordering to events today, so this both introduces newest-first ordering (the useful order for an event log) and makes paging stable; creationTimestamp is not unique on its own, so name is the tiebreaker

This works against existing CMF servers (incl. 2.3.0); no server change is required.

Blast Radius

  • Scope is limited to the on-prem confluent flink ... list commands; the change only adds a sort query parameter to the existing paginated list requests. No writes, no persistence changes, no config or migration changes.
  • Human table output is unchanged (output.NewList already sorts client-side); the only user-visible change is that -o json/-o yaml list output is now deterministically ordered — and for application event list specifically, that order is now newest-first rather than arbitrary.
  • If something goes wrong, impact is confined to these list commands (e.g. a list call surfacing a CMF error). Other confluent flink and all confluent kafka commands are unaffected.
  • Depends on CMF honoring the sort param, which is verified in cp-flink-cmf (SortPropertyMapper.transformSort + per-resource mappers map name to each resource's unique id).
  • There are no breaking changes; the change is a one-line-per-call addition and is trivially revertible.

References

  • Jira: CF-4076
  • Not the same as CF-1784 (phase-filter case-sensitivity, already fixed in CMF 2.3.0) — this pagination defect is independent.
  • A complementary CMF-side default sort (benefiting the UI/API/all clients) is a separate follow-up on cp-flink-cmf.

Test & Review

Automated tests (pkg/flink/cmf_rest_client_test.go):

  • TestListStatements_ReturnsAllItemsAcrossPages — paginates a 250-item list (spanning the 100/200 page boundaries) and asserts every item is returned exactly once; the mock server rejects any request that omits sort.
  • TestListCommands_SendUniqueSortKey — table-driven across all 13 paginated call sites, asserting the exact sort key each sends (name; name,uid for secret-mappings; creationTimestamp,desc + name for events).

Results

  • pkg/flink and internal/flink unit suites pass (including -race).
  • Flink on-prem integration tests: all List* (golden) tests pass; output unchanged (the mock ignores sort).
  • gofmt and go vet clean.

Deterministic repro of the bug — driving the real ListStatements against a server that mimics unordered OFFSET paging: without a sort, 149/150 statements were returned (one silently dropped); with the fix's sort, 150/150 were returned.

Copilot AI review requested due to automatic review settings July 24, 2026 13:55
@confluent-cla-assistant

Copy link
Copy Markdown

🎉 All Contributor License Agreements have been signed. Ready to merge.
Please push an empty commit if you would like to re-run the checks to verify CLA status for all contributors.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses CF-4076 by making CMF (on-prem) Flink list commands deterministic under offset pagination, preventing silent omissions/duplications when result sets exceed the 100-item page size.

Changes:

  • Add stable, unique sort keys (sort query param) to all paginated CMF list API calls to ensure deterministic paging.
  • Preserve intended ordering where applicable (e.g., newest-first application events) while adding a unique tiebreaker for stability.
  • Add unit tests that (1) regress the >100-items paging behavior and (2) lock in the exact per-resource sort keys sent by each paginated list call.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
pkg/flink/cmf_rest_client.go Adds stable Sort(...) parameters to all paginated CMF list requests to make offset pagination deterministic.
pkg/flink/cmf_rest_client_test.go Adds regression + table-driven tests asserting all items are returned across pages and that each list call sends the correct unique sort key.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/flink/cmf_rest_client.go Outdated
Comment on lines +245 to +246
// createdTime DESC keeps events newest-first; "name" (unique id) breaks ties for stable paging (CF-4076).
eventsPage, httpResponse, err := cmfClient.FlinkApplicationsApi.GetApplicationEvents(ctx, environment, application).Sort([]string{"creationTimestamp,desc", "name"}).Page(currentPageNumber).Size(pageSize).Execute()
@airlock-confluentinc
airlock-confluentinc Bot force-pushed the CF-4076-cmf-list-stable-sort branch 2 times, most recently from 210f314 to 370ce69 Compare July 24, 2026 14:22
The on-prem (CMF) Flink list commands page through results with offset
pagination but requested no sort order. With no ORDER BY, the server can
return rows in a different order across separate page requests, so rows near
a page boundary can be silently skipped or duplicated once a result set
exceeds the page size of 100.

Request a unique, stable sort on every paginated list call so offset paging
is deterministic:
- most resources sort by "name" (maps server-side to each unique id column)
- secret mappings sort by "name","uid" ("name" has no unique constraint)
- application events sort by "creationTimestamp,desc","name" (newest-first
  plus a unique tiebreaker)

Add regression tests asserting a >100-item list returns every item exactly
once and that each list call sends the expected sort key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@paras-negi-flink
Paras Negi (paras-negi-flink) marked this pull request as ready for review July 24, 2026 16:43
@paras-negi-flink
Paras Negi (paras-negi-flink) requested a review from a team as a code owner July 24, 2026 16:43
@airlock-confluentinc
airlock-confluentinc Bot force-pushed the CF-4076-cmf-list-stable-sort branch from 370ce69 to a91ce7a Compare July 24, 2026 16:44
@sonarqube-confluent

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants