optimizely-sdk 5.0.0.pre.beta → 5.0.1

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +202 -202
  3. data/lib/optimizely/audience.rb +127 -127
  4. data/lib/optimizely/bucketer.rb +156 -156
  5. data/lib/optimizely/condition_tree_evaluator.rb +123 -123
  6. data/lib/optimizely/config/datafile_project_config.rb +48 -32
  7. data/lib/optimizely/config/proxy_config.rb +34 -34
  8. data/lib/optimizely/config_manager/async_scheduler.rb +95 -95
  9. data/lib/optimizely/config_manager/http_project_config_manager.rb +340 -338
  10. data/lib/optimizely/config_manager/project_config_manager.rb +25 -25
  11. data/lib/optimizely/config_manager/static_project_config_manager.rb +55 -54
  12. data/lib/optimizely/decide/optimizely_decide_option.rb +28 -28
  13. data/lib/optimizely/decide/optimizely_decision.rb +60 -60
  14. data/lib/optimizely/decide/optimizely_decision_message.rb +26 -26
  15. data/lib/optimizely/decision_service.rb +563 -563
  16. data/lib/optimizely/error_handler.rb +39 -39
  17. data/lib/optimizely/event/batch_event_processor.rb +235 -235
  18. data/lib/optimizely/event/entity/conversion_event.rb +44 -44
  19. data/lib/optimizely/event/entity/decision.rb +38 -38
  20. data/lib/optimizely/event/entity/event_batch.rb +86 -86
  21. data/lib/optimizely/event/entity/event_context.rb +50 -50
  22. data/lib/optimizely/event/entity/impression_event.rb +48 -48
  23. data/lib/optimizely/event/entity/snapshot.rb +33 -33
  24. data/lib/optimizely/event/entity/snapshot_event.rb +48 -48
  25. data/lib/optimizely/event/entity/user_event.rb +22 -22
  26. data/lib/optimizely/event/entity/visitor.rb +36 -36
  27. data/lib/optimizely/event/entity/visitor_attribute.rb +38 -38
  28. data/lib/optimizely/event/event_factory.rb +156 -156
  29. data/lib/optimizely/event/event_processor.rb +25 -25
  30. data/lib/optimizely/event/forwarding_event_processor.rb +44 -44
  31. data/lib/optimizely/event/user_event_factory.rb +88 -88
  32. data/lib/optimizely/event_builder.rb +221 -221
  33. data/lib/optimizely/event_dispatcher.rb +69 -69
  34. data/lib/optimizely/exceptions.rb +193 -149
  35. data/lib/optimizely/helpers/constants.rb +459 -459
  36. data/lib/optimizely/helpers/date_time_utils.rb +30 -30
  37. data/lib/optimizely/helpers/event_tag_utils.rb +132 -132
  38. data/lib/optimizely/helpers/group.rb +31 -31
  39. data/lib/optimizely/helpers/http_utils.rb +68 -68
  40. data/lib/optimizely/helpers/sdk_settings.rb +61 -61
  41. data/lib/optimizely/helpers/validator.rb +236 -238
  42. data/lib/optimizely/helpers/variable_type.rb +67 -67
  43. data/lib/optimizely/logger.rb +46 -46
  44. data/lib/optimizely/notification_center.rb +174 -174
  45. data/lib/optimizely/notification_center_registry.rb +71 -71
  46. data/lib/optimizely/odp/lru_cache.rb +114 -114
  47. data/lib/optimizely/odp/odp_config.rb +102 -102
  48. data/lib/optimizely/odp/odp_event.rb +75 -75
  49. data/lib/optimizely/odp/odp_event_api_manager.rb +70 -70
  50. data/lib/optimizely/odp/odp_event_manager.rb +286 -286
  51. data/lib/optimizely/odp/odp_manager.rb +159 -159
  52. data/lib/optimizely/odp/odp_segment_api_manager.rb +122 -122
  53. data/lib/optimizely/odp/odp_segment_manager.rb +97 -97
  54. data/lib/optimizely/optimizely_config.rb +273 -271
  55. data/lib/optimizely/optimizely_factory.rb +184 -186
  56. data/lib/optimizely/optimizely_user_context.rb +238 -238
  57. data/lib/optimizely/params.rb +31 -31
  58. data/lib/optimizely/project_config.rb +99 -99
  59. data/lib/optimizely/semantic_version.rb +166 -166
  60. data/lib/optimizely/user_condition_evaluator.rb +391 -391
  61. data/lib/optimizely/user_profile_service.rb +35 -35
  62. data/lib/optimizely/version.rb +21 -21
  63. data/lib/optimizely.rb +1262 -1262
  64. metadata +12 -10
