ff-ruby-server-sdk 0.0.2 → 1.0.2.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.run/sdk_test.rb.run.xml +3 -3
  3. data/CHANGELOG.md +12 -2
  4. data/Gemfile +17 -3
  5. data/README.md +155 -7
  6. data/api.yaml +736 -0
  7. data/example/example.rb +100 -3
  8. data/lib/ff/ruby/server/generated/lib/openapi_client/api/client_api.rb +545 -0
  9. data/lib/ff/ruby/server/generated/lib/openapi_client/api/metrics_api.rb +89 -0
  10. data/lib/ff/ruby/server/generated/lib/openapi_client/api_client.rb +390 -0
  11. data/lib/ff/ruby/server/generated/lib/openapi_client/api_error.rb +57 -0
  12. data/lib/ff/ruby/server/generated/lib/openapi_client/configuration.rb +282 -0
  13. data/lib/ff/ruby/server/generated/lib/openapi_client/models/authentication_request.rb +232 -0
  14. data/lib/ff/ruby/server/generated/lib/openapi_client/models/authentication_request_target.rb +250 -0
  15. data/lib/ff/ruby/server/generated/lib/openapi_client/models/authentication_response.rb +223 -0
  16. data/lib/ff/ruby/server/generated/lib/openapi_client/models/clause.rb +281 -0
  17. data/lib/ff/ruby/server/generated/lib/openapi_client/models/distribution.rb +239 -0
  18. data/lib/ff/ruby/server/generated/lib/openapi_client/models/error.rb +237 -0
  19. data/lib/ff/ruby/server/generated/lib/openapi_client/models/evaluation.rb +260 -0
  20. data/lib/ff/ruby/server/generated/lib/openapi_client/models/feature_config.rb +418 -0
  21. data/lib/ff/ruby/server/generated/lib/openapi_client/models/feature_state.rb +37 -0
  22. data/lib/ff/ruby/server/generated/lib/openapi_client/models/key_value.rb +237 -0
  23. data/lib/ff/ruby/server/generated/lib/openapi_client/models/metrics.rb +231 -0
  24. data/lib/ff/ruby/server/generated/lib/openapi_client/models/metrics_data.rb +303 -0
  25. data/lib/ff/ruby/server/generated/lib/openapi_client/models/pagination.rb +274 -0
  26. data/lib/ff/ruby/server/generated/lib/openapi_client/models/prerequisite.rb +239 -0
  27. data/lib/ff/ruby/server/generated/lib/openapi_client/models/segment.rb +320 -0
  28. data/lib/ff/ruby/server/generated/lib/openapi_client/models/serve.rb +227 -0
  29. data/lib/ff/ruby/server/generated/lib/openapi_client/models/serving_rule.rb +267 -0
  30. data/lib/ff/ruby/server/generated/lib/openapi_client/models/tag.rb +233 -0
  31. data/lib/ff/ruby/server/generated/lib/openapi_client/models/target.rb +331 -0
  32. data/lib/ff/ruby/server/generated/lib/openapi_client/models/target_data.rb +253 -0
  33. data/lib/ff/ruby/server/generated/lib/openapi_client/models/target_map.rb +232 -0
  34. data/lib/ff/ruby/server/generated/lib/openapi_client/models/variation.rb +255 -0
  35. data/lib/ff/ruby/server/generated/lib/openapi_client/models/variation_map.rb +245 -0
  36. data/lib/ff/ruby/server/generated/lib/openapi_client/models/weighted_variation.rb +237 -0
  37. data/lib/ff/ruby/server/generated/lib/openapi_client/version.rb +15 -0
  38. data/lib/ff/ruby/server/generated/lib/openapi_client.rb +65 -0
  39. data/lib/ff/ruby/server/sdk/api/auth_service.rb +91 -0
  40. data/lib/ff/ruby/server/sdk/api/cf_client.rb +93 -0
  41. data/lib/ff/ruby/server/sdk/api/client_callback.rb +45 -0
  42. data/lib/ff/ruby/server/sdk/api/config.rb +140 -0
  43. data/lib/ff/ruby/server/sdk/api/config_builder.rb +116 -0
  44. data/lib/ff/ruby/server/sdk/api/default_cache.rb +112 -0
  45. data/lib/ff/ruby/server/sdk/api/evaluation.rb +29 -0
  46. data/lib/ff/ruby/server/sdk/api/evaluator.rb +526 -0
  47. data/lib/ff/ruby/server/sdk/api/file_map_store.rb +60 -0
  48. data/lib/ff/ruby/server/sdk/api/flag_evaluate_callback.rb +13 -0
  49. data/lib/ff/ruby/server/sdk/api/inner_client.rb +311 -0
  50. data/lib/ff/ruby/server/sdk/api/inner_client_flag_evaluate_callback.rb +30 -0
  51. data/lib/ff/ruby/server/sdk/api/inner_client_metrics_callback.rb +33 -0
  52. data/lib/ff/ruby/server/sdk/api/inner_client_repository_callback.rb +44 -0
  53. data/lib/ff/ruby/server/sdk/api/inner_client_updater.rb +63 -0
  54. data/lib/ff/ruby/server/sdk/api/metrics_callback.rb +19 -0
  55. data/lib/ff/ruby/server/sdk/api/metrics_event.rb +16 -0
  56. data/lib/ff/ruby/server/sdk/api/metrics_processor.rb +297 -0
  57. data/lib/ff/ruby/server/sdk/api/operators.rb +20 -0
  58. data/lib/ff/ruby/server/sdk/api/polling_processor.rb +164 -0
  59. data/lib/ff/ruby/server/sdk/api/repository_callback.rb +28 -0
  60. data/lib/ff/ruby/server/sdk/api/storage_repository.rb +263 -0
  61. data/lib/ff/ruby/server/sdk/api/summary_metrics.rb +16 -0
  62. data/lib/ff/ruby/server/sdk/api/update_processor.rb +149 -0
  63. data/lib/ff/ruby/server/sdk/common/cache.rb +27 -0
  64. data/lib/ff/ruby/server/sdk/common/closeable.rb +7 -0
  65. data/lib/ff/ruby/server/sdk/common/destroyable.rb +12 -0
  66. data/lib/ff/ruby/server/sdk/common/repository.rb +45 -0
  67. data/lib/ff/ruby/server/sdk/common/storage.rb +29 -0
  68. data/lib/ff/ruby/server/sdk/connector/connector.rb +44 -0
  69. data/lib/ff/ruby/server/sdk/connector/events.rb +118 -0
  70. data/lib/ff/ruby/server/sdk/connector/harness_connector.rb +236 -0
  71. data/lib/ff/ruby/server/sdk/connector/service.rb +19 -0
  72. data/lib/ff/ruby/server/sdk/connector/updater.rb +32 -0
  73. data/lib/ff/ruby/server/sdk/dto/message.rb +13 -0
  74. data/lib/ff/ruby/server/sdk/dto/target.rb +24 -0
  75. data/lib/ff/ruby/server/sdk/version.rb +2 -1
  76. data/lib/ff/ruby/server/sdk.rb +39 -3
  77. data/openapitools.json +7 -0
  78. data/scripts/install.sh +8 -2
  79. data/scripts/openapi.sh +76 -0
  80. data/scripts/publish.sh +1 -1
  81. data/scripts/sdk_specs.sh +1 -1
  82. metadata +263 -11
  83. data/lib/ff/ruby/server/sdk/cf_client.rb +0 -6
