Class: PatientHttp::Configuration
- Inherits:
-
Object
- Object
- PatientHttp::Configuration
- Defined in:
- lib/patient_http/configuration.rb
Overview
Configuration for the PatientHttp processor.
This class holds all configuration options for the HTTP connection pool, including connection limits, timeouts, and other HTTP client settings. It has no dependencies on any job system.
Instance Attribute Summary collapse
-
#connection_pool_size ⇒ Integer
This is the maximum number of hosts for which connections will be kept alive for at one time.
-
#connection_timeout ⇒ Numeric?
Connection timeout in seconds.
-
#default_payload_store_name ⇒ Symbol?
readonly
Get the name of the default payload store.
-
#logger ⇒ Logger
Get the logger to use to report pool events.
-
#max_connections ⇒ Integer
Maximum number of concurrent connections.
-
#max_redirects ⇒ Integer
Maximum number of redirects to follow (0 disables redirects).
-
#max_response_size ⇒ Integer
Maximum response size in bytes.
-
#protocol ⇒ Symbol?
HTTP protocol to use (:http1 or :http2).
-
#proxy_url ⇒ String?
HTTP/HTTPS proxy URL (supports authentication).
-
#raise_error_responses ⇒ Boolean
Whether to raise HttpError for non-2xx responses by default.
-
#request_timeout ⇒ Numeric
Default request timeout in seconds.
-
#retries ⇒ Integer
Number of retries for failed requests.
-
#secret_manager ⇒ SecretManager
readonly
The secret manager instance.
-
#shutdown_timeout ⇒ Numeric
Graceful shutdown timeout in seconds.
-
#user_agent ⇒ String?
Default User-Agent header value.
Instance Method Summary collapse
-
#decryption(callable = nil) {|data| ... } ⇒ Object
Set the decryption callable for decrypting payloads after deserialization.
-
#encryption(callable = nil) {|data| ... } ⇒ Object
Set the encryption callable for encrypting payloads before serialization.
- #encryption_key=(keys) ⇒ Object
-
#encryptor ⇒ Encryptor
Return an Encryptor instance.
-
#initialize(max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil) ⇒ Configuration
constructor
Initializes a new Configuration with the specified options.
-
#payload_store(name = nil) ⇒ PayloadStore::Base?
Get a registered payload store by name.
-
#payload_stores ⇒ Hash{Symbol => PayloadStore::Base}
Get all registered payload stores.
-
#preprocessor(name) ⇒ #call?
Get a registered preprocessor by name.
-
#register_payload_store(name, adapter:, **options) ⇒ void
Register a payload store for external storage of large payloads.
-
#register_preprocessor(name, callable = nil) {|outgoing_request| ... } ⇒ void
Register a named preprocessor that can be attached to requests to modify them just before they are sent -- for example, to sign requests.
-
#register_secret(name, value = nil) {|name| ... } ⇒ void
Register a named secret whose value can be referenced indirectly when building requests via secret.
-
#to_h ⇒ Hash
Convert to hash for inspection.
Constructor Details
#initialize(max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil) ⇒ Configuration
Initializes a new Configuration with the specified options.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/patient_http/configuration.rb', line 71 def initialize( max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil ) @mutex = Mutex.new # Initialize payload store configuration @payload_stores = {} @default_payload_store_name = nil # Initialize secret configuration @secrets = {} @secret_manager = SecretManager.new # Initialize preprocessor registry @preprocessors = {} @encryptor = nil self.max_connections = max_connections self.request_timeout = request_timeout self.shutdown_timeout = shutdown_timeout self.logger = logger || Logger.new($stderr, level: Logger::ERROR) self.max_response_size = max_response_size self.user_agent = user_agent self.raise_error_responses = raise_error_responses self.max_redirects = max_redirects self.connection_pool_size = connection_pool_size self.connection_timeout = connection_timeout self.proxy_url = proxy_url self.retries = retries self.protocol = protocol self.encryption_key = encryption_key end |
Instance Attribute Details
#connection_pool_size ⇒ Integer
Returns This is the maximum number of hosts for which connections will be kept alive for at one time.
38 39 40 |
# File 'lib/patient_http/configuration.rb', line 38 def connection_pool_size @connection_pool_size end |
#connection_timeout ⇒ Numeric?
Returns Connection timeout in seconds.
41 42 43 |
# File 'lib/patient_http/configuration.rb', line 41 def connection_timeout @connection_timeout end |
#default_payload_store_name ⇒ Symbol? (readonly)
Get the name of the default payload store.
365 366 367 |
# File 'lib/patient_http/configuration.rb', line 365 def default_payload_store_name @default_payload_store_name end |
#logger ⇒ Logger
Get the logger to use to report pool events. Default is to log errors to STDERR.
120 121 122 |
# File 'lib/patient_http/configuration.rb', line 120 def logger @logger end |
#max_connections ⇒ Integer
Returns Maximum number of concurrent connections.
16 17 18 |
# File 'lib/patient_http/configuration.rb', line 16 def max_connections @max_connections end |
#max_redirects ⇒ Integer
Returns Maximum number of redirects to follow (0 disables redirects).
34 35 36 |
# File 'lib/patient_http/configuration.rb', line 34 def max_redirects @max_redirects end |
#max_response_size ⇒ Integer
Returns Maximum response size in bytes.
25 26 27 |
# File 'lib/patient_http/configuration.rb', line 25 def max_response_size @max_response_size end |
#protocol ⇒ Symbol?
Returns HTTP protocol to use (:http1 or :http2). When nil, the protocol is negotiated with the server (HTTP/2 preferred for HTTPS).
51 52 53 |
# File 'lib/patient_http/configuration.rb', line 51 def protocol @protocol end |
#proxy_url ⇒ String?
Returns HTTP/HTTPS proxy URL (supports authentication).
44 45 46 |
# File 'lib/patient_http/configuration.rb', line 44 def proxy_url @proxy_url end |
#raise_error_responses ⇒ Boolean
Returns Whether to raise HttpError for non-2xx responses by default.
31 32 33 |
# File 'lib/patient_http/configuration.rb', line 31 def raise_error_responses @raise_error_responses end |
#request_timeout ⇒ Numeric
Returns Default request timeout in seconds.
19 20 21 |
# File 'lib/patient_http/configuration.rb', line 19 def request_timeout @request_timeout end |
#retries ⇒ Integer
Returns Number of retries for failed requests.
47 48 49 |
# File 'lib/patient_http/configuration.rb', line 47 def retries @retries end |
#secret_manager ⇒ SecretManager (readonly)
Returns the secret manager instance.
54 55 56 |
# File 'lib/patient_http/configuration.rb', line 54 def secret_manager @secret_manager end |
#shutdown_timeout ⇒ Numeric
Returns Graceful shutdown timeout in seconds.
22 23 24 |
# File 'lib/patient_http/configuration.rb', line 22 def shutdown_timeout @shutdown_timeout end |
#user_agent ⇒ String?
Returns Default User-Agent header value.
28 29 30 |
# File 'lib/patient_http/configuration.rb', line 28 def user_agent @user_agent end |
Instance Method Details
#decryption(callable = nil) {|data| ... } ⇒ Object
Set the decryption callable for decrypting payloads after deserialization.
206 207 208 209 |
# File 'lib/patient_http/configuration.rb', line 206 def decryption(callable = nil, &block) @decryption = resolve_callable(:decryption, callable, &block) @encryptor = nil end |
#encryption(callable = nil) {|data| ... } ⇒ Object
Set the encryption callable for encrypting payloads before serialization.
196 197 198 199 |
# File 'lib/patient_http/configuration.rb', line 196 def encryption(callable = nil, &block) @encryption = resolve_callable(:encryption, callable, &block) @encryptor = nil end |
#encryption_key=(keys) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/patient_http/configuration.rb', line 211 def encryption_key=(keys) keys = Array(keys).map(&:to_s).reject(&:empty?) if keys.empty? @encryption = nil @decryption = nil @encryptor = nil return end unless defined?(ActiveSupport::MessageEncryptor) begin require "active_support/key_generator" require "active_support/message_encryptor" rescue LoadError raise ArgumentError.new("ActiveSupport::MessageEncryptor is required for encryption_key") end end key_length = ActiveSupport::MessageEncryptor.key_len key_generator = lambda do |key| ActiveSupport::KeyGenerator.new(key).generate_key(SALT, key_length) end encryptor = ActiveSupport::MessageEncryptor.new(key_generator.call(keys.first), cipher: "aes-256-gcm") keys[1..].each { |key| encryptor.rotate(key_generator.call(key)) } encryption { |data| encryptor.encrypt_and_sign(data) } decryption { |data| encryptor.decrypt_and_verify(data) } @encryptor = nil end |
#encryptor ⇒ Encryptor
Return an Encryptor instance. If encryption and decryption are not set, then this will be an empty Encryptor that returns data unchanged.
246 247 248 |
# File 'lib/patient_http/configuration.rb', line 246 def encryptor @encryptor ||= Encryptor.new(encryption: @encryption, decryption: @decryption) end |
#payload_store(name = nil) ⇒ PayloadStore::Base?
Get a registered payload store by name.
352 353 354 355 356 357 358 359 360 |
# File 'lib/patient_http/configuration.rb', line 352 def payload_store(name = nil) if name.nil? return nil unless @default_payload_store_name @payload_stores[@default_payload_store_name] else @payload_stores[name.to_sym] end end |
#payload_stores ⇒ Hash{Symbol => PayloadStore::Base}
Get all registered payload stores.
370 371 372 |
# File 'lib/patient_http/configuration.rb', line 370 def payload_stores @payload_stores.dup end |
#preprocessor(name) ⇒ #call?
Get a registered preprocessor by name.
310 311 312 |
# File 'lib/patient_http/configuration.rb', line 310 def preprocessor(name) @preprocessors[name.to_s] end |
#register_payload_store(name, adapter:, **options) ⇒ void
This method returns an undefined value.
Register a payload store for external storage of large payloads.
The name is included in the serialized references to the stored data. Changing it will cause any existing reference to become invalid.
Multiple stores can be registered for migration purposes. The last store registered becomes the default used for new writes. References to other registered stores remain valid for reading.
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/patient_http/configuration.rb', line 328 def register_payload_store(name, adapter:, **) name = name.to_sym adapter = adapter.to_sym # Trigger autoload for common adapters ensure_adapter_loaded(adapter) unless PayloadStore::Base.lookup(adapter) raise ArgumentError, "Unknown payload store adapter: #{adapter.inspect}. " \ "Available adapters: #{PayloadStore::Base.registered_adapters.inspect}" end store = PayloadStore::Base.create(adapter, **) @mutex.synchronize do @payload_stores = @payload_stores.merge(name => store) @default_payload_store_name = name end end |
#register_preprocessor(name, callable = nil) {|outgoing_request| ... } ⇒ void
This method returns an undefined value.
Register a named preprocessor that can be attached to requests to modify them just before they are sent -- for example, to sign requests.
The preprocessor can be provided as a callable or a block taking a single argument. When a request that references the preprocessor is sent, it is invoked with an OutgoingRequest after secret references have been resolved and the x-request-id and default user-agent headers have been set. It can change the request headers and append query parameters.
Requests reference preprocessors by name only, so the callable (and any credentials it uses) stays on the processor side and is never serialized.
295 296 297 298 299 300 301 302 303 304 |
# File 'lib/patient_http/configuration.rb', line 295 def register_preprocessor(name, callable = nil, &block) preprocessor = resolve_callable(:preprocessor, callable, &block) raise ArgumentError.new("register_preprocessor requires a callable or a block") if preprocessor.nil? validate_preprocessor_parameters!(preprocessor) @mutex.synchronize do @preprocessors = @preprocessors.merge(name.to_s => preprocessor) end end |
#register_secret(name, value = nil) {|name| ... } ⇒ void
This method returns an undefined value.
Register a named secret whose value can be referenced indirectly when building requests via PatientHttp.secret.
The value can be provided directly or as a block (callable). A block is invoked lazily with the secret name each time the secret is resolved, which is useful for values that should be read on demand (for example, from the environment).
262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/patient_http/configuration.rb', line 262 def register_secret(name, value = nil, &block) if value.nil? && block.nil? raise ArgumentError.new("register_secret requires a value or a block") end if !value.nil? && block raise ArgumentError.new("register_secret accepts either a value or a block, not both") end @mutex.synchronize do @secrets[name.to_s] = block || value @secret_manager = SecretManager.new(secrets: @secrets.dup) end end |
#to_h ⇒ Hash
Convert to hash for inspection
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/patient_http/configuration.rb', line 376 def to_h { "max_connections" => max_connections, "request_timeout" => request_timeout, "shutdown_timeout" => shutdown_timeout, "logger" => logger, "max_response_size" => max_response_size, "user_agent" => user_agent, "raise_error_responses" => raise_error_responses, "max_redirects" => max_redirects, "connection_pool_size" => connection_pool_size, "connection_timeout" => connection_timeout, "proxy_url" => proxy_url, "retries" => retries, "protocol" => protocol, "payload_stores" => payload_stores.keys, "default_payload_store" => default_payload_store_name, "secrets" => @mutex.synchronize { @secrets.keys }, "preprocessors" => @mutex.synchronize { @preprocessors.keys } } end |