Skip to content

Commit b6e03a1

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

File tree

12 files changed

+564
-150
lines changed

12 files changed

+564
-150
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import io.fabric8.kubernetes.api.model.HasMetadata;
2424
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider;
2525
import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider;
26+
import io.javaoperatorsdk.operator.config.loader.provider.EnvVarConfigProvider;
27+
import io.javaoperatorsdk.operator.config.loader.provider.PrirityListConfigProvider;
28+
import io.javaoperatorsdk.operator.config.loader.provider.SystemPropertyConfigProvider;
2629
import io.javaoperatorsdk.operator.processing.retry.GenericRetry;
2730

2831
public class ConfigLoader {
@@ -134,7 +137,11 @@ public static ConfigLoader getDefault() {
134137
private final ConfigProvider configProvider;
135138

136139
public ConfigLoader() {
137-
this(new DefaultConfigProvider(), DEFAULT_CONTROLLER_KEY_PREFIX, DEFAULT_OPERATOR_KEY_PREFIX);
140+
this(
141+
new PrirityListConfigProvider(
142+
List.of(new EnvVarConfigProvider(), new SystemPropertyConfigProvider())),
143+
DEFAULT_CONTROLLER_KEY_PREFIX,
144+
DEFAULT_OPERATOR_KEY_PREFIX);
138145
}
139146

140147
public ConfigLoader(ConfigProvider configProvider) {

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

Lines changed: 0 additions & 103 deletions
This file was deleted.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.config.loader.provider;
17+
18+
import java.time.Duration;
19+
20+
/** Utility for converting raw string config values to typed instances. */
21+
final class ConfigValueConverter {
22+
23+
private ConfigValueConverter() {}
24+
25+
/**
26+
* Converts {@code raw} to an instance of {@code type}. Supported types: {@link String}, {@link
27+
* Boolean}, {@link Integer}, {@link Long}, {@link Double}, and {@link Duration} (ISO-8601 format,
28+
* e.g. {@code PT30S}).
29+
*
30+
* @throws IllegalArgumentException if {@code type} is not supported
31+
*/
32+
public static <T> T convert(String raw, Class<T> type) {
33+
final Object converted;
34+
if (type == String.class) {
35+
converted = raw;
36+
} else if (type == Boolean.class) {
37+
converted = Boolean.parseBoolean(raw);
38+
} else if (type == Integer.class) {
39+
converted = Integer.parseInt(raw);
40+
} else if (type == Long.class) {
41+
converted = Long.parseLong(raw);
42+
} else if (type == Double.class) {
43+
converted = Double.parseDouble(raw);
44+
} else if (type == Duration.class) {
45+
converted = Duration.parse(raw);
46+
} else {
47+
throw new IllegalArgumentException("Unsupported config type: " + type.getName());
48+
}
49+
return type.cast(converted);
50+
}
51+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.config.loader.provider;
17+
18+
import java.util.Optional;
19+
import java.util.function.Function;
20+
21+
import io.javaoperatorsdk.operator.config.loader.ConfigProvider;
22+
23+
/**
24+
* A {@link ConfigProvider} that resolves configuration values from environment variables.
25+
*
26+
* <p>The key is converted to an environment variable name by replacing dots and hyphens with
27+
* underscores and converting to upper case (e.g. {@code josdk.cache-sync.timeout} → {@code
28+
* JOSDK_CACHE_SYNC_TIMEOUT}).
29+
*
30+
* <p>Supported value types are: {@link String}, {@link Boolean}, {@link Integer}, {@link Long},
31+
* {@link Double}, and {@link java.time.Duration} (ISO-8601 format, e.g. {@code PT30S}).
32+
*/
33+
public class EnvVarConfigProvider implements ConfigProvider {
34+
35+
private final Function<String, String> envLookup;
36+
37+
public EnvVarConfigProvider() {
38+
this(System::getenv);
39+
}
40+
41+
EnvVarConfigProvider(Function<String, String> envLookup) {
42+
this.envLookup = envLookup;
43+
}
44+
45+
@Override
46+
public <T> Optional<T> getValue(String key, Class<T> type) {
47+
if (key == null) {
48+
return Optional.empty();
49+
}
50+
String raw = envLookup.apply(toEnvKey(key));
51+
if (raw == null) {
52+
return Optional.empty();
53+
}
54+
return Optional.of(ConfigValueConverter.convert(raw, type));
55+
}
56+
57+
static String toEnvKey(String key) {
58+
return key.trim().replace('.', '_').replace('-', '_').toUpperCase();
59+
}
60+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.config.loader.provider;
17+
18+
import java.util.List;
19+
import java.util.Optional;
20+
21+
import io.javaoperatorsdk.operator.config.loader.ConfigProvider;
22+
23+
/**
24+
* A {@link ConfigProvider} that delegates to an ordered list of providers. Providers are queried in
25+
* list order; the first non-empty result wins.
26+
*/
27+
public class PrirityListConfigProvider implements ConfigProvider {
28+
29+
private final List<ConfigProvider> providers;
30+
31+
public PrirityListConfigProvider(List<ConfigProvider> providers) {
32+
this.providers = List.copyOf(providers);
33+
}
34+
35+
@Override
36+
public <T> Optional<T> getValue(String key, Class<T> type) {
37+
for (ConfigProvider provider : providers) {
38+
Optional<T> value = provider.getValue(key, type);
39+
if (value.isPresent()) {
40+
return value;
41+
}
42+
}
43+
return Optional.empty();
44+
}
45+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.config.loader.provider;
17+
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
import java.io.UncheckedIOException;
21+
import java.nio.file.Files;
22+
import java.nio.file.Path;
23+
import java.util.Optional;
24+
import java.util.Properties;
25+
26+
import io.javaoperatorsdk.operator.config.loader.ConfigProvider;
27+
28+
/**
29+
* A {@link ConfigProvider} that resolves configuration values from a {@link Properties} file.
30+
*
31+
* <p>Keys are looked up as-is against the loaded properties. Supported value types are: {@link
32+
* String}, {@link Boolean}, {@link Integer}, {@link Long}, {@link Double}, and {@link
33+
* java.time.Duration} (ISO-8601 format, e.g. {@code PT30S}).
34+
*/
35+
public class PropertiesConfigProvider implements ConfigProvider {
36+
37+
private final Properties properties;
38+
39+
/**
40+
* Loads properties from the given file path.
41+
*
42+
* @throws UncheckedIOException if the file cannot be read
43+
*/
44+
public PropertiesConfigProvider(Path path) {
45+
this.properties = load(path);
46+
}
47+
48+
/** Uses the supplied {@link Properties} instance directly. */
49+
public PropertiesConfigProvider(Properties properties) {
50+
this.properties = properties;
51+
}
52+
53+
@Override
54+
public <T> Optional<T> getValue(String key, Class<T> type) {
55+
if (key == null) {
56+
return Optional.empty();
57+
}
58+
String raw = properties.getProperty(key);
59+
if (raw == null) {
60+
return Optional.empty();
61+
}
62+
return Optional.of(ConfigValueConverter.convert(raw, type));
63+
}
64+
65+
private static Properties load(Path path) {
66+
try (InputStream in = Files.newInputStream(path)) {
67+
Properties props = new Properties();
68+
props.load(in);
69+
return props;
70+
} catch (IOException e) {
71+
throw new UncheckedIOException("Failed to load config properties from " + path, e);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)