Skip to content

Commit 1d37e9f

Browse files
committed
chore: Improve naming
- rename cache.rs to configuration.rs - rename ConfigurationSnapshot to Configuration. Snapshot did not add meaningful information. - Rename models::Configuration to ConfigurationJson to make clear this is the format used for data transport - Add some comments to make ambiguities more clear - Add some comments to start discussion with AppConfig Server team about some naming issues. Signed-off-by: Rainer Schoenberger <[email protected]>
1 parent bfd911c commit 1d37e9f

8 files changed

+74
-52
lines changed

src/client/app_configuration_http.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::client::cache::ConfigurationSnapshot;
15+
use crate::client::configuration::Configuration;
1616
pub use crate::client::feature_proxy::FeatureProxy;
1717
use crate::client::feature_snapshot::FeatureSnapshot;
1818
pub use crate::client::property_proxy::PropertyProxy;
@@ -33,7 +33,7 @@ use super::{AppConfigurationClient, ConfigurationId};
3333
/// AppConfiguration client implementation that connects to a server
3434
#[derive(Debug)]
3535
pub struct AppConfigurationClientHttp {
36-
latest_config_snapshot: Arc<Mutex<ConfigurationSnapshot>>,
36+
latest_config_snapshot: Arc<Mutex<Configuration>>,
3737
_thread_terminator: std::sync::mpsc::Sender<()>,
3838
}
3939

