launchdarkly-server-sdk 8.8.3-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +13 -0
  3. data/README.md +61 -0
  4. data/lib/launchdarkly-server-sdk.rb +1 -0
  5. data/lib/ldclient-rb/cache_store.rb +45 -0
  6. data/lib/ldclient-rb/config.rb +658 -0
  7. data/lib/ldclient-rb/context.rb +565 -0
  8. data/lib/ldclient-rb/evaluation_detail.rb +387 -0
  9. data/lib/ldclient-rb/events.rb +642 -0
  10. data/lib/ldclient-rb/expiring_cache.rb +77 -0
  11. data/lib/ldclient-rb/flags_state.rb +88 -0
  12. data/lib/ldclient-rb/impl/big_segments.rb +117 -0
  13. data/lib/ldclient-rb/impl/broadcaster.rb +78 -0
  14. data/lib/ldclient-rb/impl/context.rb +96 -0
  15. data/lib/ldclient-rb/impl/context_filter.rb +166 -0
  16. data/lib/ldclient-rb/impl/data_source.rb +188 -0
  17. data/lib/ldclient-rb/impl/data_store.rb +109 -0
  18. data/lib/ldclient-rb/impl/dependency_tracker.rb +102 -0
  19. data/lib/ldclient-rb/impl/diagnostic_events.rb +129 -0
  20. data/lib/ldclient-rb/impl/evaluation_with_hook_result.rb +34 -0
  21. data/lib/ldclient-rb/impl/evaluator.rb +539 -0
  22. data/lib/ldclient-rb/impl/evaluator_bucketing.rb +86 -0
  23. data/lib/ldclient-rb/impl/evaluator_helpers.rb +50 -0
  24. data/lib/ldclient-rb/impl/evaluator_operators.rb +131 -0
  25. data/lib/ldclient-rb/impl/event_sender.rb +100 -0
  26. data/lib/ldclient-rb/impl/event_summarizer.rb +68 -0
  27. data/lib/ldclient-rb/impl/event_types.rb +136 -0
  28. data/lib/ldclient-rb/impl/flag_tracker.rb +58 -0
  29. data/lib/ldclient-rb/impl/integrations/consul_impl.rb +170 -0
  30. data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +300 -0
  31. data/lib/ldclient-rb/impl/integrations/file_data_source.rb +229 -0
  32. data/lib/ldclient-rb/impl/integrations/redis_impl.rb +306 -0
  33. data/lib/ldclient-rb/impl/integrations/test_data/test_data_source.rb +40 -0
  34. data/lib/ldclient-rb/impl/migrations/migrator.rb +287 -0
  35. data/lib/ldclient-rb/impl/migrations/tracker.rb +136 -0
  36. data/lib/ldclient-rb/impl/model/clause.rb +45 -0
  37. data/lib/ldclient-rb/impl/model/feature_flag.rb +254 -0
  38. data/lib/ldclient-rb/impl/model/preprocessed_data.rb +64 -0
  39. data/lib/ldclient-rb/impl/model/segment.rb +132 -0
  40. data/lib/ldclient-rb/impl/model/serialization.rb +72 -0
  41. data/lib/ldclient-rb/impl/repeating_task.rb +46 -0
  42. data/lib/ldclient-rb/impl/sampler.rb +25 -0
  43. data/lib/ldclient-rb/impl/store_client_wrapper.rb +141 -0
  44. data/lib/ldclient-rb/impl/store_data_set_sorter.rb +55 -0
  45. data/lib/ldclient-rb/impl/unbounded_pool.rb +34 -0
  46. data/lib/ldclient-rb/impl/util.rb +95 -0
  47. data/lib/ldclient-rb/impl.rb +13 -0
  48. data/lib/ldclient-rb/in_memory_store.rb +100 -0
  49. data/lib/ldclient-rb/integrations/consul.rb +45 -0
  50. data/lib/ldclient-rb/integrations/dynamodb.rb +92 -0
  51. data/lib/ldclient-rb/integrations/file_data.rb +108 -0
  52. data/lib/ldclient-rb/integrations/redis.rb +98 -0
  53. data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +663 -0
  54. data/lib/ldclient-rb/integrations/test_data.rb +213 -0
  55. data/lib/ldclient-rb/integrations/util/store_wrapper.rb +246 -0
  56. data/lib/ldclient-rb/integrations.rb +6 -0
  57. data/lib/ldclient-rb/interfaces.rb +974 -0
  58. data/lib/ldclient-rb/ldclient.rb +822 -0
  59. data/lib/ldclient-rb/memoized_value.rb +32 -0
  60. data/lib/ldclient-rb/migrations.rb +230 -0
  61. data/lib/ldclient-rb/non_blocking_thread_pool.rb +46 -0
  62. data/lib/ldclient-rb/polling.rb +102 -0
  63. data/lib/ldclient-rb/reference.rb +295 -0
  64. data/lib/ldclient-rb/requestor.rb +102 -0
  65. data/lib/ldclient-rb/simple_lru_cache.rb +25 -0
  66. data/lib/ldclient-rb/stream.rb +196 -0
  67. data/lib/ldclient-rb/util.rb +132 -0
  68. data/lib/ldclient-rb/version.rb +3 -0
  69. data/lib/ldclient-rb.rb +27 -0
  70. metadata +400 -0
