lhotari opened a new pull request, #25363:
URL: https://github.com/apache/pulsar/pull/25363

   Continuation of #13951 (originally authored by @michaeljmarshall). Rebased 
onto master, merge conflicts resolved, and all reviewer feedback addressed.
   
   ### Motivation
   
   In some client use cases it is helpful to start refreshing the OAuth2 token 
in the background before it expires. This reduces latency spikes caused by 
blocking token-fetch calls and improves resilience when the Identity Provider 
is temporarily unavailable — the client can tolerate an outage lasting up to 
`(1 - earlyTokenRefreshPercent) * expires_in` seconds.
   
   ### Modifications
   
   **Core feature (`AuthenticationOAuth2`)**
   * Add optional preemptive background token refresh, scheduled at 
`earlyTokenRefreshPercent * expires_in` milliseconds after a successful fetch.
   * Default value is `1` (100 %), which **disables** the feature and preserves 
existing behaviour.
   * On refresh failure the scheduler retries with exponential backoff; a final 
synchronous attempt is made on the next `getAuthData()` call if the token has 
since expired.
   * Replace the per-instance `ScheduledThreadPoolExecutor` (raised as a 
reviewer concern) with a **shared static `INTERNAL_SCHEDULER`** that uses 
`io.netty.util.concurrent.DefaultThreadFactory` (daemon threads, named 
`oauth2-token-refresher`) and allows the core thread to time out after 10 s of 
idle time — so no OS thread is held when no instances are actively refreshing.
   * Callers may supply their own `ScheduledExecutorService`; this class never 
shuts it down.
   * `close()` cancels the pending refresh task via the scheduler thread to 
avoid a race where a running refresh re-schedules itself; neither the shared 
nor the caller-supplied scheduler is shut down.
   
   **Configuration via JSON string (`configure()`)**
   * Add `earlyTokenRefreshPercent` parameter, enabling the feature for 
broker-side / reflection-created instances.
   * Accepts a **decimal** (`"0.8"` → 0.8) or an **integer percentage** (`"80"` 
→ 0.8, `"100"` → 1.0 = disabled).
   
   **`AuthenticationOAuth2Builder`** (new)
   * Fluent builder exposing `setEarlyTokenRefreshPercent(double)` and 
`setEarlyTokenRefreshExecutor(ScheduledExecutorService)` for programmatic 
construction with full control.
   
   **`ClientCredentialsConfiguration`** (new)
   * Immutable value-object for client-credentials parameters, used by the 
builder.
   
   **`AuthenticationFactoryOAuth2`** (updated)
   * `clientCredentials()` overloads delegate to `ClientCredentialsBuilder`; 
uses the default (early-refresh disabled) `AuthenticationOAuth2` constructor.
   
   **`AuthenticationOAuth2StandardAuthzServer`** (updated)
   * Overrides `parseAuthParameters()` to inject the RFC 8414 well-known 
metadata path, so the `configure()` refactor is transparent to subclasses.
   
   ### Verifying this change
   
   New and updated unit tests in `AuthenticationOAuth2Test`:
   * Token caching and expiry-driven refresh (no early refresh).
   * Early refresh schedules background calls before expiry.
   * External scheduler is used when provided, and is **not** shut down on 
`close()`.
   * `configure()` via default constructor: decimal and integer 
`earlyTokenRefreshPercent` values, disabled (`100`), zero and non-numeric 
values throw `IllegalArgumentException`.
   * `parseEarlyRefreshPercent` unit tests for all branches.
   * Background scheduler actually triggers `authenticate()` when enabled via 
`configure()`.
   
   ### Does this pull request potentially affect one of the following parts?
   
   - **Default behaviour is unchanged** — `earlyTokenRefreshPercent` defaults 
to `1` (disabled).
   - Adds new configuration surface for OAuth2 users wanting proactive token 
management.
   - Thread-resource concern (one thread per client) addressed by shared daemon 
executor that releases the thread when idle.
   
   ### Documentation
   
   - [x] `doc` — configuration parameter `earlyTokenRefreshPercent` documented 
in javadoc and builder javadoc.
   
   Closes #13951


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to