Skip to content

Make AuthProvider.content() return CompletableFuture for async auth flows #1544

Description

@ricardozanini

Current API

public interface AuthProvider {
  String scheme();
  String content(WorkflowContext workflow, TaskContext task, WorkflowModel model, URI uri);
}

Problem

The content() method returns String synchronously, forcing implementers to block on async operations.

For OAuth2/OIDC flows using reactive clients (e.g., Quarkus OIDC Client with Uni<Tokens>), we must block:

@Override
public String content(...) {
    // Quarkus OIDC Client returns Uni<Tokens> (async)
    Uni<Tokens> tokensUni = client.getTokens();
    
    // FORCED TO BLOCK - wasteful! 🚫
    Tokens tokens = tokensUni.await().atMost(connectionTimeout);
    return tokens.getAccessToken();
}

This wastes threads and prevents efficient reactive pipelines.

Proposed API

public interface AuthProvider {
  String scheme();
  CompletableFuture<String> content(WorkflowContext workflow, TaskContext task, WorkflowModel model, URI uri);
}

Benefits

  • Non-blocking: Reactive auth clients can chain naturally
  • Thread efficiency: No blocking during token negotiation
  • Backward compatible: Existing sync implementations return CompletableFuture.completedFuture(value)

Example: Async OAuth2 Implementation

@Override
public CompletableFuture<String> content(...) {
    return client.getTokens()                    // Uni<Tokens>
        .convert().toCompletionStage()           // CompletionStage<Tokens>
        .toCompletableFuture()                   // CompletableFuture<Tokens>
        .thenApply(Tokens::getAccessToken);      // CompletableFuture<String>
}

Migration for Existing Implementations

Sync implementations wrap with completedFuture:

@Override
public CompletableFuture<String> content(...) {
    String token = /* compute synchronously */;
    return CompletableFuture.completedFuture(token);
}

Impact: Low - small API change, high performance benefit for reactive auth flows.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions