Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions lib/ldclient-rb/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Config
#
# @param opts [Hash] the configuration options
# @option opts [Logger] :logger See {#logger}.
# @option opts [String] :base_uri ("https://sdk.launchdarkly.com") See {#base_uri}.
# @option opts [String] :stream_uri ("https://stream.launchdarkly.com") See {#stream_uri}.
# @option opts [String] :events_uri ("https://events.launchdarkly.com") See {#events_uri}.
# @option opts [Integer] :capacity (10000) See {#capacity}.
# @option opts [Float] :flush_interval (30) See {#flush_interval}.
Expand All @@ -42,6 +44,8 @@ class Config
# @option plugins [Array<Interfaces::Plugins::Plugin]
#
def initialize(opts = {})
@base_uri = (opts[:base_uri] || Config.default_base_uri).chomp("/")
@stream_uri = (opts[:stream_uri] || Config.default_stream_uri).chomp("/")
@events_uri = (opts[:events_uri] || Config.default_events_uri).chomp("/")
@capacity = opts[:capacity] || Config.default_capacity
@logger = opts[:logger] || Config.default_logger
Expand Down Expand Up @@ -82,6 +86,22 @@ def initialize(opts = {})
#
attr_accessor :instance_id

#
# The base URL for the LaunchDarkly polling service. The polling data sources use it unless
# their builder sets a base URI. Set it to the URL of a Relay Proxy instance to get flag data
# from the Relay Proxy.
# @return [String]
#
attr_reader :base_uri

#
# The base URL for the LaunchDarkly streaming service. The streaming data source uses it unless
# its builder sets a base URI. Set it to the URL of a Relay Proxy instance to get flag data
# from the Relay Proxy.
# @return [String]
#
attr_reader :stream_uri

#
# The base URL for the LaunchDarkly events server. This is configurable mainly for testing
# purposes; most users should use the default value.
Expand Down Expand Up @@ -351,6 +371,22 @@ def self.default_capacity
10000
end

#
# The default value for {#base_uri}.
# @return [String] "https://sdk.launchdarkly.com"
#
def self.default_base_uri
DataSystem::PollingDataSourceBuilder::DEFAULT_BASE_URI
end

#
# The default value for {#stream_uri}.
# @return [String] "https://stream.launchdarkly.com"
#
def self.default_stream_uri
DataSystem::StreamingDataSourceBuilder::DEFAULT_BASE_URI
end

#
# The default value for {#events_uri}.
# @return [String] "https://events.launchdarkly.com"
Expand Down
12 changes: 12 additions & 0 deletions lib/ldclient-rb/data_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ module LaunchDarkly
# data_system: LaunchDarkly::DataSystem.polling
# )
#
# == Relay Proxy
#
# Every data source uses the URIs from the SDK configuration, unless its builder
# sets a base URI. To get data from a Relay Proxy instance, set the URIs in the
# SDK configuration:
#
# config = LaunchDarkly::Config.new(
# base_uri: "https://relay.example.com",
# stream_uri: "https://relay.example.com",
# events_uri: "https://relay.example.com"
# )
#
# == Custom Configurations
#
# For advanced use cases, you can build custom configurations using the
Expand Down
32 changes: 21 additions & 11 deletions lib/ldclient-rb/data_system/data_source_builder_common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ module DataSystem
# {FDv1PollingDataSourceBuilder}, and {StreamingDataSourceBuilder} to provide
# a consistent set of HTTP connection settings.
#
# Each builder that includes this module must define a +DEFAULT_BASE_URI+ constant
# which is used as the fallback when {#base_uri} has not been called.
# A setting that the builder does not set comes from the SDK configuration. The
# base URI comes from {LaunchDarkly::Config#base_uri} for the polling builders and
# from {LaunchDarkly::Config#stream_uri} for the streaming builder. The socket factory
# and the timeouts come from {LaunchDarkly::Config#socket_factory},
# {LaunchDarkly::Config#read_timeout} and {LaunchDarkly::Config#connect_timeout}.
#
# Each builder that includes this module must define a private +config_base_uri+
# method that returns the base URI from the SDK configuration.
#
module DataSourceBuilderCommon
#
# Sets the base URI for HTTP requests.
#
# Use this to point the SDK at a Relay Proxy instance or any other URI
# that implements the corresponding LaunchDarkly API.
# that implements the corresponding LaunchDarkly API. This value overrides
# the base URI in the SDK configuration.
#
# @param uri [String] The base URI (e.g. "https://relay.example.com")
# @return [self] the builder, for chaining
Expand All @@ -31,6 +38,7 @@ def base_uri(uri)

