ibm_appconfiguration_ruby_sdk 0.1.0.pre.rc.0 → 0.1.0.pre.rc.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +162 -168
  4. data/examples/app.rb +73 -57
  5. data/lib/ibm_appconfiguration_ruby_sdk/{core/api_manager.rb → api_manager.rb} +98 -35
  6. data/lib/ibm_appconfiguration_ruby_sdk/app_configuration.rb +76 -54
  7. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/retry_manager/background_retry_manager.rb → background_retry_manager.rb} +34 -36
  8. data/lib/ibm_appconfiguration_ruby_sdk/config_fetcher.rb +226 -0
  9. data/lib/ibm_appconfiguration_ruby_sdk/configuration.rb +54 -0
  10. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/configuration_handler.rb → configuration_handler.rb} +201 -204
  11. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/constants.rb → constants.rb} +62 -2
  12. data/lib/ibm_appconfiguration_ruby_sdk/errors.rb +73 -0
  13. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/file_manager.rb → file_manager.rb} +5 -7
  14. data/lib/ibm_appconfiguration_ruby_sdk/logger.rb +87 -0
  15. data/lib/ibm_appconfiguration_ruby_sdk/{core/metering.rb → metering.rb} +75 -41
  16. data/lib/ibm_appconfiguration_ruby_sdk/models/evaluation_result.rb +54 -0
  17. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/feature.rb +17 -33
  18. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/property.rb +23 -39
  19. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/rule.rb +2 -0
  20. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/secret_property.rb +9 -7
  21. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/segment.rb +2 -0
  22. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/models → models}/segment_rules.rb +4 -2
  23. data/lib/ibm_appconfiguration_ruby_sdk/{core/url_builder.rb → url_builder.rb} +36 -6
  24. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/utils.rb → utils.rb} +35 -39
  25. data/lib/ibm_appconfiguration_ruby_sdk/version.rb +1 -1
  26. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/websocket_client/websocket_client.rb → websocket/client.rb} +3 -1
  27. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/websocket_client → websocket}/connection_manager.rb +96 -129
  28. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/websocket_client → websocket}/driver_socket.rb +10 -8
  29. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/websocket_client/connectivity.rb → websocket/retry_policy.rb} +24 -10
  30. data/lib/ibm_appconfiguration_ruby_sdk/{configurations/internal/websocket_client → websocket}/state.rb +9 -7
  31. data/lib/ibm_appconfiguration_ruby_sdk/websocket/watchdog.rb +64 -0
  32. data/lib/ibm_appconfiguration_ruby_sdk.rb +2 -0
  33. data/spec/api_manager_spec.rb +239 -0
  34. data/spec/app_configuration_spec.rb +386 -0
  35. data/spec/background_retry_manager_spec.rb +160 -0
  36. data/spec/config_fetcher_spec.rb +188 -0
  37. data/spec/configuration_handler_spec.rb +185 -0
  38. data/spec/configuration_spec.rb +74 -0
  39. data/spec/errors_spec.rb +142 -0
  40. data/spec/file_manager_spec.rb +132 -0
  41. data/spec/logger_spec.rb +121 -0
  42. data/spec/metering_spec.rb +166 -0
  43. data/spec/models/evaluation_result_spec.rb +75 -0
  44. data/spec/models/feature_spec.rb +109 -0
  45. data/spec/models/property_spec.rb +76 -0
  46. data/spec/models/rule_spec.rb +97 -0
  47. data/spec/models/secret_property_spec.rb +119 -0
  48. data/spec/models/segment_rules_spec.rb +64 -0
  49. data/spec/models/segment_spec.rb +57 -0
  50. data/{lib/ibm_appconfiguration_ruby_sdk/configurations/internal/websocket_client/retry_policy.rb → spec/spec_helper.rb} +13 -21
  51. data/spec/url_builder_spec.rb +179 -0
  52. data/spec/utils_spec.rb +269 -0
  53. data/spec/websocket/connection_manager_spec.rb +459 -0
  54. data/spec/websocket/driver_socket_spec.rb +41 -0
  55. data/spec/websocket/retry_policy_spec.rb +98 -0
  56. data/spec/websocket/watchdog_spec.rb +72 -0
  57. metadata +64 -24
  58. data/lib/ibm_appconfiguration_ruby_sdk/configurations/internal/logger.rb +0 -98
  59. data/lib/ibm_appconfiguration_ruby_sdk/configurations/internal/retry_manager/config_fetcher.rb +0 -254
  60. data/lib/ibm_appconfiguration_ruby_sdk/configurations/internal/websocket_client/watchdog.rb +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1539bbf23de03af81f99e3be2c4e76e108e28979fc35b67cf9f65c8a485f1001
