[fix][admin] Reject empty cluster migration URL: fix inverted ClusterUrl.isEmpty() - #26473
Open
SongOf wants to merge 1 commit into
Open
[fix][admin] Reject empty cluster migration URL: fix inverted ClusterUrl.isEmpty()#26473SongOf wants to merge 1 commit into
SongOf wants to merge 1 commit into
Conversation
SongOf
force-pushed
the
fix/cluster-url-is-empty
branch
from
September 6, 2026 09:32
f15f59b to
85b9c0f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
ClusterPolicies.ClusterUrl#isEmpty()has its condition inverted:It only returns
truewhen both HTTP URLs are set and both broker URLs are unset, and returnsfalsefor aClusterUrlwhose four fields are allnull.Its only caller is the cluster-migration admin endpoint (
ClustersBase#updateClusterMigration), which uses it to rejectmigrated=truewithout a target:Because of the inverted predicate this guard never fires for the case it exists for.
pulsar-admin clusters update-cluster-migration --migratedwith no--service-url/--broker-urloptions is accepted and persisted; later, when the broker redirects producers/consumers withCommandTopicMigrated, the client receives null URLs and fails inHandlerState#setRedirectedClusterURI(logged, not surfaced), so the affected producers/consumers reconnect in a loop with no clear error. Conversely, a legitimateClusterUrlcarrying only the HTTP endpoints is rejected as "empty".Modifications
ClusterPolicies.ClusterUrl#isEmpty()now returnstrueonly when none of the four URLs is set (null or blank). Any single configured URL — HTTP or binary, plain or TLS — makes it non-empty. No signature, wire, or REST change; the guard inClustersBase#updateClusterMigrationis unchanged and now behaves as its error message says.Verifying this change
This change added tests and can be verified as follows:
ClusterUrlTest(pulsar-client-admin-api) — pins the predicate: all-null / all-blank is empty; HTTP-only, broker-only, and fully populated URLs are not. Fails on the unpatched code (testNoUrlIsEmpty,testBlankUrlsAreEmpty,testHttpOnlyUrlIsNotEmpty).AdminTest#clusters(pulsar-broker) — adds the end-to-end assertion at the admin resource:updateClusterMigration(..., migrated=true, new ClusterUrl())returns400 BAD_REQUEST, and aClusterUrlwith only a broker service URL is accepted and read back viagetClusterMigration. On the unpatched code the empty-URL call is accepted and the test fails atfail("should have failed"). ThevalidateSuperUserAccessAsyncinvocation count in this test is bumped 24 → 26 for the two accepted calls (the rejected call fails at the guard before any authorization check).Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes
This is an internal behavior change: the only user-visible effect is that
POST /admin/v2/clusters/{cluster}/migrate?migrated=truewith an empty body/URL now returns400as documented, instead of being accepted. No public API, schema, configuration, wire protocol, REST endpoint shape, CLI option, or metric changes.Documentation
docdoc-requireddoc-not-neededdoc-complete