/** * Enhanced Token Manager with Circuit Breaker Protection */ import { TokenManager, TokenManagerConfig } from './TokenManager'; import { CircuitBreaker, CircuitState } from '../utils/CircuitBreaker'; export interface EnhancedTokenManagerConfig extends TokenManagerConfig { circuitBreaker?: { failureThreshold?: number; successThreshold?: number; timeout?: number; monitoringWindow?: number; }; } /** * Token Manager with built-in circuit breaker for resilient token operations */ export class TokenManagerWithCircuitBreaker extends TokenManager { private readonly circuitBreaker: CircuitBreaker; constructor(config: EnhancedTokenManagerConfig) { super(config); // Initialize circuit breaker with token-specific configuration this.circuitBreaker = new CircuitBreaker({ failureThreshold: config.circuitBreaker?.failureThreshold ?? 3, successThreshold: config.circuitBreaker?.successThreshold ?? 2, timeout: config.circuitBreaker?.timeout ?? 30000, // 30 seconds monitoringWindow: config.circuitBreaker?.monitoringWindow ?? 300000, // 5 minutes expectedErrors: [ 'Failed to fetch token', 'Token endpoint returned', 'HTTP 4', // 400-499 errors 'HTTP 5', // 500-599 errors 'Token fetch failed' ], ignoredErrors: [ 'Token cannot be empty', 'Token is too short', 'Invalid JWT token format', 'No token source configured' ] }); // Forward circuit breaker events this.circuitBreaker.on('stateChange', (newState, oldState) => { // Emit circuit breaker state change (simplified) console.log(`Circuit breaker state changed: ${oldState} -> ${newState}`); }); } /** * Get token with circuit breaker protection */ public async getToken(): Promise { // Check if we have a valid token first (doesn't go through circuit breaker) if (this.isTokenValid()) { return super.getToken(); } // Use circuit breaker for token fetching return this.circuitBreaker.execute(async () => { return super.getToken(); }); } /** * Fetch token with circuit breaker protection */ public async fetchToken(): Promise { return this.circuitBreaker.execute(async () => { return super.fetchToken(); }); } /** * Refresh token with circuit breaker protection */ public async refreshToken(): Promise { return this.circuitBreaker.execute(async () => { return super.refreshToken(); }); } /** * Get circuit breaker state */ public getCircuitBreakerState(): CircuitState { return this.circuitBreaker.getState(); } /** * Get circuit breaker metrics */ public getCircuitBreakerMetrics(): any { return this.circuitBreaker.getMetrics(); } /** * Check if token operations are available (not blocked by circuit breaker) */ public isTokenOperationAvailable(): boolean { return this.circuitBreaker.isAvailable(); } /** * Manually reset circuit breaker (for recovery scenarios) */ public resetCircuitBreaker(): void { this.circuitBreaker.reset(); } /** * Override destroy to cleanup circuit breaker */ public destroy(): void { super.destroy(); // Circuit breaker doesn't need explicit cleanup, but we could add it if needed } }