#
# Sets a custom socket factory for HTTP connections.
# This value overrides {LaunchDarkly::Config#socket_factory}.
#
# @param factory [#open] A socket factory that responds to +open+
# @return [self] the builder, for chaining
Expand All @@ -42,6 +50,7 @@ def socket_factory(factory)

#
# Sets the read timeout for HTTP connections.
# This value overrides {LaunchDarkly::Config#read_timeout}.
#
# @param timeout [Float] Timeout in seconds
# @return [self] the builder, for chaining
Expand All @@ -53,6 +62,7 @@ def read_timeout(timeout)

#
# Sets the connect timeout for HTTP connections.
# This value overrides {LaunchDarkly::Config#connect_timeout}.
#
# @param timeout [Float] Timeout in seconds
# @return [self] the builder, for chaining
Expand All @@ -63,18 +73,18 @@ def connect_timeout(timeout)
end

#
# Builds an HttpConfigOptions instance from the current builder settings.
# Uses +self.class::DEFAULT_BASE_URI+ if {#base_uri} was not explicitly set.
# Read/connect timeouts default to HttpConfigOptions defaults if not set.
# Builds an HttpConfigOptions instance from the builder settings. A setting
# that the builder does not set comes from the SDK configuration.
#
# @param config [LaunchDarkly::Config] the SDK configuration
# @return [LaunchDarkly::Impl::DataSystem::HttpConfigOptions]
#
private def build_http_config
private def build_http_config(config)
LaunchDarkly::Impl::DataSystem::HttpConfigOptions.new(
base_uri: (@base_uri || self.class::DEFAULT_BASE_URI).chomp("/"),
socket_factory: @socket_factory,
read_timeout: @read_timeout,
connect_timeout: @connect_timeout
base_uri: (@base_uri || config_base_uri(config)).chomp("/"),
socket_factory: @socket_factory || config.socket_factory,
read_timeout: @read_timeout || config.read_timeout,
connect_timeout: @connect_timeout || config.connect_timeout
)
end
end
Expand Down
12 changes: 10 additions & 2 deletions lib/ldclient-rb/data_system/polling_data_source_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@ def requester(requester)
# @return [LaunchDarkly::Impl::DataSystem::PollingDataSource]
#
def build(sdk_key, config)
http_opts = build_http_config
http_opts = build_http_config(config)
requester = @requester || LaunchDarkly::Impl::DataSystem::HTTPPollingRequester.new(sdk_key, http_opts, config)
LaunchDarkly::Impl::DataSystem::PollingDataSource.new(effective_poll_interval(config.logger), requester, config.logger)
end

private def config_base_uri(config)
config.base_uri
end
end

#
Expand Down Expand Up @@ -238,10 +242,14 @@ def requester(requester)
# @return [LaunchDarkly::Impl::DataSystem::PollingDataSource]
#
def build(sdk_key, config)
http_opts = build_http_config
http_opts = build_http_config(config)
requester = @requester || LaunchDarkly::Impl::DataSystem::HTTPFDv1PollingRequester.new(sdk_key, http_opts, config)
LaunchDarkly::Impl::DataSystem::PollingDataSource.new(effective_poll_interval(config.logger), requester, config.logger)
end

private def config_base_uri(config)
config.base_uri
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,17 @@ def initial_reconnect_delay(delay)
# @return [LaunchDarkly::Impl::DataSystem::StreamingDataSource]
#
def build(sdk_key, config)
http_opts = build_http_config
http_opts = build_http_config(config)
LaunchDarkly::Impl::DataSystem::StreamingDataSource.new(
sdk_key, http_opts,
@initial_reconnect_delay || DEFAULT_INITIAL_RECONNECT_DELAY,
config
)
end

