Skip to content

Commit 685829c

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent e47e23f commit 685829c

File tree

4 files changed

+104
-52
lines changed

4 files changed

+104
-52
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/loader/ConfigLoader.java

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,16 @@ public class ConfigLoader {
2727

2828
public static final ConfigLoader DEFAULT = new ConfigLoader();
2929

30-
/**
31-
* Key prefix for operator-level (ConfigurationService) properties, e.g. {@code
32-
* josdk.concurrent.reconciliation.threads}.
33-
*/
34-
public static final String OPERATOR_KEY_PREFIX = "josdk.";
30+
public static final String DEFAULT_OPERATOR_KEY_PREFIX = "josdk.";
31+
public static final String DEFAULT_CONTROLLER_KEY_PREFIX = "josdk.controller.";
3532

3633
/**
3734
* Key prefix for controller-level properties. The controller name is inserted between this prefix
3835
* and the property name, e.g. {@code josdk.controller.my-controller.finalizer}.
3936
*/
40-
public static final String CONTROLLER_KEY_PREFIX = "josdk.controller.";
37+
private final String controllerKeyPrefix;
38+
39+
private final String operatorKeyPrefix;
4140

4241
// ---------------------------------------------------------------------------
4342
// Operator-level (ConfigurationServiceOverrider) bindings
@@ -48,43 +47,43 @@ public class ConfigLoader {
4847
private static final List<ConfigBinding<ConfigurationServiceOverrider, ?>> OPERATOR_BINDINGS =
4948
List.of(
5049
new ConfigBinding<>(
51-
OPERATOR_KEY_PREFIX + "check.crd.and.validate.local.model",
50+
"check-crd",
5251
Boolean.class,
5352
ConfigurationServiceOverrider::checkingCRDAndValidateLocalModel),
5453
new ConfigBinding<>(
55-
OPERATOR_KEY_PREFIX + "concurrent.reconciliation.threads",
54+
"reconciliation.termination-timeout",
55+
Duration.class,
56+
ConfigurationServiceOverrider::withReconciliationTerminationTimeout),
57+
new ConfigBinding<>(
58+
"reconciliation.concurrent-threads",
5659
Integer.class,
5760
ConfigurationServiceOverrider::withConcurrentReconciliationThreads),
5861
new ConfigBinding<>(
59-
OPERATOR_KEY_PREFIX + "concurrent.workflow.executor.threads",
62+
"workflow.executor-threads",
6063
Integer.class,
6164
ConfigurationServiceOverrider::withConcurrentWorkflowExecutorThreads),
6265
new ConfigBinding<>(
63-
OPERATOR_KEY_PREFIX + "close.client.on.stop",
66+
"close-client-on-stop",
6467
Boolean.class,
6568
ConfigurationServiceOverrider::withCloseClientOnStop),
6669
new ConfigBinding<>(
67-
OPERATOR_KEY_PREFIX + "stop.on.informer.error.during.startup",
70+
"informer.stop-on-error-during-startup",
6871
Boolean.class,
6972
ConfigurationServiceOverrider::withStopOnInformerErrorDuringStartup),
7073
new ConfigBinding<>(
71-
OPERATOR_KEY_PREFIX + "cache.sync.timeout",
74+
"informer.cache-sync-timeout",
7275
Duration.class,
7376
ConfigurationServiceOverrider::withCacheSyncTimeout),
7477
new ConfigBinding<>(
75-
OPERATOR_KEY_PREFIX + "reconciliation.termination.timeout",
76-
Duration.class,
77-
ConfigurationServiceOverrider::withReconciliationTerminationTimeout),
78-
new ConfigBinding<>(
79-
OPERATOR_KEY_PREFIX + "ssa.based.create.update.match.for.dependent.resources",
78+
"dependent-resources.ssa-based-create-update-match",
8079
Boolean.class,
8180
ConfigurationServiceOverrider::withSSABasedCreateUpdateMatchForDependentResources),
8281
new ConfigBinding<>(
83-
OPERATOR_KEY_PREFIX + "use.ssa.to.patch.primary.resource",
82+
"use-ssa-to-patch-primary-resource",
8483
Boolean.class,
8584
ConfigurationServiceOverrider::withUseSSAToPatchPrimaryResource),
8685
new ConfigBinding<>(
87-
OPERATOR_KEY_PREFIX + "clone.secondary.resources.when.getting.from.cache",
86+
"clone-secondary-resources-when-getting-from-cache",
8887
Boolean.class,
8988
ConfigurationServiceOverrider::withCloneSecondaryResourcesWhenGettingFromCache));
9089

@@ -99,47 +98,54 @@ public class ConfigLoader {
9998
new ConfigBinding<>(
10099
"finalizer", String.class, ControllerConfigurationOverrider::withFinalizer),
101100
new ConfigBinding<>(
102-
"generation.aware",
101+
"generation-aware",
103102
Boolean.class,
104103
ControllerConfigurationOverrider::withGenerationAware),
105104
new ConfigBinding<>(
106-
"label.selector",
105+
"label-selector",
107106
String.class,
108107
ControllerConfigurationOverrider::withLabelSelector),
109108
new ConfigBinding<>(
110-
"reconciliation.max.interval",
109+
"max-reconciliation-interval",
111110
Duration.class,
112111
ControllerConfigurationOverrider::withReconciliationMaxInterval),
113112
new ConfigBinding<>(
114-
"field.manager",
113+
"field-manager",
115114
String.class,
116115
ControllerConfigurationOverrider::withFieldManager),
117116
new ConfigBinding<>(
118-
"trigger.reconciler.on.all.events",
117+
"trigger-reconciler-on-all-events",
119118
Boolean.class,
120119
ControllerConfigurationOverrider::withTriggerReconcilerOnAllEvents),
121120
new ConfigBinding<>(
122-
"informer.list.limit",
121+
"informer-list-limit",
123122
Long.class,
124123
ControllerConfigurationOverrider::withInformerListLimit));
125124

126125
private final ConfigProvider configProvider;
127126

128127
public ConfigLoader() {
129-
this(new DefaultConfigProvider());
128+
this(new DefaultConfigProvider(), DEFAULT_CONTROLLER_KEY_PREFIX, DEFAULT_OPERATOR_KEY_PREFIX);
130129
}
131130

132131
public ConfigLoader(ConfigProvider configProvider) {
132+
this(configProvider, DEFAULT_CONTROLLER_KEY_PREFIX, DEFAULT_OPERATOR_KEY_PREFIX);
133+
}
134+
135+
public ConfigLoader(
136+
ConfigProvider configProvider, String controllerKeyPrefix, String operatorKeyPrefix) {
133137
this.configProvider = configProvider;
138+
this.controllerKeyPrefix = controllerKeyPrefix;
139+
this.operatorKeyPrefix = operatorKeyPrefix;
134140
}
135141

136142
/**
137143
* Returns a {@link Consumer} that applies every operator-level property found in the {@link
138144
* ConfigProvider} to the given {@link ConfigurationServiceOverrider}. Returns {@code null} when
139-
* no binding has a matching value, preserving the previous behaviour.
145+
* no binding has a matching value, preserving the previous behavior.
140146
*/
141147
public Consumer<ConfigurationServiceOverrider> applyConfigs() {
142-
return buildConsumer(OPERATOR_BINDINGS, null);
148+
return buildConsumer(OPERATOR_BINDINGS, operatorKeyPrefix);
143149
}
144150

145151
/**
@@ -151,7 +157,7 @@ public Consumer<ConfigurationServiceOverrider> applyConfigs() {
151157
@SuppressWarnings("unchecked")
152158
public <R extends HasMetadata>
153159
Consumer<ControllerConfigurationOverrider<R>> applyControllerConfigs(String controllerName) {
154-
String prefix = CONTROLLER_KEY_PREFIX + controllerName + ".";
160+
String prefix = controllerKeyPrefix + controllerName + ".";
155161
// Cast is safe: the setter BiConsumer<ControllerConfigurationOverrider<?>, T> is covariant in
156162
// its first parameter for our usage – we only ever call it with
157163
// ControllerConfigurationOverrider<R>.

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/loader/DefaultConfigProvider.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@
1717

1818
import java.time.Duration;
1919
import java.util.Optional;
20+
import java.util.function.Function;
2021

2122
public class DefaultConfigProvider implements ConfigProvider {
2223

24+
private final Function<String, String> envLookup;
25+
26+
public DefaultConfigProvider() {
27+
this(System::getenv);
28+
}
29+
30+
DefaultConfigProvider(Function<String, String> envLookup) {
31+
this.envLookup = envLookup;
32+
}
33+
2334
/**
2435
* Looks up {@code key} first as an environment variable (dots and hyphens replaced by
2536
* underscores, uppercased, e.g. {@code josdk.cache.sync.timeout} → {@code
@@ -38,7 +49,7 @@ public <T> Optional<T> getValue(String key, Class<T> type) {
3849

3950
private String resolveRaw(String key) {
4051
String envKey = key.replace('.', '_').replace('-', '_').toUpperCase();
41-
String envValue = System.getenv(envKey);
52+
String envValue = envLookup.apply(envKey);
4253
if (envValue != null) {
4354
return envValue;
4455
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/loader/ConfigLoaderTest.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void applyConfigsReturnsNullWhenNothingConfigured() {
5252
@Test
5353
void applyConfigsAppliesConcurrentReconciliationThreads() {
5454
var loader =
55-
new ConfigLoader(mapProvider(Map.of("josdk.concurrent.reconciliation.threads", 7)));
55+
new ConfigLoader(mapProvider(Map.of("josdk.reconciliation.concurrent-threads", 7)));
5656

5757
var base = new BaseConfigurationService(null);
5858
var result =
@@ -63,8 +63,7 @@ void applyConfigsAppliesConcurrentReconciliationThreads() {
6363

6464
@Test
6565
void applyConfigsAppliesConcurrentWorkflowExecutorThreads() {
66-
var loader =
67-
new ConfigLoader(mapProvider(Map.of("josdk.concurrent.workflow.executor.threads", 3)));
66+
var loader = new ConfigLoader(mapProvider(Map.of("josdk.workflow.executor-threads", 3)));
6867

6968
var base = new BaseConfigurationService(null);
7069
var result =
@@ -76,12 +75,12 @@ void applyConfigsAppliesConcurrentWorkflowExecutorThreads() {
7675
@Test
7776
void applyConfigsAppliesBooleanFlags() {
7877
var values = new HashMap<String, Object>();
79-
values.put("josdk.check.crd.and.validate.local.model", true);
80-
values.put("josdk.close.client.on.stop", false);
81-
values.put("josdk.stop.on.informer.error.during.startup", false);
82-
values.put("josdk.ssa.based.create.update.match.for.dependent.resources", false);
83-
values.put("josdk.use.ssa.to.patch.primary.resource", false);
84-
values.put("josdk.clone.secondary.resources.when.getting.from.cache", true);
78+
values.put("josdk.check-crd", true);
79+
values.put("josdk.close-client-on-stop", false);
80+
values.put("josdk.informer.stop-on-error-during-startup", false);
81+
values.put("josdk.dependent-resources.ssa-based-create-update-match", false);
82+
values.put("josdk.use-ssa-to-patch-primary-resource", false);
83+
values.put("josdk.clone-secondary-resources-when-getting-from-cache", true);
8584
var loader = new ConfigLoader(mapProvider(values));
8685

8786
var base = new BaseConfigurationService(null);
@@ -99,8 +98,8 @@ void applyConfigsAppliesBooleanFlags() {
9998
@Test
10099
void applyConfigsAppliesDurations() {
101100
var values = new HashMap<String, Object>();
102-
values.put("josdk.cache.sync.timeout", Duration.ofSeconds(10));
103-
values.put("josdk.reconciliation.termination.timeout", Duration.ofSeconds(5));
101+
values.put("josdk.informer.cache-sync-timeout", Duration.ofSeconds(10));
102+
values.put("josdk.reconciliation.termination-timeout", Duration.ofSeconds(5));
104103
var loader = new ConfigLoader(mapProvider(values));
105104

106105
var base = new BaseConfigurationService(null);
@@ -115,7 +114,7 @@ void applyConfigsAppliesDurations() {
115114
void applyConfigsOnlyAppliesPresentKeys() {
116115
// Only one key present — other defaults must be unchanged.
117116
var loader =
118-
new ConfigLoader(mapProvider(Map.of("josdk.concurrent.reconciliation.threads", 12)));
117+
new ConfigLoader(mapProvider(Map.of("josdk.reconciliation.concurrent-threads", 12)));
119118

120119
var base = new BaseConfigurationService(null);
121120
var result =
@@ -185,23 +184,23 @@ public <T> Optional<T> getValue(String key, Class<T> type) {
185184
assertThat(queriedKeys)
186185
.contains(
187186
"josdk.controller.ctrl.finalizer",
188-
"josdk.controller.ctrl.generation.aware",
189-
"josdk.controller.ctrl.label.selector",
190-
"josdk.controller.ctrl.reconciliation.max.interval",
191-
"josdk.controller.ctrl.field.manager",
192-
"josdk.controller.ctrl.trigger.reconciler.on.all.events",
193-
"josdk.controller.ctrl.informer.list.limit");
187+
"josdk.controller.ctrl.generation-aware",
188+
"josdk.controller.ctrl.label-selector",
189+
"josdk.controller.ctrl.max-reconciliation-interval",
190+
"josdk.controller.ctrl.field-manager",
191+
"josdk.controller.ctrl.trigger-reconciler-on-all-events",
192+
"josdk.controller.ctrl.informer-list-limit");
194193
}
195194

196195
// -- key prefix constants ---------------------------------------------------
197196

198197
@Test
199198
void operatorKeyPrefixIsJosdkDot() {
200-
assertThat(ConfigLoader.OPERATOR_KEY_PREFIX).isEqualTo("josdk.");
199+
assertThat(ConfigLoader.DEFAULT_OPERATOR_KEY_PREFIX).isEqualTo("josdk.");
201200
}
202201

203202
@Test
204203
void controllerKeyPrefixIsJosdkControllerDot() {
205-
assertThat(ConfigLoader.CONTROLLER_KEY_PREFIX).isEqualTo("josdk.controller.");
204+
assertThat(ConfigLoader.DEFAULT_CONTROLLER_KEY_PREFIX).isEqualTo("josdk.controller.");
206205
}
207206
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/loader/DefaultConfigProviderTest.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,49 @@ class DefaultConfigProviderTest {
2626

2727
private final DefaultConfigProvider provider = new DefaultConfigProvider();
2828

29-
// -- system property tests --------------------------------------------------
30-
3129
@Test
3230
void returnsEmptyWhenNeitherEnvNorPropertyIsSet() {
3331
assertThat(provider.getValue("josdk.no.such.key", String.class)).isEmpty();
3432
}
3533

34+
// -- env variable tests -----------------------------------------------------
35+
36+
@Test
37+
void readsStringFromEnvVariable() {
38+
var envProvider = new DefaultConfigProvider(k -> k.equals("JOSDK_TEST_STRING") ? "from-env" : null);
39+
assertThat(envProvider.getValue("josdk.test.string", String.class)).hasValue("from-env");
40+
}
41+
42+
@Test
43+
void envVariableKeyUsesUppercaseWithUnderscores() {
44+
// dots and hyphens both become underscores, key is uppercased
45+
var envProvider = new DefaultConfigProvider(k -> k.equals("JOSDK_CACHE_SYNC_TIMEOUT") ? "PT10S" : null);
46+
assertThat(envProvider.getValue("josdk.cache-sync.timeout", Duration.class))
47+
.hasValue(Duration.ofSeconds(10));
48+
}
49+
50+
@Test
51+
void envVariableTakesPrecedenceOverSystemProperty() {
52+
System.setProperty("josdk.test.precedence", "from-sysprop");
53+
try {
54+
var envProvider = new DefaultConfigProvider(k -> k.equals("JOSDK_TEST_PRECEDENCE") ? "from-env" : null);
55+
assertThat(envProvider.getValue("josdk.test.precedence", String.class)).hasValue("from-env");
56+
} finally {
57+
System.clearProperty("josdk.test.precedence");
58+
}
59+
}
60+
61+
@Test
62+
void fallsBackToSystemPropertyWhenEnvVariableAbsent() {
63+
System.setProperty("josdk.test.fallback", "from-sysprop");
64+
try {
65+
var envProvider = new DefaultConfigProvider(k -> null);
66+
assertThat(envProvider.getValue("josdk.test.fallback", String.class)).hasValue("from-sysprop");
67+
} finally {
68+
System.clearProperty("josdk.test.fallback");
69+
}
70+
}
71+
3672
@Test
3773
void readsStringFromSystemProperty() {
3874
System.setProperty("josdk.test.string", "hello");

0 commit comments

Comments
 (0)