From bec81a23fb56b007e922bedde3b3994e95ee64ba Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Wed, 3 Apr 2024 13:14:18 -0700 Subject: [PATCH 01/10] added request decorator class --- lib/splitclient-rb.rb | 4 + .../engine/api/no_op_header_decorator.rb | 14 +++ .../engine/api/request_context.rb | 15 +++ .../engine/api/request_decorator.rb | 51 ++++++++++ spec/engine/api/request_decorator_spec.rb | 99 +++++++++++++++++++ 5 files changed, 183 insertions(+) create mode 100644 lib/splitclient-rb/engine/api/no_op_header_decorator.rb create mode 100644 lib/splitclient-rb/engine/api/request_context.rb create mode 100644 lib/splitclient-rb/engine/api/request_decorator.rb create mode 100644 spec/engine/api/request_decorator_spec.rb diff --git a/lib/splitclient-rb.rb b/lib/splitclient-rb.rb index 642db7d5..ff1cbd9c 100644 --- a/lib/splitclient-rb.rb +++ b/lib/splitclient-rb.rb @@ -61,6 +61,10 @@ require 'splitclient-rb/engine/api/splits' require 'splitclient-rb/engine/api/events' require 'splitclient-rb/engine/api/telemetry_api' +require 'splitclient-rb/engine/api/no_op_header_decorator' +require 'splitclient-rb/engine/api/request_context' +require 'splitclient-rb/engine/api/request_decorator' + require 'splitclient-rb/engine/common/impressions_counter' require 'splitclient-rb/engine/common/impressions_manager' require 'splitclient-rb/engine/common/noop_impressions_counter' diff --git a/lib/splitclient-rb/engine/api/no_op_header_decorator.rb b/lib/splitclient-rb/engine/api/no_op_header_decorator.rb new file mode 100644 index 00000000..7c21c619 --- /dev/null +++ b/lib/splitclient-rb/engine/api/no_op_header_decorator.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module SplitIoClient + module Api + class NoOpHeaderDecorator + def initialize + true + end + def get_header_overrides(request_context) + {} + end + end + end +end diff --git a/lib/splitclient-rb/engine/api/request_context.rb b/lib/splitclient-rb/engine/api/request_context.rb new file mode 100644 index 00000000..aef00c5f --- /dev/null +++ b/lib/splitclient-rb/engine/api/request_context.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module SplitIoClient + module Api + class RequestContext + def initialize(headers) + @headers = headers + end + + def headers + @headers + end + end + end +end diff --git a/lib/splitclient-rb/engine/api/request_decorator.rb b/lib/splitclient-rb/engine/api/request_decorator.rb new file mode 100644 index 00000000..3ea01bec --- /dev/null +++ b/lib/splitclient-rb/engine/api/request_decorator.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module SplitIoClient + module Api + class RequestDecorator + FORBIDDEN_HEADERS = [ + "SplitSDKVersion", + "SplitMachineIp", + "SplitMachineName", + "SplitImpressionsMode", + "Host", + "Referrer", + "Content-Type", + "Content-Length", + "Content-Encoding", + "Accept", + "Keep-Alive", + "X-Fastly-Debug" + ] + + def initialize(custom_header_decorator) + @custom_header_decorator = custom_header_decorator + if @custom_header_decorator.nil? + @custom_header_decorator = SplitIoClient::Api::NoOpHeaderDecorator.new + end + end + + def decorate_headers(request) + custom_headers = @custom_header_decorator.get_header_overrides(SplitIoClient::Api::RequestContext.new(request.headers.clone)) + custom_headers.keys().each do |header| + if is_header_allowed(header) + if request.headers[header].is_a?(Array) + request.headers[header] = custom_headers[header].join(',') + else + request.headers[header] = custom_headers[header] + end + end + end + request + rescue StandardError => e + raise e, 'Problem adding custom header in request decorator', e.backtrace + end + + private + + def is_header_allowed(header) + return !FORBIDDEN_HEADERS.map { |forbidden| forbidden.downcase }.include?(header.downcase) + end + end + end +end diff --git a/spec/engine/api/request_decorator_spec.rb b/spec/engine/api/request_decorator_spec.rb new file mode 100644 index 00000000..42c85e08 --- /dev/null +++ b/spec/engine/api/request_decorator_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'spec_helper' + +class MyCustomDecorator3 + def initialize + true + end + def get_header_overrides(request_context) + ["value"] + end +end + +class MyCustomDecorator2 + def initialize + true + end + def get_header_overrides(request_context) + headers = request_context.headers + headers["UserCustomHeader"] = ["value"] + for header in SplitIoClient::Api::RequestDecorator::FORBIDDEN_HEADERS + headers[header] = ["val"] + end + headers + end +end + +class MyCustomDecorator + def initialize + true + end + def get_header_overrides(request_context) + headers = request_context.headers + headers["UserCustomHeader"] = ["value"] + headers["AnotherCustomHeader"] = ["val1", "val2"] + headers + end +end + +describe SplitIoClient::Api::RequestDecorator do + + let(:api_client) do + Faraday.new do |builder| + builder.use SplitIoClient::FaradayMiddleware::Gzip + builder.adapter :net_http_persistent + end + end + let(:url) { 'https://example.org?hello=world' } + let(:params) { { hello: :world } } + + before do + stub_request(:get, url).to_return(status: 200) + end + + context 'request decorator' do + it 'no op mode' do + request_decorator = described_class.new(nil) + + api_client.get(url, params) do |req| + req.headers = {} + req = request_decorator.decorate_headers(req) + expect(req.headers).to eq({}) + end + end + + it 'add custom headers' do + request_decorator = described_class.new(MyCustomDecorator.new) + + api_client.get(url, params) do |req| + req.headers = {} + req = request_decorator.decorate_headers(req) + expect(req.headers['UserCustomHeader']).to eq("value") + expect(req.headers['AnotherCustomHeader']).to eq("val1, val2") + end + end + + it 'add forbidden headers' do + request_decorator = described_class.new(MyCustomDecorator2.new) + + api_client.get(url, params) do |req| + req.headers = {} + req = request_decorator.decorate_headers(req) + expect(req.headers['UserCustomHeader']).to eq("value") + expect(req.headers.length).to eq(1) + end + end + + it 'handle errors' do + request_decorator = described_class.new(MyCustomDecorator3.new) + + api_client.get(url, params) do |req| + req.headers = {} + expect { req = request_decorator.decorate_headers(req) }.to raise_error( + 'Problem adding custom header in request decorator' + ) + end + end + end +end From 5f50d2ab47c4ae4553fa155c4c21655dc5bb122e Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Wed, 3 Apr 2024 13:20:30 -0700 Subject: [PATCH 02/10] polish --- lib/splitclient-rb/engine/api/no_op_header_decorator.rb | 3 --- spec/engine/api/request_decorator_spec.rb | 9 --------- 2 files changed, 12 deletions(-) diff --git a/lib/splitclient-rb/engine/api/no_op_header_decorator.rb b/lib/splitclient-rb/engine/api/no_op_header_decorator.rb index 7c21c619..055e3bf4 100644 --- a/lib/splitclient-rb/engine/api/no_op_header_decorator.rb +++ b/lib/splitclient-rb/engine/api/no_op_header_decorator.rb @@ -3,9 +3,6 @@ module SplitIoClient module Api class NoOpHeaderDecorator - def initialize - true - end def get_header_overrides(request_context) {} end diff --git a/spec/engine/api/request_decorator_spec.rb b/spec/engine/api/request_decorator_spec.rb index 42c85e08..d71bd5f9 100644 --- a/spec/engine/api/request_decorator_spec.rb +++ b/spec/engine/api/request_decorator_spec.rb @@ -3,18 +3,12 @@ require 'spec_helper' class MyCustomDecorator3 - def initialize - true - end def get_header_overrides(request_context) ["value"] end end class MyCustomDecorator2 - def initialize - true - end def get_header_overrides(request_context) headers = request_context.headers headers["UserCustomHeader"] = ["value"] @@ -26,9 +20,6 @@ def get_header_overrides(request_context) end class MyCustomDecorator - def initialize - true - end def get_header_overrides(request_context) headers = request_context.headers headers["UserCustomHeader"] = ["value"] From 49efcddebda9edc317996cb89cf2f06eb21558d1 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Fri, 5 Apr 2024 10:34:32 -0700 Subject: [PATCH 03/10] replaced request with headers dict --- .../engine/api/request_decorator.rb | 12 ++--- spec/engine/api/request_decorator_spec.rb | 48 +++++-------------- 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/lib/splitclient-rb/engine/api/request_decorator.rb b/lib/splitclient-rb/engine/api/request_decorator.rb index 3ea01bec..964ebb4d 100644 --- a/lib/splitclient-rb/engine/api/request_decorator.rb +++ b/lib/splitclient-rb/engine/api/request_decorator.rb @@ -25,18 +25,18 @@ def initialize(custom_header_decorator) end end - def decorate_headers(request) - custom_headers = @custom_header_decorator.get_header_overrides(SplitIoClient::Api::RequestContext.new(request.headers.clone)) + def decorate_headers(headers) + custom_headers = @custom_header_decorator.get_header_overrides(SplitIoClient::Api::RequestContext.new(headers.clone)) custom_headers.keys().each do |header| if is_header_allowed(header) - if request.headers[header].is_a?(Array) - request.headers[header] = custom_headers[header].join(',') + if custom_headers[header].is_a?(Array) + headers[header] = custom_headers[header].join(',') else - request.headers[header] = custom_headers[header] + headers[header] = custom_headers[header] end end end - request + headers rescue StandardError => e raise e, 'Problem adding custom header in request decorator', e.backtrace end diff --git a/spec/engine/api/request_decorator_spec.rb b/spec/engine/api/request_decorator_spec.rb index d71bd5f9..11d33037 100644 --- a/spec/engine/api/request_decorator_spec.rb +++ b/spec/engine/api/request_decorator_spec.rb @@ -29,62 +29,40 @@ def get_header_overrides(request_context) end describe SplitIoClient::Api::RequestDecorator do - - let(:api_client) do - Faraday.new do |builder| - builder.use SplitIoClient::FaradayMiddleware::Gzip - builder.adapter :net_http_persistent - end - end - let(:url) { 'https://example.org?hello=world' } - let(:params) { { hello: :world } } - - before do - stub_request(:get, url).to_return(status: 200) - end - context 'request decorator' do it 'no op mode' do request_decorator = described_class.new(nil) - api_client.get(url, params) do |req| - req.headers = {} - req = request_decorator.decorate_headers(req) - expect(req.headers).to eq({}) - end + headers = {} + headers = request_decorator.decorate_headers(headers) + expect(headers).to eq({}) end it 'add custom headers' do request_decorator = described_class.new(MyCustomDecorator.new) - api_client.get(url, params) do |req| - req.headers = {} - req = request_decorator.decorate_headers(req) - expect(req.headers['UserCustomHeader']).to eq("value") - expect(req.headers['AnotherCustomHeader']).to eq("val1, val2") - end + headers = {} + headers = request_decorator.decorate_headers(headers) + expect(headers['UserCustomHeader']).to eq("value") + expect(headers['AnotherCustomHeader']).to eq("val1,val2") end it 'add forbidden headers' do request_decorator = described_class.new(MyCustomDecorator2.new) - api_client.get(url, params) do |req| - req.headers = {} - req = request_decorator.decorate_headers(req) - expect(req.headers['UserCustomHeader']).to eq("value") - expect(req.headers.length).to eq(1) - end + headers = {} + headers = request_decorator.decorate_headers(headers) + expect(headers['UserCustomHeader']).to eq("value") + expect(headers.length).to eq(1) end it 'handle errors' do request_decorator = described_class.new(MyCustomDecorator3.new) - api_client.get(url, params) do |req| - req.headers = {} - expect { req = request_decorator.decorate_headers(req) }.to raise_error( + headers = {} + expect { headers = request_decorator.decorate_headers(headers) }.to raise_error( 'Problem adding custom header in request decorator' ) - end end end end From 35743bdc7bf10ec078f06280810b2ff1ee5bb51f Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Fri, 5 Apr 2024 12:46:48 -0700 Subject: [PATCH 04/10] updated httpclient class --- lib/splitclient-rb/engine/api/client.rb | 7 +++-- spec/engine/api/client_spec.rb | 41 +++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/lib/splitclient-rb/engine/api/client.rb b/lib/splitclient-rb/engine/api/client.rb index 9ddaf94c..c6fba161 100644 --- a/lib/splitclient-rb/engine/api/client.rb +++ b/lib/splitclient-rb/engine/api/client.rb @@ -3,8 +3,9 @@ module SplitIoClient module Api class Client - def initialize(config) + def initialize(config, request_decorator) @config = config + @request_decorator = request_decorator check_faraday_compatibility end @@ -13,6 +14,7 @@ def get_api(url, api_key, params = {}, cache_control_headers = false) api_client.get(url, params) do |req| req.headers = common_headers(api_key).merge('Accept-Encoding' => 'gzip') req.headers = req.headers.merge('Cache-Control' => 'no-cache') if cache_control_headers + req.headers = @request_decorator.decorate_headers(req.headers) req.options[:timeout] = @config.read_timeout req.options[:open_timeout] = @config.connection_timeout @@ -29,12 +31,13 @@ def post_api(url, api_key, data, headers = {}, params = {}) req.headers = common_headers(api_key) .merge('Content-Type' => 'application/json') .merge(headers) - + machine_ip = @config.machine_ip machine_name = @config.machine_name req.headers = req.headers.merge('SplitSDKMachineIP' => machine_ip) unless machine_ip.empty? || machine_ip == 'unknown' req.headers = req.headers.merge('SplitSDKMachineName' => machine_name) unless machine_name.empty? || machine_name == 'unknown' + req.headers = @request_decorator.decorate_headers(req.headers) req.body = data.to_json diff --git a/spec/engine/api/client_spec.rb b/spec/engine/api/client_spec.rb index b91de530..c4ab30c6 100644 --- a/spec/engine/api/client_spec.rb +++ b/spec/engine/api/client_spec.rb @@ -2,8 +2,29 @@ require 'spec_helper' +class MyCustomDecorator + def get_header_overrides(request_context) + headers = request_context.headers + headers["UserCustomHeader"] = ["value"] + headers["AnotherCustomHeader"] = ["val1", "val2"] + headers + end +end + +$headers = {} + +class MyRequestDecorator < SplitIoClient::Api::RequestDecorator + def initialize(custom_header_decorator) + end + + def decorate_headers(headers) + $headers = headers + headers + end +end + describe SplitIoClient::Api::Client do - describe '#get_api' do + describe '#api' do it 'makes GET request without error' do url = 'https://example.org?hello=world' api_key = 'abc-def-ghi' @@ -11,7 +32,7 @@ stub_request(:get, url).to_return(status: 200) - expect { described_class.new(@default_config).get_api(url, api_key, params) }.not_to raise_error + expect { described_class.new(@default_config, SplitIoClient::Api::RequestDecorator.new(nil)).get_api(url, api_key, params) }.not_to raise_error end it 'makes POST request without error' do @@ -21,7 +42,21 @@ stub_request(:post, url).to_return(status: 200) - expect { described_class.new(@default_config).post_api(url, api_key, data) }.not_to raise_error + expect { described_class.new(@default_config, SplitIoClient::Api::RequestDecorator.new(nil)).post_api(url, api_key, data) }.not_to raise_error end + + it 'verify calling request decorator' do + url = 'https://example.org?hello=world' + api_key = 'abc-def-ghi' + params = { hello: :world } + + stub_request(:get, url).to_return(status: 200) + + client = described_class.new(@default_config, MyRequestDecorator.new(nil)) + client.get_api(url, api_key, params) + + expect($headers).to eq({"Accept-Encoding"=>"gzip,deflate"}) + end + end end From 5232aa0d86dd098c8fd392f63aeb985a501d488e Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Tue, 9 Apr 2024 12:03:04 -0700 Subject: [PATCH 05/10] updated push classes, fetcher classes and request_decorator --- .../cache/fetchers/segment_fetcher.rb | 9 +++-- .../cache/fetchers/split_fetcher.rb | 5 ++- lib/splitclient-rb/engine/api/client.rb | 7 ++-- lib/splitclient-rb/engine/api/segments.rb | 4 +- lib/splitclient-rb/engine/api/splits.rb | 4 +- lib/splitclient-rb/sse/event_source/client.rb | 15 +++++++- spec/cache/fetchers/segment_fetch_spec.rb | 8 ++-- spec/cache/fetchers/split_fetch_spec.rb | 6 +-- spec/engine/api/segments_spec.rb | 2 +- spec/engine/api/splits_spec.rb | 6 +-- spec/sse/event_source/client_spec.rb | 38 ++++++++++++++----- 11 files changed, 67 insertions(+), 37 deletions(-) diff --git a/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb b/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb index 12867c79..34b8790c 100644 --- a/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +++ b/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb @@ -4,12 +4,13 @@ module Fetchers class SegmentFetcher attr_reader :segments_repository - def initialize(segments_repository, api_key, config, telemetry_runtime_producer) + def initialize(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) @segments_repository = segments_repository @api_key = api_key @config = config @semaphore = Mutex.new @telemetry_runtime_producer = telemetry_runtime_producer + @request_decorator = request_decorator end def call @@ -17,14 +18,14 @@ def call fetch_segments return end - + segments_thread end def fetch_segments_if_not_exists(names, cache_control_headers = false) names.each do |name| change_number = @segments_repository.get_change_number(name) - + if change_number == -1 fetch_options = { cache_control_headers: cache_control_headers, till: nil } fetch_segment(name, fetch_options) if change_number == -1 @@ -75,7 +76,7 @@ def segments_thread end def segments_api - @segments_api ||= SplitIoClient::Api::Segments.new(@api_key, @segments_repository, @config, @telemetry_runtime_producer) + @segments_api ||= SplitIoClient::Api::Segments.new(@api_key, @segments_repository, @config, @telemetry_runtime_producer, @request_decorator) end end end diff --git a/lib/splitclient-rb/cache/fetchers/split_fetcher.rb b/lib/splitclient-rb/cache/fetchers/split_fetcher.rb index d39b1aea..bcffa34e 100644 --- a/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +++ b/lib/splitclient-rb/cache/fetchers/split_fetcher.rb @@ -4,12 +4,13 @@ module Fetchers class SplitFetcher attr_reader :splits_repository - def initialize(splits_repository, api_key, config, telemetry_runtime_producer) + def initialize(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) @splits_repository = splits_repository @api_key = api_key @config = config @semaphore = Mutex.new @telemetry_runtime_producer = telemetry_runtime_producer + @request_decorator = request_decorator end def call @@ -60,7 +61,7 @@ def splits_since(since, fetch_options = { cache_control_headers: false, till: ni end def splits_api - @splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @config, @telemetry_runtime_producer) + @splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @config, @telemetry_runtime_producer, @request_decorator) end end end diff --git a/lib/splitclient-rb/engine/api/client.rb b/lib/splitclient-rb/engine/api/client.rb index c6fba161..ba0459e7 100644 --- a/lib/splitclient-rb/engine/api/client.rb +++ b/lib/splitclient-rb/engine/api/client.rb @@ -12,10 +12,9 @@ def initialize(config, request_decorator) def get_api(url, api_key, params = {}, cache_control_headers = false) api_client.get(url, params) do |req| - req.headers = common_headers(api_key).merge('Accept-Encoding' => 'gzip') - req.headers = req.headers.merge('Cache-Control' => 'no-cache') if cache_control_headers - req.headers = @request_decorator.decorate_headers(req.headers) - + headers = common_headers(api_key).merge('Accept-Encoding' => 'gzip') + headers = headers.merge('Cache-Control' => 'no-cache') if cache_control_headers + req.headers = @request_decorator.decorate_headers(headers) req.options[:timeout] = @config.read_timeout req.options[:open_timeout] = @config.connection_timeout diff --git a/lib/splitclient-rb/engine/api/segments.rb b/lib/splitclient-rb/engine/api/segments.rb index 7f4a2f8d..3e8fc08c 100644 --- a/lib/splitclient-rb/engine/api/segments.rb +++ b/lib/splitclient-rb/engine/api/segments.rb @@ -4,8 +4,8 @@ module SplitIoClient module Api # Retrieves segment changes from the Split Backend class Segments < Client - def initialize(api_key, segments_repository, config, telemetry_runtime_producer) - super(config) + def initialize(api_key, segments_repository, config, telemetry_runtime_producer, request_decorator) + super(config, request_decorator) @api_key = api_key @segments_repository = segments_repository @telemetry_runtime_producer = telemetry_runtime_producer diff --git a/lib/splitclient-rb/engine/api/splits.rb b/lib/splitclient-rb/engine/api/splits.rb index 2bcb804c..6f98bf48 100644 --- a/lib/splitclient-rb/engine/api/splits.rb +++ b/lib/splitclient-rb/engine/api/splits.rb @@ -4,8 +4,8 @@ module SplitIoClient module Api # Retrieves split definitions from the Split Backend class Splits < Client - def initialize(api_key, config, telemetry_runtime_producer) - super(config) + def initialize(api_key, config, telemetry_runtime_producer, request_decorator) + super(config, request_decorator) @api_key = api_key @telemetry_runtime_producer = telemetry_runtime_producer @flag_sets_filter = @config.flag_sets_filter diff --git a/lib/splitclient-rb/sse/event_source/client.rb b/lib/splitclient-rb/sse/event_source/client.rb index 022894d6..4cf6123d 100644 --- a/lib/splitclient-rb/sse/event_source/client.rb +++ b/lib/splitclient-rb/sse/event_source/client.rb @@ -20,6 +20,7 @@ def initialize(config, notification_manager_keeper, notification_processor, status_queue, + request_decorator, read_timeout: DEFAULT_READ_TIMEOUT) @config = config @api_key = api_key @@ -32,6 +33,7 @@ def initialize(config, @connected = Concurrent::AtomicBoolean.new(false) @first_event = Concurrent::AtomicBoolean.new(true) @socket = nil + @request_decorator = request_decorator end def close(status = nil) @@ -145,7 +147,6 @@ def socket_connect def process_data(partial_data) return if partial_data.nil? || partial_data == KEEP_ALIVE_RESPONSE - @config.logger.debug("Event partial data: #{partial_data}") if @config.debug_enabled events = @event_parser.parse(partial_data) events.each { |event| process_event(event) } @@ -161,11 +162,21 @@ def build_request(uri) req << "SplitSDKMachineIP: #{@config.machine_ip}\r\n" req << "SplitSDKMachineName: #{@config.machine_name}\r\n" req << "SplitSDKClientKey: #{@api_key.split(//).last(4).join}\r\n" unless @api_key.nil? + req << add_custom_headers req << "Cache-Control: no-cache\r\n\r\n" @config.logger.debug("Request info: #{req}") if @config.debug_enabled req end + def add_custom_headers + custom_headers = @request_decorator.decorate_headers({}) + all_headers = "" + custom_headers.keys().each do |header| + all_headers += header + ": " + custom_headers[header] + "\r\n" + end + all_headers + end + def process_event(event) case event.event_type when ERROR_EVENT_TYPE @@ -196,7 +207,7 @@ def dispatch_event(event) def push_status(status) return if status.nil? - + @config.logger.debug("Pushing new sse status: #{status}") @status_queue.push(status) end diff --git a/spec/cache/fetchers/segment_fetch_spec.rb b/spec/cache/fetchers/segment_fetch_spec.rb index e49c788a..4c07a84c 100644 --- a/spec/cache/fetchers/segment_fetch_spec.rb +++ b/spec/cache/fetchers/segment_fetch_spec.rb @@ -37,9 +37,9 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer) } + let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } let(:split_fetcher) do - SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer) + SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) end it 'fetch segments' do @@ -73,9 +73,9 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer) } + let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } let(:split_fetcher) do - SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer) + SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) end it 'fetch segments' do diff --git a/spec/cache/fetchers/split_fetch_spec.rb b/spec/cache/fetchers/split_fetch_spec.rb index 2d320734..078bc3f3 100644 --- a/spec/cache/fetchers/split_fetch_spec.rb +++ b/spec/cache/fetchers/split_fetch_spec.rb @@ -27,7 +27,7 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer) } + let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } it 'returns splits since' do splits = store.send(:splits_since, -1) @@ -78,7 +78,7 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new(['set_2']) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer) } + let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } before do stub_request(:get, 'https://sdk.split.io/api/splitChanges?sets=set_2&since=-1') @@ -130,7 +130,7 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer) } + let(:store) { described_class.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } it 'returns splits since' do splits = store.send(:splits_since, -1) diff --git a/spec/engine/api/segments_spec.rb b/spec/engine/api/segments_spec.rb index 755a2890..63253d98 100644 --- a/spec/engine/api/segments_spec.rb +++ b/spec/engine/api/segments_spec.rb @@ -12,7 +12,7 @@ end let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:segments_api) { described_class.new('', segments_repository, config, telemetry_runtime_producer) } + let(:segments_api) { described_class.new('', segments_repository, config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } let(:adapter) do SplitIoClient::Cache::Adapters::MemoryAdapter.new(SplitIoClient::Cache::Adapters::MemoryAdapters::MapAdapter.new) end diff --git a/spec/engine/api/splits_spec.rb b/spec/engine/api/splits_spec.rb index 7850e6db..a06cbce8 100644 --- a/spec/engine/api/splits_spec.rb +++ b/spec/engine/api/splits_spec.rb @@ -15,7 +15,7 @@ end let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:splits_api) { described_class.new('', config, telemetry_runtime_producer) } + let(:splits_api) { described_class.new('', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } it 'returns splits with segment names' do stub_request(:get, 'https://sdk.split.io/api/splitChanges?since=-1') @@ -38,7 +38,7 @@ end let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:splits_api) { described_class.new('', config, telemetry_runtime_producer) } + let(:splits_api) { described_class.new('', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } it 'returns the splits - with 2 sets param' do stub_request(:get, 'https://sdk.split.io/api/splitChanges?sets=set_1,set_2&since=-1') @@ -93,7 +93,7 @@ end let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:splits_api) { described_class.new('', config, telemetry_runtime_producer) } + let(:splits_api) { described_class.new('', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } it 'returns the splits - checking headers when cache_control_headers is false' do stub_request(:get, 'https://sdk.split.io/api/splitChanges?since=-1') diff --git a/spec/sse/event_source/client_spec.rb b/spec/sse/event_source/client_spec.rb index 416b66ad..9ce88c2a 100644 --- a/spec/sse/event_source/client_spec.rb +++ b/spec/sse/event_source/client_spec.rb @@ -3,9 +3,19 @@ require 'spec_helper' require 'http_server_mock' +class MyCustomDecorator + def get_header_overrides(request_context) + headers = request_context.headers + headers["UserCustomHeader"] = ["value"] + headers["AnotherCustomHeader"] = ["val1", "val2"] + headers + end +end + describe SplitIoClient::SSE::EventSource::Client do subject { SplitIoClient::SSE::EventSource::Client } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(MyCustomDecorator.new) } let(:log) { StringIO.new } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log)) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } @@ -25,8 +35,8 @@ end let(:parameters) do { - split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(repositories[:splits], api_key, config, telemetry_runtime_producer), - segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(repositories[:segments], api_key, config, telemetry_runtime_producer), + split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(repositories[:splits], api_key, config, telemetry_runtime_producer, request_decorator), + segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(repositories[:segments], api_key, config, telemetry_runtime_producer, request_decorator), imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, telemetry_runtime_producer: telemetry_runtime_producer } @@ -48,6 +58,7 @@ context 'tests' do it 'receive split update event' do + stub_request(:get, 'https://sdk.split.io/api/splitChanges?since=-1') .with(headers: { 'Authorization' => 'Bearer client-spec-key' }) .to_return(status: 200, body: '{"splits":[],"since":-1,"till":5564531221}') @@ -61,7 +72,7 @@ end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -92,7 +103,7 @@ end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -121,7 +132,7 @@ send_stream_content(res, event_segment_update) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -144,7 +155,7 @@ send_stream_content(res, event_control) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -166,7 +177,7 @@ send_stream_content(res, event_invalid_format) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -188,7 +199,7 @@ send_stream_content(res, event_occupancy) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(true) @@ -208,7 +219,7 @@ send_stream_content(res, event_error, 400) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) @@ -226,7 +237,7 @@ send_stream_content(res, event_error, 400) end start_workers - sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) connected = sse_client.start(server.base_uri) expect(connected).to eq(false) @@ -235,6 +246,13 @@ stop_workers end end + + it "append custom headers" do + sse_client = subject.new(config, api_token, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) + req = sse_client.send :build_request, URI("http://localhost") + expect(req).to include("UserCustomHeader: value") + expect(req).to include("AnotherCustomHeader: val1,val2") + end end private From ed8497a00be5fc099631d3cd3525cbf1f5233856 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Tue, 9 Apr 2024 12:12:03 -0700 Subject: [PATCH 06/10] polishing --- lib/splitclient-rb/sse/event_source/client.rb | 13 +++---------- spec/engine/api/client_spec.rb | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/splitclient-rb/sse/event_source/client.rb b/lib/splitclient-rb/sse/event_source/client.rb index 4cf6123d..9bbccd9e 100644 --- a/lib/splitclient-rb/sse/event_source/client.rb +++ b/lib/splitclient-rb/sse/event_source/client.rb @@ -155,6 +155,8 @@ def process_data(partial_data) end def build_request(uri) + custom_headers = @request_decorator.decorate_headers({}) + req = "GET #{uri.request_uri} HTTP/1.1\r\n" req << "Host: #{uri.host}\r\n" req << "Accept: text/event-stream\r\n" @@ -162,21 +164,12 @@ def build_request(uri) req << "SplitSDKMachineIP: #{@config.machine_ip}\r\n" req << "SplitSDKMachineName: #{@config.machine_name}\r\n" req << "SplitSDKClientKey: #{@api_key.split(//).last(4).join}\r\n" unless @api_key.nil? - req << add_custom_headers + custom_headers.keys().each{ |header| req << header + ": " + custom_headers[header] + "\r\n" } req << "Cache-Control: no-cache\r\n\r\n" @config.logger.debug("Request info: #{req}") if @config.debug_enabled req end - def add_custom_headers - custom_headers = @request_decorator.decorate_headers({}) - all_headers = "" - custom_headers.keys().each do |header| - all_headers += header + ": " + custom_headers[header] + "\r\n" - end - all_headers - end - def process_event(event) case event.event_type when ERROR_EVENT_TYPE diff --git a/spec/engine/api/client_spec.rb b/spec/engine/api/client_spec.rb index c4ab30c6..818b7baa 100644 --- a/spec/engine/api/client_spec.rb +++ b/spec/engine/api/client_spec.rb @@ -55,7 +55,7 @@ def decorate_headers(headers) client = described_class.new(@default_config, MyRequestDecorator.new(nil)) client.get_api(url, api_key, params) - expect($headers).to eq({"Accept-Encoding"=>"gzip,deflate"}) + expect($headers).to eq({"Accept-Encoding"=>"gzip", "Authorization" => "Bearer abc-def-ghi", "SplitSDKVersion" => "ruby-8.3.1"}) end end From 367704eddc45d56320cf99d28866e853a1d651d5 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Tue, 9 Apr 2024 12:20:25 -0700 Subject: [PATCH 07/10] polish --- lib/splitclient-rb/sse/event_source/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/splitclient-rb/sse/event_source/client.rb b/lib/splitclient-rb/sse/event_source/client.rb index 9bbccd9e..efec0b37 100644 --- a/lib/splitclient-rb/sse/event_source/client.rb +++ b/lib/splitclient-rb/sse/event_source/client.rb @@ -164,7 +164,7 @@ def build_request(uri) req << "SplitSDKMachineIP: #{@config.machine_ip}\r\n" req << "SplitSDKMachineName: #{@config.machine_name}\r\n" req << "SplitSDKClientKey: #{@api_key.split(//).last(4).join}\r\n" unless @api_key.nil? - custom_headers.keys().each{ |header| req << header + ": " + custom_headers[header] + "\r\n" } + custom_headers.keys().each{ |header| req << "#{header}: #{custom_headers[header]}\r\n" } req << "Cache-Control: no-cache\r\n\r\n" @config.logger.debug("Request info: #{req}") if @config.debug_enabled req From ee90ad39bc0f444a0cea1282cb4646fe33c148e7 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Thu, 11 Apr 2024 15:44:46 -0700 Subject: [PATCH 08/10] factory and config integration with specs --- .../cache/repositories/events_repository.rb | 5 ++- lib/splitclient-rb/engine/api/client.rb | 9 ++-- lib/splitclient-rb/engine/api/events.rb | 4 +- lib/splitclient-rb/engine/api/impressions.rb | 6 +-- .../engine/api/telemetry_api.rb | 6 +-- lib/splitclient-rb/engine/auth_api_client.rb | 4 +- lib/splitclient-rb/engine/push_manager.rb | 4 +- lib/splitclient-rb/split_config.rb | 14 +++++++ lib/splitclient-rb/split_factory.rb | 15 +++---- .../clients/split_client_spec.rb | 5 ++- spec/cache/fetchers/segment_fetch_spec.rb | 9 ++-- .../repositories/events_repository_spec.rb | 8 ++-- .../impressions_repository_spec.rb | 10 +++-- spec/cache/senders/events_sender_spec.rb | 3 +- .../senders/impressions_count_sender_spec.rb | 5 ++- .../senders/impressions_formatter_spec.rb | 5 ++- .../impressions_sender_adapter_spec.rb | 5 ++- spec/cache/senders/impressions_sender_spec.rb | 5 ++- .../senders/localhost_repo_cleaner_spec.rb | 7 ++-- spec/engine/api/events_spec.rb | 5 ++- spec/engine/api/impressions_spec.rb | 7 ++-- spec/engine/api/telemetry_api_spec.rb | 3 +- spec/engine/auth_api_client_spec.rb | 7 ++-- spec/engine/common/impression_manager_spec.rb | 5 ++- .../memory_unique_keys_tracker_spec.rb | 5 ++- .../redis_unique_keys_tracker_spec.rb | 5 ++- spec/engine/push_manager_spec.rb | 15 +++---- spec/engine/sync_manager_spec.rb | 13 +++--- spec/engine/synchronizer_spec.rb | 7 ++-- spec/splitclient/split_client_spec.rb | 3 +- spec/splitclient/split_config_spec.rb | 14 +++++++ spec/sse/event_source/client_spec.rb | 2 +- spec/sse/sse_handler_spec.rb | 9 ++-- spec/sse/workers/segments_worker_spec.rb | 7 ++-- spec/sse/workers/splits_worker_spec.rb | 41 ++++++++++--------- spec/telemetry/synchronizer_spec.rb | 3 +- 36 files changed, 168 insertions(+), 112 deletions(-) diff --git a/lib/splitclient-rb/cache/repositories/events_repository.rb b/lib/splitclient-rb/cache/repositories/events_repository.rb index 307f22ea..e1275158 100644 --- a/lib/splitclient-rb/cache/repositories/events_repository.rb +++ b/lib/splitclient-rb/cache/repositories/events_repository.rb @@ -6,7 +6,7 @@ class EventsRepository < Repository extend Forwardable def_delegators :@repository, :add, :clear, :batch - def initialize(config, api_key, telemetry_runtime_producer) + def initialize(config, api_key, telemetry_runtime_producer, request_decorator) super(config) @repository = case @config.events_adapter.class.to_s when 'SplitIoClient::Cache::Adapters::MemoryAdapter' @@ -17,6 +17,7 @@ def initialize(config, api_key, telemetry_runtime_producer) @api_key = api_key @telemetry_runtime_producer = telemetry_runtime_producer + @request_decorator = request_decorator end def post_events @@ -49,7 +50,7 @@ def event(key, traffic_type, event_type, time, value, properties) private def events_api - @events_api ||= SplitIoClient::Api::Events.new(@api_key, @config, @telemetry_runtime_producer) + @events_api ||= SplitIoClient::Api::Events.new(@api_key, @config, @telemetry_runtime_producer, @request_decorator) end end end diff --git a/lib/splitclient-rb/engine/api/client.rb b/lib/splitclient-rb/engine/api/client.rb index ba0459e7..af1d804e 100644 --- a/lib/splitclient-rb/engine/api/client.rb +++ b/lib/splitclient-rb/engine/api/client.rb @@ -27,16 +27,16 @@ def get_api(url, api_key, params = {}, cache_control_headers = false) def post_api(url, api_key, data, headers = {}, params = {}) api_client.post(url) do |req| - req.headers = common_headers(api_key) + headers = common_headers(api_key) .merge('Content-Type' => 'application/json') .merge(headers) machine_ip = @config.machine_ip machine_name = @config.machine_name - req.headers = req.headers.merge('SplitSDKMachineIP' => machine_ip) unless machine_ip.empty? || machine_ip == 'unknown' - req.headers = req.headers.merge('SplitSDKMachineName' => machine_name) unless machine_name.empty? || machine_name == 'unknown' - req.headers = @request_decorator.decorate_headers(req.headers) + headers = headers.merge('SplitSDKMachineIP' => machine_ip) unless machine_ip.empty? || machine_ip == 'unknown' + headers = headers.merge('SplitSDKMachineName' => machine_name) unless machine_name.empty? || machine_name == 'unknown' + req.headers = @request_decorator.decorate_headers(headers) req.body = data.to_json @@ -48,6 +48,7 @@ def post_api(url, api_key, data, headers = {}, params = {}) end rescue StandardError => e @config.logger.warn("#{e}\nURL:#{url}\ndata:#{data}\nparams:#{params}") + puts e raise e, 'Split SDK failed to connect to backend to post information', e.backtrace end diff --git a/lib/splitclient-rb/engine/api/events.rb b/lib/splitclient-rb/engine/api/events.rb index fd81fd54..d1f6356a 100644 --- a/lib/splitclient-rb/engine/api/events.rb +++ b/lib/splitclient-rb/engine/api/events.rb @@ -3,8 +3,8 @@ module SplitIoClient module Api class Events < Client - def initialize(api_key, config, telemetry_runtime_producer) - super(config) + def initialize(api_key, config, telemetry_runtime_producer, request_decorator) + super(config, request_decorator) @api_key = api_key @telemetry_runtime_producer = telemetry_runtime_producer end diff --git a/lib/splitclient-rb/engine/api/impressions.rb b/lib/splitclient-rb/engine/api/impressions.rb index f71804dc..fae6b61c 100644 --- a/lib/splitclient-rb/engine/api/impressions.rb +++ b/lib/splitclient-rb/engine/api/impressions.rb @@ -3,8 +3,8 @@ module SplitIoClient module Api class Impressions < Client - def initialize(api_key, config, telemetry_runtime_producer) - super(config) + def initialize(api_key, config, telemetry_runtime_producer, request_decorator) + super(config, request_decorator) @api_key = api_key @telemetry_runtime_producer = telemetry_runtime_producer end @@ -21,7 +21,7 @@ def post(impressions) if response.success? @config.split_logger.log_if_debug("Impressions reported: #{total_impressions(impressions)}") - + bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0) @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::IMPRESSIONS_SYNC, bucket) @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::IMPRESSIONS_SYNC, (Time.now.to_f * 1000.0).to_i) diff --git a/lib/splitclient-rb/engine/api/telemetry_api.rb b/lib/splitclient-rb/engine/api/telemetry_api.rb index 80497406..a05ad85a 100644 --- a/lib/splitclient-rb/engine/api/telemetry_api.rb +++ b/lib/splitclient-rb/engine/api/telemetry_api.rb @@ -3,8 +3,8 @@ module SplitIoClient module Api class TelemetryApi < Client - def initialize(config, api_key, telemetry_runtime_producer) - super(config) + def initialize(config, api_key, telemetry_runtime_producer, request_decorator) + super(config, request_decorator) @api_key = api_key @telemetry_runtime_producer = telemetry_runtime_producer end @@ -33,7 +33,7 @@ def post_telemetry(url, obj, method) if response.success? @config.split_logger.log_if_debug("Telemetry post succeeded: record #{method}.") - + bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0) @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::TELEMETRY_SYNC, bucket) @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::TELEMETRY_SYNC, (Time.now.to_f * 1000.0).to_i) diff --git a/lib/splitclient-rb/engine/auth_api_client.rb b/lib/splitclient-rb/engine/auth_api_client.rb index e0d7a903..c174a995 100644 --- a/lib/splitclient-rb/engine/auth_api_client.rb +++ b/lib/splitclient-rb/engine/auth_api_client.rb @@ -6,9 +6,9 @@ module SplitIoClient module Engine class AuthApiClient - def initialize(config, telemetry_runtime_producer) + def initialize(config, telemetry_runtime_producer, request_decorator) @config = config - @api_client = SplitIoClient::Api::Client.new(@config) + @api_client = SplitIoClient::Api::Client.new(@config, request_decorator) @telemetry_runtime_producer = telemetry_runtime_producer end diff --git a/lib/splitclient-rb/engine/push_manager.rb b/lib/splitclient-rb/engine/push_manager.rb index e36a9588..65c09690 100644 --- a/lib/splitclient-rb/engine/push_manager.rb +++ b/lib/splitclient-rb/engine/push_manager.rb @@ -3,10 +3,10 @@ module SplitIoClient module Engine class PushManager - def initialize(config, sse_handler, api_key, telemetry_runtime_producer) + def initialize(config, sse_handler, api_key, telemetry_runtime_producer, request_decorator) @config = config @sse_handler = sse_handler - @auth_api_client = AuthApiClient.new(@config, telemetry_runtime_producer) + @auth_api_client = AuthApiClient.new(@config, telemetry_runtime_producer, request_decorator) @api_key = api_key @back_off = Engine::BackOff.new(@config.auth_retry_back_off_base, 1) @telemetry_runtime_producer = telemetry_runtime_producer diff --git a/lib/splitclient-rb/split_config.rb b/lib/splitclient-rb/split_config.rb index da434c91..420fdce9 100644 --- a/lib/splitclient-rb/split_config.rb +++ b/lib/splitclient-rb/split_config.rb @@ -123,6 +123,9 @@ def initialize(opts = {}) @on_demand_fetch_max_retries = SplitConfig.default_on_demand_fetch_max_retries @flag_sets_filter = SplitConfig.sanitize_flag_set_filter(opts[:flag_sets_filter], @split_validator, opts[:cache_adapter], @logger) + + @header_override_callback = SplitConfig.header_override_callback(opts[:header_override_callback]) + startup_log end @@ -303,6 +306,17 @@ def initialize(opts = {}) # @return [Array] attr_accessor :flag_sets_filter + # + # Custom Headers override + # + # @return SplitIoClient::Api::CustomHeaderDecorator + attr_accessor :header_override_callback + + def self.header_override_callback(header_override_callback) + return header_override_callback if header_override_callback.class.method_defined? :get_header_overrides + nil + end + def self.default_counter_refresh_rate(adapter) return 300 if adapter == :redis # Send bulk impressions count - Refresh rate: 5 min. diff --git a/lib/splitclient-rb/split_factory.rb b/lib/splitclient-rb/split_factory.rb index 10b9b46e..527ead09 100644 --- a/lib/splitclient-rb/split_factory.rb +++ b/lib/splitclient-rb/split_factory.rb @@ -33,6 +33,7 @@ def initialize(api_key, config_hash = {}) flag_sets_invalid = 0 @config = SplitConfig.new(config_hash.merge(localhost_mode: @api_key == LOCALHOST_API_KEY )) + @request_decorator = Api::RequestDecorator.new(@config.header_override_callback) if config_hash.key?(:flag_sets_filter) flag_sets_count = store_flag_sets.length() @@ -178,8 +179,8 @@ def build_telemetry_components end def build_fetchers - @split_fetcher = SplitFetcher.new(@splits_repository, @api_key, @config, @runtime_producer) - @segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key, @config, @runtime_producer) + @split_fetcher = SplitFetcher.new(@splits_repository, @api_key, @config, @runtime_producer, @request_decorator) + @segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key, @config, @runtime_producer, @request_decorator) end def build_synchronizer @@ -203,9 +204,9 @@ def build_streaming_components notification_manager_keeper = SSE::NotificationManagerKeeper.new(@config, @runtime_producer, @push_status_queue) notification_processor = SSE::NotificationProcessor.new(@config, splits_worker, segments_worker) event_parser = SSE::EventSource::EventParser.new(config) - sse_client = SSE::EventSource::Client.new(@config, @api_key, @runtime_producer, event_parser, notification_manager_keeper, notification_processor, @push_status_queue) + sse_client = SSE::EventSource::Client.new(@config, @api_key, @runtime_producer, event_parser, notification_manager_keeper, notification_processor, @push_status_queue, @request_decorator) @sse_handler = SSE::SSEHandler.new(@config, splits_worker, segments_worker, sse_client) - @push_manager = Engine::PushManager.new(@config, @sse_handler, @api_key, @runtime_producer) + @push_manager = Engine::PushManager.new(@config, @sse_handler, @api_key, @runtime_producer, @request_decorator) end def build_sync_manager @@ -221,11 +222,11 @@ def build_repositories @splits_repository = SplitsRepository.new(@config, @flag_sets_repository, @flag_sets_filter) @segments_repository = SegmentsRepository.new(@config) @impressions_repository = ImpressionsRepository.new(@config) - @events_repository = EventsRepository.new(@config, @api_key, @runtime_producer) + @events_repository = EventsRepository.new(@config, @api_key, @runtime_producer, @request_decorator) end def build_telemetry_synchronizer(flag_sets, flag_sets_invalid) - @telemetry_api = Api::TelemetryApi.new(@config, @api_key, @runtime_producer) + @telemetry_api = Api::TelemetryApi.new(@config, @api_key, @runtime_producer, @request_decorator) @telemetry_synchronizer = Telemetry::Synchronizer.new(@config, @telemetry_consumers, @init_producer, repositories, @telemetry_api, flag_sets, flag_sets_invalid) end @@ -260,7 +261,7 @@ def build_impression_counter end def build_impressions_sender_adapter - @impressions_api = Api::Impressions.new(@api_key, @config, @runtime_producer) + @impressions_api = Api::Impressions.new(@api_key, @config, @runtime_producer, @request_decorator) @impressions_sender_adapter = Cache::Senders::ImpressionsSenderAdapter.new(@config, @telemetry_api, @impressions_api) end diff --git a/spec/allocations/splitclient-rb/clients/split_client_spec.rb b/spec/allocations/splitclient-rb/clients/split_client_spec.rb index 0dd15231..11207e2a 100644 --- a/spec/allocations/splitclient-rb/clients/split_client_spec.rb +++ b/spec/allocations/splitclient-rb/clients/split_client_spec.rb @@ -5,6 +5,7 @@ describe SplitIoClient::SplitClient do let(:config) { SplitIoClient::SplitConfig.new(impressions_queue_size: 10) } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:flag_sets_repository) {SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new([])} let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([])} let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } @@ -17,8 +18,8 @@ let(:filter_adapter) { SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } let(:api_key) { 'SplitClient-key' } - let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) } - let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) } + let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) } + let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) } let(:evaluator) { SplitIoClient::Engine::Parser::Evaluator.new(segments_repository, splits_repository, config) } let(:sender_adapter) do SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, diff --git a/spec/cache/fetchers/segment_fetch_spec.rb b/spec/cache/fetchers/segment_fetch_spec.rb index 4c07a84c..ab7b9249 100644 --- a/spec/cache/fetchers/segment_fetch_spec.rb +++ b/spec/cache/fetchers/segment_fetch_spec.rb @@ -18,6 +18,7 @@ { name: 'employees', added: [], removed: [], since: 1_473_863_075_059, till: 1_473_863_075_059 } ] end + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } before do stub_request(:get, 'https://sdk.split.io/api/segmentChanges/employees?since=-1') @@ -37,9 +38,9 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } + let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, request_decorator) } let(:split_fetcher) do - SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) + SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, request_decorator) end it 'fetch segments' do @@ -73,9 +74,9 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) } + let(:segment_fetcher) { described_class.new(segments_repository, '', config, telemetry_runtime_producer, request_decorator) } let(:split_fetcher) do - SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, SplitIoClient::Api::RequestDecorator.new(nil)) + SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, '', config, telemetry_runtime_producer, request_decorator) end it 'fetch segments' do diff --git a/spec/cache/repositories/events_repository_spec.rb b/spec/cache/repositories/events_repository_spec.rb index 765ce369..47dcbef3 100644 --- a/spec/cache/repositories/events_repository_spec.rb +++ b/spec/cache/repositories/events_repository_spec.rb @@ -19,10 +19,10 @@ ) ) end - + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } let(:telemetry_runtime_consumer) { SplitIoClient::Telemetry::RuntimeConsumer.new(config) } - let(:repository) { described_class.new(config, nil, telemetry_runtime_producer) } + let(:repository) { described_class.new(config, nil, telemetry_runtime_producer, request_decorator) } before do stub_request(:post, 'https://events.split.io/api/events/bulk') @@ -76,7 +76,7 @@ events_queue_size: events_queue_size ) end - let(:repository) { described_class.new(config, nil, nil) } + let(:repository) { described_class.new(config, nil, nil, nil) } let(:adapter) { config.events_adapter } before do @@ -97,7 +97,7 @@ it 'with ip_addresses_enabled set false' do config = SplitIoClient::SplitConfig.new(cache_adapter: :redis, events_queue_size: 3, ip_addresses_enabled: false) - repository = described_class.new(config, nil, nil) + repository = described_class.new(config, nil, nil, nil) adapter = config.events_adapter config.events_queue_size.times do |index| repository.add(index.to_s, 'traffic_type', 'event_type', (Time.now.to_f * 1000).to_i, 'value', nil, 0) diff --git a/spec/cache/repositories/impressions_repository_spec.rb b/spec/cache/repositories/impressions_repository_spec.rb index 7a4e0c3a..c3071f8c 100644 --- a/spec/cache/repositories/impressions_repository_spec.rb +++ b/spec/cache/repositories/impressions_repository_spec.rb @@ -4,6 +4,8 @@ require 'set' describe SplitIoClient::Cache::Repositories::ImpressionsRepository do + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } + RSpec.shared_examples 'Impressions Repository' do let(:ip) { config.machine_ip } let(:machine_name) { config.machine_name } @@ -111,8 +113,8 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'ImpressionsRepository-memory-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, @@ -168,8 +170,8 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'ImpressionsRepository-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, diff --git a/spec/cache/senders/events_sender_spec.rb b/spec/cache/senders/events_sender_spec.rb index fa124d33..afdb27c4 100644 --- a/spec/cache/senders/events_sender_spec.rb +++ b/spec/cache/senders/events_sender_spec.rb @@ -5,8 +5,9 @@ describe SplitIoClient::Cache::Senders::EventsSender do RSpec.shared_examples 'Events Sender' do |cache_adapter| let(:config) { SplitIoClient::SplitConfig.new(cache_adapter: cache_adapter) } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, nil, telemetry_runtime_producer) } + let(:repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, nil, telemetry_runtime_producer, request_decorator) } let(:sender) { described_class.new(repository, config) } before :each do diff --git a/spec/cache/senders/impressions_count_sender_spec.rb b/spec/cache/senders/impressions_count_sender_spec.rb index ccb7be9c..84fb304e 100644 --- a/spec/cache/senders/impressions_count_sender_spec.rb +++ b/spec/cache/senders/impressions_count_sender_spec.rb @@ -4,6 +4,7 @@ describe SplitIoClient::Cache::Senders::ImpressionsCountSender do subject { SplitIoClient::Cache::Senders::ImpressionsCountSender } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } before :each do impression_counter.inc('feature1', make_timestamp('2020-09-02 09:15:11')) @@ -48,8 +49,8 @@ let(:impression_counter) { SplitIoClient::Engine::Common::ImpressionCounter.new } let(:impressions_sender_adapter) do telemetry_runtime_producer = SplitIoClient::Telemetry::RuntimeProducer.new(config) - impressions_api = SplitIoClient::Api::Impressions.new('key-test', config, telemetry_runtime_producer) - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, 'key-test', telemetry_runtime_producer) + impressions_api = SplitIoClient::Api::Impressions.new('key-test', config, telemetry_runtime_producer, request_decorator) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, 'key-test', telemetry_runtime_producer, request_decorator) SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) end diff --git a/spec/cache/senders/impressions_formatter_spec.rb b/spec/cache/senders/impressions_formatter_spec.rb index 621ffdd7..2b4a52ef 100644 --- a/spec/cache/senders/impressions_formatter_spec.rb +++ b/spec/cache/senders/impressions_formatter_spec.rb @@ -5,6 +5,7 @@ describe SplitIoClient::Cache::Senders::ImpressionsFormatter do RSpec.shared_examples 'Impressions Formatter' do |cache_adapter| let(:config) { SplitIoClient::SplitConfig.new(impressions_queue_size: 5, cache_adapter: cache_adapter) } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:repository) { SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:formatter) { described_class.new(repository) } let(:formatted_impressions) { formatter.send(:call, true) } @@ -19,8 +20,8 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'ImpressionsFormatter-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, diff --git a/spec/cache/senders/impressions_sender_adapter_spec.rb b/spec/cache/senders/impressions_sender_adapter_spec.rb index 4506ad57..0be6701d 100644 --- a/spec/cache/senders/impressions_sender_adapter_spec.rb +++ b/spec/cache/senders/impressions_sender_adapter_spec.rb @@ -92,10 +92,11 @@ context 'memory' do let(:config) { SplitIoClient::SplitConfig.new } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:api_key) { 'ImpressionsSenderAdapter_Memory' } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) } - let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) } + let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) } + let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) } let(:sender) { subject.new(config, telemetry_api, impressions_api) } it 'record_uniques_key' do diff --git a/spec/cache/senders/impressions_sender_spec.rb b/spec/cache/senders/impressions_sender_spec.rb index 9976a1de..22eaf069 100644 --- a/spec/cache/senders/impressions_sender_spec.rb +++ b/spec/cache/senders/impressions_sender_spec.rb @@ -10,9 +10,10 @@ impressions_queue_size: 5 ) end + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:repository) { SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:impression_api) { SplitIoClient::Api::Impressions.new(nil, config, telemetry_runtime_producer) } + let(:impression_api) { SplitIoClient::Api::Impressions.new(nil, config, telemetry_runtime_producer, request_decorator) } let(:sender) { described_class.new(repository, config, impression_api) } let(:formatted_impressions) { SplitIoClient::Cache::Senders::ImpressionsFormatter.new(repository).call(true) } let(:treatment1) { { treatment: 'on', label: 'custom_label1', change_number: 123_456 } } @@ -23,7 +24,7 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'ImpressionsSender-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impression_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, diff --git a/spec/cache/senders/localhost_repo_cleaner_spec.rb b/spec/cache/senders/localhost_repo_cleaner_spec.rb index d03d8220..a6f69c3b 100644 --- a/spec/cache/senders/localhost_repo_cleaner_spec.rb +++ b/spec/cache/senders/localhost_repo_cleaner_spec.rb @@ -5,11 +5,12 @@ describe SplitIoClient::Cache::Senders::LocalhostRepoCleaner do context '#clear_repositories' do let(:config) { SplitIoClient::SplitConfig.new } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:impressions_repository) { SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } let(:events_repository) do - SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'localhost', runtime_producer) + SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'localhost', runtime_producer, request_decorator) end let(:impression_counter) { SplitIoClient::Engine::Common::ImpressionCounter.new } let(:impression_observer) { SplitIoClient::Observers::ImpressionObserver.new } @@ -17,8 +18,8 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'LocalhostRepoCleaner-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, diff --git a/spec/engine/api/events_spec.rb b/spec/engine/api/events_spec.rb index 0fbed080..0a903445 100644 --- a/spec/engine/api/events_spec.rb +++ b/spec/engine/api/events_spec.rb @@ -10,9 +10,10 @@ transport_debug_enabled: true ) end + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:events_api) { described_class.new('', config, telemetry_runtime_producer) } + let(:events_api) { described_class.new('', config, telemetry_runtime_producer, request_decorator) } let(:events) do [{ e: { @@ -84,7 +85,7 @@ ip_addresses_enabled: false ) - api = described_class.new('', custom_config, telemetry_runtime_producer) + api = described_class.new('', custom_config, telemetry_runtime_producer, request_decorator) stub_request(:post, 'https://events.split.io/api/events/bulk') .with(headers: { diff --git a/spec/engine/api/impressions_spec.rb b/spec/engine/api/impressions_spec.rb index d95b5456..25484b2c 100644 --- a/spec/engine/api/impressions_spec.rb +++ b/spec/engine/api/impressions_spec.rb @@ -10,9 +10,10 @@ transport_debug_enabled: true ) end + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:log) { StringIO.new } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:impressions_api) { described_class.new('', config, telemetry_runtime_producer) } + let(:impressions_api) { described_class.new('', config, telemetry_runtime_producer, request_decorator) } let(:impressions) do [ { @@ -41,7 +42,7 @@ it 'post impressions with impressions_mode in debug' do custom_config = SplitIoClient::SplitConfig.new(logger: Logger.new(log), impressions_mode: :debug) - custom_api = described_class.new('', custom_config, telemetry_runtime_producer) + custom_api = described_class.new('', custom_config, telemetry_runtime_producer, request_decorator) stub_request(:post, 'https://events.split.io/api/testImpressions/bulk') .with(headers: { @@ -94,7 +95,7 @@ ip_addresses_enabled: false ) - api = described_class.new('', custom_config, telemetry_runtime_producer) + api = described_class.new('', custom_config, telemetry_runtime_producer, request_decorator) stub_request(:post, 'https://events.split.io/api/testImpressions/bulk') .with(headers: { diff --git a/spec/engine/api/telemetry_api_spec.rb b/spec/engine/api/telemetry_api_spec.rb index 7b3f961b..badf7d33 100644 --- a/spec/engine/api/telemetry_api_spec.rb +++ b/spec/engine/api/telemetry_api_spec.rb @@ -3,10 +3,11 @@ require 'spec_helper' describe SplitIoClient::Api::TelemetryApi do + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:log) { StringIO.new } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log), debug_enabled: true, transport_debug_enabled: true) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:telemetry_api) { described_class.new(config, 'api-key-test', telemetry_runtime_producer) } + let(:telemetry_api) { described_class.new(config, 'api-key-test', telemetry_runtime_producer, request_decorator) } before do stub_request(:post, 'https://telemetry.split.io/api/v1/metrics/usage') diff --git a/spec/engine/auth_api_client_spec.rb b/spec/engine/auth_api_client_spec.rb index 096aae2c..51127bd6 100644 --- a/spec/engine/auth_api_client_spec.rb +++ b/spec/engine/auth_api_client_spec.rb @@ -9,6 +9,7 @@ File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/auth_body_response.json')) end + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:api_key) { 'AuthApiClient-key' } let(:log) { StringIO.new } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log)) } @@ -17,7 +18,7 @@ it 'authenticate success' do stub_request(:get, config.auth_service_url).to_return(status: 200, body: body_response) - auth_api_client = subject.new(config, telemetry_runtime_producer) + auth_api_client = subject.new(config, telemetry_runtime_producer, request_decorator) response = auth_api_client.authenticate(api_key) expect(response[:push_enabled]).to eq(true) @@ -28,7 +29,7 @@ it 'auth server return 500' do stub_request(:get, config.auth_service_url).to_return(status: 500) - auth_api_client = subject.new(config, telemetry_runtime_producer) + auth_api_client = subject.new(config, telemetry_runtime_producer, request_decorator) response = auth_api_client.authenticate(api_key) expect(response[:push_enabled]).to eq(false) @@ -38,7 +39,7 @@ it 'auth server return 401' do stub_request(:get, config.auth_service_url).to_return(status: 401) - auth_api_client = subject.new(config, telemetry_runtime_producer) + auth_api_client = subject.new(config, telemetry_runtime_producer, request_decorator) response = auth_api_client.authenticate(api_key) expect(response[:push_enabled]).to eq(false) diff --git a/spec/engine/common/impression_manager_spec.rb b/spec/engine/common/impression_manager_spec.rb index 7044183a..0df8eb61 100644 --- a/spec/engine/common/impression_manager_spec.rb +++ b/spec/engine/common/impression_manager_spec.rb @@ -6,6 +6,7 @@ describe SplitIoClient::Engine::Common::ImpressionManager do subject { SplitIoClient::Engine::Common::ImpressionManager } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:log) { StringIO.new } let(:impression_listener) { MyImpressionListener.new } let(:impression_counter) { SplitIoClient::Engine::Common::ImpressionCounter.new } @@ -15,8 +16,8 @@ bf = SplitIoClient::Cache::Filter::BloomFilter.new(1_000) filter_adapter = SplitIoClient::Cache::Filter::FilterAdapter.new(config, bf) api_key = 'ImpressionManager-key' - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) sender_adapter = SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) SplitIoClient::Engine::Impressions::UniqueKeysTracker.new(config, diff --git a/spec/engine/impressions/memory_unique_keys_tracker_spec.rb b/spec/engine/impressions/memory_unique_keys_tracker_spec.rb index cdff51b6..745f55e8 100644 --- a/spec/engine/impressions/memory_unique_keys_tracker_spec.rb +++ b/spec/engine/impressions/memory_unique_keys_tracker_spec.rb @@ -6,6 +6,7 @@ describe SplitIoClient::Engine::Impressions::UniqueKeysTracker do subject { SplitIoClient::Engine::Impressions::UniqueKeysTracker } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:log) { StringIO.new } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log)) } let(:bf) { SplitIoClient::Cache::Filter::BloomFilter.new(1_000) } @@ -14,8 +15,8 @@ context 'with sender_adapter' do let(:api_key) { 'UniqueKeysTracker-key' } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) } - let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) } + let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) } + let(:impressions_api) { SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) } let(:sender_adapter) { SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) } it 'track - full cache and send bulk' do diff --git a/spec/engine/impressions/redis_unique_keys_tracker_spec.rb b/spec/engine/impressions/redis_unique_keys_tracker_spec.rb index 9ad42288..6518cb36 100644 --- a/spec/engine/impressions/redis_unique_keys_tracker_spec.rb +++ b/spec/engine/impressions/redis_unique_keys_tracker_spec.rb @@ -6,14 +6,15 @@ describe SplitIoClient::Engine::Impressions::UniqueKeysTracker do subject { SplitIoClient::Engine::Impressions::UniqueKeysTracker } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:config) do SplitIoClient::SplitConfig.new(logger: Logger.new(StringIO.new), cache_adapter: :redis, redis_namespace: 'tracker-prefix') end let(:sender_adapter) do api_key = 'UniqueKeysTracker-key' runtime_producer = SplitIoClient::Telemetry::RuntimeProducer.new(config) - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, runtime_producer, request_decorator) SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api) end diff --git a/spec/engine/push_manager_spec.rb b/spec/engine/push_manager_spec.rb index 03f2187b..49d7b9df 100644 --- a/spec/engine/push_manager_spec.rb +++ b/spec/engine/push_manager_spec.rb @@ -6,6 +6,7 @@ describe SplitIoClient::Engine::PushManager do subject { SplitIoClient::Engine::PushManager } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:body_response) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/auth_body_response.json')) } let(:api_key) { 'PushManager-key' } let(:log) { StringIO.new } @@ -15,8 +16,8 @@ let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, runtime_producer) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, runtime_producer, request_decorator) } let(:splits_worker) { SplitIoClient::SSE::Workers::SplitsWorker.new(split_fetcher, config, splits_repository, runtime_producer, segment_fetcher) } let(:segments_worker) { SplitIoClient::SSE::Workers::SegmentsWorker.new(segment_fetcher, config, segments_repository) } let(:push_status_queue) { Queue.new } @@ -34,7 +35,7 @@ let(:synchronizer) { SplitIoClient::Engine::Synchronizer.new(repositories, config, params) } let(:event_parser) { SplitIoClient::SSE::EventSource::EventParser.new(config) } let(:notification_processor) { SplitIoClient::SSE::NotificationProcessor.new(config, splits_worker, segments_worker) } - let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) } + let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) } context 'start_sse' do it 'must connect to server' do @@ -48,7 +49,7 @@ sse_handler = SplitIoClient::SSE::SSEHandler.new(config, splits_worker, segments_worker, sse_client) - push_manager = subject.new(config, sse_handler, api_key, runtime_producer) + push_manager = subject.new(config, sse_handler, api_key, runtime_producer, request_decorator) connected = push_manager.start_sse expect(a_request(:get, config.auth_service_url)).to have_been_made.times(1) @@ -65,7 +66,7 @@ sse_handler = SplitIoClient::SSE::SSEHandler.new(config, splits_worker, segments_worker, sse_client) - push_manager = subject.new(config, sse_handler, api_key, runtime_producer) + push_manager = subject.new(config, sse_handler, api_key, runtime_producer, request_decorator) connected = push_manager.start_sse expect(a_request(:get, config.auth_service_url)).to have_been_made.times(1) @@ -81,7 +82,7 @@ sse_handler = SplitIoClient::SSE::SSEHandler.new(config, splits_worker, segments_worker, sse_client) - push_manager = subject.new(config, sse_handler, api_key, runtime_producer) + push_manager = subject.new(config, sse_handler, api_key, runtime_producer, request_decorator) connected = push_manager.start_sse expect(a_request(:get, config.auth_service_url)).to have_been_made.times(1) @@ -104,7 +105,7 @@ config.streaming_service_url = server.base_uri sse_handler = SplitIoClient::SSE::SSEHandler.new(config, splits_worker, segments_worker, sse_client) - push_manager = subject.new(config, sse_handler, api_key, runtime_producer) + push_manager = subject.new(config, sse_handler, api_key, runtime_producer, request_decorator) connected = push_manager.start_sse expect(a_request(:get, config.auth_service_url)).to have_been_made.times(1) diff --git a/spec/engine/sync_manager_spec.rb b/spec/engine/sync_manager_spec.rb index 7bedc97b..b6733d57 100644 --- a/spec/engine/sync_manager_spec.rb +++ b/spec/engine/sync_manager_spec.rb @@ -8,6 +8,7 @@ let(:event_control) { "d4\r\nid: 123\nevent: message\ndata: {\"id\":\"1\",\"clientId\":\"emptyClientId\",\"timestamp\": 1582056812285,\"encoding\": \"json\",\"channel\": \"control_pri\",\"data\":\"{\\\"type\\\" : \\\"CONTROL\\\",\\\"controlType\\\":\\\"STREAMING_DISABLED\\\"}\"}\n\n\r\n" } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:splits) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json')) } let(:segment1) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment1.json')) } let(:segment2) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment2.json')) } @@ -22,7 +23,7 @@ let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:impressions_repository) { SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer) } + let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer, request_decorator) } let(:impression_counter) { SplitIoClient::Engine::Common::ImpressionCounter.new } let(:repositories) do { @@ -34,8 +35,8 @@ end let(:sync_params) do { - split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer), - segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer), + split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator), + segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator), imp_counter: impression_counter, telemetry_runtime_producer: telemetry_runtime_producer, unique_keys_tracker: SplitIoClient::Engine::Impressions::NoopUniqueKeysTracker.new @@ -47,7 +48,7 @@ let(:runtime_consumer) { SplitIoClient::Telemetry::RuntimeConsumer.new(config) } let(:evaluation_consumer) { SplitIoClient::Telemetry::EvaluationConsumer.new(config) } let(:telemetry_consumers) { { init: init_consumer, runtime: runtime_consumer, evaluation: evaluation_consumer } } - let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) } + let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) } let(:telemetry_synchronizer) { SplitIoClient::Telemetry::Synchronizer.new(config, telemetry_consumers, init_producer, repositories, telemetry_api, 0, 0) } let(:status_manager) { SplitIoClient::Engine::StatusManager.new(config) } let(:splits_worker) { SplitIoClient::SSE::Workers::SplitsWorker.new(synchronizer, config, splits_repository, telemetry_runtime_producer, sync_params[:segment_fetcher]) } @@ -56,9 +57,9 @@ let(:event_parser) { SplitIoClient::SSE::EventSource::EventParser.new(config) } let(:push_status_queue) { Queue.new } let(:notification_manager_keeper) { SplitIoClient::SSE::NotificationManagerKeeper.new(config, telemetry_runtime_producer, push_status_queue) } - let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) } + let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) } let(:sse_handler) { SplitIoClient::SSE::SSEHandler.new(config, splits_worker, segments_worker, sse_client) } - let(:push_manager) { SplitIoClient::Engine::PushManager.new(config, sse_handler, api_key, telemetry_runtime_producer) } + let(:push_manager) { SplitIoClient::Engine::PushManager.new(config, sse_handler, api_key, telemetry_runtime_producer, request_decorator) } before do mock_split_changes_with_since(splits, '-1') diff --git a/spec/engine/synchronizer_spec.rb b/spec/engine/synchronizer_spec.rb index 5a406419..b112b8ba 100644 --- a/spec/engine/synchronizer_spec.rb +++ b/spec/engine/synchronizer_spec.rb @@ -5,6 +5,7 @@ describe SplitIoClient::Engine::Synchronizer do subject { SplitIoClient::Engine::Synchronizer } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:splits) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json')) } let(:segment1) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment1.json')) } let(:segment2) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment2.json')) } @@ -23,12 +24,12 @@ splits: splits_repository, segments: segments_repository, impressions: SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config), - events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, runtime_producer) + events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, runtime_producer, request_decorator) } parameters = { - split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, runtime_producer), - segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, runtime_producer), + split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, runtime_producer, request_decorator), + segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, runtime_producer, request_decorator), telemetry_runtime_producer: runtime_producer, unique_keys_tracker: SplitIoClient::Engine::Impressions::NoopUniqueKeysTracker.new } diff --git a/spec/splitclient/split_client_spec.rb b/spec/splitclient/split_client_spec.rb index c82d225d..f6d080af 100644 --- a/spec/splitclient/split_client_spec.rb +++ b/spec/splitclient/split_client_spec.rb @@ -4,13 +4,14 @@ describe SplitIoClient::SplitClient do let(:config) { SplitIoClient::SplitConfig.new(cache_adapter: :memory, impressions_mode: :debug) } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:flag_sets_repository) {SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new([]) } let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([]) } let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:impressions_repository) {SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'sdk_key', runtime_producer) } + let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, 'sdk_key', runtime_producer, request_decorator) } let(:impression_manager) { SplitIoClient::Engine::Common::ImpressionManager.new(config, impressions_repository, SplitIoClient::Engine::Common::NoopImpressionCounter.new, runtime_producer, SplitIoClient::Observers::NoopImpressionObserver.new, SplitIoClient::Engine::Impressions::NoopUniqueKeysTracker.new) } let(:evaluation_producer) { SplitIoClient::Telemetry::EvaluationProducer.new(config) } let(:evaluator) { SplitIoClient::Engine::Parser::Evaluator.new(segments_repository, splits_repository, config) } diff --git a/spec/splitclient/split_config_spec.rb b/spec/splitclient/split_config_spec.rb index 1c867aa4..5a2f4f2f 100644 --- a/spec/splitclient/split_config_spec.rb +++ b/spec/splitclient/split_config_spec.rb @@ -180,5 +180,19 @@ configs = SplitIoClient::SplitConfig.new(flag_sets_filter: ['1set', 12]) expect(configs.flag_sets_filter).to eq ['1set'] end + + it "test header_override_callback validation" do + configs = SplitIoClient::SplitConfig.new(header_override_callback: "something") + expect(configs.header_override_callback).to be_nil + + class MyCustomDecorator + def get_header_overrides(request_context) + ["value"] + end + end + custom_decorator = MyCustomDecorator.new + configs = SplitIoClient::SplitConfig.new(header_override_callback: custom_decorator) + expect(configs.header_override_callback).to be(custom_decorator) + end end end diff --git a/spec/sse/event_source/client_spec.rb b/spec/sse/event_source/client_spec.rb index 9ce88c2a..815b7ee7 100644 --- a/spec/sse/event_source/client_spec.rb +++ b/spec/sse/event_source/client_spec.rb @@ -30,7 +30,7 @@ def get_header_overrides(request_context) splits: SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter), segments: SplitIoClient::Cache::Repositories::SegmentsRepository.new(config), impressions: SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config), - events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer) + events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer, request_decorator) } end let(:parameters) do diff --git a/spec/sse/sse_handler_spec.rb b/spec/sse/sse_handler_spec.rb index e6a314dc..a071a4dd 100644 --- a/spec/sse/sse_handler_spec.rb +++ b/spec/sse/sse_handler_spec.rb @@ -6,6 +6,7 @@ describe SplitIoClient::SSE::SSEHandler do subject { SplitIoClient::SSE::SSEHandler } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:api_key) { 'SSEHandler-key' } let(:log) { StringIO.new } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log)) } @@ -21,13 +22,13 @@ splits: splits_repository, segments: segments_repository, impressions: SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config), - events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer) + events: SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer, request_decorator) } end let(:parameters) do { - split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer), - segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer), + split_fetcher: SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator), + segment_fetcher: SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator), imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, telemetry_runtime_producer: telemetry_runtime_producer } @@ -37,7 +38,7 @@ let(:segments_worker) { SplitIoClient::SSE::Workers::SegmentsWorker.new(synchronizer, config, segments_repository) } let(:notification_processor) { SplitIoClient::SSE::NotificationProcessor.new(config, splits_worker, segments_worker) } let(:event_parser) { SplitIoClient::SSE::EventSource::EventParser.new(config) } - let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue) } + let(:sse_client) { SplitIoClient::SSE::EventSource::Client.new(config, api_key, telemetry_runtime_producer, event_parser, notification_manager_keeper, notification_processor, push_status_queue, request_decorator) } it 'start - should connect' do mock_server do |server| diff --git a/spec/sse/workers/segments_worker_spec.rb b/spec/sse/workers/segments_worker_spec.rb index 37d6e868..e810e722 100644 --- a/spec/sse/workers/segments_worker_spec.rb +++ b/spec/sse/workers/segments_worker_spec.rb @@ -6,6 +6,7 @@ describe SplitIoClient::SSE::Workers::SegmentsWorker do subject { SplitIoClient::SSE::Workers::SegmentsWorker } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:splits) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json')) } let(:segment1) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment1.json')) } let(:segment2) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment2.json')) } @@ -19,9 +20,9 @@ let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:impressions_repository) { SplitIoClient::Cache::Repositories::ImpressionsRepository.new(config) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer) } + let(:events_repository) { SplitIoClient::Cache::Repositories::EventsRepository.new(config, api_key, telemetry_runtime_producer, request_decorator) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) } let(:repositories) { { splits: splits_repository, segments: segments_repository } } let(:impression_counter) { SplitIoClient::Engine::Common::ImpressionCounter.new } let(:params) { { split_fetcher: split_fetcher, segment_fetcher: segment_fetcher, imp_counter: impression_counter, telemetry_runtime_producer: telemetry_runtime_producer } } diff --git a/spec/sse/workers/splits_worker_spec.rb b/spec/sse/workers/splits_worker_spec.rb index 5cae7f59..c6b0d7bd 100644 --- a/spec/sse/workers/splits_worker_spec.rb +++ b/spec/sse/workers/splits_worker_spec.rb @@ -7,6 +7,7 @@ describe SplitIoClient::SSE::Workers::SplitsWorker do subject { SplitIoClient::SSE::Workers::SplitsWorker } + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:splits) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/splits.json')) } let(:segment1) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment1.json')) } let(:segment2) { File.read(File.join(SplitIoClient.root, 'spec/test_data/integrations/segment2.json')) } @@ -27,12 +28,12 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([])} let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:synchronizer) do - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) repositories = { splits: splits_repository, @@ -44,7 +45,7 @@ segment_fetcher: segment_fetcher, imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, impressions_sender_adapter: SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api), - impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) } SplitIoClient::Engine::Synchronizer.new(repositories, config, params) @@ -102,12 +103,12 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([])} let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:synchronizer) do - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) repositories = { splits: splits_repository, @@ -119,7 +120,7 @@ segment_fetcher: segment_fetcher, imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, impressions_sender_adapter: SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api), - impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) } SplitIoClient::Engine::Synchronizer.new(repositories, config, params) @@ -172,12 +173,12 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new(["set_1"])} let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:synchronizer) do - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) repositories = { splits: splits_repository, @@ -189,7 +190,7 @@ segment_fetcher: segment_fetcher, imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, impressions_sender_adapter: SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api), - impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) } SplitIoClient::Engine::Synchronizer.new(repositories, config, params) @@ -224,12 +225,12 @@ let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([])} let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) } let(:telemetry_runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } - let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer) } - let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer) } + let(:split_fetcher) { SplitIoClient::Cache::Fetchers::SplitFetcher.new(splits_repository, api_key, config, telemetry_runtime_producer, request_decorator) } + let(:segment_fetcher) { SplitIoClient::Cache::Fetchers::SegmentFetcher.new(segments_repository, api_key, config, telemetry_runtime_producer, request_decorator) } let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) } let(:synchronizer) do - telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer) - impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + telemetry_api = SplitIoClient::Api::TelemetryApi.new(config, api_key, telemetry_runtime_producer, request_decorator) + impressions_api = SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) repositories = { splits: splits_repository, @@ -241,7 +242,7 @@ segment_fetcher: segment_fetcher, imp_counter: SplitIoClient::Engine::Common::ImpressionCounter.new, impressions_sender_adapter: SplitIoClient::Cache::Senders::ImpressionsSenderAdapter.new(config, telemetry_api, impressions_api), - impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer) + impressions_api: SplitIoClient::Api::Impressions.new(api_key, config, telemetry_runtime_producer, request_decorator) } SplitIoClient::Engine::Synchronizer.new(repositories, config, params) diff --git a/spec/telemetry/synchronizer_spec.rb b/spec/telemetry/synchronizer_spec.rb index 18e67594..6e880adc 100644 --- a/spec/telemetry/synchronizer_spec.rb +++ b/spec/telemetry/synchronizer_spec.rb @@ -30,6 +30,7 @@ end context 'Memory' do + let(:request_decorator) { SplitIoClient::Api::RequestDecorator.new(nil) } let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(log)) } let(:evaluation_consumer) { SplitIoClient::Telemetry::EvaluationConsumer.new(config) } let(:init_consumer) { SplitIoClient::Telemetry::InitConsumer.new(config) } @@ -42,7 +43,7 @@ let(:runtime_producer) { SplitIoClient::Telemetry::RuntimeProducer.new(config) } let(:evaluation_producer) { SplitIoClient::Telemetry::EvaluationProducer.new(config) } let(:init_producer) { SplitIoClient::Telemetry::InitProducer.new(config) } - let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer) } + let(:telemetry_api) { SplitIoClient::Api::TelemetryApi.new(config, api_key, runtime_producer, request_decorator) } let(:telemetry_consumers) { { init: init_consumer, runtime: runtime_consumer, evaluation: evaluation_consumer } } let(:body_usage) { "{\"lS\":{\"sp\":111111222,\"se\":111111222,\"im\":111111222,\"ic\":111111222,\"ev\":111111222,\"te\":111111222,\"to\":111111222},\"mL\":{\"t\":[0,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ts\":[0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tc\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcs\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tf\":[0,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tfs\":[0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcf\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcfs\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tr\":[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"mE\":{\"t\":2,\"ts\":1,\"tc\":1,\"tcs\":0,\"tf\":2,\"tfs\":1,\"tcf\":1,\"tcfs\":0,\"tr\":1},\"hE\":{\"sp\":{},\"se\":{\"400\":1},\"im\":{},\"ic\":{},\"ev\":{\"500\":2,\"501\":1},\"te\":{},\"to\":{}},\"hL\":{\"sp\":[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"se\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"im\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ic\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ev\":[0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"te\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"to\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"tR\":1,\"aR\":1,\"iQ\":3,\"iDe\":1,\"iDr\":2,\"spC\":3,\"seC\":3,\"skC\":7,\"sL\":444555,\"eQ\":4,\"eD\":1,\"sE\":[{\"e\":50,\"d\":222222333,\"t\":222222333},{\"e\":70,\"d\":0,\"t\":222222333},{\"e\":70,\"d\":1,\"t\":222222333}],\"t\":[\"tag-1\",\"tag-2\"],\"ufs\":{\"sp\":5}}" } let(:empty_body_usage) { "{\"lS\":{\"sp\":0,\"se\":0,\"im\":0,\"ic\":0,\"ev\":0,\"te\":0,\"to\":0},\"mL\":{\"t\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ts\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tc\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcs\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tf\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tfs\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcf\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tcfs\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"tr\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"mE\":{\"t\":0,\"ts\":0,\"tc\":0,\"tcs\":0,\"tf\":0,\"tfs\":0,\"tcf\":0,\"tcfs\":0,\"tr\":0},\"hE\":{\"sp\":{},\"se\":{},\"im\":{},\"ic\":{},\"ev\":{},\"te\":{},\"to\":{}},\"hL\":{\"sp\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"se\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"im\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ic\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"ev\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"te\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"to\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"tR\":0,\"aR\":0,\"iQ\":0,\"iDe\":0,\"iDr\":0,\"spC\":0,\"seC\":0,\"skC\":0,\"sL\":0,\"eQ\":0,\"eD\":0,\"sE\":[],\"t\":[],\"ufs\":{\"sp\":0}}" } From 684cfdc450914220a4cc01bdad56ce0476dced70 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Thu, 11 Apr 2024 15:51:17 -0700 Subject: [PATCH 09/10] polish --- lib/splitclient-rb/engine/api/client.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/splitclient-rb/engine/api/client.rb b/lib/splitclient-rb/engine/api/client.rb index af1d804e..8238f7c4 100644 --- a/lib/splitclient-rb/engine/api/client.rb +++ b/lib/splitclient-rb/engine/api/client.rb @@ -48,7 +48,6 @@ def post_api(url, api_key, data, headers = {}, params = {}) end rescue StandardError => e @config.logger.warn("#{e}\nURL:#{url}\ndata:#{data}\nparams:#{params}") - puts e raise e, 'Split SDK failed to connect to backend to post information', e.backtrace end From 2a5879b7163a1b21afea80c3bbf2962c3b35cd23 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Thu, 11 Apr 2024 21:34:47 -0700 Subject: [PATCH 10/10] added validation error logging for header_override_callback config --- lib/splitclient-rb/split_config.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/splitclient-rb/split_config.rb b/lib/splitclient-rb/split_config.rb index 420fdce9..29578b59 100644 --- a/lib/splitclient-rb/split_config.rb +++ b/lib/splitclient-rb/split_config.rb @@ -124,7 +124,7 @@ def initialize(opts = {}) @flag_sets_filter = SplitConfig.sanitize_flag_set_filter(opts[:flag_sets_filter], @split_validator, opts[:cache_adapter], @logger) - @header_override_callback = SplitConfig.header_override_callback(opts[:header_override_callback]) + @header_override_callback = SplitConfig.header_override_callback(opts[:header_override_callback], @logger) startup_log end @@ -312,9 +312,12 @@ def initialize(opts = {}) # @return SplitIoClient::Api::CustomHeaderDecorator attr_accessor :header_override_callback - def self.header_override_callback(header_override_callback) - return header_override_callback if header_override_callback.class.method_defined? :get_header_overrides - nil + def self.header_override_callback(header_override_callback, logger) + if !header_override_callback.class.method_defined? :get_header_overrides + logger.error("Custom Header Override instance does not have required `get_header_overrides` method. Instance is ignored.") + return nil + end + header_override_callback end def self.default_counter_refresh_rate(adapter)