Skip to content

fix: respect virtual host and port in dubbo provider bootstrap#1556

Open
chxbca wants to merge 4 commits intosofastack:masterfrom
chxbca:bugfix/virtual-host-port-dubbo-provider-bootstrap
Open

fix: respect virtual host and port in dubbo provider bootstrap#1556
chxbca wants to merge 4 commits intosofastack:masterfrom
chxbca:bugfix/virtual-host-port-dubbo-provider-bootstrap

Conversation

@chxbca
Copy link
Copy Markdown

@chxbca chxbca commented Mar 26, 2026

Motivation:

DubboProviderBootstrap.copyServerFields() only copied host and port, and ignored virtualHost / virtualPort from ServerConfig.

This causes the Dubbo provider to publish or register the bound address instead of the expected virtual address in NAT, container, load balancer, or port-mapping scenarios.

Fixes #1119.

Modification:

  • update DubboProviderBootstrap.copyServerFields() to prefer virtualHost over host
  • update DubboProviderBootstrap.copyServerFields() to prefer virtualPort over port
  • keep fallback behavior when virtualHost is blank or virtualPort is null
  • add unit tests for:
    • virtual host and virtual port both configured
    • no virtual address configured
    • blank virtual host with virtual port configured
    • only virtual host configured
    • only virtual port configured

Result:

Fixes #1119.

Summary by CodeRabbit

  • New Features

    • Dubbo provider bootstrap now respects virtual host/port settings, falls back to bound host/port when needed, and uses the resolved address when generating service endpoints. Caching was improved to correctly distinguish different virtual/bound address combinations.
  • Tests

    • Added tests covering virtual host/port combinations, fallback rules, URL generation (including uniqueId) and cache reuse behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

Dubbo provider bootstrap now resolves host/port from ServerConfig.virtualHost/virtualPort (falling back to host/port), uses the resolved values when building registration URLs, caches ProtocolConfig instances keyed by a derived server cache key string, and exposes copyServerFields for testing.

Changes

Cohort / File(s) Summary
Provider bootstrap logic
bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java
Use resolveHost/resolvePort (virtual → fallback) when setting ProtocolConfig and when constructing URLs. copyServerFields changed to package-private and annotated @VisibleForTesting. Introduced getOrCreateProtocolConfig(ServerConfig) and buildServerCacheKey(...) to cache by derived key.
Singleton cache key type
bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboSingleton.java
Changed SERVER_MAP key type from ConcurrentMap<ServerConfig, ProtocolConfig> to ConcurrentMap<String, ProtocolConfig> (cache now keyed by server cache key string).
Tests and test setup
bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java
Clear DubboSingleton.SERVER_MAP in @Before. Added tests covering virtualHost/virtualPort resolution (including blank/whitespace handling and partial virtual settings), URL construction using resolved values (including uniqueId presence), and cache behavior (distinct resolved addresses → distinct cached ProtocolConfig; identical resolved address → reused instance).

Sequence Diagram(s)

sequenceDiagram
  participant Provider as DubboProviderBootstrap
  participant Server as ServerConfig
  participant Cache as DubboSingleton (SERVER_MAP)
  participant Protocol as ProtocolConfig
  participant Registry as Registry/URL builder

  Note over Provider,Server: export / copy server fields
  Provider->>Server: read host, port, virtualHost, virtualPort
  Provider->>Provider: resolveHost(server), resolvePort(server)
  Provider->>Cache: getOrCreateProtocolConfig(buildServerCacheKey(resolved, original))
  Cache-->>Provider: ProtocolConfig (cached or new)
  Provider->>Protocol: copyServerFields(server, protocol)  -- sets host/port to resolved values
  Provider->>Registry: buildUrls(protocol, resolvedHost, resolvedPort)
  Registry-->>Provider: registration URLs (include uniqueId)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through code with eager paws,

swapped hosts and ports with careful laws,
virtual maps now lead the way,
caches remember what they say,
containers cheer and clap their claws!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: respecting virtual host and port configuration in the Dubbo provider bootstrap logic.
Linked Issues check ✅ Passed The PR implementation aligns with issue #1119 requirements: virtualHost/virtualPort are now preferred over host/port in copyServerFields, with proper fallback behavior and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the virtual host/port handling in Dubbo provider bootstrap; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java (1)

