Skip to content

feat: add customBaseURL CNAME support to NetworkOptions#701

Merged
thomson-t merged 3 commits into
mainfrom
feat/cname-custom-base-url
May 14, 2026
Merged

feat: add customBaseURL CNAME support to NetworkOptions#701
thomson-t merged 3 commits into
mainfrom
feat/cname-custom-base-url

Conversation

@jamesnrokt
Copy link
Copy Markdown
Collaborator

Summary

Adds NetworkOptions.Builder.setCustomBaseURL(String) which routes all mParticle endpoint traffic (config, events, identity, alias, audience) through a single HTTPS CNAME host. Mirrors iOS work from mparticle-apple-sdk#760.

What changed

  • NetworkOptions: new customBaseURL field + getter; Builder.setCustomBaseURL(@NonNull String) validates HTTPS scheme, requires a host, and stores host(:port) only — path/query/fragment ignored.
  • MParticleBaseClientImpl.getUrl: when customBaseURL is set:
    • Skips the pod prefix (the CNAME's CDN handles regional routing).
    • Logs a warning and ignores any per-endpoint DomainMapping and overridesSubdirectory (unsupported with CDN routing).
    • Rewrites paths to: /config/v4/<key>/config, /nativeevents/v2/<key>/events, /identity/v1/<path>, /nativeevents/v1/identity/<key>/alias, /nativeevents/v1/<key>/audience.
  • android-core/proguard.pro: adds -keep rules for MParticle$Internal and ConfigManager.getNetworkOptions() so downstream kits can navigate the public extension surface after R8 minification.

Downstream

The Rokt kit reads NetworkOptions.customBaseURL and forwards it to the Rokt SDK: mparticle-integrations/mparticle-android-integration-rokt#143

Test plan

Added 9 androidTest cases in MParticleBaseClientImplTest:

  • Custom CNAME routes config endpoint via /config/v4/
  • Custom CNAME routes events endpoint via /nativeevents/v2/
  • Custom CNAME routes identity endpoint via /identity/v1/
  • Custom CNAME routes alias endpoint via /nativeevents/v1/identity/
  • Custom CNAME routes audience endpoint via /nativeevents/v1/<key>/audience
  • Non-HTTPS values rejected
  • Path/query stripped
  • Port preserved
  • Malformed URL rejected

Locally: :android-core:testDebugUnitTest passes (existing unit suite); :android-core:compileDebugAndroidTestKotlin compiles. AndroidTest suite runs on CI emulator.

🤖 Generated with Claude Code

Adds NetworkOptions.Builder.setCustomBaseURL(String) which routes all
mParticle endpoint traffic (config, events, identity, alias, audience)
through a single HTTPS CNAME host. When set, customBaseURL takes
priority over individual domain mappings and rewrites paths to match
CDN routing: /config/v4/, /nativeevents/v2/, /identity/v1/,
/nativeevents/v1/identity/, /nativeevents/v1/<key>/audience.

Also adds R8 keep rules for MParticle$Internal and
ConfigManager.getNetworkOptions() so kits can read customBaseURL after
minification.

The Rokt kit reads NetworkOptions.customBaseURL and forwards it to the
Rokt SDK: mparticle-integrations/mparticle-android-integration-rokt#143

Mirrors iOS work from mparticle-apple-sdk#760.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jamesnrokt jamesnrokt requested a review from a team as a code owner May 13, 2026 19:28
@cursor
Copy link
Copy Markdown

cursor Bot commented May 13, 2026

PR Summary

Medium Risk
Changes core URL construction for all network endpoints by introducing a global customBaseURL override, which could misroute traffic or break uploads/config/identity if path/host resolution is wrong; mitigated by extensive new instrumentation tests and input validation.

Overview
Adds NetworkOptions.Builder.setCustomBaseURL() (stored as host[:port]) and JSON serialization/deserialization support so a single HTTPS CNAME can override per-endpoint domain mappings.

Updates MParticleBaseClientImpl.getUrl() to resolve hosts via a new resolveHost() helper that prioritizes customBaseURL, adjusts endpoint path prefixes for CDN-style routing, and logs/ignores unsupported combinations (domain mappings and overridesSubdirectory when a custom base is set). Adds Android instrumentation tests covering endpoint URL rewriting, validation (HTTPS-only, malformed/path stripping, port preservation), and persistence via UploadSettings, plus ProGuard -keep rules for MParticle$Internal and ConfigManager.getNetworkOptions().

Reviewed by Cursor Bugbot for commit 91b1485. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 96950e7. Configure here.

thomson-t
thomson-t previously approved these changes May 13, 2026
Comment thread android-core/src/main/java/com/mparticle/networking/NetworkOptions.java Outdated
Comment thread android-core/src/main/java/com/mparticle/networking/NetworkOptions.java Outdated
Comment thread android-core/proguard.pro
Copy link
Copy Markdown

@denischilik denischilik left a comment

Choose a reason for hiding this comment

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

Looks good to me but I think customBaseURL lost during database serialization round-trip should be addressed

NetworkOptions.toJson() and withNetworkOptions(String) did not include
customBaseURL, so any value was silently dropped when UploadSettings
serialized NetworkOptions to the upload database. Events and alias
uploads read back NetworkOptions without customBaseURL and routed to
the default mParticle endpoints instead of the partner CNAME.

Also:
- Extract the customBaseURL/DomainMapping host-resolution branch out of
  getUrl() into a private resolveHost() helper plus a small ResolvedHost
  value type, lowering getUrl()'s cyclomatic complexity.
- Switch java.net.URL / java.net.MalformedURLException to imports.
- Add two androidTest cases covering the round-trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thomson-t
thomson-t previously approved these changes May 13, 2026
@sonarqubecloud
Copy link
Copy Markdown

@thomson-t thomson-t merged commit 5285149 into main May 14, 2026
16 of 18 checks passed
@thomson-t thomson-t deleted the feat/cname-custom-base-url branch May 14, 2026 15:21
mparticle-automation added a commit that referenced this pull request May 14, 2026
## [5.79.0](v5.78.5...v5.79.0) (2026-05-14)

### Features

* add customBaseURL CNAME support to NetworkOptions ([#701](#701)) ([5285149](5285149)), closes [mparticle-apple-sdk#760](mParticle/mparticle-apple-sdk#760)
* Add max persistence age override option [TRIAGE-608] ([#699](#699)) ([ca88322](ca88322))

### Bug Fixes

* increase MPLatch timeout from 5s to 30s ([#695](#695)) ([20f723f](20f723f))

### Updates & Maintenance

* Update submodules ([59a4a9a](59a4a9a))
@mparticle-automation
Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 5.79.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

4 participants