Skip to content

feat: add customBaseURL CNAME support to NetworkOptions#702

Merged
jamesnrokt merged 6 commits into
workstation/6.0-Releasefrom
feat/cname-custom-base-url-6.0
May 20, 2026
Merged

feat: add customBaseURL CNAME support to NetworkOptions#702
jamesnrokt merged 6 commits into
workstation/6.0-Releasefrom
feat/cname-custom-base-url-6.0

Conversation

@jamesnrokt
Copy link
Copy Markdown
Collaborator

Summary

Port of #701 onto workstation/6.0-Release, with the Rokt kit passthrough included since kits now live in this repo.

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

Core (android-core):

  • 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.
    • Rewrites paths to: /config/v4/<key>/config, /nativeevents/v2/<key>/events, /identity/v1/<path>, /nativeevents/v1/identity/<key>/alias, /nativeevents/v1/<key>/audience.
  • proguard.pro: adds -keep rules for MParticle$Internal and ConfigManager.getNetworkOptions() so the Rokt kit can navigate the public extension surface after R8 minification.

Rokt kit (kits/rokt/rokt):

  • In RoktKit.onKitCreate, reads MParticle.getInstance().Internal().configManager.networkOptions.customBaseURL and forwards it to Rokt.setCustomBaseURL(URL("https://<host>")) before Rokt.init.
  • Logic extracted into a private applyCustomBaseURLIfSet() method for testability.
  • No-op when customBaseURL is null, empty, or MParticle is uninitialized.

Pre-merge dependency

The Rokt kit's com.rokt:roktsdk:4.14.0 does not yet expose Rokt.setCustomBaseURL(URL). A follow-up commit will bump the Rokt SDK to the 5.x release containing that API (currently on workstation/5.0.0 and main in ROKT/sdk-android-source, see PR #993). The kit change itself is correct against the upcoming API.

Test plan

  • Added 9 androidTest cases in MParticleBaseClientImplTest (HTTPS validation, path/query stripping, port preservation, malformed-URL rejection, and per-endpoint URL routing).
  • Added 6 unit tests in kits/rokt/rokt's RoktKitTests for the kit passthrough (forwards URL, preserves port, no-op when null/empty/uninitialized).
  • :android-core:testDebugUnitTest passes locally; :android-core:compileDebugAndroidTestKotlin compiles.
  • :kits:android-rokt:rokt:testDebugUnitTest passes locally against a SNAPSHOT roktsdk (60 tests, 0 failures).

🤖 Generated with Claude Code

jamesnrokt and others added 2 commits May 13, 2026 15:45
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>
When the integrating app sets a custom CNAME on MParticleOptions via
NetworkOptions.customBaseURL, forward it to the Rokt SDK so Rokt traffic
routes through the same first-party domain. No-op when customBaseURL is
unset, empty, or MParticle is uninitialized.

Mirrors the iOS Rokt kit behavior added in 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 20:05
@cursor
Copy link
Copy Markdown

cursor Bot commented May 13, 2026

PR Summary

Medium Risk
Changes core URL construction for config/events/identity/audience/alias and introduces a new override that can bypass per-endpoint domain mappings; mistakes here could break networking or certificate pinning behavior. Added tests reduce risk but behavior impacts all outbound requests when enabled.

Overview
Adds NetworkOptions.Builder.setCustomBaseURL(...) to route all SDK traffic through a single HTTPS CNAME host, persisting the validated host(:port) through JSON serialization.

Updates MParticleBaseClientImpl.getUrl to prioritize customBaseURL over per-endpoint DomainMapping, emit warnings when incompatible options are set, and rewrite endpoint paths for CDN-style routing while still generating a fallback defaultUrl.

Propagates the setting into the Rokt kit by forwarding networkOptions.customBaseURL to Rokt.setCustomBaseURL(...), adds Proguard/R8 keep rules needed for that internal access, and expands android/instrumentation + unit tests to cover URL generation, validation, and passthrough behavior.

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

jamesnrokt and others added 3 commits May 13, 2026 17:03
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>
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 05d908b. Configure here.

NetworkOptionsManager.validateAndResolve auto-populates a default
DomainMapping for every endpoint, so the previous check fired the
"customBaseURL is set; domain mapping for X is ignored" warning on
every getUrl() call for every endpoint — even when the integrator
never configured a custom mapping. Compare against the default URL
so the warning only fires for genuinely user-configured mappings
that conflict with customBaseURL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

@jamesnrokt jamesnrokt merged commit bf388f9 into workstation/6.0-Release May 20, 2026
22 of 23 checks passed
@jamesnrokt jamesnrokt deleted the feat/cname-custom-base-url-6.0 branch May 20, 2026 19:24
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