Skip to content

refactor: extract provider-specific config into ProviderProfile (Strategy)#78

Merged
TheMeinerLP merged 1 commit into
feat/r2-supportfrom
refactor/provider-profiles
Jul 13, 2026
Merged

refactor: extract provider-specific config into ProviderProfile (Strategy)#78
TheMeinerLP merged 1 commit into
feat/r2-supportfrom
refactor/provider-profiles

Conversation

@TheMeinerLP

Copy link
Copy Markdown
Owner

Summary

Stacked on #77. S3Configuration was starting to accumulate provider-specific optional fields (account-id for R2, alongside the generic ones) that only ever matter for one particular backend — adding the next provider's shorthand would mean growing the shared interface again.

Introduces a proper Strategy pattern instead of the inline if (usingAccountId) branch #77 had in S3FileSystemFactory:

  • ProviderProfile: the strategy contract (resolve()) plus a stable id() for explicit selection.
  • R2Profile / GenericS3Profile: one strategy per provider convention. R2Profile derives the endpoint from account-id; GenericS3Profile passes endpoint-url/force-path-style/region through unchanged and is the fallback.
  • ProviderProfiles: selects the strategy. New optional provider config field picks one explicitly by name (r2/generic) if set; otherwise falls back to auto-detecting from which fields are populated (e.g. account-id set → r2), so existing zero-config setups keep working unchanged.

S3FileSystemFactory itself no longer has any R2-specific logic, it just asks ProviderProfiles.resolve() for the effective connection settings. Adding a future provider's own shorthand means adding one small profile class + registering it, not touching the shared config interface or the factory.

No config/behavior change for existing users; provider is opt-in for when you want to be explicit instead of relying on auto-detection.

Test plan

  • ./gradlew compileJava passes
  • ./gradlew spotlessApply — no formatting changes beyond this refactor

S3Configuration was starting to accumulate provider-specific optional
fields (account-id for R2, alongside checksum-validation and the
generic fields) that only ever matter for one particular backend.
Adding the next provider's shorthand would mean growing the shared
interface again.

Introduces a small ProviderProfile abstraction instead: each profile
knows how to recognize its own shorthand config and resolve it into
the plain endpoint-url/force-path-style/region settings
S3FileSystemFactory already understood. The factory itself no longer
has any R2-specific logic - it just asks ProviderProfiles.resolve()
for the effective connection settings.

- ProviderProfile: the resolve contract + ResolvedEndpoint record
- R2Profile: derives the R2 endpoint from account-id, forces path-style
- GenericS3Profile: passes cfg's own endpoint-url/force-path-style/
  region through unchanged - the fallback, tried last
- ProviderProfiles: tries each profile in order, first match wins

No config/behavior change for existing users. Adding a future
provider's own shorthand (e.g. a hypothetical B2 profile) now means
adding one small profile class, not touching the shared config
interface or the factory.
@TheMeinerLP
TheMeinerLP merged commit df6d641 into feat/r2-support Jul 13, 2026
4 checks passed
TheMeinerLP added a commit that referenced this pull request Jul 13, 2026
Resolves the squash-merge ancestry gap left by #77's squash-merge:
this branch had #78's ProviderProfile refactor on top of the
pre-squash commit, so a normal merge against main's post-squash tip
showed spurious conflicts on lines that were actually already
superseded (main's version) by this branch's version (confirmed
identical file-by-file diff before this merge).
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.

1 participant