@@ -0,0 +1,311 @@
1
+ require_relative "evaluator"
2
+ require_relative "evaluation"
3
+ require_relative "auth_service"
4
+ require_relative "client_callback"
5
+ require_relative "update_processor"
6
+ require_relative "polling_processor"
7
+ require_relative "metrics_processor"
8
+ require_relative "storage_repository"
9
+ require_relative "inner_client_updater"
10
+ require_relative "inner_client_metrics_callback"
11
+ require_relative "inner_client_repository_callback"
12
+ require_relative "inner_client_flag_evaluate_callback"
13
+
14
+ require_relative "../connector/harness_connector"
15
+
16
+ class InnerClient < ClientCallback
17
+
18
+ def initialize(api_key = nil, config = nil, connector = nil)
19
+
20
+ if api_key == nil || api_key == ""
21
+
22
+ raise "SDK key is not provided"
23
+ end
24
+
25
+ if config == nil
26
+
27
+ @config = ConfigBuilder.new.build
28
+ else
29
+
30
+ unless config.kind_of?(Config)
31
+
32
+ raise "The 'config' parameter must be of '" + Config.to_s + "' data type"
33
+ end
34
+
35
+ @config = config
36
+ end
37
+
38
+ @config.logger.debug "Ruby SDK version: " + Ff::Ruby::Server::Sdk::VERSION
39
+
40
+ if connector == nil
41
+
42
+ @connector = HarnessConnector.new(api_key, config = @config, on_unauthorized = self)
43
+
44
+ else
45
+
46
+ unless connector.kind_of?(Connector)
47
+
48
+ raise "The 'connector' parameter must be of '" + Connector.to_s + "' data type"
49
+ end
50
+
51
+ @connector = connector
52
+ end
53
+
54
+ @closing = false
55
+ @failure = false
56
+ @initialized = false
57
+ @poller_ready = false
58
+ @stream_ready = false
59
+ @metrics_ready = false
60
+
61
+ @my_mutex = Mutex.new
62
+
63
+ @repository_callback = InnerClientRepositoryCallback.new(@config.logger)
64
+
65
+ setup
66
+ end
67
+
68
+ def bool_variation(identifier, target, default_value)
69
+
70
+ @evaluator.bool_variation(identifier, target, default_value, @evaluator_callback)
71
+ end
72
+
73
+ def string_variation(identifier, target, default_value)
74
+
75
+ @evaluator.string_variation(identifier, target, default_value, @evaluator_callback)
76
+ end
77
+
78
+ def number_variation(identifier, target, default_value)
79
+
80
+ @evaluator.number_variation(identifier, target, default_value, @evaluator_callback)
81
+ end
82
+
83
+ def json_variation(identifier, target, default_value)
84
+
85
+ @evaluator.json_variation(identifier, target, default_value, @evaluator_callback)
86
+ end
87
+
88
+ def on_auth_success
89
+
90
+ @config.logger.info "SDK successfully logged in"
91
+
92
+ if @closing
93
+
94
+ return
95
+ end
96
+
97
+ @poll_processor.start
98
+
99
+ if @config.stream_enabled
100
+
101
+ @update_processor.start
102
+ end
103
+
104
+ if @config.analytics_enabled
105
+
106
+ @metrics_processor.start
107
+ end
108
+
109
+ end
110
+
111
+ def close
112
+
113
+ @config.logger.info "Closing the client: " + self.to_s
114
+
115
+ @closing = true
116
+
117
+ off
118
+
119
+ @auth_service.close
120
+ @repository.close
121
+ @poll_processor.close
122
+ @update_processor.close
123
+ @metrics_processor.close
124
+ @connector.close
125
+ end
126
+
127
+ def is_closing
128
+
129
+ @closing
130
+ end
131
+
132
+ def off
133
+
134
+ # TODO: Implement - Reactivity support
135
+ end
136
+
137
+ def on_unauthorized
138
+
139
+ if @closing
140
+
141
+ return
142
+ end
143
+
144
+ @poll_processor.stop
145
+
146
+ if @config.stream_enabled
147
+
148
+ @update_processor.stop
149
+ end
150
+
151
+ if @config.analytics_enabled
152
+
153
+ @metrics_processor.stop
154
+ end
155
+
156
+ @auth_service.start_async
157
+ end
158
+
159
+ def on_poller_ready(poller)
160
+
161
+ on_processor_ready(poller)
162
+ end
163
+
164
+ def on_poller_error(e)
165
+
166
+ @config.logger.error "Poller error: " + e.to_s
167
+ end
168
+
169
+ def on_poller_iteration(poller)
170
+
171
+ @config.logger.debug "Poller iterated" + poller.to_s
172
+ end
173
+
174
+ def update(message, manual)
175
+
176
+ if @config.stream_enabled && manual
177
+
178
+ @config.logger.warn "You run the update method manually with the stream enabled. Please turn off the stream in this case."
179
+ end
180
+
181
+ @update_processor.update(message)
182
+ end
183
+
184
+ def on_update_processor_ready
185
+
186
+ on_processor_ready(@update_processor)
187
+ end
188
+
189
+ def on_metrics_processor_ready
190
+
191
+ on_processor_ready(@metrics_processor)
192
+ end
193
+
194
+ def on_processor_ready(processor)
195
+
196
+ if @closing
197
+
198
+ return
199
+ end
200
+
201
+ if processor == @poll_processor
202
+
203
+ @poller_ready = true
204
+ @config.logger.info "PollingProcessor ready"
205
+ end
206
+
207
+ if processor == @update_processor
208
+
209
+ @stream_ready = true
210
+ @config.logger.info "Updater ready"
211
+ end
212
+
213
+ if processor == @metrics_processor
214
+
215
+ @metrics_ready = true
216
+ @config.logger.info "Metrics ready"
217
+ end
218
+
219
+ if (@config.stream_enabled && !@stream_ready) ||
220
+ (@config.analytics_enabled && !@metrics_ready) ||
221
+ !@poller_ready
222
+
223
+ return
224
+ end
225
+
226
+ @initialized = true
227
+
228
+ # TODO: notify - Reactivity support
229
+ # TODO: notify_consumers - Reactivity support
230
+
231
+ @config.logger.info "Initialization is completed"
232
+ end
233
+
234
+ def wait_for_initialization
235
+
236
+ synchronize do
237
+
238
+ @config.logger.info "Waiting for the initialization to finish"
239
+
240
+ until @initialized
241
+
242
+ sleep(1)
243
+ end
244
+
245
+ if @failure
246
+
247
+ raise "Initialization failed"
248
+ end
249
+
250
+ @config.logger.info "Waiting for the initialization completed"
251
+ end
252
+ end
253
+
254
+ protected
255
+
256
+ def setup
257
+
258
+ @config.logger.info "SDK is not initialized yet! If store is used then values will be loaded from store" +
259
+ " otherwise default values will be used in meantime. You can use waitForInitialization method for SDK" +
260
+ " to be ready."
261
+
262
+ @repository = StorageRepository.new(@config.cache, @repository_callback, @config.store, @config.logger)
263
+
264
+ @metrics_callback = InnerClientMetricsCallback.new(self, @config.logger)
265
+ @metrics_processor = MetricsProcessor.new(@connector, @config, @metrics_callback)
266
+
267
+ @evaluator = Evaluator.new(@repository, logger = @config.logger)
268
+ @evaluator_callback = InnerClientFlagEvaluateCallback.new(@metrics_processor, logger = @config.logger)
269
+
270
+ @auth_service = AuthService.new(
271
+
272
+ connector = @connector,
273
+ poll_interval_in_sec = @config.poll_interval_in_seconds,
274
+ callback = self,
275
+ logger = @config.logger
276
+ )
277
+
278
+ @poll_processor = PollingProcessor.new(
279
+
280
+ connector = @connector,
281
+ repository = @repository,
282
+ poll_interval_in_sec = @config.poll_interval_in_seconds,
283
+ callback = self,
284
+ logger = @config.logger
285
+ )
286
+
287
+ @updater = InnerClientUpdater.new(
288
+
289
+ poll_processor = @poll_processor,
290
+ client_callback = self,
291
+ logger = @config.logger
292
+ )
293
+
294
+ @update_processor = UpdateProcessor.new(
295
+
296
+ connector = @connector,
297
+ repository = @repository,
298
+ callback = @updater,
299
+ logger = @config.logger
300
+ )
301
+
302
+ @auth_service.start_async
303
+ end
304
+
305
+ private
306
+
307
+ def synchronize(&block)
308
+
309
+ @my_mutex.synchronize(&block)
310
+ end
311
+ end
@@ -0,0 +1,30 @@
1
+ require_relative "metrics_processor"
2
+ require_relative "flag_evaluate_callback"
3
+
4
+ class InnerClientFlagEvaluateCallback < FlagEvaluateCallback
5
+
6
+ def initialize(metrics_processor, logger = nil)
7
+
8
+ unless metrics_processor.kind_of?(MetricsProcessor)
9
+
10
+ raise "The 'metrics_processor' parameter must be of '" + MetricsProcessor.to_s + "' data type"
11
+ end
12
+
13
+ if logger != nil
14
+
15
+ @logger = logger
16
+ else
17
+
18
+ @logger = Logger.new(STDOUT)
19
+ end
20
+
21
+ @metrics_processor = metrics_processor
22
+ end
23
+
24
+ def process_evaluation(feature_config, target, variation)
25
+
26
+ @logger.debug "Processing evaluation: " + feature_config.feature.to_s + ", " + target.identifier.to_s
27
+
28
+ @metrics_processor.push_to_queue(target, feature_config, variation)
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "client_callback"
2
+ require_relative "metrics_callback"
3
+
4
+ class InnerClientMetricsCallback < MetricsCallback
5
+
6
+ def initialize(client_callback, logger = nil)
7
+
8
+ unless client_callback.kind_of?(ClientCallback)
9
+
10
+ raise "The 'client_callback' parameter must be of '" + ClientCallback.to_s + "' data type"
11
+ end
12
+
13
+ if logger != nil
14
+
15
+ @logger = logger
16
+ else
17
+
18
+ @logger = Logger.new(STDOUT)
19
+ end
20
+
21
+ @client_callback = client_callback
22
+ end
23
+
24
+ def on_metrics_ready
25
+
26
+ @client_callback.on_metrics_processor_ready
27
+ end
28
+
29
+ def on_metrics_error(error)
30
+
31
+ @logger.error "Metrics error: " + error.to_s
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ require_relative "inner_client"
2
+ require_relative "repository_callback"
3
+
4
+ class InnerClientRepositoryCallback < RepositoryCallback
5
+
6
+ def initialize(logger = nil)
7
+
8
+ if logger != nil
9
+
10
+ @logger = logger
11
+ else
12
+
13
+ @logger = Logger.new(STDOUT)
14
+ end
15
+ end
16
+
17
+ def on_flag_stored(identifier)
18
+
19
+ @logger.debug "On flag stored: " + identifier
20
+
21
+ # TODO: Notify consumers
22
+ end
23
+
24
+ def on_flag_deleted(identifier)
25
+
26
+ @logger.debug "On flag deleted: " + identifier
27
+
28
+ # TODO: Notify consumers
29
+ end
30
+
31
+ def on_segment_stored(identifier)
32
+
33
+ @logger.debug "On segment stored: " + identifier
34
+
35
+ # TODO: Notify consumers
36
+ end
37
+
38
+ def on_segment_deleted(identifier)
39
+
40
+ @logger.debug "On segment deleted: " + identifier
41
+
42
+ # TODO: Notify consumers
43
+ end
44
+ end
@@ -0,0 +1,63 @@
1
+ require "logger"
2
+
3
+ require_relative "../connector/updater"
4
+
5
+ class InnerClientUpdater < Updater
6
+
7
+ def initialize(
8
+
9
+ poll_processor,
10
+ client_callback,
11
+ logger = nil
12
+ )
13
+
14
+ unless poll_processor.kind_of?(PollingProcessor)
15
+
16
+ raise "The 'poll_processor' parameter must be of '" + PollingProcessor.to_s + "' data type"
17
+ end
18
+
19
+ unless client_callback.kind_of?(ClientCallback)
20
+
21
+ raise "The 'client_callback' parameter must be of '" + ClientCallback.to_s + "' data type"
22
+ end
23
+
24
+ if logger != nil
25
+
26
+ @logger = logger
27
+ else
28
+
29
+ @logger = Logger.new(STDOUT)
30
+ end
31
+
32
+ @poll_processor = poll_processor
33
+ @client_callback = client_callback
34
+ end
35
+
36
+ def on_connected
37
+
38
+ @poll_processor.stop
39
+ end
40
+
41
+ def on_disconnected
42
+
43
+ unless @client_callback.is_closing
44
+
45
+ @poll_processor.start
46
+ end
47
+ end
48
+
49
+ def on_ready
50
+
51
+ @client_callback.on_update_processor_ready()
52
+ end
53
+
54
+ def on_error
55
+
56
+ @logger.error "Error occurred"
57
+ end
58
+
59
+ def update(message)
60
+
61
+ @client_callback.update(message, false)
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+
2
+ class MetricsCallback
3
+
4
+ def initialize
5
+ super
6
+
7
+ @tbi = "To be implemented"
8
+ end
9
+
10
+ def on_metrics_ready
11
+
12
+ raise @tbi
13
+ end
14
+
15
+ def on_metrics_error(error)
16
+
17
+ raise @tbi
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ class MetricsEvent
2
+
3
+ attr_accessor :feature_config, :target, :variation
4
+
5
+ def initialize(
6
+
7
+ feature_config,
8
+ target,
9
+ variation
10
+ )
11
+
12
+ @target = target
13
+ @variation = variation
14
+ @feature_config = feature_config
15
+ end
16
+ end