Skip to content

[feat][misc] PIP-478: dedicated pulsar-tls-factory-api and pulsar-http-client-api SPI modules#26222

Open
lhotari wants to merge 1 commit into
apache:masterfrom
lhotari:lh-pip-478-tls-http-client-spi
Open

[feat][misc] PIP-478: dedicated pulsar-tls-factory-api and pulsar-http-client-api SPI modules#26222
lhotari wants to merge 1 commit into
apache:masterfrom
lhotari:lh-pip-478-tls-http-client-spi

Conversation

@lhotari

@lhotari lhotari commented Jul 22, 2026

Copy link
Copy Markdown
Member

PIP: #25890

Motivation

This is the first implementation PR for PIP-478. The implementation is split into a series of PRs submitted one at a time; this one lands only the foundation the rest of the PIP builds on: two small, dependency-light SPI modules. Nothing consumes them yet, so there is no behavioural change to any existing module.

  • pulsar-tls-factory-api — the purpose-driven PulsarTlsFactory TLS SPI that replaces PIP-337. A factory is asked only for a ready-built TLS object for a given TlsPurpose, with rotation confined to a reload callback (rebuild-not-mutate) and key material never crossing a Pulsar API — so KMS/HSM and workload-identity integrations become first-class instead of requiring a fork of the SSL layer. The flat TlsPolicy value type carries cert/key/trust material (PEM or keystore), ciphers/protocols, hostname verification, and three orthogonal provider axes: the TLS engine (JDK vs native OpenSSL), the JSSE (SSLContext) provider (jsseProvider), and the JCA crypto provider that parses key material (jcaProvider).
  • pulsar-http-client-api — the framework-managed PulsarHttpClient SPI, so authentication plugins share the client's HTTP runtime (event loops, timers, DNS caches, TLS-material refresh) instead of spinning up private AsyncHttpClient instances.

They live in their own modules — rather than inside a client artifact — so the sibling broker-side PIP can depend on them without importing a client jar.

Modifications

  • New module pulsar-tls-factory-api: PulsarTlsFactory, TlsPolicy, TlsPurpose, TlsFactoryInitContext, TlsHandle, TlsEndpoint.
  • New module pulsar-http-client-api (depends on the former): PulsarHttpClient, PulsarHttpClientFactory, PulsarHttpClientConfig, HttpRequest, HttpResponse.
  • Build wiring: settings.gradle.kts, pulsar-bom, the pulsar-common test dependency on the SPI types, and the binary-license check.
  • Unit tests for TlsPolicy validation and TlsPurpose.

Both modules compile standalone against master; no existing code references them.

Verifying this change

This change added tests and can be verified as follows:

  • TlsPolicyValidationTestTlsPolicy builder validation (PEM vs keystore, required fields).
  • TlsPurposeTestTlsPurpose identity, role, and equality.
  • The two modules build and pass check standalone (./gradlew :pulsar-tls-factory-api:build :pulsar-http-client-api:build), and ./gradlew quickCheck (license headers + checkstyle) passes over the tree.

Does this pull request potentially affect one of the following parts:

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency) — adds two new modules to settings.gradle.kts and pulsar-bom; no third-party dependencies added.
  • The public API — introduces the org.apache.pulsar.tls and org.apache.pulsar.http SPI packages as new public API. They are additive and unreferenced by existing code in this PR.
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Documentation

Matching PR in forked repository

PR in forked repository: lhotari/pulsar (Personal CI)

This PR was prepared with the assistance of Claude Code (Opus 4.8); the change was reviewed and is submitted by a human contributor who takes responsibility for it, per the ASF Generative Tooling guidance.

…p-client-api SPI modules

### Motivation

This is the first implementation PR for
[PIP-478](apache#25890) (design doc). It introduces
the two small, dependency-light SPI modules the rest of the PIP builds on, with no
behavioural change to any existing module — nothing consumes them yet.

- `pulsar-tls-factory-api` — the purpose-driven `PulsarTlsFactory` TLS SPI that
  replaces PIP-337: a factory is asked only for a ready-built TLS object for a given
  `TlsPurpose`, with rotation confined to a reload callback (rebuild-not-mutate) and
  key material never crossing a Pulsar API. The flat `TlsPolicy` value type carries
  cert/key/trust material, ciphers/protocols, hostname verification, and three
  orthogonal provider axes — the TLS engine, the JSSE (`SSLContext`) provider
  (`jsseProvider`), and the JCA crypto provider that parses key material
  (`jcaProvider`).
- `pulsar-http-client-api` — the framework-managed `PulsarHttpClient` SPI so auth
  plugins share the client's HTTP runtime (event loops, timers, DNS, TLS refresh)
  instead of spinning up private `AsyncHttpClient` instances.

They live in their own modules so the sibling broker-side PIP can depend on them
without importing a client artifact.

### Modifications

- New module `pulsar-tls-factory-api`: `PulsarTlsFactory`, `TlsPolicy`, `TlsPurpose`,
  `TlsFactoryInitContext`, `TlsHandle`, `TlsEndpoint`.
- New module `pulsar-http-client-api` (depends on the former): `PulsarHttpClient`,
  `PulsarHttpClientFactory`, `PulsarHttpClientConfig`, `HttpRequest`, `HttpResponse`.
- Build wiring: `settings.gradle.kts`, `pulsar-bom`, the `pulsar-common` test
  dependency on the SPI types, and the binary-license check.
- Unit tests for `TlsPolicy` validation and `TlsPurpose`.

Assisted-by: Claude Opus 4.8 (Claude Code)
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