206-207: Apply virtual host/port resolution in buildUrls() for consistency.

The method constructs URLs using server.getHost() and server.getPort() directly at lines 206-207, but elsewhere in the class copyServerFields() applies virtual address resolution via resolveHost() and resolvePort() helpers (lines 135-142). Since both methods handle host/port configuration, buildUrls() should use the same resolution logic to ensure consistent URL construction when virtual addresses are configured.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java`
around lines 206 - 207, buildUrls() currently concatenates server.getHost() and
server.getPort() directly; change it to use the same virtual address resolution
helpers used in copyServerFields(): call resolveHost(...) and resolvePort(...)
(the same overloads used there) when constructing the host and port parts so
that buildUrls() uses resolved values rather than raw
server.getHost()/server.getPort(); keep existing usage of server.getProtocol()
and server.getContextPath() unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java`:
- Around line 206-207: buildUrls() currently concatenates server.getHost() and
server.getPort() directly; change it to use the same virtual address resolution
helpers used in copyServerFields(): call resolveHost(...) and resolvePort(...)
(the same overloads used there) when constructing the host and port parts so
that buildUrls() uses resolved values rather than raw
server.getHost()/server.getPort(); keep existing usage of server.getProtocol()
and server.getContextPath() unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 307847d5-fc64-40e9-a0a1-ba3d6777496f

📥 Commits

Reviewing files that changed from the base of the PR and between ec810c2 and 614294f.

📒 Files selected for processing (2)
  • bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java
  • bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java

@sofastack-cla sofastack-cla bot added cla:no Need sign CLA size/L labels Mar 26, 2026
@sofastack-cla sofastack-cla bot added cla:yes CLA is ok and removed cla:no Need sign CLA labels Mar 26, 2026
@sunhailin-Leo sunhailin-Leo requested a review from Copilot March 26, 2026 11:56
Copy link
Copy Markdown

Copilot AI left a comment

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 fixes Dubbo provider address publication/registration in NAT/container/LB/port-mapping scenarios by ensuring virtualHost / virtualPort from ServerConfig are used (with fallbacks) when building Dubbo ProtocolConfig and provider URLs.

Changes:

  • Prefer virtualHost over host and virtualPort over port in DubboProviderBootstrap.copyServerFields() (with fallbacks).
  • Update buildUrls() to use the same resolved host/port.
  • Add unit tests covering virtual host/port combinations and URL generation.

Reviewed changes

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

File Description
bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java Resolve host/port using virtualHost/virtualPort and apply to ProtocolConfig + URL construction.
bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java Add tests validating virtual host/port resolution and URL output.

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

}

