Class: AbstractTokenProvider
- Inherits:
-
Object
- Object
- AbstractTokenProvider
- Defined in:
- lib/fluent/plugin/auth/tokenprovider_base.rb
Overview
AbstractTokenProvider defines the interface and shared logic for all token providers. Enhanced with retry logic and better token expiry management to prevent timeout issues.
Direct Known Subclasses
AadTokenProvider, AzCliTokenProvider, ManagedIdentityTokenProvider, WorkloadIdentity
Instance Method Summary collapse
-
#fetch_token ⇒ Object
Abstract method: must be implemented by subclasses to fetch a new token.
-
#get_health_status ⇒ Object
Thread-safe wrapper for health_status when called externally.
-
#get_token ⇒ Object
Public method to get a valid token, refreshing if needed with enhanced retry logic.
-
#health_status ⇒ Object
Health check method - returns health status as hash Note: This method should be called from within a synchronized context.
-
#initialize(outconfiguration) ⇒ AbstractTokenProvider
constructor
A new instance of AbstractTokenProvider.
-
#log_health_status(context = "") ⇒ Object
Log health status for operational visibility.
Constructor Details
#initialize(outconfiguration) ⇒ AbstractTokenProvider
Returns a new instance of AbstractTokenProvider.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 9 def initialize(outconfiguration) @logger = setup_logger(outconfiguration) setup_config(outconfiguration) @token_state = { access_token: nil, expiry_time: nil, token_details_mutex: Mutex.new, refresh_in_progress: false, consecutive_failures: 0, last_failure_time: nil, creation_time: Time.now, refresh_count: 0, last_successful_refresh: nil } # Simplified retry configuration using constants @retry_config = { max_retries: KustoConstants::Authentication::DEFAULT_MAX_RETRIES, base_delay: KustoConstants::Authentication::DEFAULT_BASE_DELAY, backoff_multiplier: KustoConstants::Authentication::DEFAULT_BACKOFF_MULTIPLIER, max_delay: KustoConstants::Authentication::DEFAULT_MAX_DELAY } # Minimal health configuration for 12-hour reset @health_config = { max_token_age: KustoConstants::HealthCheck::MAX_COMPONENT_AGE_SECONDS, max_refresh_cycles: KustoConstants::HealthCheck::MAX_REFRESH_CYCLES } # HTTP timeout configuration - consistent across all token providers @http_config = { open_timeout: KustoConstants::Authentication::HTTP_OPEN_TIMEOUT, read_timeout: KustoConstants::Authentication::HTTP_READ_TIMEOUT, write_timeout: KustoConstants::Authentication::HTTP_WRITE_TIMEOUT } end |
Instance Method Details
#fetch_token ⇒ Object
Abstract method: must be implemented by subclasses to fetch a new token.
47 48 49 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 47 def fetch_token raise NotImplementedError, 'Subclasses must implement fetch_token' end |
#get_health_status ⇒ Object
Thread-safe wrapper for health_status when called externally
86 87 88 89 90 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 86 def get_health_status @token_state[:token_details_mutex].synchronize do health_status end end |
#get_token ⇒ Object
Public method to get a valid token, refreshing if needed with enhanced retry logic.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 52 def get_token @token_state[:token_details_mutex].synchronize do if saved_token_need_refresh? if @token_state[:refresh_in_progress] @logger.debug("Token refresh already in progress, waiting...") return wait_for_refresh_completion end @logger.info("Refreshing token. Previous expiry: #{@token_state[:expiry_time]}") refresh_saved_token_with_retry @logger.info("New token expiry: #{@token_state[:expiry_time]}") else @logger.debug("Reusing existing token (expires at #{@token_state[:expiry_time]})") end @token_state[:access_token] end end |
#health_status ⇒ Object
Health check method - returns health status as hash Note: This method should be called from within a synchronized context
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 72 def health_status { token_valid: !saved_token_need_refresh?, token_expires_at: @token_state[:expiry_time], consecutive_failures: @token_state[:consecutive_failures], last_failure_time: @token_state[:last_failure_time], refresh_in_progress: @token_state[:refresh_in_progress], refresh_count: @token_state[:refresh_count], last_successful_refresh: @token_state[:last_successful_refresh], token_age_hours: @token_state[:creation_time] ? (Time.now - @token_state[:creation_time]) / 3600 : 0 } end |
#log_health_status(context = "") ⇒ Object
Log health status for operational visibility
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/fluent/plugin/auth/tokenprovider_base.rb', line 93 def log_health_status(context = "") status = health_status context_prefix = context.empty? ? "" : "#{context}: " @logger.info("#{context_prefix}Token provider health - " \ "valid: #{status[:token_valid]}, " \ "expires_at: #{status[:token_expires_at]}, " \ "failures: #{status[:consecutive_failures]}, " \ "refresh_count: #{status[:refresh_count]}, " \ "age_hours: #{status[:token_age_hours].round(1)}") if status[:consecutive_failures] > 0 @logger.warn("#{context_prefix}Token provider has #{status[:consecutive_failures]} consecutive failures, " \ "last failure: #{status[:last_failure_time]}") end end |