@@ -1,123 +1,123 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2019, 2022, Optimizely and contributors
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- module Optimizely
19
- module ConditionTreeEvaluator
20
- # Operator types
21
- AND_CONDITION = 'and'
22
- OR_CONDITION = 'or'
23
- NOT_CONDITION = 'not'
24
-
25
- EVALUATORS_BY_OPERATOR_TYPE = {
26
- AND_CONDITION => :and_evaluator,
27
- OR_CONDITION => :or_evaluator,
28
- NOT_CONDITION => :not_evaluator
29
- }.freeze
30
-
31
- OPERATORS = [AND_CONDITION, OR_CONDITION, NOT_CONDITION].freeze
32
-
33
- module_function
34
-
35
- def evaluate(conditions, leaf_evaluator)
36
- # Top level method to evaluate audience conditions.
37
- #
38
- # conditions - Nested array of and/or conditions.
39
- # Example: ['and', operand_1, ['or', operand_2, operand_3]]
40
- #
41
- # leaf_evaluator - Function which will be called to evaluate leaf condition values.
42
- #
43
- # Returns boolean if the given user attributes match/don't match the given conditions,
44
- # nil if the given conditions are invalid or can't be evaluated.
45
-
46
- if conditions.is_a? Array
47
- first_operator = conditions[0]
48
- rest_of_conditions = conditions[1..]
49
-
50
- # Operator to apply is not explicit - assume 'or'
51
- unless EVALUATORS_BY_OPERATOR_TYPE.include?(conditions[0])
52
- first_operator = OR_CONDITION
53
- rest_of_conditions = conditions
54
- end
55
-
56
- return send(EVALUATORS_BY_OPERATOR_TYPE[first_operator], rest_of_conditions, leaf_evaluator)
57
- end
58
-
59
- leaf_evaluator.call(conditions)
60
- end
61
-
62
- def and_evaluator(conditions, leaf_evaluator)
63
- # Evaluates an array of conditions as if the evaluator had been applied
64
- # to each entry and the results AND-ed together.
65
- #
66
- # conditions - Array of conditions ex: [operand_1, operand_2]
67
- #
68
- # leaf_evaluator - Function which will be called to evaluate leaf condition values.
69
- #
70
- # Returns boolean if the user attributes match/don't match the given conditions,
71
- # nil if the user attributes and conditions can't be evaluated.
72
-
73
- found_nil = false
74
- conditions.each do |condition|
75
- result = evaluate(condition, leaf_evaluator)
76
- return result if result == false
77
-
78
- found_nil = true if result.nil?
79
- end
80
-
81
- found_nil ? nil : true
82
- end
83
-
84
- def not_evaluator(single_condition, leaf_evaluator)
85
- # Evaluates an array of conditions as if the evaluator had been applied
86
- # to a single entry and NOT was applied to the result.
87
- #
88
- # single_condition - Array of a single condition ex: [operand_1]
89
- #
90
- # leaf_evaluator - Function which will be called to evaluate leaf condition values.
91
- #
92
- # Returns boolean if the user attributes match/don't match the given conditions,
93
- # nil if the user attributes and conditions can't be evaluated.
94
-
95
- return nil if single_condition.empty?
96
-
97
- result = evaluate(single_condition[0], leaf_evaluator)
98
- result.nil? ? nil : !result
99
- end
100
-
101
- def or_evaluator(conditions, leaf_evaluator)
102
- # Evaluates an array of conditions as if the evaluator had been applied
103
- # to each entry and the results OR-ed together.
104
- #
105
- # conditions - Array of conditions ex: [operand_1, operand_2]
106
- #
107
- # leaf_evaluator - Function which will be called to evaluate leaf condition values.
108
- #
109
- # Returns boolean if the user attributes match/don't match the given conditions,
110
- # nil if the user attributes and conditions can't be evaluated.
111
-
112
- found_nil = false
113
- conditions.each do |condition|
114
- result = evaluate(condition, leaf_evaluator)
115
- return result if result == true
116
-
117
- found_nil = true if result.nil?
118
- end
119
-
120
- found_nil ? nil : false
121
- end
122
- end
123
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2019, 2022, Optimizely and contributors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module Optimizely
19
+ module ConditionTreeEvaluator
20
+ # Operator types
21
+ AND_CONDITION = 'and'
22
+ OR_CONDITION = 'or'
23
+ NOT_CONDITION = 'not'
24
+
25
+ EVALUATORS_BY_OPERATOR_TYPE = {
26
+ AND_CONDITION => :and_evaluator,
27
+ OR_CONDITION => :or_evaluator,
28
+ NOT_CONDITION => :not_evaluator
29
+ }.freeze
30
+
31
+ OPERATORS = [AND_CONDITION, OR_CONDITION, NOT_CONDITION].freeze
32
+
33
+ module_function
34
+
35
+ def evaluate(conditions, leaf_evaluator)
36
+ # Top level method to evaluate audience conditions.
37
+ #
38
+ # conditions - Nested array of and/or conditions.
39
+ # Example: ['and', operand_1, ['or', operand_2, operand_3]]
40
+ #
41
+ # leaf_evaluator - Function which will be called to evaluate leaf condition values.
42
+ #
43
+ # Returns boolean if the given user attributes match/don't match the given conditions,
44
+ # nil if the given conditions are invalid or can't be evaluated.
45
+
46
+ if conditions.is_a? Array
47
+ first_operator = conditions[0]
48
+ rest_of_conditions = conditions[1..]
49
+
50
+ # Operator to apply is not explicit - assume 'or'
51
+ unless EVALUATORS_BY_OPERATOR_TYPE.include?(conditions[0])
52
+ first_operator = OR_CONDITION
53
+ rest_of_conditions = conditions
54
+ end
55
+
56
+ return send(EVALUATORS_BY_OPERATOR_TYPE[first_operator], rest_of_conditions, leaf_evaluator)
57
+ end
58
+
59
+ leaf_evaluator.call(conditions)
60
+ end
61
+
62
+ def and_evaluator(conditions, leaf_evaluator)
63
+ # Evaluates an array of conditions as if the evaluator had been applied
64
+ # to each entry and the results AND-ed together.
65
+ #
66
+ # conditions - Array of conditions ex: [operand_1, operand_2]
67
+ #
68
+ # leaf_evaluator - Function which will be called to evaluate leaf condition values.
69
+ #
70
+ # Returns boolean if the user attributes match/don't match the given conditions,
71
+ # nil if the user attributes and conditions can't be evaluated.
72
+
73
+ found_nil = false
74
+ conditions.each do |condition|
75
+ result = evaluate(condition, leaf_evaluator)
76
+ return result if result == false
77
+
78
+ found_nil = true if result.nil?
79
+ end
80
+
81
+ found_nil ? nil : true
82
+ end
83
+
84
+ def not_evaluator(single_condition, leaf_evaluator)
85
+ # Evaluates an array of conditions as if the evaluator had been applied
86
+ # to a single entry and NOT was applied to the result.
87
+ #
88
+ # single_condition - Array of a single condition ex: [operand_1]
89
+ #
90
+ # leaf_evaluator - Function which will be called to evaluate leaf condition values.
91
+ #
92
+ # Returns boolean if the user attributes match/don't match the given conditions,
93
+ # nil if the user attributes and conditions can't be evaluated.
94
+
95
+ return nil if single_condition.empty?
96
+
97
+ result = evaluate(single_condition[0], leaf_evaluator)
98
+ result.nil? ? nil : !result
99
+ end
100
+
101
+ def or_evaluator(conditions, leaf_evaluator)
102
+ # Evaluates an array of conditions as if the evaluator had been applied
103
+ # to each entry and the results OR-ed together.
104
+ #
105
+ # conditions - Array of conditions ex: [operand_1, operand_2]
106
+ #
107
+ # leaf_evaluator - Function which will be called to evaluate leaf condition values.
108
+ #
109
+ # Returns boolean if the user attributes match/don't match the given conditions,
110
+ # nil if the user attributes and conditions can't be evaluated.
111
+
112
+ found_nil = false
113
+ conditions.each do |condition|
114
+ result = evaluate(condition, leaf_evaluator)
115
+ return result if result == true
116
+
117
+ found_nil = true if result.nil?
118
+ end
119
+
120
+ found_nil ? nil : false
121
+ end
122
+ end
123
+ end
@@ -223,8 +223,9 @@ module Optimizely
223
223
  experiment = @experiment_key_map[experiment_key]