private void copyServerFields(ServerConfig serverConfig, ProtocolConfig protocolConfig) {
void copyServerFields(ServerConfig serverConfig, ProtocolConfig protocolConfig) {
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

copyServerFields was changed from private to package-private for test access; the repo commonly annotates such methods with @VisibleForTesting to document intent and discourage production callers from depending on it. Consider adding the annotation (and import) here.

Copilot uses AI. Check for mistakes.
Comment on lines +116 to +120
void copyServerFields(ServerConfig serverConfig, ProtocolConfig protocolConfig) {
protocolConfig.setId(serverConfig.getId());
protocolConfig.setName(serverConfig.getProtocol());
protocolConfig.setHost(serverConfig.getHost());
protocolConfig.setPort(serverConfig.getPort());
protocolConfig.setHost(resolveHost(serverConfig));
protocolConfig.setPort(resolvePort(serverConfig));
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

copyServerFields now derives ProtocolConfig host/port from virtualHost/virtualPort. However, copyServers caches ProtocolConfig instances in DubboSingleton.SERVER_MAP keyed by ServerConfig, and ServerConfig.equals/hashCode only considers protocol/host/port (not virtualHost/virtualPort). This means different ServerConfig instances that share the same bound host/port but differ in virtualHost/virtualPort can collide and reuse a ProtocolConfig with the wrong published address. Consider changing the cache key to include the resolved host/port (or virtualHost/virtualPort), or avoid caching by ServerConfig.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java (1)

219-239: Consider adding an explicit test for same key + conflicting non-address fields.

This test validates reuse for identical resolved addresses, but cache behavior is still implicit when two ServerConfigs share the same cache key and differ in fields like serialization, threadpool, or threads. Adding one explicit test would lock expected behavior (reuse-first vs reject-conflict) and prevent silent config bleed regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java`
around lines 219 - 239, Add an explicit unit test in DubboProviderBootstrapTest
that covers two ServerConfig instances which resolve to the same cache key (same
virtualHost/virtualPort) but differ in non-address fields (e.g.,
setSerialization(...), setThreadpool(...), setThreads(...)); call
dubboProviderBootstrap.getOrCreateProtocolConfig(...) for both and assert the
expected policy (either Assert.assertSame to lock reuse-first behavior or assert
that a conflict/error is raised depending on the intended contract) so the cache
behavior for conflicting non-address fields is explicitly specified and
prevented from regressing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java`:
- Around line 163-166: The test in DubboProviderBootstrapTest currently asserts
that the generated URL string starts with "?uniqueId=" which is order-sensitive
and flaky; update the assertions around buildUrls() and the url variable to
parse the URL's query string (or split on '?' and then on '&') and assert that
one of the query parameters equals or starts with "uniqueId=" (i.e., verify
presence of uniqueId key/value rather than its position), using the existing url
from dubboProviderBootstrap.buildUrls().get(0).toString() in the test to locate
and validate the parameter.

---

Nitpick comments:
In
`@bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java`:
- Around line 219-239: Add an explicit unit test in DubboProviderBootstrapTest
that covers two ServerConfig instances which resolve to the same cache key (same
virtualHost/virtualPort) but differ in non-address fields (e.g.,
setSerialization(...), setThreadpool(...), setThreads(...)); call
dubboProviderBootstrap.getOrCreateProtocolConfig(...) for both and assert the
expected policy (either Assert.assertSame to lock reuse-first behavior or assert
that a conflict/error is raised depending on the intended contract) so the cache
behavior for conflicting non-address fields is explicitly specified and
prevented from regressing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7190a399-9f53-47a1-a495-e81aaaae2e6e

📥 Commits

Reviewing files that changed from the base of the PR and between a3b4fa5 and 386cdf2.

📒 Files selected for processing (3)
  • bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java
  • bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboSingleton.java
  • bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • bootstrap/bootstrap-dubbo/src/main/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrap.java

Comment on lines +163 to +166
String url = dubboProviderBootstrap.buildUrls().get(0).toString();
Assert.assertTrue(url.startsWith("dubbo://10.0.0.1:80/" + DemoService.class.getName()));
Assert.assertTrue(url.contains("?uniqueId="));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

uniqueId assertion is order-sensitive and can become flaky.

Lines 165 and 183 require uniqueId to be the first query parameter (?uniqueId=). If parameter order changes, the test fails even when uniqueId exists.

Proposed test hardening
-        Assert.assertTrue(url.contains("?uniqueId="));
+        Assert.assertTrue(url.contains("uniqueId="));
...
-        Assert.assertTrue(url.contains("?uniqueId="));
+        Assert.assertTrue(url.contains("uniqueId="));

Also applies to: 181-184

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@bootstrap/bootstrap-dubbo/src/test/java/com/alipay/sofa/rpc/bootstrap/dubbo/DubboProviderBootstrapTest.java`
around lines 163 - 166, The test in DubboProviderBootstrapTest currently asserts
that the generated URL string starts with "?uniqueId=" which is order-sensitive
and flaky; update the assertions around buildUrls() and the url variable to
parse the URL's query string (or split on '?' and then on '&') and assert that
one of the query parameters equals or starts with "uniqueId=" (i.e., verify
presence of uniqueId key/value rather than its position), using the existing url
from dubboProviderBootstrap.buildUrls().get(0).toString() in the test to locate
and validate the parameter.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dubbo ProtocolConfig doesn't use server's virtualHost at all

2 participants