4
- data.tar.gz: 3fcd5d046f1eb0585b514160d9b8313c9c05fb3909fab6551bdfd0af184eeba4
3
+ metadata.gz: d0d47f7822d5632c7775640cab20fb93c102b2c87f95ad8ac8d9a727ab6095b2
4
+ data.tar.gz: 64a9b3fabe1ff624452c0091304840e7bafa30b3322d47b2415334265ea4a2ce
5
5
  SHA512:
6
- metadata.gz: 15f0f0389d53fd30f95e0be5a68743b35f68f2702633e8b7e0fa0aa1e403ec93283ace4e54b57815a34ddf180f7d55031977ba049bda36be946aabdd431466e5
7
- data.tar.gz: c69ea5eb9f37de2b1369ade29206c5b5774085373fd7879b67383eacfe2c2fbd1206ce6467cb9034bd027968851b792118248ac728d63a69775ab024054c9e45
6
+ metadata.gz: 768acdd48dd6f827b6c9e8d38e4af4231117425e94fa278dbc7380d2be5779652939575a0d3a82a599e9ef922ee3423a598cd21be842cf7bb145d72ef8a9a4d2
7
+ data.tar.gz: 112afe2227835c6dc7a67ae2f0f1a80f187d840e48ee9a8c69c29477cb6b609ba2f48fed3991030befd9302480f105819599be6a1f2589cec136901bdff273c1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## CHANGELOG
2
2
 
3
+ ## [0.1.0-rc.1] - 2026-08-24
4
+
5
+ - `init` and `set_context` postional arguments changed to keyword.
6
+ - classes namespaced under `IbmAppconfigurationRubySdk` module.
7
+ - replaced `puts` logging with structured stdlib `::Logger`.
8
+ - improved error handling.
9
+ - folder re-structure.
10
+ - retries related fixes.
11
+ - added test suite.
12
+ - todos completed.
13
+
3
14
  ## [0.1.0-rc.0] - 2026-06-16
4
15
 
5
16
  - Initial release
data/README.md CHANGED
@@ -26,13 +26,13 @@ the cloud to activate or deactivate features in your application or environment,
26
26
  Installation is done using the `gem install` command or by adding it to your Gemfile.
27
27
 
28
28
  ```bash
29
- gem install ibm_appconfiguration_ruby_sdk
29
+ gem install ibm_appconfiguration_ruby_sdk --pre
30
30
  ```
31
31
 
32
32
  Or add this line to your application's Gemfile:
33
33
 
34
34
  ```ruby
35
- gem 'ibm_appconfiguration_ruby_sdk'
35
+ gem "ibm_appconfiguration_ruby_sdk", "0.1.0.pre.rc.1"
36
36
  ```
37
37
 
38
38
  And then execute:
@@ -46,7 +46,7 @@ bundle install
46
46
  To import the module:
47
47
 
48
48
  ```ruby
49
- require 'ibm_appconfiguration_ruby_sdk'
49
+ require "ibm_appconfiguration_ruby_sdk"
50
50
  ```
51
51
 
52
52
  ## Usage
@@ -54,53 +54,61 @@ require 'ibm_appconfiguration_ruby_sdk'
54
54
  Initialize the SDK to connect with your App Configuration service instance.
55
55
 
56
56
  ```ruby
57
- require 'ibm_appconfiguration_ruby_sdk'
57
+ require "ibm_appconfiguration_ruby_sdk"
58
+
59
+ region = "us-south"
60
+ guid = "<guid>"
61
+ apikey = "<apikey>"
62
+ collection_id = "airlines-webapp"
63
+ environment_id = "dev"
64
+
65
+ # (Optional) SDK-wide options — call before .instance
66
+ IbmAppconfigurationRubySdk::AppConfiguration.configure do |config|
67
+ config.debug = false # set true for verbose SDK logging
68
+ config.use_private_endpoint = false # set true to use IBM private network
69
+ end
58
70
 
59
71
  # Get the singleton instance
60
- app_config_client = IbmAppconfigurationRubySdk::AppConfiguration.instance
61
-
62
- region = 'us-south'
63
- guid = '<guid>'
64
- apikey = '<apikey>'
65
- collection_id = 'airlines-webapp'
66
- environment_id = 'dev'
72
+ client = IbmAppconfigurationRubySdk::AppConfiguration.instance
67
73
 
68
- # Enable debug logging (optional)
69
- app_config_client.set_debug(true)
74
+ # Initialize the SDK — keyword arguments are required
75
+ client.init(region: region, guid: guid, apikey: apikey)
70
76
 
71
- # Initialize the SDK
72
- app_config_client.init(region, guid, apikey)
77
+ # Register a listener before set_context so it fires on the very first config fetch
78
+ client.register_configuration_update_listener do
79
+ # called on every configuration refresh (initial load + live updates)
80
+ end
73
81
 
74
82
  # Set context
75
- app_config_client.set_context(collection_id, environment_id)
83
+ client.set_context(collection_id, environment_id)
76
84
  ```