224
224
  return experiment if experiment
225
225
 
226
- @logger.log Logger::ERROR, "Experiment key '#{experiment_key}' is not in datafile."
227
- @error_handler.handle_error InvalidExperimentError
226
+ invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
227
+ @logger.log Logger::ERROR, invalid_experiment_error.message
228
+ @error_handler.handle_error invalid_experiment_error
228
229
  nil
229
230
  end
230
231
 
@@ -238,8 +239,9 @@ module Optimizely
238
239
  experiment = @experiment_id_map[experiment_id]
239
240
  return experiment if experiment
240
241
 
241
- @logger.log Logger::ERROR, "Experiment id '#{experiment_id}' is not in datafile."
242
- @error_handler.handle_error InvalidExperimentError
242
+ invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
243
+ @logger.log Logger::ERROR, invalid_experiment_error.message
244
+ @error_handler.handle_error invalid_experiment_error
243
245
  nil
244
246
  end
245
247
 
@@ -253,8 +255,9 @@ module Optimizely
253
255
  experiment = @experiment_id_map[experiment_id]
254
256
  return experiment['key'] unless experiment.nil?
255
257
 
256
- @logger.log Logger::ERROR, "Experiment id '#{experiment_id}' is not in datafile."
257
- @error_handler.handle_error InvalidExperimentError
258
+ invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
259
+ @logger.log Logger::ERROR, invalid_experiment_error.message
260
+ @error_handler.handle_error invalid_experiment_error
258
261
  nil