private def config_base_uri(config)
config.stream_uri
end
end
end
end
16 changes: 16 additions & 0 deletions spec/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ module LaunchDarkly
expect(subject.new(capacity: 50).capacity).to eq 50
end
end
describe ".base_uri" do
it "defaults to the LaunchDarkly polling service" do
expect(subject.new.base_uri).to eq "https://sdk.launchdarkly.com"
end
it "can be set and removes a trailing slash" do
expect(subject.new(base_uri: "https://relay.example.com/").base_uri).to eq "https://relay.example.com"
end
end
describe ".stream_uri" do
it "defaults to the LaunchDarkly streaming service" do
expect(subject.new.stream_uri).to eq "https://stream.launchdarkly.com"
end
it "can be set and removes a trailing slash" do
expect(subject.new(stream_uri: "https://relay.example.com/").stream_uri).to eq "https://relay.example.com"
end
end
describe "@events_uri" do
it "can be read" do
expect(subject.new.events_uri).to eq subject.default_events_uri
Expand Down
73 changes: 73 additions & 0 deletions spec/data_system/data_source_builder_common_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

require "spec_helper"

module LaunchDarkly
module DataSystem
{
PollingDataSourceBuilder => :base_uri,
FDv1PollingDataSourceBuilder => :base_uri,
StreamingDataSourceBuilder => :stream_uri,
}.each do |builder_class, uri_option|
RSpec.describe builder_class do
let(:socket_factory) { double("socket factory") }

def http_config_of(builder, config)
http_config = nil
allow(Impl::DataSystem::HttpConfigOptions).to receive(:new).and_wrap_original do |original, **args|
http_config = original.call(**args)
end
builder.build("sdk-key", config)
http_config
end

it "uses the default URI and HTTP options" do
config = Config.new(logger: $null_log)
http_config = http_config_of(described_class.new, config)

expect(http_config.base_uri).to eq described_class::DEFAULT_BASE_URI
expect(http_config.socket_factory).to be_nil
expect(http_config.read_timeout).to eq Config.default_read_timeout
expect(http_config.connect_timeout).to eq Config.default_connect_timeout
end

it "uses the URI and HTTP options from the SDK configuration" do
config = Config.new(
logger: $null_log,
uri_option => "https://relay.example.com/",
socket_factory: socket_factory,
read_timeout: 15,
connect_timeout: 4
)
http_config = http_config_of(described_class.new, config)

expect(http_config.base_uri).to eq "https://relay.example.com"
expect(http_config.socket_factory).to be socket_factory
expect(http_config.read_timeout).to eq 15
expect(http_config.connect_timeout).to eq 4
end

it "uses the builder settings in place of the SDK configuration" do
config = Config.new(
logger: $null_log,
uri_option => "https://relay.example.com",
socket_factory: double("config socket factory"),
read_timeout: 15,
connect_timeout: 4
)
builder = described_class.new
.base_uri("https://builder.example.com/")
.socket_factory(socket_factory)
.read_timeout(20)
.connect_timeout(6)
http_config = http_config_of(builder, config)

expect(http_config.base_uri).to eq "https://builder.example.com"
expect(http_config.socket_factory).to be socket_factory
expect(http_config.read_timeout).to eq 20
expect(http_config.connect_timeout).to eq 6
end
end
end
end
end
11 changes: 1 addition & 10 deletions spec/impl/data_system/streaming_headers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,7 @@ module DataSystem
RSpec.describe "StreamingDataSource FDv1 fallback header detection" do
let(:logger) { double("Logger", info: nil, warn: nil, error: nil, debug: nil) }
let(:sdk_key) { "test-sdk-key" }
let(:config) do
double(
"Config",
logger: logger,
stream_uri: "https://stream.example.com",
socket_factory: nil,
initial_reconnect_delay: 1,
instance_id: nil
)
end
let(:config) { LaunchDarkly::Config.new(logger: logger, stream_uri: "https://stream.example.com") }

let(:synchronizer) { LaunchDarkly::DataSystem::StreamingDataSourceBuilder.new.build(sdk_key, config) }

Expand Down
11 changes: 1 addition & 10 deletions spec/impl/data_system/streaming_synchronizer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,7 @@ module DataSystem
RSpec.describe StreamingDataSource do
let(:logger) { double("Logger", info: nil, warn: nil, error: nil, debug: nil) }
let(:sdk_key) { "test-sdk-key" }
let(:config) do
double(
"Config",
logger: logger,
stream_uri: "https://stream.example.com",
socket_factory: nil,
initial_reconnect_delay: 1,
instance_id: nil
)
end
let(:config) { LaunchDarkly::Config.new(logger: logger, stream_uri: "https://stream.example.com") }

# Mock SSE event
class MockSSEEvent
Expand Down
Loading