77
85
 
78
86
  > :warning: It is expected that initialization to be done **only once**.
79
87
 
80
- After the SDK is initialized successfully, the feature flags & properties can be retrieved using the `app_config_client` as shown in the below code snippet.
88
+ After the SDK is initialized successfully, the feature flags & properties can be retrieved using the `client` as shown in the below code snippet.
81
89
 
82
90
  <details><summary>Expand to view the example snippet</summary>
83
91
 
84
92
  ```ruby
85
93
  # Get feature
86
- feature = app_config_client.get_feature('online-check-in')
94
+ feature = client.get_feature("online-check-in")
87
95
  if feature
88
96
  result = feature.get_current_value(entity_id, entity_attributes)
89
- puts result
97
+ puts result.value
90
98
  end
91
99
 
92
100
  # Get property
93
- property = app_config_client.get_property('check-in-charges')
101
+ property = client.get_property("check-in-charges")
94
102
  if property
95
103
  result = property.get_current_value(entity_id, entity_attributes)
96
- puts result
104
+ puts result.value
97
105
  end
98
106
  ```
99
107
  </details>
100
108
 
101
109
  where,
102
- - **region**: Region name where the App Configuration service instance is created.
103
- See list of supported locations [here](https://cloud.ibm.com/catalog/services/app-configuration). Eg:- `us-south`, `au-syd`, `eu-gb`, `us-east`, `eu-de`, `ca-tor`, `jp-tok`, `jp-osa` etc.
110
+ - **region**: Region name where the App Configuration service instance is created.
111
+ See list of supported locations [here](https://cloud.ibm.com/catalog/services/app-configuration). Eg:- `us-south`, `au-syd`, `eu-gb`, `us-east`, `eu-de`, `ca-tor`, `jp-tok`, `jp-osa` etc.
104
112
  - **guid**: Instance Id of the App Configuration service. Obtain it from the service credentials section of the App
105
113
  Configuration dashboard.
106
114
  - **apikey**: ApiKey of the App Configuration service. Obtain it from the service credentials section of the App
@@ -110,22 +118,30 @@ See list of supported locations [here](https://cloud.ibm.com/catalog/services/ap
110
118
 
111
119
  ### Connect using private network connection (optional)
112
120
 
113
- Set the SDK to connect to App Configuration service by using a private endpoint that is accessible only through the IBM Cloud private network.
121
+ Set the SDK to connect to App Configuration service by using a private endpoint that is accessible only through the IBM Cloud private network. This must be configured before calling `init`.
122
+
123
+ Via the `configure` block (preferred):
114
124
 
115
125
  ```ruby
116
- app_config_client.use_private_endpoint(true)
126
+ IbmAppconfigurationRubySdk::AppConfiguration.configure do |config|
127
+ config.use_private_endpoint = true
128
+ end
117
129
  ```
118
130
 
119
- This must be done before calling the `init` method on the SDK.
131
+ Or directly on the client instance (must be called before `init`):
132
+
133
+ ```ruby
134
+ client.use_private_endpoint(true)
135
+ ```
120
136
 
121
137
  ### (Optional)
122
138
 
123
139
  In order for your application and SDK to continue its operations even during the unlikely scenario of App Configuration service across your application restarts, you can configure the SDK to work using a persistent cache. The SDK uses the persistent cache to store the App Configuration data that will be available across your application restarts.
124
140
 
125
141
  ```ruby
126
- app_config_client.set_context(collection_id, environment_id, {
127
- persistent_cache_directory: '/var/lib/docker/volumes/'
128
- })
142
+ client.set_context(collection_id, environment_id,
143
+ persistent_cache_directory: "/var/lib/docker/volumes/"
144
+ )
129
145
  ```
130
146
 
131
147
  * **persistent_cache_directory**: Absolute path to a directory which has read & write permission for the user. The SDK will create a file - `appconfiguration.json` in the specified directory, and it will be used as the persistent cache to store the App Configuration service information.
@@ -139,10 +155,10 @@ Please ensure that the cache file is not lost or deleted in any case. For exampl
139
155
  The SDK is also designed to serve configurations, perform feature flag & property evaluations without being connected to App Configuration service.
140
156
 
141
157
  ```ruby
142
- app_config_client.set_context(collection_id, environment_id, {
143
- bootstrap_file: 'saflights/flights.json',
158
+ client.set_context(collection_id, environment_id,
159
+ bootstrap_file: "saflights/flights.json",
144
160
  live_config_update_enabled: false
145
- })
161
+ )
146
162
  ```
147
163
 
148
164
  This usecase will throw error if given `bootstrap_file` is not found or if unable to parse the json coming from the bootstrap file.
@@ -153,13 +169,13 @@ This usecase will throw error if given `bootstrap_file` is not found or if unabl
153
169
  ## Get single feature
154
170
 
155
171
  ```ruby
156
- feature = app_config_client.get_feature('online-check-in') # feature can be nil in case of an invalid feature id
172
+ feature = client.get_feature("online-check-in") # feature can be nil in case of an invalid feature id
157
173
 
158
174
  if feature
159
- puts "Feature Name: #{feature.get_feature_name}"
160
- puts "Feature Id: #{feature.get_feature_id}"
161
- puts "Feature Type: #{feature.get_feature_data_type}"
162
- if feature.is_enabled?
175
+ puts "Feature Name: #{feature.name}"
176
+ puts "Feature Id: #{feature.feature_id}"
177
+ puts "Feature Type: #{feature.type}"
178
+ if feature.enabled?
163
179
  # feature flag is enabled
164
180
  else
165
181
  # feature flag is disabled
@@ -170,100 +186,87 @@ end
170
186
  ## Get all features
171
187
 
172
188
  ```ruby
173
- features = app_config_client.get_features
174
- feature = features['online-check-in']
189
+ features = client.get_features
190
+ feature = features["online-check-in"]
175
191
 
176
192
  if feature
177
- puts "Feature Name: #{feature.get_feature_name}"
178
- puts "Feature Id: #{feature.get_feature_id}"
179
- puts "Feature Type: #{feature.get_feature_data_type}"
180
- puts "Is feature enabled? #{feature.is_enabled?}"
193
+ puts "Feature Name: #{feature.name}"
194
+ puts "Feature Id: #{feature.feature_id}"
195
+ puts "Feature Type: #{feature.type}"
196
+ puts "Is feature enabled? #{feature.enabled?}"
181
197
  end
182
198
  ```
183
199
 
184
200
  ## Evaluate a feature
185
201
 
186
- Use the `feature.get_current_value(entity_id, entity_attributes)` method to evaluate the value of the feature flag. This method returns a Hash containing evaluated value, feature flag enabled status & evaluation details.
202
+ Use the `feature.get_current_value(entity_id, entity_attributes)` method to evaluate the value of the feature flag. This method returns an `EvaluationResult` struct containing the evaluated value, feature flag enabled status, and evaluation details.
187
203
 
188
204
  ```ruby
189
- entity_id = 'john_doe'
205
+ entity_id = "john_doe"
190
206
  entity_attributes = {
191
- city: 'Bangalore',
192
- country: 'India'
207
+ city: "Bangalore",
208
+ country: "India"
193
209
  }
194
210
 
195
211
  result = feature.get_current_value(entity_id, entity_attributes)
196
- puts result[:value] # Evaluated value of the feature flag. The type of evaluated value will match the type of feature flag (Boolean, String, Numeric).
197
- puts result[:is_enabled] # enabled status.
198
- puts result[:details] # a Hash containing detailed information of the evaluation. See below
199
-
200
- # the `result[:details]` will have the following
201
- puts result[:details][:value_type] # a string value. Example: DISABLED_VALUE
202
- puts result[:details][:reason] # a string value. Example: Disabled value of the feature flag since the feature flag is disabled.
203
- puts result[:details][:segment_name] # (only if applicable, else it is nil) a string value containing the segment name for which the feature flag was evaluated.
204
- puts result[:details][:rollout_percentage_applied] # (only if applicable, else it is nil) a boolean value. True if the entity_id was part of the rollout percentage evaluation, false otherwise.
205
- puts result[:details][:error_type] # (only if applicable, else it is nil) contains the error message if any error occurred during the evaluation.
212
+ puts result.value # Evaluated value of the feature flag. The type matches the feature flag type (Boolean, String, Numeric).
213
+ puts result.enabled # enabled status (true/false).
214
+ puts result.details # an EvaluationDetails struct with detailed evaluation information. See below.
215
+
216
+ # the `result.details` struct has the following fields:
217
+ puts result.details.value_type # e.g. "DISABLED_VALUE"
218
+ puts result.details.rollout_percentage_applied # (only if applicable, else nil) Boolean
219
+ puts result.details.segment_name # (only if applicable, else nil) e.g. "premium-users"
220
+ puts result.details.error_type # (only if applicable, else nil) error message if evaluation failed
206
221
  ```
207
222
 
208
223
  - **entity_id**: Id of the Entity. This will be a string identifier related to the Entity against which the feature is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
209
224
  - **entity_attributes**: A Hash consisting of the attribute name and their values that defines the specified entity. This is an optional parameter if the feature flag is not configured with any targeting definition. If the targeting is configured, then entity_attributes should be provided for the rule evaluation. An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the specified entity satisfies the targeting rules, and returns the appropriate feature flag value.
210
225
 
211
- ## Send custom metrics
212
-
213
- Record custom metrics for experiments using the track method. Calling track will queue the metric event, which will be sent in batches to the App Configuration servers.
214
-
215
- ```ruby
216
- app_config_client.track(event_key, entity_id)
217
- ```
218
-
219
- where
220
- - **event_key**: The event key for the metric associated with the running experiment. The event key in your metric and the event key in your code must match exactly.
221
-
222
226
  ## Get single property
223
227
 
224
228
  ```ruby
225
- property = app_config_client.get_property('check-in-charges') # property can be nil in case of an invalid property id
229
+ property = client.get_property("check-in-charges") # property can be nil in case of an invalid property id
226
230
 
227
231
  if property
228
- puts "Property Name: #{property.get_property_name}"
229
- puts "Property Id: #{property.get_property_id}"
230
- puts "Property Type: #{property.get_property_data_type}"
232
+ puts "Property Name: #{property.name}"
233
+ puts "Property Id: #{property.property_id}"
234
+ puts "Property Type: #{property.type}"
231
235
  end
232
236
  ```
233
237
 
234
238
  ## Get all properties
235
239
 
236
240
  ```ruby
237
- properties = app_config_client.get_properties
238
- property = properties['check-in-charges']
241
+ properties = client.get_properties
242
+ property = properties["check-in-charges"]
239
243
 
240
244
  if property
241
- puts "Property Name: #{property.get_property_name}"
242
- puts "Property Id: #{property.get_property_id}"
243
- puts "Property Type: #{property.get_property_data_type}"
245
+ puts "Property Name: #{property.name}"
246
+ puts "Property Id: #{property.property_id}"
247
+ puts "Property Type: #{property.type}"
244
248
  end
245
249
  ```
246
250
 
247
251
  ## Evaluate a property
248
252
 
249
- Use the `property.get_current_value(entity_id, entity_attributes)` method to evaluate the value of the property. This method returns a Hash containing evaluated value & evaluation details.
253
+ Use the `property.get_current_value(entity_id, entity_attributes)` method to evaluate the value of the property. This method returns an `EvaluationResult` struct containing the evaluated value and evaluation details.
250
254
 
251
255
  ```ruby
252
- entity_id = 'john_doe'
256
+ entity_id = "john_doe"
253
257
  entity_attributes = {
254
- city: 'Bangalore',
255
- country: 'India'
258
+ city: "Bangalore",
259
+ country: "India"
256
260
  }
257
261
 
258
262
  result = property.get_current_value(entity_id, entity_attributes)
259
- puts result[:value] # Evaluated value of the property. The type of evaluated value will match the type of property (Boolean, String, Numeric).
260
- puts result[:details] # a Hash containing detailed information of the evaluation. See below
261
-
262
- # the `result[:details]` will have the following
263
- puts result[:details][:value_type] # a string value. Example: DEFAULT_VALUE
264
- puts result[:details][:reason] # a string value. Example: Default value of the property.
265
- puts result[:details][:segment_name] # (only if applicable, else it is nil) a string value containing the segment name for which the property was evaluated.
266
- puts result[:details][:error_type] # (only if applicable, else it is nil) contains the error message if any error occurred during the evaluation.
263
+ puts result.value # Evaluated value of the property. The type matches the property type (Boolean, String, Numeric).
264
+ puts result.details # an EvaluationDetails struct with detailed evaluation information. See below.
265
+
266
+ # the `result.details` struct has the following fields:
267
+ puts result.details.value_type # e.g. "DEFAULT_VALUE"
268
+ puts result.details.segment_name # (only if applicable, else nil) e.g. "premium-users"
269
+ puts result.details.error_type # (only if applicable, else nil) error message if evaluation failed
267
270
  ```
268
271
 
269
272
  - **entity_id**: Id of the Entity. This will be a string identifier related to the Entity against which the property is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
@@ -274,7 +277,7 @@ puts result[:details][:error_type] # (only if applicable, else it is nil) contai
274
277
  Explicit method for getting the secret references stored in App Configuration.
275
278
 
276
279
  ```ruby
277
- secret_property_object = app_config_client.get_secret(property_id, secrets_manager_service)
280
+ secret_property_object = client.get_secret(property_id, secrets_manager_service)
278
281
  ```
279
282
 
280
283
  - **property_id**: property_id is the unique string identifier, using this we will be able to fetch the property which will provide the necessary metadata to fetch the secret.
@@ -287,10 +290,10 @@ Use the `secret_property_object.get_current_value(entity_id, entity_attributes)`
287
290
  Note that the output of this method call is different from `get_current_value` invoked using feature & property objects. This method returns the actual secret value of the evaluated secret reference. The response contains the secret data from the Secrets Manager.
288
291
 
289
292
  ```ruby
290
- entity_id = 'john_doe'
293
+ entity_id = "john_doe"
291
294
  entity_attributes = {
292
- city: 'Bangalore',
293
- country: 'India'
295
+ city: "Bangalore",
296
+ country: "India"
294
297
  }
295
298
 
296
299
  begin
@@ -301,69 +304,54 @@ rescue StandardError => e
301
304
  end
302
305
  ```
303
306
 
304
- ## How to access the secret data from a successful response
307
+ ## Fetching the client across other modules
305
308
 
306
- <details><summary>Full example:</summary>
309
+ Once the SDK is initialized, the client can be obtained across other modules as shown below:
307
310
 
308
311
  ```ruby
309
- require 'ibm_appconfiguration_ruby_sdk'
310
- require 'ibm_secrets_manager_sdk'
311
-
312
- app_config_client = IbmAppconfigurationRubySdk::AppConfiguration.instance
313
-
314
- begin
315
- app_config_client.init(region, guid, apikey)
316
- app_config_client.set_context(collection_id, environment_id)
317
- rescue StandardError => e
318
- puts "Failed to initialize app configuration sdk: #{e}"
319
- end
320
-
321
- # Initialize Secrets Manager client
322
- authenticator = IbmCloudSdkCore::Authenticators::IamAuthenticator.new(
323
- apikey: '<SECRETS_MANAGER_APIKEY>'
324
- )
325
-
326
- secrets_manager_service = IbmCloudSecretsManagerApiV2::SecretsManagerV2.new(
327
- authenticator: authenticator
328
- )
329
- secrets_manager_service.service_url = '<SECRETS_MANAGER_INSTANCE_URL>'
330
-
331
- begin
332
- secret_property_object = app_config_client.get_secret(property_id, secrets_manager_service)
333
- response = secret_property_object.get_current_value(entity_id, entity_attributes)
312
+ # **other modules**
334
313
 
335
- # For Arbitrary secret type
336
- puts response.result['payload']
314
+ require "ibm_appconfiguration_ruby_sdk"
337
315
 
338
- # For username-password secret type
339
- puts response.result['username']
340
- puts response.result['password']
316
+ client = IbmAppconfigurationRubySdk::AppConfiguration.instance
341
317
 
342
- # For key-value secret type
343
- puts response.result['data']['key1']
344
- puts response.result['data']['key2']
345
- rescue StandardError => e
346
- # handle the error
347
- puts "Error: #{e}"
348
- end
318
+ feature = client.get_feature("online-check-in")
319
+ result = feature.get_current_value(entity_id, entity_attributes)
320
+ puts result.value
321
+ puts result.enabled
349
322
  ```
350
- </details>
351
323
 
352
- ## Fetching the app_config_client across other modules
324
+ ## Error handling
353
325
 
354
- Once the SDK is initialized, the app_config_client can be obtained across other modules as shown below:
326
+ The SDK raises typed errors that you can rescue individually or collectively.
355
327
 
356
328
  ```ruby
357
- # **other modules**
358
-
359
- require 'ibm_appconfiguration_ruby_sdk'
329
+ begin
330
+ client.init(region: region, guid: guid, apikey: apikey)
331
+ client.set_context(collection_id, environment_id)
332
+ rescue IbmAppconfigurationRubySdk::AuthenticationError => e
333
+ # HTTP 401 — invalid or expired API key
334
+ warn "Authentication failed (HTTP #{e.http_status}): #{e.message}"
335
+ rescue IbmAppconfigurationRubySdk::APIError => e
336
+ # Any other HTTP error from the service
337
+ warn "API error (HTTP #{e.http_status}): #{e.message}"
338
+ rescue IbmAppconfigurationRubySdk::ConfigurationError => e
339
+ # SDK used incorrectly — e.g. missing init parameters
340
+ warn "SDK configuration error: #{e.message}"
341
+ end
342
+ ```
360
343
 
361
- app_config_client = IbmAppconfigurationRubySdk::AppConfiguration.instance
344
+ Error class hierarchy:
362
345
 
363
- feature = app_config_client.get_feature('online-check-in')
364
- enabled = feature.is_enabled?
365
- result = feature.get_current_value(entity_id, entity_attributes)
366
- ```
346
+ | Class | Trigger |
347
+ | --- | --- |
348
+ | `IbmAppconfigurationRubySdk::Error` | Base class — rescue this to catch all SDK errors |
349
+ | `IbmAppconfigurationRubySdk::ConfigurationError` | Incorrect SDK usage (missing params, wrong call order) |
350
+ | `IbmAppconfigurationRubySdk::APIError` | HTTP error from the service (carries `http_status` & `http_body`) |
351
+ | `IbmAppconfigurationRubySdk::AuthenticationError` | HTTP 401 |
352
+ | `IbmAppconfigurationRubySdk::RateLimitError` | HTTP 429 |
353
+ | `IbmAppconfigurationRubySdk::InvalidRequestError` | HTTP 400 / 422 |
354
+ | `IbmAppconfigurationRubySdk::ServerError` | HTTP 5xx |
367
355
 
368
356
  ## Supported Data types
369
357
 
@@ -373,13 +361,13 @@ format accordingly as shown in the below table.
373
361
 
374
362
  <details><summary>View Table</summary>
375
363
 
376
- | **Feature or Property value** | **DataType** | **DataFormat** | **Type of data returned <br> by `get_current_value[:value]`** | **Example output** |
364
+ | **Feature or Property value** | **DataType** | **DataFormat** | **Type of data returned <br> by `result.value`** | **Example output** |
377
365
  | ------------------------------------------------------------------------------------------------------ | ------------ | -------------- | ----------------------------------------------------- | -------------------------------------------------------------------- |
378
- | `true` | BOOLEAN | not applicable | `Boolean` | `true` |
366
+ | `true` | BOOLEAN | not applicable | `Boolean` | `true` |
379
367
  | `25` | NUMERIC | not applicable | `Numeric` | `25` |
380
- | "a string text" | STRING | TEXT | `String` | `"a string text"` |
381
- | <pre>{<br> "firefox": {<br> "name": "Firefox",<br> "pref_url": "about:config"<br> }<br>}</pre> | STRING | JSON | `Hash` | `{"firefox"=>{"name"=>"Firefox","pref_url"=>"about:config"}}` |
382
- | <pre>men:<br> - John Smith<br> - Bill Jones<br>women:<br> - Mary Smith<br> - Susan Williams</pre> | STRING | YAML | `String` | `"men:\n - John Smith\n - Bill Jones\nwomen:\n - Mary Smith\n - Susan Williams"` |
368
+ | "a string text" | STRING | TEXT | `String` | `"a string text"` |
369
+ | <pre>{<br> "firefox": {<br> "name": "Firefox",<br> "pref_url": "about:config"<br> }<br>}</pre> | STRING | JSON | `Hash` | `{"firefox"=>{"name"=>"Firefox","pref_url"=>"about:config"}}` |
370
+ | <pre>men:<br> - John Smith<br> - Bill Jones<br>women:<br> - Mary Smith<br> - Susan Williams</pre> | STRING | YAML | `String` | `"men:\n - John Smith\n - Bill Jones\nwomen:\n - Mary Smith\n - Susan Williams"` |
383
371
 
384
372
  For property of type secret reference, refer to readme section [evaluate-a-secret-property](#evaluate-a-secret-property)
385
373
  </details>
@@ -387,17 +375,17 @@ For property of type secret reference, refer to readme section [evaluate-a-secre
387
375
  <details><summary>Feature flag</summary>
388
376
 
389
377
  ```ruby
390
- feature = app_config_client.get_feature('json-feature')
391
- feature.get_feature_data_type # STRING
392
- feature.get_feature_data_format # JSON
378
+ feature = client.get_feature("json-feature")
379
+ feature.type # STRING
380
+ feature.data_format # JSON
393
381
 
394
382
  # Example (traversing the returned Hash)
395
383
  result = feature.get_current_value(entity_id, entity_attributes)
396
- puts result[:value]['key'] # prints the value of the key
384
+ puts result.value["key"] # prints the value of the key
397
385
 
398
- feature = app_config_client.get_feature('yaml-feature')
399
- feature.get_feature_data_type # STRING
400
- feature.get_feature_data_format # YAML
386
+ feature = client.get_feature("yaml-feature")
387
+ feature.type # STRING
388
+ feature.data_format # YAML
401
389
  feature.get_current_value(entity_id, entity_attributes)
402
390
  ```
403
391
  </details>
@@ -405,31 +393,31 @@ feature.get_current_value(entity_id, entity_attributes)
405
393
  <details><summary>Property</summary>
406
394
 
407
395
  ```ruby
408
- property = app_config_client.get_property('json-property')
409
- property.get_property_data_type # STRING
410
- property.get_property_data_format # JSON
396
+ property = client.get_property("json-property")
397
+ property.type # STRING
398
+ property.data_format # JSON
411
399
 
412
400
  # Example (traversing the returned Hash)
413
401
  result = property.get_current_value(entity_id, entity_attributes)
414
- puts result[:value]['key'] # prints the value of the key
402
+ puts result.value["key"] # prints the value of the key
415
403
 
416
- property = app_config_client.get_property('yaml-property')
417
- property.get_property_data_type # STRING
418
- property.get_property_data_format # YAML
404
+ property = client.get_property("yaml-property")
405
+ property.type # STRING
406
+ property.data_format # YAML
419
407
  property.get_current_value(entity_id, entity_attributes)
420
408
  ```
421
409
  </details>
422
410
 
423
411
  ## Set listener for feature and property data changes
424
412
 
425
- The SDK provides a callback mechanism to notify you in real-time when feature flag's or property's configuration changes. You can register a configuration update listener using the same app_config_client.
413
+ The SDK provides a callback mechanism to notify you in real-time when feature flag's or property's configuration changes. Register the listener after `init` but before `set_context` so it fires on the very first configuration fetch.
426
414
 
427
415
  ```ruby
428
- app_config_client.register_configuration_update_listener do
416
+ client.register_configuration_update_listener do
429
417
  # **add your code**
430
418
  # To find the effect of any configuration changes, you can call the feature or property related methods
431
419
 
432
- # feature = app_config_client.get_feature('online-check-in')
420
+ # feature = client.get_feature("online-check-in")
433
421
  # new_result = feature.get_current_value(entity_id, entity_attributes)
434
422
  end
435
423
  ```
@@ -439,7 +427,13 @@ end
439
427
  Use this method to enable/disable the logging in SDK.
440
428
 
441
429
  ```ruby
442
- app_config_client.set_debug(true)
430
+ # Via the configure block (call before .instance)
431
+ IbmAppconfigurationRubySdk::AppConfiguration.configure do |config|
432
+ config.debug = true
433
+ end
434
+
435
+ # Or directly on the client instance
436
+ client.set_debug(true)
443
437
  ```
444
438
 
445
439
  ## Examples
@@ -457,7 +451,7 @@ https://{region}.apprapp.cloud.ibm.com:443
457
451
  wss://{region}.apprapp.cloud.ibm.com:443
458
452
  ```
459
453
 
460
- If opted for private endpoint by setting `app_config_client.use_private_endpoint(true)` then the allowlist will be
454
+ If opted for private endpoint by setting `config.use_private_endpoint = true` (or `client.use_private_endpoint(true)`) then the allowlist will be
461
455
 
462
456
  ```
463
457
  https://cloud.ibm.com:443
@@ -471,4 +465,4 @@ where `region` is the region where your App Configuration service instance is pr
471
465
  ## License
472
466
 
473
467
  This project is released under the Apache 2.0 license. The license's full text can be found
474
- in [LICENSE](https://github.com/IBM/appconfiguration-ruby-sdk/blob/master/LICENSE)
468
+ in [LICENSE](https://github.com/IBM/appconfiguration-ruby-sdk/blob/master/LICENSE)