259
262
  end
260
263
 
@@ -268,8 +271,9 @@ module Optimizely
268
271
  event = @event_key_map[event_key]
269
272
  return event if event
270
273
 
271
- @logger.log Logger::ERROR, "Event '#{event_key}' is not in datafile."
272
- @error_handler.handle_error InvalidEventError
274
+ invalid_event_error = InvalidEventError.new(event_key)
275
+ @logger.log Logger::ERROR, invalid_event_error.message
276
+ @error_handler.handle_error invalid_event_error
273
277
  nil
274
278
  end
275
279
 
@@ -283,8 +287,9 @@ module Optimizely
283
287
  audience = @audience_id_map[audience_id]
284
288
  return audience if audience
285
289
 
286
- @logger.log Logger::ERROR, "Audience '#{audience_id}' is not in datafile."
287
- @error_handler.handle_error InvalidAudienceError
290
+ invalid_audience_error = InvalidAudienceError.new(audience_id)
291
+ @logger.log Logger::ERROR, invalid_audience_error.message
292
+ @error_handler.handle_error invalid_audience_error
288
293
  nil
289
294
  end
290
295
 
@@ -308,13 +313,15 @@ module Optimizely
308
313
  variation = variation_id_map[variation_id]
309
314
  return variation if variation
310
315
 
311
- @logger.log Logger::ERROR, "Variation id '#{variation_id}' is not in datafile."
312
- @error_handler.handle_error InvalidVariationError
316
+ invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
317
+ @logger.log Logger::ERROR, invalid_variation_error.message
318
+ @error_handler.handle_error invalid_variation_error
313
319
  return nil
314
320
  end
315
321
 
316
- @logger.log Logger::ERROR, "Experiment key '#{experiment_key}' is not in datafile."
317
- @error_handler.handle_error InvalidExperimentError
322
+ invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
323
+ @logger.log Logger::ERROR, invalid_experiment_error.message
324
+ @error_handler.handle_error invalid_experiment_error
318
325
  nil
319
326
  end
320
327
 
@@ -331,13 +338,15 @@ module Optimizely
331
338
  variation = variation_id_map_by_experiment_id[variation_id]
332
339
  return variation if variation
333
340
 
334
- @logger.log Logger::ERROR, "Variation id '#{variation_id}' is not in datafile."
335
- @error_handler.handle_error InvalidVariationError
341
+ invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
342
+ @logger.log Logger::ERROR, invalid_variation_error.message
343
+ @error_handler.handle_error invalid_variation_error
336
344
  return nil
337
345
  end
338
346
 
339
- @logger.log Logger::ERROR, "Experiment id '#{experiment_id}' is not in datafile."
340
- @error_handler.handle_error InvalidExperimentError
347
+ invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
348
+ @logger.log Logger::ERROR, invalid_experiment_error.message
349
+ @error_handler.handle_error invalid_experiment_error
341
350
  nil
342
351
  end
343
352
 
@@ -354,13 +363,15 @@ module Optimizely
354
363
  variation = variation_key_map[variation_key]
355
364
  return variation['id'] if variation
356
365
 
