|
17 | 17 |
|
18 | 18 | import java.time.Duration; |
19 | 19 | import java.util.List; |
| 20 | +import java.util.Optional; |
20 | 21 | import java.util.function.Consumer; |
21 | 22 |
|
22 | 23 | import io.fabric8.kubernetes.api.model.HasMetadata; |
23 | 24 | import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider; |
24 | 25 | import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider; |
| 26 | +import io.javaoperatorsdk.operator.processing.retry.GenericRetry; |
25 | 27 |
|
26 | 28 | public class ConfigLoader { |
27 | 29 |
|
@@ -87,6 +89,14 @@ public class ConfigLoader { |
87 | 89 | Boolean.class, |
88 | 90 | ConfigurationServiceOverrider::withCloneSecondaryResourcesWhenGettingFromCache)); |
89 | 91 |
|
| 92 | + // --------------------------------------------------------------------------- |
| 93 | + // Controller-level retry property suffixes |
| 94 | + // --------------------------------------------------------------------------- |
| 95 | + static final String RETRY_MAX_ATTEMPTS_SUFFIX = "retry.max-attempts"; |
| 96 | + static final String RETRY_INITIAL_INTERVAL_SUFFIX = "retry.initial-interval"; |
| 97 | + static final String RETRY_INTERVAL_MULTIPLIER_SUFFIX = "retry.interval-multiplier"; |
| 98 | + static final String RETRY_MAX_INTERVAL_SUFFIX = "retry.max-interval"; |
| 99 | + |
90 | 100 | // --------------------------------------------------------------------------- |
91 | 101 | // Controller-level (ControllerConfigurationOverrider) bindings |
92 | 102 | // The key used at runtime is built as: |
@@ -163,7 +173,47 @@ Consumer<ControllerConfigurationOverrider<R>> applyControllerConfigs(String cont |
163 | 173 | // ControllerConfigurationOverrider<R>. |
164 | 174 | List<ConfigBinding<ControllerConfigurationOverrider<R>, ?>> bindings = |
165 | 175 | (List<ConfigBinding<ControllerConfigurationOverrider<R>, ?>>) (List<?>) CONTROLLER_BINDINGS; |
166 | | - return buildConsumer(bindings, prefix); |
| 176 | + Consumer<ControllerConfigurationOverrider<R>> consumer = buildConsumer(bindings, prefix); |
| 177 | + |
| 178 | + Consumer<ControllerConfigurationOverrider<R>> retryStep = buildRetryConsumer(prefix); |
| 179 | + if (retryStep != null) { |
| 180 | + consumer = consumer == null ? retryStep : consumer.andThen(retryStep); |
| 181 | + } |
| 182 | + |
| 183 | + return consumer; |
| 184 | + } |
| 185 | + |
| 186 | + /** |
| 187 | + * If at least one retry property is present for the given prefix, returns a {@link Consumer} that |
| 188 | + * builds a {@link GenericRetry} starting from {@link GenericRetry#defaultLimitedExponentialRetry} |
| 189 | + * and overrides only the properties that are explicitly set. |
| 190 | + */ |
| 191 | + private <R extends HasMetadata> Consumer<ControllerConfigurationOverrider<R>> buildRetryConsumer( |
| 192 | + String prefix) { |
| 193 | + Optional<Integer> maxAttempts = |
| 194 | + configProvider.getValue(prefix + RETRY_MAX_ATTEMPTS_SUFFIX, Integer.class); |
| 195 | + Optional<Long> initialInterval = |
| 196 | + configProvider.getValue(prefix + RETRY_INITIAL_INTERVAL_SUFFIX, Long.class); |
| 197 | + Optional<Double> intervalMultiplier = |
| 198 | + configProvider.getValue(prefix + RETRY_INTERVAL_MULTIPLIER_SUFFIX, Double.class); |
| 199 | + Optional<Long> maxInterval = |
| 200 | + configProvider.getValue(prefix + RETRY_MAX_INTERVAL_SUFFIX, Long.class); |
| 201 | + |
| 202 | + if (maxAttempts.isEmpty() |
| 203 | + && initialInterval.isEmpty() |
| 204 | + && intervalMultiplier.isEmpty() |
| 205 | + && maxInterval.isEmpty()) { |
| 206 | + return null; |
| 207 | + } |
| 208 | + |
| 209 | + return overrider -> { |
| 210 | + GenericRetry retry = GenericRetry.defaultLimitedExponentialRetry(); |
| 211 | + maxAttempts.ifPresent(retry::setMaxAttempts); |
| 212 | + initialInterval.ifPresent(retry::setInitialInterval); |
| 213 | + intervalMultiplier.ifPresent(retry::setIntervalMultiplier); |
| 214 | + maxInterval.ifPresent(retry::setMaxInterval); |
| 215 | + overrider.withRetry(retry); |
| 216 | + }; |
167 | 217 | } |
168 | 218 |
|
169 | 219 | /** |
|
0 commit comments