Skip to content

Commit 9176c64

Browse files
committed
feat: non static reference of services (#1865)
1 parent bd00db4 commit 9176c64

File tree

63 files changed

+646
-633
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+646
-633
lines changed

Diff for: micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/AbstractMicrometerMetricsTestFixture.java

+8-16
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
import java.util.HashSet;
44
import java.util.Set;
55

6-
import org.junit.jupiter.api.AfterAll;
7-
import org.junit.jupiter.api.BeforeAll;
86
import org.junit.jupiter.api.Test;
97
import org.junit.jupiter.api.TestInstance;
108
import org.junit.jupiter.api.extension.RegisterExtension;
119

1210
import io.fabric8.kubernetes.api.model.ConfigMap;
1311
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
14-
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
1512
import io.javaoperatorsdk.operator.api.reconciler.*;
1613
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
1714
import io.javaoperatorsdk.operator.processing.event.ResourceID;
@@ -23,26 +20,21 @@
2320

2421
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
2522
public abstract class AbstractMicrometerMetricsTestFixture {
26-
@RegisterExtension
27-
LocallyRunOperatorExtension operator =
28-
LocallyRunOperatorExtension.builder().withReconciler(new MetricsCleaningTestReconciler())
29-
.build();
3023

3124
protected final TestSimpleMeterRegistry registry = new TestSimpleMeterRegistry();
3225
protected final MicrometerMetrics metrics = getMetrics();
3326
protected static final String testResourceName = "micrometer-metrics-cr";
3427

35-
protected abstract MicrometerMetrics getMetrics();
3628

37-
@BeforeAll
38-
void setup() {
39-
ConfigurationServiceProvider.overrideCurrent(overrider -> overrider.withMetrics(metrics));
40-
}
29+
@RegisterExtension
30+
LocallyRunOperatorExtension operator =
31+
LocallyRunOperatorExtension.builder()
32+
.withConfigurationService(overrider -> overrider.withMetrics(metrics))
33+
.withReconciler(new MetricsCleaningTestReconciler())
34+
.build();
4135

42-
@AfterAll
43-
void reset() {
44-
ConfigurationServiceProvider.reset();
45-
}
36+
37+
protected abstract MicrometerMetrics getMetrics();
4638

4739
@Test
4840
void properlyHandlesResourceDeletion() throws Exception {

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerManager.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class ControllerManager {
2222
@SuppressWarnings("rawtypes")
2323
private final Map<String, Controller> controllers = new HashMap<>();
2424
private boolean started = false;
25+
private final ExecutorServiceManager executorServiceManager;
26+
27+
public ControllerManager(ExecutorServiceManager executorServiceManager) {
28+
this.executorServiceManager = executorServiceManager;
29+
}
30+
2531

2632
public synchronized void shouldStart() {
2733
if (started) {
@@ -33,15 +39,15 @@ public synchronized void shouldStart() {
3339
}
3440

3541
public synchronized void start(boolean startEventProcessor) {
36-
ExecutorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
42+
executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
3743
c.start(startEventProcessor);
3844
return null;
3945
}, c -> "Controller Starter for: " + c.getConfiguration().getName());
4046
started = true;
4147
}
4248

4349
public synchronized void stop() {
44-
ExecutorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
50+
executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
4551
log.debug("closing {}", c);
4652
c.stop();
4753
return null;
@@ -50,7 +56,7 @@ public synchronized void stop() {
5056
}
5157

5258
public synchronized void startEventProcessing() {
53-
ExecutorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
59+
executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
5460
c.startEventProcessing();
5561
return null;
5662
}, c -> "Event processor starter for: " + c.getConfiguration().getName());

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java

+37-32
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElector;
1313
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectorBuilder;
1414
import io.fabric8.kubernetes.client.extended.leaderelection.resourcelock.LeaseLock;
15-
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
16-
import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager;
15+
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1716
import io.javaoperatorsdk.operator.api.config.LeaderElectionConfiguration;
1817

1918
public class LeaderElectionManager {
@@ -24,41 +23,19 @@ public class LeaderElectionManager {
2423
private final ControllerManager controllerManager;
2524
private String identity;
2625
private CompletableFuture<?> leaderElectionFuture;
26+
private final ConfigurationService configurationService;
27+
private final KubernetesClient kubernetesClient;
2728

28-
public LeaderElectionManager(ControllerManager controllerManager) {
29+
public LeaderElectionManager(KubernetesClient kubernetesClient,
30+
ControllerManager controllerManager,
31+
ConfigurationService configurationService) {
32+
this.kubernetesClient = kubernetesClient;
2933
this.controllerManager = controllerManager;
30-
}
31-
32-
public void init(LeaderElectionConfiguration config, KubernetesClient client) {
33-
this.identity = identity(config);
34-
final var leaseNamespace =
35-
config.getLeaseNamespace().orElseGet(
36-
() -> ConfigurationServiceProvider.instance().getClientConfiguration().getNamespace());
37-
if (leaseNamespace == null) {
38-
final var message =
39-
"Lease namespace is not set and cannot be inferred. Leader election cannot continue.";
40-
log.error(message);
41-
throw new IllegalArgumentException(message);
42-
}
43-
final var lock = new LeaseLock(leaseNamespace, config.getLeaseName(), identity);
44-
// releaseOnCancel is not used in the underlying implementation
45-
leaderElector =
46-
new LeaderElectorBuilder(
47-
client, ExecutorServiceManager.instance().executorService())
48-
.withConfig(
49-
new LeaderElectionConfig(
50-
lock,
51-
config.getLeaseDuration(),
52-
config.getRenewDeadline(),
53-
config.getRetryPeriod(),
54-
leaderCallbacks(),
55-
true,
56-
config.getLeaseName()))
57-
.build();
34+
this.configurationService = configurationService;
5835
}
5936

6037
public boolean isLeaderElectionEnabled() {
61-
return leaderElector != null;
38+
return configurationService.getLeaderElectionConfiguration().isPresent();
6239
}
6340

6441
private LeaderCallbacks leaderCallbacks() {
@@ -90,6 +67,7 @@ private String identity(LeaderElectionConfiguration config) {
9067

9168
public void start() {
9269
if (isLeaderElectionEnabled()) {
70+
init(configurationService.getLeaderElectionConfiguration().orElseThrow());
9371
leaderElectionFuture = leaderElector.start();
9472
}
9573
}
@@ -99,4 +77,31 @@ public void stop() {
9977
leaderElectionFuture.cancel(false);
10078
}
10179
}
80+
81+
private void init(LeaderElectionConfiguration config) {
82+
this.identity = identity(config);
83+
final var leaseNamespace =
84+
config.getLeaseNamespace().orElseGet(
85+
() -> configurationService.getClientConfiguration().getNamespace());
86+
if (leaseNamespace == null) {
87+
final var message =
88+
"Lease namespace is not set and cannot be inferred. Leader election cannot continue.";
89+
log.error(message);
90+
throw new IllegalArgumentException(message);
91+
}
92+
final var lock = new LeaseLock(leaseNamespace, config.getLeaseName(), identity);
93+
// releaseOnCancel is not used in the underlying implementation
94+
leaderElector = new LeaderElectorBuilder(
95+
kubernetesClient, configurationService.getExecutorServiceManager().cachingExecutorService())
96+
.withConfig(
97+
new LeaderElectionConfig(
98+
lock,
99+
config.getLeaseDuration(),
100+
config.getRenewDeadline(),
101+
config.getRetryPeriod(),
102+
leaderCallbacks(),
103+
true,
104+
config.getLeaseName()))
105+
.build();
106+
}
102107
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java

+25-20
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
import io.fabric8.kubernetes.client.KubernetesClient;
1515
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
1616
import io.fabric8.kubernetes.client.Version;
17+
import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
1718
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1819
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider;
19-
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
2020
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
2121
import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider;
22-
import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager;
2322
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
2423
import io.javaoperatorsdk.operator.processing.Controller;
2524
import io.javaoperatorsdk.operator.processing.LifecycleAware;
@@ -29,17 +28,18 @@ public class Operator implements LifecycleAware {
2928
private static final Logger log = LoggerFactory.getLogger(Operator.class);
3029
private static final int DEFAULT_MAX_CONCURRENT_REQUEST = 512;
3130
private final KubernetesClient kubernetesClient;
32-
private final ControllerManager controllerManager = new ControllerManager();
33-
private final LeaderElectionManager leaderElectionManager =
34-
new LeaderElectionManager(controllerManager);
31+
private final ControllerManager controllerManager;
32+
private final LeaderElectionManager leaderElectionManager;
33+
private final ConfigurationService configurationService;
3534
private volatile boolean started = false;
3635

36+
3737
public Operator() {
3838
this((KubernetesClient) null);
3939
}
4040

4141
public Operator(KubernetesClient kubernetesClient) {
42-
this(kubernetesClient, ConfigurationServiceProvider.instance());
42+
this(kubernetesClient, new BaseConfigurationService());
4343
}
4444

4545
/**
@@ -56,7 +56,8 @@ public Operator(Consumer<ConfigurationServiceOverrider> overrider) {
5656
}
5757

5858
public Operator(KubernetesClient client, Consumer<ConfigurationServiceOverrider> overrider) {
59-
this(client, ConfigurationServiceProvider.overrideCurrent(overrider));
59+
this(client, ConfigurationService
60+
.newOverriddenConfigurationService(new BaseConfigurationService(), overrider));
6061
}
6162

6263
/**
@@ -67,15 +68,19 @@ public Operator(KubernetesClient client, Consumer<ConfigurationServiceOverrider>
6768
* @param configurationService provides configuration
6869
*/
6970
public Operator(KubernetesClient kubernetesClient, ConfigurationService configurationService) {
71+
this.configurationService = configurationService;
72+
final var executorServiceManager = configurationService.getExecutorServiceManager();
73+
controllerManager = new ControllerManager(executorServiceManager);
7074
this.kubernetesClient =
7175
kubernetesClient != null ? kubernetesClient
7276
: new KubernetesClientBuilder()
7377
.withConfig(new ConfigBuilder()
7478
.withMaxConcurrentRequests(DEFAULT_MAX_CONCURRENT_REQUEST).build())
7579
.build();
76-
ConfigurationServiceProvider.set(configurationService);
77-
configurationService.getLeaderElectionConfiguration()
78-
.ifPresent(c -> leaderElectionManager.init(c, this.kubernetesClient));
80+
81+
82+
leaderElectionManager =
83+
new LeaderElectionManager(kubernetesClient, controllerManager, configurationService);
7984
}
8085

8186
/**
@@ -86,8 +91,7 @@ public Operator(KubernetesClient kubernetesClient, ConfigurationService configur
8691
*/
8792
@Deprecated(forRemoval = true)
8893
public void installShutdownHook() {
89-
installShutdownHook(
90-
Duration.ofSeconds(ConfigurationServiceProvider.instance().getTerminationTimeoutSeconds()));
94+
installShutdownHook(Duration.ofSeconds(configurationService.getTerminationTimeoutSeconds()));
9195
}
9296

9397
/**
@@ -123,9 +127,8 @@ public synchronized void start() {
123127
if (started) {
124128
return;
125129
}
126-
ExecutorServiceManager.init();
127130
controllerManager.shouldStart();
128-
final var version = ConfigurationServiceProvider.instance().getVersion();
131+
final var version = configurationService.getVersion();
129132
log.info(
130133
"Operator SDK {} (commit: {}) built on {} starting...",
131134
version.getSdkVersion(),
@@ -149,12 +152,11 @@ public void stop(Duration gracefulShutdownTimeout) throws OperatorException {
149152
if (!started) {
150153
return;
151154
}
152-
final var configurationService = ConfigurationServiceProvider.instance();
153155
log.info(
154156
"Operator SDK {} is shutting down...", configurationService.getVersion().getSdkVersion());
155157
controllerManager.stop();
156158

157-
ExecutorServiceManager.stop(gracefulShutdownTimeout);
159+
configurationService.getExecutorServiceManager().stop(gracefulShutdownTimeout);
158160
leaderElectionManager.stop();
159161
if (configurationService.closeClientOnStop()) {
160162
kubernetesClient.close();
@@ -179,8 +181,7 @@ public void stop() throws OperatorException {
179181
*/
180182
public <P extends HasMetadata> RegisteredController<P> register(Reconciler<P> reconciler)
181183
throws OperatorException {
182-
final var controllerConfiguration =
183-
ConfigurationServiceProvider.instance().getConfigurationFor(reconciler);
184+
final var controllerConfiguration = configurationService.getConfigurationFor(reconciler);
184185
return register(reconciler, controllerConfiguration);
185186
}
186187

@@ -210,7 +211,7 @@ public <P extends HasMetadata> RegisteredController<P> register(Reconciler<P> re
210211
" reconciler named " + ReconcilerUtils.getNameFor(reconciler)
211212
+ " because its configuration cannot be found.\n" +
212213
" Known reconcilers are: "
213-
+ ConfigurationServiceProvider.instance().getKnownReconcilerNames());
214+
+ configurationService.getKnownReconcilerNames());
214215
}
215216

216217
final var controller = new Controller<>(reconciler, configuration, kubernetesClient);
@@ -239,7 +240,7 @@ public <P extends HasMetadata> RegisteredController<P> register(Reconciler<P> re
239240
public <P extends HasMetadata> RegisteredController<P> register(Reconciler<P> reconciler,
240241
Consumer<ControllerConfigurationOverrider<P>> configOverrider) {
241242
final var controllerConfiguration =
242-
ConfigurationServiceProvider.instance().getConfigurationFor(reconciler);
243+
configurationService.getConfigurationFor(reconciler);
243244
var configToOverride = ControllerConfigurationOverrider.override(controllerConfiguration);
244245
configOverrider.accept(configToOverride);
245246
return register(reconciler, configToOverride.build());
@@ -264,4 +265,8 @@ public RuntimeInfo getRuntimeInfo() {
264265
boolean isStarted() {
265266
return started;
266267
}
268+
269+
public ConfigurationService getConfigurationService() {
270+
return configurationService;
271+
}
267272
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile
107107
" annotation for reconciler: " + reconciler);
108108
}
109109
Class<Reconciler<P>> reconcilerClass = (Class<Reconciler<P>>) reconciler.getClass();
110-
final var resourceClass = ConfigurationServiceProvider.instance().getResourceClassResolver()
111-
.getResourceClass(reconcilerClass);
110+
final var resourceClass = getResourceClassResolver().getResourceClass(reconcilerClass);
112111

113112
final var name = ReconcilerUtils.getNameFor(reconciler);
114113
final var generationAware = valueOrDefault(
@@ -152,7 +151,7 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile
152151
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::labelSelector,
153152
Constants.NO_VALUE_SET),
154153
null,
155-
Utils.instantiate(annotation.itemStore(), ItemStore.class, context));
154+
Utils.instantiate(annotation.itemStore(), ItemStore.class, context), this);
156155

157156
ResourceEventFilter<P> answer = deprecatedEventFilter(annotation);
158157
config.setEventFilter(answer != null ? answer : ResourceEventFilters.passthrough());

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import java.time.Duration;
44
import java.util.Optional;
55
import java.util.Set;
6-
import java.util.concurrent.*;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.LinkedBlockingDeque;
8+
import java.util.concurrent.ThreadPoolExecutor;
9+
import java.util.concurrent.TimeUnit;
10+
import java.util.function.Consumer;
711

812
import org.slf4j.Logger;
913
import org.slf4j.LoggerFactory;
@@ -248,4 +252,19 @@ default ManagedWorkflowFactory getWorkflowFactory() {
248252
default ResourceClassResolver getResourceClassResolver() {
249253
return new DefaultResourceClassResolver();
250254
}
255+
256+
static ConfigurationService newOverriddenConfigurationService(
257+
ConfigurationService baseConfiguration,
258+
Consumer<ConfigurationServiceOverrider> overrider) {
259+
if (overrider != null) {
260+
final var toOverride = new ConfigurationServiceOverrider(baseConfiguration);
261+
overrider.accept(toOverride);
262+
return toOverride.build();
263+
}
264+
return baseConfiguration;
265+
}
266+
267+
default ExecutorServiceManager getExecutorServiceManager() {
268+
return new ExecutorServiceManager(this);
269+
}
251270
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,10 @@ public ResourceClassResolver getResourceClassResolver() {
236236
}
237237

238238
/**
239-
* @deprecated Use {@link ConfigurationServiceProvider#overrideCurrent(Consumer)} instead
240-
* @param original that will be overriding
239+
* @deprecated Use
240+
* {@link ConfigurationService#newOverriddenConfigurationService(ConfigurationService, Consumer)}
241+
* instead
242+
* @param original that will be overridden
241243
* @return current overrider
242244
*/
243245
@Deprecated(since = "2.2.0")

0 commit comments

Comments
 (0)