357
- @logger.log Logger::ERROR, "Variation key '#{variation_key}' is not in datafile."
358
- @error_handler.handle_error InvalidVariationError
366
+ invalid_variation_error = InvalidVariationError.new(variation_key: variation_key)
367
+ @logger.log Logger::ERROR, invalid_variation_error.message
368
+ @error_handler.handle_error invalid_variation_error
359
369
  return nil
360
370
  end
361
371
 
362
- @logger.log Logger::ERROR, "Experiment id '#{experiment_id}' is not in datafile."
363
- @error_handler.handle_error InvalidExperimentError
372
+ invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
373
+ @logger.log Logger::ERROR, invalid_experiment_error.message
374
+ @error_handler.handle_error invalid_experiment_error
364
375
  nil
365
376
  end
366
377
 
@@ -377,13 +388,15 @@ module Optimizely
377
388
  variation = variation_key_map[variation_key]
378
389
  return variation['id'] if variation
379
390
 
380
- @logger.log Logger::ERROR, "Variation key '#{variation_key}' is not in datafile."
381
- @error_handler.handle_error InvalidVariationError
391
+ invalid_variation_error = InvalidVariationError.new(variation_key: variation_key)
392
+ @logger.log Logger::ERROR, invalid_variation_error.message
393
+ @error_handler.handle_error invalid_variation_error
382
394
  return nil
383
395
  end
384
396
 
385
- @logger.log Logger::ERROR, "Experiment key '#{experiment_key}' is not in datafile."
386
- @error_handler.handle_error InvalidExperimentError
397
+ invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
398
+ @logger.log Logger::ERROR, invalid_experiment_error.message
399
+ @error_handler.handle_error invalid_experiment_error
387
400
  nil
388
401
  end
389
402
 
@@ -397,8 +410,9 @@ module Optimizely
397
410
  experiment = @experiment_id_map[experiment_id]
398
411
  return experiment['forcedVariations'] if experiment
399
412
 
400
- @logger.log Logger::ERROR, "Experiment ID '#{experiment_id}' is not in datafile."
401
- @error_handler.handle_error InvalidExperimentError
413
+ invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
414
+ @logger.log Logger::ERROR, invalid_experiment_error.message
415
+ @error_handler.handle_error invalid_experiment_error
402
416
  end
403
417
 
404
418
  def get_attribute_id(attribute_key)
@@ -420,8 +434,9 @@ module Optimizely
420
434
  end
421
435
  return attribute_key if has_reserved_prefix
422
436
 
423
- @logger.log Logger::ERROR, "Attribute key '#{attribute_key}' is not in datafile."
424
- @error_handler.handle_error InvalidAttributeError
437
+ invalid_attribute_error = InvalidAttributeError.new(attribute_key)
438
+ @logger.log Logger::ERROR, invalid_attribute_error.message
439
+ @error_handler.handle_error invalid_attribute_error
425
440
  nil
426
441
  end
427
442
 
@@ -439,8 +454,9 @@ module Optimizely
439
454
  variation = variation_id_map[variation_id]
440
455
  return true if variation
441
456
 
442
- @logger.log Logger::ERROR, "Variation ID '#{variation_id}' is not in datafile."
443
- @error_handler.handle_error InvalidVariationError
457
+ invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
458
+ @logger.log Logger::ERROR, invalid_variation_error.message
459
+ @error_handler.handle_error invalid_variation_error
444
460
  end
445
461
 
446
462
  false
@@ -1,34 +1,34 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright 2020, Optimizely and contributors
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
- #
18
-
19
- module Optimizely
20
- class ProxyConfig
21
- attr_reader :host, :port, :username, :password
22
-
23
- def initialize(host, port = nil, username = nil, password = nil)
24
- # host - DNS name or IP address of proxy
25
- # port - port to use to acess the proxy
26
- # username - username if authorization is required
27
- # password - password if authorization is required
28
- @host = host
29
- @port = port
30
- @username = username
31
- @password = password
32
- end
33
- end
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020, Optimizely and contributors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ #
18
+
19
+ module Optimizely
20
+ class ProxyConfig
21
+ attr_reader :host, :port, :username, :password
22
+
23
+ def initialize(host, port = nil, username = nil, password = nil)
24
+ # host - DNS name or IP address of proxy
25
+ # port - port to use to acess the proxy
26
+ # username - username if authorization is required
27
+ # password - password if authorization is required
28
+ @host = host
29
+ @port = port
30
+ @username = username
31
+ @password = password
32
+ end
33
+ end
34
+ end