@@ -56,7 +56,7 @@ impl AppConfigurationClientHttp {
5656
let server_client = ServerClientImpl::new(service_address, token_provider)?;
5757

5858
// Populate initial configuration
59-
let latest_config_snapshot: Arc<Mutex<ConfigurationSnapshot>> = Arc::new(Mutex::new(
59+
let latest_config_snapshot: Arc<Mutex<Configuration>> = Arc::new(Mutex::new(
6060
Self::get_configuration_snapshot(&server_client, &configuration_id)?,
6161
));
6262

@@ -78,16 +78,16 @@ impl AppConfigurationClientHttp {
7878
fn get_configuration_snapshot(
7979
server_client: &ServerClientImpl,
8080
configuration_id: &ConfigurationId,
81-
) -> Result<ConfigurationSnapshot> {
81+
) -> Result<Configuration> {
8282
let configuration = server_client.get_configuration(configuration_id)?;
83-
ConfigurationSnapshot::new(&configuration_id.environment_id, configuration)
83+
Configuration::new(&configuration_id.environment_id, configuration)
8484
}
8585

8686
fn wait_for_configuration_update(
8787
socket: &mut WebSocket<MaybeTlsStream<TcpStream>>,
8888
server_client_impl: &ServerClientImpl,
8989
configuration_id: &ConfigurationId,
90-
) -> Result<ConfigurationSnapshot> {
90+
) -> Result<Configuration> {
9191
loop {
9292
// read() blocks until something happens.
9393
match socket.read()? {
@@ -110,7 +110,7 @@ impl AppConfigurationClientHttp {
110110

111111
fn update_configuration_on_change(
112112
mut socket: WebSocket<MaybeTlsStream<TcpStream>>,
113-
latest_config_snapshot: Arc<Mutex<ConfigurationSnapshot>>,
113+
latest_config_snapshot: Arc<Mutex<Configuration>>,
114114
server_client_impl: ServerClientImpl,
115115
configuration_id: ConfigurationId,
116116
) -> std::sync::mpsc::Sender<()> {
@@ -146,7 +146,7 @@ impl AppConfigurationClientHttp {
146146
}
147147

148148
fn update_cache_in_background(
149-
latest_config_snapshot: Arc<Mutex<ConfigurationSnapshot>>,
149+
latest_config_snapshot: Arc<Mutex<Configuration>>,
150150
server_client_impl: ServerClientImpl,
151151
configuration_id: ConfigurationId,
152152
) -> Result<std::sync::mpsc::Sender<()>> {
@@ -245,17 +245,17 @@ mod tests {
245245
configuration_feature1_enabled, configuration_property1_enabled,
246246
example_configuration_enterprise,
247247
};
248-
use crate::{models::Configuration, Feature, Property};
248+
use crate::{models::ConfigurationJson, Feature, Property};
249249
use rstest::rstest;
250250

251251
#[rstest]
252252
fn test_get_feature_persistence(
253-
example_configuration_enterprise: Configuration,
254-
configuration_feature1_enabled: Configuration,
253+
example_configuration_enterprise: ConfigurationJson,
254+
configuration_feature1_enabled: ConfigurationJson,
255255
) {
256256
let client = {
257257
let configuration_snapshot =
258-
ConfigurationSnapshot::new("dev", example_configuration_enterprise).unwrap();
258+
Configuration::new("dev", example_configuration_enterprise).unwrap();
259259

260260
let (sender, _) = std::sync::mpsc::channel();
261261

@@ -272,7 +272,7 @@ mod tests {
272272

273273
// We simulate an update of the configuration:
274274
let configuration_snapshot =
275-
ConfigurationSnapshot::new("environment_id", configuration_feature1_enabled).unwrap();
275+
Configuration::new("environment_id", configuration_feature1_enabled).unwrap();
276276
*client.latest_config_snapshot.lock().unwrap() = configuration_snapshot;
277277
// The feature value should not have changed (as we did not retrieve it again)
278278
let feature_value2 = feature.get_value(&entity).unwrap();
@@ -287,12 +287,12 @@ mod tests {
287287

288288
#[rstest]
289289
fn test_get_property_persistence(
290-
example_configuration_enterprise: Configuration,
291-
configuration_property1_enabled: Configuration,
290+
example_configuration_enterprise: ConfigurationJson,
291+
configuration_property1_enabled: ConfigurationJson,
292292
) {
293293
let client = {
294294
let configuration_snapshot =
295-
ConfigurationSnapshot::new("dev", example_configuration_enterprise).unwrap();
295+
Configuration::new("dev", example_configuration_enterprise).unwrap();
296296

297297
let (sender, _) = std::sync::mpsc::channel();
298298

@@ -309,7 +309,7 @@ mod tests {
309309

310310
// We simulate an update of the configuration:
311311
let configuration_snapshot =
312-
ConfigurationSnapshot::new("environment_id", configuration_property1_enabled).unwrap();
312+
Configuration::new("environment_id", configuration_property1_enabled).unwrap();
313313
*client.latest_config_snapshot.lock().unwrap() = configuration_snapshot;
314314
// The property value should not have changed (as we did not retrieve it again)
315315
let property_value2 = property.get_value(&entity).unwrap();

src/client/app_configuration_offline.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::client::cache::ConfigurationSnapshot;
15+
use crate::client::configuration::Configuration;
1616
pub use crate::client::feature_proxy::FeatureProxy;
1717
use crate::client::feature_snapshot::FeatureSnapshot;
1818
pub use crate::client::property_proxy::PropertyProxy;
1919
use crate::client::property_snapshot::PropertySnapshot;
2020
use crate::errors::{DeserializationError, Error, Result};
21-
use crate::models::Configuration;
21+
use crate::models::ConfigurationJson;
2222

2323
use super::AppConfigurationClient;
2424

2525
/// AppConfiguration client using a local file with a configuration snapshot
2626
#[derive(Debug)]
2727
pub struct AppConfigurationOffline {
28-
pub(crate) config_snapshot: ConfigurationSnapshot,
28+
pub(crate) config_snapshot: Configuration,
2929
}
3030

3131
impl AppConfigurationOffline {
@@ -44,7 +44,7 @@ impl AppConfigurationOffline {
4444
})?;
4545
let reader = std::io::BufReader::new(file);
4646

47-
let configuration: Configuration = serde_json::from_reader(reader).map_err(|e| {
47+
let configuration: ConfigurationJson = serde_json::from_reader(reader).map_err(|e| {
4848
Error::DeserializationError(DeserializationError {
4949
string: format!(
5050
"Error deserializing Configuration from file '{}'",
@@ -53,7 +53,7 @@ impl AppConfigurationOffline {
5353
source: e.into(),
5454
})
5555
})?;
56-
let config_snapshot = ConfigurationSnapshot::new(environment_id, configuration)?;
56+
let config_snapshot = Configuration::new(environment_id, configuration)?;
5757

5858
Ok(Self { config_snapshot })
5959
}

src/client/cache.rs src/client/configuration.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@
1515
use std::collections::{HashMap, HashSet};
1616

1717
use crate::errors::{ConfigurationAccessError, Result};
18-
use crate::models::{Configuration, Feature, Property, Segment, TargetingRule};
18+
use crate::models::{ConfigurationJson, Feature, Property, Segment, TargetingRule};
1919

20+
/// Represents all the configuration data needed for the client to perform
21+
/// feature/propery evaluation.
22+
/// It contains a subset of models::ConfigurationJson, adding indexing.
2023
#[derive(Debug, Default)]
21-
pub(crate) struct ConfigurationSnapshot {
24+
pub(crate) struct Configuration {
2225
pub(crate) features: HashMap<String, Feature>,
2326
pub(crate) properties: HashMap<String, Property>,
2427
pub(crate) segments: HashMap<String, Segment>,
2528
}
2629

27-
impl ConfigurationSnapshot {
30+
impl Configuration {
2831
pub fn get_feature(&self, feature_id: &str) -> Result<&Feature> {
2932
self.features.get(feature_id).ok_or_else(|| {
3033
ConfigurationAccessError::FeatureNotFound {
@@ -43,7 +46,8 @@ impl ConfigurationSnapshot {
4346
})
4447
}
4548

46-
pub fn new(environment_id: &str, configuration: Configuration) -> Result<Self> {
49+
/// Constructs the Configuration, by consuming and filtering data in exchange format
50+
pub fn new(environment_id: &str, configuration: ConfigurationJson) -> Result<Self> {
4751
let environment = configuration
4852
.environments
4953
.into_iter()
@@ -69,7 +73,7 @@ impl ConfigurationSnapshot {
6973
for segment in configuration.segments {
7074
segments.insert(segment.segment_id.clone(), segment.clone());
7175
}
72-
Ok(ConfigurationSnapshot {
76+
Ok(Configuration {
7377
features,
7478
properties,
7579
segments,
@@ -106,14 +110,14 @@ mod tests {
106110
use super::*;
107111
use crate::errors::Error;
108112
use crate::models::tests::example_configuration_enterprise;
109-
use crate::models::Configuration;
113+
use crate::models::ConfigurationJson;
110114

111115
use rstest::*;
112116

113117
#[rstest]
114-
fn test_filter_configurations(example_configuration_enterprise: Configuration) {
118+
fn test_filter_configurations(example_configuration_enterprise: ConfigurationJson) {
115119
let result =
116-
ConfigurationSnapshot::new("does_for_sure_not_exist", example_configuration_enterprise);
120+
Configuration::new("does_for_sure_not_exist", example_configuration_enterprise);
117121
assert!(result.is_err());
118122

119123
assert!(matches!(

src/client/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mod app_configuration_http;
1717
mod app_configuration_ibm_cloud;
1818
mod app_configuration_offline;
1919

20-
pub(crate) mod cache;
20+
pub(crate) mod configuration;
2121
pub(crate) mod feature_proxy;
2222
pub(crate) mod feature_snapshot;
2323
pub(crate) mod property_proxy;

src/models.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ use serde::Deserialize;
1818

1919
use crate::Value;
2020

21+
/// Represents AppConfig data in a structure intended for data exchange
22+
/// (typically JSON encoded) used by
23+
/// - AppConfig Server REST API (/config endpoint)
24+
/// - AppConfig database dumps (via Web GUI)
25+
/// - Offline configuration files used in offline-mode
2126
#[derive(Debug, Deserialize)]
22-
pub(crate) struct Configuration {
27+
pub(crate) struct ConfigurationJson {
2328
pub environments: Vec<Environment>,
2429
pub segments: Vec<Segment>,
2530
}
@@ -55,6 +60,8 @@ pub(crate) struct Feature {
5560
pub _format: Option<String>,
5661
pub enabled_value: ConfigValue,
5762
pub disabled_value: ConfigValue,
63+
// NOTE: why is this field called `segment_rules` and not `targeting_rules`?
64+
// This causes quite som ambiguity with SegmentRule vs TargetingRule.
5865
pub segment_rules: Vec<TargetingRule>,
5966
pub enabled: bool,
6067
pub rollout_percentage: u32,
@@ -71,6 +78,8 @@ pub(crate) struct Property {
7178
#[serde(rename = "format")]
7279
pub _format: Option<String>,
7380
pub value: ConfigValue,
81+
// NOTE: why is this field called `segment_rules` and not `targeting_rules`?
82+
// This causes quite som ambiguity with SegmentRule vs TargetingRule.
7483
pub segment_rules: Vec<TargetingRule>,
7584
}
7685

@@ -165,15 +174,26 @@ impl TryFrom<(ValueKind, ConfigValue)> for Value {
165174
}
166175
}
167176

177+
/// Represents a Rule of a Segment.
178+
/// Those are the rules to check if an entity belongs to a segment.
179+
/// NOTE: This is easily confused with `TargetingRule`, which is
180+
/// sometimes also called "SegmentRule".
168181
#[derive(Clone, Debug, Deserialize)]
169182
pub(crate) struct SegmentRule {
170183
pub attribute_name: String,
171184
pub operator: String,
172185
pub values: Vec<String>,
173186
}
174187

188+
/// Associates a Feature/Property to one or more Segments
189+
/// NOTE: This is easily confused with `SegmentRule`, as the field name in
190+
/// Features containing TargetingRules is called `segment_rules`
175191
#[derive(Debug, Deserialize, Clone)]
176192
pub(crate) struct TargetingRule {
193+
/// The list of targeted segments
194+
/// NOTE: no rules by itself, but the rules are found in the segments
195+
/// NOTE: why list of lists?
196+
/// NOTE: why is this field called "rules"?
177197
pub rules: Vec<Segments>,
178198
pub value: ConfigValue,
179199
pub order: u32,
@@ -205,17 +225,17 @@ pub(crate) mod tests {
205225
// Create a [`Configuration`] object from the data files
206226
pub(crate) fn example_configuration_enterprise(
207227
example_configuration_enterprise_path: PathBuf,
208-
) -> Configuration {
228+
) -> ConfigurationJson {
209229
let content = fs::File::open(example_configuration_enterprise_path)
210230
.expect("file should open read only");
211-
let configuration: Configuration =
231+
let configuration: ConfigurationJson =
212232
serde_json::from_reader(content).expect("Error parsing JSON into Configuration");
213233
configuration
214234
}
215235

216236
#[fixture]
217-
pub(crate) fn configuration_feature1_enabled() -> Configuration {
218-
Configuration {
237+
pub(crate) fn configuration_feature1_enabled() -> ConfigurationJson {
238+
ConfigurationJson {
219239
environments: vec![Environment {
220240
_name: "name".to_string(),
221241
environment_id: "environment_id".to_string(),
@@ -237,8 +257,8 @@ pub(crate) mod tests {
237257
}
238258

239259
#[fixture]
240-
pub(crate) fn configuration_property1_enabled() -> Configuration {
241-
Configuration {
260+
pub(crate) fn configuration_property1_enabled() -> ConfigurationJson {
261+
ConfigurationJson {
242262
environments: vec![Environment {
243263
_name: "name".to_string(),
244264
environment_id: "environment_id".to_string(),
@@ -258,7 +278,7 @@ pub(crate) mod tests {
258278
}
259279

260280
#[fixture]
261-
pub(crate) fn configuration_unordered_segment_rules() -> Configuration {
281+
pub(crate) fn configuration_unordered_segment_rules() -> ConfigurationJson {
262282
let segment_rules = vec![
263283
TargetingRule {
264284
rules: vec![Segments {
@@ -279,7 +299,7 @@ pub(crate) mod tests {
279299
];
280300
assert!(segment_rules[0].order > segment_rules[1].order);
281301

282-
Configuration {
302+
ConfigurationJson {
283303
environments: vec![Environment {
284304
_name: "name".to_string(),
285305
environment_id: "environment_id".to_string(),

src/network/http_client.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// limitations under the License.
1414

1515
use super::TokenProvider;
16-
use crate::models::Configuration;
16+
use crate::models::ConfigurationJson;
1717
use crate::{ConfigurationId, Error, Result};
1818
use reqwest::blocking::Client;
1919
use std::cell::RefCell;
@@ -99,7 +99,7 @@ impl ServerClientImpl {
9999
})
100100
}
101101

102-
pub fn get_configuration(&self, collection: &ConfigurationId) -> Result<Configuration> {
102+
pub fn get_configuration(&self, collection: &ConfigurationId) -> Result<ConfigurationJson> {
103103
let url = format!(
104104
"{}/feature/v1/instances/{}/config",
105105
self.service_address.base_url(ServiceAddressProtocol::Https),

src/tests/test_get_feature.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414

1515
use std::collections::HashMap;
1616

17-
use crate::models::Configuration;
17+
use crate::models::ConfigurationJson;
1818

19-
use crate::client::cache::ConfigurationSnapshot;
19+
use crate::client::configuration::Configuration;
2020
use crate::client::AppConfigurationClient;
2121
use crate::{AppConfigurationOffline, Value};
2222
use rstest::*;
@@ -36,10 +36,9 @@ fn test_get_feature_doesnt_exist(client_enterprise: Box<dyn AppConfigurationClie
3636
}
3737

3838
#[rstest]
39-
fn test_get_feature_ordered(configuration_unordered_segment_rules: Configuration) {
39+
fn test_get_feature_ordered(configuration_unordered_segment_rules: ConfigurationJson) {
4040
let config_snapshot =
41-
ConfigurationSnapshot::new("environment_id", configuration_unordered_segment_rules)
42-
.unwrap();
41+
Configuration::new("environment_id", configuration_unordered_segment_rules).unwrap();
4342

4443
let client = AppConfigurationOffline { config_snapshot };
4544

0 commit comments

Comments
 (0)