@@ -0,0 +1,92 @@
1
+ require "ldclient-rb/impl/integrations/dynamodb_impl"
2
+ require "ldclient-rb/integrations/util/store_wrapper"
3
+
4
+ module LaunchDarkly
5
+ module Integrations
6
+ #
7
+ # Integration with [DynamoDB](https://aws.amazon.com/dynamodb/).
8
+ #
9
+ # Note that in order to use this integration, you must first install one of the AWS SDK gems: either
10
+ # `aws-sdk-dynamodb`, or the full `aws-sdk`.
11
+ #
12
+ # @since 5.5.0
13
+ #
14
+ module DynamoDB
15
+ #
16
+ # Creates a DynamoDB-backed persistent feature store. For more details about how and why you can
17
+ # use a persistent feature store, see the
18
+ # [SDK reference guide](https://docs.launchdarkly.com/sdk/features/storing-data#ruby).
19
+ #
20
+ # To use this method, you must first install one of the AWS SDK gems: either `aws-sdk-dynamodb`, or
21
+ # the full `aws-sdk`. Then, put the object returned by this method into the `feature_store` property
22
+ # of your client configuration ({LaunchDarkly::Config}).
23
+ #
24
+ # @example Configuring the feature store
25
+ # store = LaunchDarkly::Integrations::DynamoDB::new_feature_store("my-table-name")
26
+ # config = LaunchDarkly::Config.new(feature_store: store)
27
+ # client = LaunchDarkly::LDClient.new(my_sdk_key, config)
28
+ #
29
+ # Note that the specified table must already exist in DynamoDB. It must have a partition key called
30
+ # "namespace", and a sort key called "key" (both strings). The SDK does not create the table
31
+ # automatically because it has no way of knowing what additional properties (such as permissions
32
+ # and throughput) you would want it to have.
33
+ #
34
+ # By default, the DynamoDB client will try to get your AWS credentials and region name from
35
+ # environment variables and/or local configuration files, as described in the AWS SDK documentation.
36
+ # You can also specify any supported AWS SDK options in `dynamodb_opts`-- or, provide an
37
+ # already-configured DynamoDB client in `existing_client`.
38
+ #
39
+ # @param table_name [String] name of an existing DynamoDB table
40
+ # @param opts [Hash] the configuration options
41
+ # @option opts [Hash] :dynamodb_opts options to pass to the DynamoDB client constructor (ignored if you specify `:existing_client`)
42
+ # @option opts [Object] :existing_client an already-constructed DynamoDB client for the feature store to use
43
+ # @option opts [String] :prefix namespace prefix to add to all keys used by LaunchDarkly
44
+ # @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
45
+ # @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching
46
+ # @option opts [Integer] :capacity (1000) maximum number of items in the cache
47
+ # @return [LaunchDarkly::Interfaces::FeatureStore] a feature store object
48
+ #
49
+ def self.new_feature_store(table_name, opts = {})
50
+ core = LaunchDarkly::Impl::Integrations::DynamoDB::DynamoDBFeatureStoreCore.new(table_name, opts)
51
+ LaunchDarkly::Integrations::Util::CachingStoreWrapper.new(core, opts)
52
+ end
53
+
54
+ #
55
+ # Creates a DynamoDB-backed Big Segment store.
56
+ #
57
+ # Big Segments are a specific type of segments. For more information, read the LaunchDarkly
58
+ # documentation: https://docs.launchdarkly.com/home/users/big-segments
59
+ #
60
+ # To use this method, you must first install one of the AWS SDK gems: either `aws-sdk-dynamodb`, or
61
+ # the full `aws-sdk`. Then, put the object returned by this method into the `store` property of your
62
+ # Big Segments configuration (see `Config`).
63
+ #
64
+ # @example Configuring Big Segments
65
+ # store = LaunchDarkly::Integrations::DynamoDB::new_big_segment_store("my-table-name")
66
+ # config = LaunchDarkly::Config.new(big_segments: LaunchDarkly::BigSegmentsConfig.new(store: store)
67
+ # client = LaunchDarkly::LDClient.new(my_sdk_key, config)
68
+ #
69
+ # Note that the specified table must already exist in DynamoDB. It must have a partition key called
70
+ # "namespace", and a sort key called "key" (both strings). The SDK does not create the table
71
+ # automatically because it has no way of knowing what additional properties (such as permissions
72
+ # and throughput) you would want it to have.
73
+ #
74
+ # By default, the DynamoDB client will try to get your AWS credentials and region name from
75
+ # environment variables and/or local configuration files, as described in the AWS SDK documentation.
76
+ # You can also specify any supported AWS SDK options in `dynamodb_opts`-- or, provide an
77
+ # already-configured DynamoDB client in `existing_client`.
78
+ #
79
+ # @param opts [Hash] the configuration options (these are all the same as for `new_feature_store`,
80
+ # except that there are no caching parameters)
81
+ # @option opts [Hash] :dynamodb_opts options to pass to the DynamoDB client constructor (ignored if you specify `:existing_client`)
82
+ # @option opts [Object] :existing_client an already-constructed DynamoDB client for the feature store to use
83
+ # @option opts [String] :prefix namespace prefix to add to all keys used by LaunchDarkly
84
+ # @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
85
+ # @return [LaunchDarkly::Interfaces::BigSegmentStore] a Big Segment store object
86
+ #
87
+ def self.new_big_segment_store(table_name, opts)
88
+ LaunchDarkly::Impl::Integrations::DynamoDB::DynamoDBBigSegmentStore.new(table_name, opts)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,108 @@
1
+ require 'ldclient-rb/impl/integrations/file_data_source'
2
+
3
+ module LaunchDarkly
4
+ module Integrations
5
+ #
6
+ # Provides a way to use local files as a source of feature flag state. This allows using a
7
+ # predetermined feature flag state without an actual LaunchDarkly connection.
8
+ #
9
+ # Reading flags from a file is only intended for pre-production environments. Production
10
+ # environments should always be configured to receive flag updates from LaunchDarkly.
11
+ #
12
+ # To use this component, call {FileData#data_source}, and store its return value in the
13
+ # {Config#data_source} property of your LaunchDarkly client configuration. In the options
14
+ # to `data_source`, set `paths` to the file path(s) of your data file(s):
15
+ #
16
+ # file_source = LaunchDarkly::Integrations::FileData.data_source(paths: [ myFilePath ])
17
+ # config = LaunchDarkly::Config.new(data_source: file_source)
18
+ #
19
+ # This will cause the client not to connect to LaunchDarkly to get feature flags. The
20
+ # client may still make network connections to send analytics events, unless you have disabled
21
+ # this with {Config#send_events} or {Config#offline?}.
22
+ #
23
+ # Flag data files can be either JSON or YAML. They contain an object with three possible
24
+ # properties:
25
+ #
26
+ # - `flags`: Feature flag definitions.
27
+ # - `flagValues`: Simplified feature flags that contain only a value.
28
+ # - `segments`: Context segment definitions.
29
+ #
30
+ # The format of the data in `flags` and `segments` is defined by the LaunchDarkly application
31
+ # and is subject to change. Rather than trying to construct these objects yourself, it is simpler
32
+ # to request existing flags directly from the LaunchDarkly server in JSON format, and use this
33
+ # output as the starting point for your file. In Linux you would do this:
34
+ #
35
+ # ```
36
+ # curl -H "Authorization: YOUR_SDK_KEY" https://sdk.launchdarkly.com/sdk/latest-all
37
+ # ```
38
+ #
39
+ # The output will look something like this (but with many more properties):
40
+ #
41
+ # {
42
+ # "flags": {
43
+ # "flag-key-1": {
44
+ # "key": "flag-key-1",
45
+ # "on": true,
46
+ # "variations": [ "a", "b" ]
47
+ # }
48
+ # },
49
+ # "segments": {
50
+ # "segment-key-1": {
51
+ # "key": "segment-key-1",
52
+ # "includes": [ "user-key-1" ]
53
+ # }
54
+ # }
55
+ # }
56
+ #
57
+ # Data in this format allows the SDK to exactly duplicate all the kinds of flag behavior supported
58
+ # by LaunchDarkly. However, in many cases you will not need this complexity, but will just want to
59
+ # set specific flag keys to specific values. For that, you can use a much simpler format:
60
+ #
61
+ # {
62
+ # "flagValues": {
63
+ # "my-string-flag-key": "value-1",
64
+ # "my-boolean-flag-key": true,
65
+ # "my-integer-flag-key": 3
66
+ # }
67
+ # }
68
+ #
69
+ # Or, in YAML:
70
+ #
71
+ # flagValues:
72
+ # my-string-flag-key: "value-1"
73
+ # my-boolean-flag-key: true
74
+ # my-integer-flag-key: 1
75
+ #
76
+ # It is also possible to specify both "flags" and "flagValues", if you want some flags
77
+ # to have simple values and others to have complex behavior. However, it is an error to use the
78
+ # same flag key or segment key more than once, either in a single file or across multiple files.
79
+ #
80
+ # If the data source encounters any error in any file-- malformed content, a missing file, or a
81
+ # duplicate key-- it will not load flags from any of the files.
82
+ #
83
+ module FileData
84
+ #
85
+ # Returns a factory for the file data source component.
86
+ #
87
+ # @param options [Hash] the configuration options
88
+ # @option options [Array] :paths The paths of the source files for loading flag data. These
89
+ # may be absolute paths or relative to the current working directory.
90
+ # @option options [Boolean] :auto_update True if the data source should watch for changes to
91
+ # the source file(s) and reload flags whenever there is a change. Auto-updating will only
92
+ # work if all of the files you specified have valid directory paths at startup time.
93
+ # Note that the default implementation of this feature is based on polling the filesystem,
94
+ # which may not perform well. If you install the 'listen' gem (not included by default, to
95
+ # avoid adding unwanted dependencies to the SDK), its native file watching mechanism will be
96
+ # used instead.
97
+ # @option options [Float] :poll_interval The minimum interval, in seconds, between checks for
98
+ # file modifications - used only if auto_update is true, and if the native file-watching
99
+ # mechanism from 'listen' is not being used. The default value is 1 second.
100
+ # @return an object that can be stored in {Config#data_source}
101
+ #
102
+ def self.data_source(options={})
103
+ lambda { |sdk_key, config|
104
+ Impl::Integrations::FileDataSourceImpl.new(config.feature_store, config.data_source_update_sink, config.logger, options) }
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,98 @@
1
+ require "ldclient-rb/impl/integrations/redis_impl"
2
+
3
+ module LaunchDarkly
4
+ module Integrations
5
+ #
6
+ # Integration with [Redis](https://redis.io/).
7
+ #
8
+ # Note that in order to use this integration, you must first install the `redis` and `connection-pool`
9
+ # gems.
10
+ #
11
+ # @since 5.5.0
12
+ #
13
+ module Redis
14
+ #
15
+ # Default value for the `redis_url` option for {new_feature_store}. This points to an instance of
16
+ # Redis running at `localhost` with its default port.
17
+ #
18
+ # @return [String] the default Redis URL
19
+ #
20
+ def self.default_redis_url
21
+ 'redis://localhost:6379/0'
22
+ end
23
+
24
+ #
25
+ # Default value for the `prefix` option for {new_feature_store}.
26
+ #
27
+ # @return [String] the default key prefix
28
+ #
29
+ def self.default_prefix
30
+ 'launchdarkly'
31
+ end
32
+
33
+ #
34
+ # Creates a Redis-backed persistent feature store. For more details about how and why you can
35
+ # use a persistent feature store, see the
36
+ # [SDK reference guide](https://docs.launchdarkly.com/sdk/features/storing-data#rubys).
37
+ #
38
+ # To use this method, you must first have the `redis` and `connection-pool` gems installed. Then,
39
+ # put the object returned by this method into the `feature_store` property of your
40
+ # client configuration.
41
+ #
42
+ # @example Configuring the feature store
43
+ # store = LaunchDarkly::Integrations::Redis::new_feature_store(redis_url: "redis://my-server")
44
+ # config = LaunchDarkly::Config.new(feature_store: store)
45
+ # client = LaunchDarkly::LDClient.new(my_sdk_key, config)
46
+ #
47
+ # @param opts [Hash] the configuration options
48
+ # @option opts [String] :redis_url (default_redis_url) URL of the Redis instance (shortcut for omitting `redis_opts`)
49
+ # @option opts [Hash] :redis_opts options to pass to the Redis constructor (if you want to specify more than just `redis_url`)
50
+ # @option opts [String] :prefix (default_prefix) namespace prefix to add to all hash keys used by LaunchDarkly
51
+ # @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
52
+ # @option opts [Integer] :max_connections size of the Redis connection pool
53
+ # @option opts [Integer] :expiration (15) expiration time for the in-memory cache, in seconds; 0 for no local caching
54
+ # @option opts [Integer] :capacity (1000) maximum number of items in the cache
55
+ # @option opts [Object] :pool custom connection pool, if desired
56
+ # @option opts [Boolean] :pool_shutdown_on_close whether calling `close` should shutdown the custom connection pool;
57
+ # this is true by default, and should be set to false only if you are managing the pool yourself and want its
58
+ # lifecycle to be independent of the SDK client
59
+ # @return [LaunchDarkly::Interfaces::FeatureStore] a feature store object
60
+ #
61
+ def self.new_feature_store(opts = {})
62
+ LaunchDarkly::Impl::Integrations::Redis::RedisFeatureStore.new(opts)
63
+ end
64
+
65
+ #
66
+ # Creates a Redis-backed Big Segment store.
67
+ #
68
+ # Big Segments are a specific type of segments. For more information, read the LaunchDarkly
69
+ # documentation: https://docs.launchdarkly.com/home/users/big-segments
70
+ #
71
+ # To use this method, you must first have the `redis` and `connection-pool` gems installed. Then,
72
+ # put the object returned by this method into the `store` property of your Big Segments configuration
73
+ # (see `Config`).
74
+ #
75
+ # @example Configuring Big Segments
76
+ # store = LaunchDarkly::Integrations::Redis::new_big_segment_store(redis_url: "redis://my-server")
77
+ # config = LaunchDarkly::Config.new(big_segments: LaunchDarkly::BigSegmentsConfig.new(store: store)
78
+ # client = LaunchDarkly::LDClient.new(my_sdk_key, config)
79
+ #
80
+ # @param opts [Hash] the configuration options (these are all the same as for `new_feature_store`,
81
+ # except that there are no caching parameters)
82
+ # @option opts [String] :redis_url (default_redis_url) URL of the Redis instance (shortcut for omitting `redis_opts`)
83
+ # @option opts [Hash] :redis_opts options to pass to the Redis constructor (if you want to specify more than just `redis_url`)
84
+ # @option opts [String] :prefix (default_prefix) namespace prefix to add to all hash keys used by LaunchDarkly
85
+ # @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
86
+ # @option opts [Integer] :max_connections size of the Redis connection pool
87
+ # @option opts [Object] :pool custom connection pool, if desired
88
+ # @option opts [Boolean] :pool_shutdown_on_close whether calling `close` should shutdown the custom connection pool;
89
+ # this is true by default, and should be set to false only if you are managing the pool yourself and want its
90
+ # lifecycle to be independent of the SDK client
91
+ # @return [LaunchDarkly::Interfaces::BigSegmentStore] a Big Segment store object
92
+ #
93
+ def self.new_big_segment_store(opts)
94
+ LaunchDarkly::Impl::Integrations::Redis::RedisBigSegmentStore.new(opts)
95
+ end
96
+ end
97
+ end
98
+ end