cache;
diff --git a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java
index a58d58bd2a..89fbcef70f 100644
--- a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java
+++ b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java
@@ -9,9 +9,9 @@
import com.github.benmanes.caffeine.cache.Caffeine;
/**
- * A factory for Caffeine-backed
- * {@link BoundedItemStore}. The implementation uses a {@link CaffeineBoundedCache} to store
- * resources and progressively evict them if they haven't been used in a while. The idea about
+ * A factory for Caffeine-backed {@link
+ * BoundedItemStore}. The implementation uses a {@link CaffeineBoundedCache} to store resources and
+ * progressively evict them if they haven't been used in a while. The idea about
* CaffeinBoundedItemStore-s is that, caffeine will cache the resources which were recently used,
* and will evict resource, which are not used for a while. This is ideal for startup performance
* and efficiency when all resources should be cached to avoid undue load on the API server. This is
@@ -20,11 +20,11 @@
* happen that some / many of these resources are then seldom or even reconciled anymore. In that
* situation, large amounts of memory might be consumed to cache resources that are never used
* again.
- *
- * Note that if a resource is reconciled and is not present anymore in cache, it will transparently
- * be fetched again from the API server. Similarly, since associated secondary resources are usually
- * reconciled too, they might need to be fetched and populated to the cache, and will remain there
- * for some time, for subsequent reconciliations.
+ *
+ *
Note that if a resource is reconciled and is not present anymore in cache, it will
+ * transparently be fetched again from the API server. Similarly, since associated secondary
+ * resources are usually reconciled too, they might need to be fetched and populated to the cache,
+ * and will remain there for some time, for subsequent reconciliations.
*/
public class CaffeineBoundedItemStores {
@@ -39,11 +39,8 @@ private CaffeineBoundedItemStores() {}
*/
@SuppressWarnings("unused")
public static BoundedItemStore boundedItemStore(
- KubernetesClient client, Class rClass,
- Duration accessExpireDuration) {
- Cache cache = Caffeine.newBuilder()
- .expireAfterAccess(accessExpireDuration)
- .build();
+ KubernetesClient client, Class rClass, Duration accessExpireDuration) {
+ Cache cache = Caffeine.newBuilder().expireAfterAccess(accessExpireDuration).build();
return boundedItemStore(client, rClass, cache);
}
@@ -51,5 +48,4 @@ public static BoundedItemStore boundedItemStore(
KubernetesClient client, Class rClass, Cache cache) {
return new BoundedItemStore<>(new CaffeineBoundedCache<>(cache), rClass, client);
}
-
}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCacheTestBase.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCacheTestBase.java
index 21adf81cc0..05d31a7479 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCacheTestBase.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCacheTestBase.java
@@ -17,7 +17,8 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
-public abstract class BoundedCacheTestBase> {
+public abstract class BoundedCacheTestBase<
+ P extends CustomResource> {
private static final Logger log = LoggerFactory.getLogger(BoundedCacheTestBase.class);
@@ -42,34 +43,46 @@ void reconciliationWorksWithLimitedCache() {
}
private void assertConfigMapsDeleted() {
- await().atMost(Duration.ofSeconds(30))
- .untilAsserted(() -> IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST).forEach(i -> {
- var cm = extension().get(ConfigMap.class, RESOURCE_NAME_PREFIX + i);
- assertThat(cm).isNull();
- }));
+ await()
+ .atMost(Duration.ofSeconds(30))
+ .untilAsserted(
+ () ->
+ IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
+ .forEach(
+ i -> {
+ var cm = extension().get(ConfigMap.class, RESOURCE_NAME_PREFIX + i);
+ assertThat(cm).isNull();
+ }));
}
private void deleteTestResources() {
- IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST).forEach(i -> {
- var cm = extension().get(customResourceClass(), RESOURCE_NAME_PREFIX + i);
- var deleted = extension().delete(cm);
- if (!deleted) {
- log.warn("Custom resource might not be deleted: {}", cm);
- }
- });
+ IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
+ .forEach(
+ i -> {
+ var cm = extension().get(customResourceClass(), RESOURCE_NAME_PREFIX + i);
+ var deleted = extension().delete(cm);
+ if (!deleted) {
+ log.warn("Custom resource might not be deleted: {}", cm);
+ }
+ });
}
private void updateTestResources() {
- IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST).forEach(i -> {
- var cm = extension().get(ConfigMap.class, RESOURCE_NAME_PREFIX + i);
- cm.getData().put(DATA_KEY, UPDATED_PREFIX + i);
- extension().replace(cm);
- });
+ IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
+ .forEach(
+ i -> {
+ var cm = extension().get(ConfigMap.class, RESOURCE_NAME_PREFIX + i);
+ cm.getData().put(DATA_KEY, UPDATED_PREFIX + i);
+ extension().replace(cm);
+ });
}
void assertConfigMapData(String dataPrefix) {
- await().untilAsserted(() -> IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
- .forEach(i -> assertConfigMap(i, dataPrefix)));
+ await()
+ .untilAsserted(
+ () ->
+ IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
+ .forEach(i -> assertConfigMap(i, dataPrefix)));
}
private void assertConfigMap(int i, String prefix) {
@@ -79,9 +92,11 @@ private void assertConfigMap(int i, String prefix) {
}
private void createTestResources() {
- IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST).forEach(i -> {
- extension().create(createTestResource(i));
- });
+ IntStream.range(0, NUMBER_OF_RESOURCE_TO_TEST)
+ .forEach(
+ i -> {
+ extension().create(createTestResource(i));
+ });
}
abstract P createTestResource(int index);
@@ -89,7 +104,4 @@ private void createTestResources() {
abstract Class customResourceClass();
abstract LocallyRunOperatorExtension extension();
-
-
-
}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheClusterScopeIT.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheClusterScopeIT.java
index 252b20f4a4..0c16c1227b 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheClusterScopeIT.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheClusterScopeIT.java
@@ -19,21 +19,22 @@ public class CaffeineBoundedCacheClusterScopeIT
@RegisterExtension
LocallyRunOperatorExtension extension =
LocallyRunOperatorExtension.builder()
- .withReconciler(new BoundedCacheClusterScopeTestReconciler(), o -> {
- o.withItemStore(boundedItemStore(
- new KubernetesClientBuilder().build(),
- BoundedCacheClusterScopeTestCustomResource.class,
- Duration.ofMinutes(1),
- 1));
- })
+ .withReconciler(
+ new BoundedCacheClusterScopeTestReconciler(),
+ o -> {
+ o.withItemStore(
+ boundedItemStore(
+ new KubernetesClientBuilder().build(),
+ BoundedCacheClusterScopeTestCustomResource.class,
+ Duration.ofMinutes(1),
+ 1));
+ })
.build();
@Override
BoundedCacheClusterScopeTestCustomResource createTestResource(int index) {
var res = new BoundedCacheClusterScopeTestCustomResource();
- res.setMetadata(new ObjectMetaBuilder()
- .withName(RESOURCE_NAME_PREFIX + index)
- .build());
+ res.setMetadata(new ObjectMetaBuilder().withName(RESOURCE_NAME_PREFIX + index).build());
res.setSpec(new BoundedCacheTestSpec());
res.getSpec().setData(INITIAL_DATA_PREFIX + index);
res.getSpec().setTargetNamespace(extension.getNamespace());
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheNamespacedIT.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheNamespacedIT.java
index ae7f8f5873..534d7b2027 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheNamespacedIT.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCacheNamespacedIT.java
@@ -18,19 +18,22 @@ class CaffeineBoundedCacheNamespacedIT
@RegisterExtension
LocallyRunOperatorExtension extension =
- LocallyRunOperatorExtension.builder().withReconciler(new BoundedCacheTestReconciler(), o -> {
- o.withItemStore(boundedItemStore(
- new KubernetesClientBuilder().build(), BoundedCacheTestCustomResource.class,
- Duration.ofMinutes(1),
- 1));
- })
+ LocallyRunOperatorExtension.builder()
+ .withReconciler(
+ new BoundedCacheTestReconciler(),
+ o -> {
+ o.withItemStore(
+ boundedItemStore(
+ new KubernetesClientBuilder().build(),
+ BoundedCacheTestCustomResource.class,
+ Duration.ofMinutes(1),
+ 1));
+ })
.build();
BoundedCacheTestCustomResource createTestResource(int index) {
var res = new BoundedCacheTestCustomResource();
- res.setMetadata(new ObjectMetaBuilder()
- .withName(RESOURCE_NAME_PREFIX + index)
- .build());
+ res.setMetadata(new ObjectMetaBuilder().withName(RESOURCE_NAME_PREFIX + index).build());
res.setSpec(new BoundedCacheTestSpec());
res.getSpec().setData(INITIAL_DATA_PREFIX + index);
res.getSpec().setTargetNamespace(extension.getNamespace());
@@ -46,5 +49,4 @@ Class customResourceClass() {
LocallyRunOperatorExtension extension() {
return extension;
}
-
}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/AbstractTestReconciler.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/AbstractTestReconciler.java
index 10ab50138a..b059ac033b 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/AbstractTestReconciler.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/AbstractTestReconciler.java
@@ -28,7 +28,8 @@
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
-public abstract class AbstractTestReconciler>
+public abstract class AbstractTestReconciler<
+ P extends CustomResource>
implements Reconciler {
private static final Logger log =
@@ -37,9 +38,7 @@ public abstract class AbstractTestReconciler
reconcile(
- P resource,
- Context
context) {
+ public UpdateControl
reconcile(P resource, Context
context) {
var maybeConfigMap = context.getSecondaryResource(ConfigMap.class);
maybeConfigMap.ifPresentOrElse(
cm -> updateConfigMapIfNeeded(cm, resource, context),
@@ -58,33 +57,39 @@ protected void updateConfigMapIfNeeded(ConfigMap cm, P resource, Context
cont
}
protected void createConfigMap(P resource, Context
context) {
- var cm = new ConfigMapBuilder()
- .withMetadata(new ObjectMetaBuilder()
- .withName(resource.getMetadata().getName())
- .withNamespace(resource.getSpec().getTargetNamespace())
- .build())
- .withData(Map.of(DATA_KEY, resource.getSpec().getData()))
- .build();
+ var cm =
+ new ConfigMapBuilder()
+ .withMetadata(
+ new ObjectMetaBuilder()
+ .withName(resource.getMetadata().getName())
+ .withNamespace(resource.getSpec().getTargetNamespace())
+ .build())
+ .withData(Map.of(DATA_KEY, resource.getSpec().getData()))
+ .build();
cm.addOwnerReference(resource);
context.getClient().configMaps().resource(cm).create();
}
@Override
- public List> prepareEventSources(
- EventSourceContext context) {
+ public List> prepareEventSources(EventSourceContext context) {
var boundedItemStore =
- boundedItemStore(new KubernetesClientBuilder().build(),
- ConfigMap.class, Duration.ofMinutes(1), 1); // setting max size for testing purposes
-
- var es = new InformerEventSource<>(
- InformerEventSourceConfiguration.from(ConfigMap.class, primaryClass())
- .withItemStore(boundedItemStore)
- .withSecondaryToPrimaryMapper(
- Mappers.fromOwnerReferences(context.getPrimaryResourceClass(),
- this instanceof BoundedCacheClusterScopeTestReconciler))
- .build(),
- context);
+ boundedItemStore(
+ new KubernetesClientBuilder().build(),
+ ConfigMap.class,
+ Duration.ofMinutes(1),
+ 1); // setting max size for testing purposes
+
+ var es =
+ new InformerEventSource<>(
+ InformerEventSourceConfiguration.from(ConfigMap.class, primaryClass())
+ .withItemStore(boundedItemStore)
+ .withSecondaryToPrimaryMapper(
+ Mappers.fromOwnerReferences(
+ context.getPrimaryResourceClass(),
+ this instanceof BoundedCacheClusterScopeTestReconciler))
+ .build(),
+ context);
return List.of(es);
}
@@ -96,17 +101,18 @@ private void ensureStatus(P resource) {
}
public static BoundedItemStore boundedItemStore(
- KubernetesClient client, Class rClass,
+ KubernetesClient client,
+ Class rClass,
Duration accessExpireDuration,
// max size is only for testing purposes
long cacheMaxSize) {
- Cache cache = Caffeine.newBuilder()
- .expireAfterAccess(accessExpireDuration)
- .maximumSize(cacheMaxSize)
- .build();
+ Cache cache =
+ Caffeine.newBuilder()
+ .expireAfterAccess(accessExpireDuration)
+ .maximumSize(cacheMaxSize)
+ .build();
return CaffeineBoundedItemStores.boundedItemStore(client, rClass, cache);
}
protected abstract Class primaryClass();
-
}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestCustomResource.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestCustomResource.java
index a77416715e..6fc9a5babc 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestCustomResource.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestCustomResource.java
@@ -11,5 +11,4 @@
@Version("v1")
@ShortNames("bccs")
public class BoundedCacheClusterScopeTestCustomResource
- extends CustomResource {
-}
+ extends CustomResource {}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestReconciler.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestReconciler.java
index 84448fc9d8..93f103cbf2 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestReconciler.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/clusterscope/BoundedCacheClusterScopeTestReconciler.java
@@ -4,8 +4,8 @@
import io.javaoperatorsdk.operator.processing.event.source.cache.sample.AbstractTestReconciler;
@ControllerConfiguration
-public class BoundedCacheClusterScopeTestReconciler extends
- AbstractTestReconciler {
+public class BoundedCacheClusterScopeTestReconciler
+ extends AbstractTestReconciler {
@Override
protected Class primaryClass() {
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestCustomResource.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestCustomResource.java
index a5e37917ba..9b77aa7bf8 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestCustomResource.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestCustomResource.java
@@ -10,5 +10,4 @@
@Version("v1")
@ShortNames("bct")
public class BoundedCacheTestCustomResource
- extends CustomResource implements Namespaced {
-}
+ extends CustomResource implements Namespaced {}
diff --git a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestStatus.java b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestStatus.java
index 2bdd434d23..5aa5ca2258 100644
--- a/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestStatus.java
+++ b/caffeine-bounded-cache-support/src/test/java/io/javaoperatorsdk/operator/processing/event/source/cache/sample/namespacescope/BoundedCacheTestStatus.java
@@ -1,4 +1,3 @@
package io.javaoperatorsdk.operator.processing.event.source.cache.sample.namespacescope;
-public class BoundedCacheTestStatus {
-}
+public class BoundedCacheTestStatus {}
diff --git a/contributing/eclipse-google-style.xml b/contributing/eclipse-google-style.xml
deleted file mode 100644
index 64340b1054..0000000000
--- a/contributing/eclipse-google-style.xml
+++ /dev/null
@@ -1,337 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/contributing/eclipse.importorder b/contributing/eclipse.importorder
deleted file mode 100644
index 8a156041e9..0000000000
--- a/contributing/eclipse.importorder
+++ /dev/null
@@ -1,7 +0,0 @@
-0=java
-1=javax
-2=org
-3=io
-4=com
-5=
-6=\#
diff --git a/docs/content/en/blog/news/_index.md b/docs/content/en/blog/news/_index.md
index c609aa2543..646c97f954 100644
--- a/docs/content/en/blog/news/_index.md
+++ b/docs/content/en/blog/news/_index.md
@@ -1,4 +1,4 @@
---
-title: News
+title: Posts
weight: 20
---
diff --git a/docs/content/en/blog/news/nonssa-vs-ssa.md b/docs/content/en/blog/news/nonssa-vs-ssa.md
new file mode 100644
index 0000000000..8ea7497771
--- /dev/null
+++ b/docs/content/en/blog/news/nonssa-vs-ssa.md
@@ -0,0 +1,117 @@
+---
+title: From legacy approach to server-side apply
+date: 2025-02-25
+author: >-
+ [Attila Mészáros](https://github.com/csviri)
+---
+
+From version 5 of Java Operator SDK [server side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/)
+is a first-class feature and is used by default to update resources.
+As we will see, unfortunately (or fortunately), using it requires changes for your reconciler implementation.
+
+For this reason, we prepared a feature flag, which you can flip if you are not prepared to migrate yet:
+[`ConfigurationService.useSSAToPatchPrimaryResource`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L493)
+
+Setting this flag to false will make the operations done by `UpdateControl` using the former approach (not SSA).
+Similarly, the finalizer handling won't utilize SSA handling.
+The plan is to keep this flag and allow the use of the former approach (non-SSA) also in future releases.
+
+For dependent resources, a separate flag exists (this was true also before v5) to use SSA or not:
+[`ConfigurationService.ssaBasedCreateUpdateMatchForDependentResources`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java#L373)
+
+
+## Resource handling without and with SSA
+
+Until version 5, changing primary resources through `UpdateControl` did not use server-side apply.
+So usually, the implementation of the reconciler looked something like this:
+
+```java
+
+ @Override
+ public UpdateControl reconcile(WebPage webPage, Context context) {
+
+ reconcileLogicForManagedResources(webPage);
+ webPage.setStatus(updatedStatusForWebPage(webPage));
+
+ return UpdateControl.patchStatus(webPage);
+ }
+
+```
+
+In other words, after the reconciliation of managed resources, the reconciler updates the status of the
+primary resource passed as an argument to the reconciler.
+Such changes on the primary are fine since we don't work directly with the cached object, the argument is
+already cloned.
+
+So, how does this change with SSA?
+For SSA, the updates should contain (only) the "fully specified intent".
+In other words, we should only fill in the values we care about.
+In practice, it means creating a **fresh copy** of the resource and setting only what is necessary:
+
+```java
+
+@Override
+public UpdateControl reconcile(WebPage webPage, Context context) {
+
+ reconcileLogicForManagedResources(webPage);
+
+ WebPage statusPatch = new WebPage();
+ statusPatch.setMetadata(new ObjectMetaBuilder()
+ .withName(webPage.getMetadata().getName())
+ .withNamespace(webPage.getMetadata().getNamespace())
+ .build());
+ statusPatch.setStatus(updatedStatusForWebPage(webPage));
+
+ return UpdateControl.patchStatus(statusPatch);
+}
+```
+
+Note that we just filled out the status here since we patched the status (not the resource spec).
+Since the status is a sub-resource in Kubernetes, it will only update the status part.
+
+Every controller you register will have its default [field manager](https://kubernetes.io/docs/reference/using-api/server-side-apply/#managers).
+You can override the field manager name using [`ControllerConfiguration.fieldManager`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java#L89).
+That will set the field manager for the primary resource and dependent resources as well.
+
+## Migrating to SSA
+
+Using the legacy or the new SSA way of resource management works well.
+However, migrating existing resources to SSA might be a challenge.
+We strongly recommend testing the migration, thus implementing an integration test where
+a custom resource is created using the legacy approach and is managed by the new approach.
+
+We prepared an integration test to demonstrate how such migration, even in a simple case, can go wrong,
+and how to fix it.
+
+To fix some cases, you might need to [strip managed fields](https://kubernetes.io/docs/reference/using-api/server-side-apply/#clearing-managedfields)
+from the custom resource.
+
+See [`StatusPatchSSAMigrationIT`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuspatchnonlocking/StatusPatchSSAMigrationIT.java) for details.
+
+Feel free to report common issues, so we can prepare some utilities to handle them.
+
+## Optimistic concurrency control
+
+When you create a resource for SSA as mentioned above, the framework will apply changes even if the underlying resource
+or status subresource is changed while the reconciliation was running.
+First, it always forces the conflicts in the background as advised in [Kubernetes docs](https://kubernetes.io/docs/reference/using-api/server-side-apply/#using-server-side-apply-in-a-controller),
+ in addition to that since the resource version is not set it won't do optimistic locking. If you still
+want to have optimistic locking for the patch, use the resource version of the original resource:
+
+```java
+@Override
+public UpdateControl reconcile(WebPage webPage, Context context) {
+
+ reconcileLogicForManagedResources(webPage);
+
+ WebPage statusPatch = new WebPage();
+ statusPatch.setMetadata(new ObjectMetaBuilder()
+ .withName(webPage.getMetadata().getName())
+ .withNamespace(webPage.getMetadata().getNamespace())
+ .withResourceVersion(webPage.getMetadata().getResourceVersion())
+ .build());
+ statusPatch.setStatus(updatedStatusForWebPage(webPage));
+
+ return UpdateControl.patchStatus(statusPatch);
+}
+```
diff --git a/docs/content/en/blog/releases/v5-release.md b/docs/content/en/blog/releases/v5-release.md
index 8d5fe36dbe..6d14dfb73a 100644
--- a/docs/content/en/blog/releases/v5-release.md
+++ b/docs/content/en/blog/releases/v5-release.md
@@ -41,7 +41,7 @@ to `false`.
See some identified problematic migration cases and how to handle them
in [StatusPatchSSAMigrationIT](https://github.com/operator-framework/java-operator-sdk/blob/1635c9ea338f8e89bacc547808d2b409de8734cf/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuspatchnonlocking/StatusPatchSSAMigrationIT.java).
-TODO using new instance to update status always,
+For more detailed description, see our [blog post](../news/nonssa-vs-ssa.md) on SSA.
### Event Sources related changes
diff --git a/docs/content/en/docs/contributing/_index.md b/docs/content/en/docs/contributing/_index.md
index e67c45ebb6..dfe6dec99c 100644
--- a/docs/content/en/docs/contributing/_index.md
+++ b/docs/content/en/docs/contributing/_index.md
@@ -72,9 +72,9 @@ avoid getting a PR rejected simply because of code style issues), you can import
following code style schemes based on the IDE you use:
- for *Intellij IDEA*
- import [contributing/intellij-google-style.xml](contributing/intellij-google-style.xml)
+ install [google-java-format](https://plugins.jetbrains.com/plugin/8527-google-java-format) plugin
- for *Eclipse*
- import [contributing/eclipse-google-style.xml](contributing/eclipse-google-style.xml)
+ follow [these intructions](https://github.com/google/google-java-format?tab=readme-ov-file#eclipse)
## Thanks
diff --git a/docs/go.mod b/docs/go.mod
index 00890a6408..65768398bb 100644
--- a/docs/go.mod
+++ b/docs/go.mod
@@ -2,4 +2,4 @@ module github.com/google/docsy-example
go 1.12
-require github.com/google/docsy v0.10.0 // indirect
+require github.com/google/docsy v0.11.0 // indirect
diff --git a/docs/go.sum b/docs/go.sum
index 1b3ed24b03..c7a05f45f1 100644
--- a/docs/go.sum
+++ b/docs/go.sum
@@ -1,9 +1,12 @@
github.com/FortAwesome/Font-Awesome v0.0.0-20240108205627-a1232e345536/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/FortAwesome/Font-Awesome v0.0.0-20240716171331-37eff7fa00de/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
github.com/google/docsy v0.9.1 h1:+jqges1YCd+yHeuZ1BUvD8V8mEGVtPxULg5j/vaJ984=
github.com/google/docsy v0.9.1/go.mod h1:saOqKEUOn07Bc0orM/JdIF3VkOanHta9LU5Y53bwN2U=
github.com/google/docsy v0.10.0 h1:6tMDacPwAyRWNCfvsn/9qGOZDQ8b0aRzjRZvnZPY5dg=
github.com/google/docsy v0.10.0/go.mod h1:c0nIAqmRTOuJ01F85U/wJPQtc3Zj9N58Kea9bOT2AJc=
+github.com/google/docsy v0.11.0 h1:QnV40cc28QwS++kP9qINtrIv4hlASruhC/K3FqkHAmM=
+github.com/google/docsy v0.11.0/go.mod h1:hGGW0OjNuG5ZbH5JRtALY3yvN8ybbEP/v2iaK4bwOUI=
github.com/twbs/bootstrap v5.2.3+incompatible h1:lOmsJx587qfF7/gE7Vv4FxEofegyJlEACeVV+Mt7cgc=
github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
github.com/twbs/bootstrap v5.3.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
diff --git a/docs/layouts/partials/scripts/mermaid.html b/docs/layouts/partials/scripts/mermaid.html
new file mode 100644
index 0000000000..ac9290a10f
--- /dev/null
+++ b/docs/layouts/partials/scripts/mermaid.html
@@ -0,0 +1,68 @@
+
+{{ $version := .Site.Params.mermaid.version | default "latest" -}}
+
+{{ $cdnurl := printf "https://cdn.jsdelivr.net/npm/mermaid@%s/dist/mermaid.esm.min.mjs" $version -}}
+{{ with try (resources.GetRemote $cdnurl) -}}
+{{ with .Err -}}
+{{ errorf "Could not retrieve mermaid script from CDN. Reason: %s." . -}}
+{{ end -}}
+{{ else -}}
+{{ errorf "Invalid Mermaid version %s, could not retrieve this version from CDN." $version -}}
+{{ end -}}
+
+
\ No newline at end of file
diff --git a/docs/package.json b/docs/package.json
index 02cc7f496a..a5a57eaa4c 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -1,7 +1,7 @@
{
- "name": "docsy-example-site",
- "version": "0.9.1",
- "version.next": "0.9.2-dev.0-unreleased",
+ "name": "java-operator-sdk",
+ "version": "0.10.0",
+ "version.next": "0.10.1-dev.0-unreleased",
"description": "Example site that uses Docsy theme for technical documentation.",
"repository": "github:google/docsy-example",
"homepage": "https://javaoperatorsdk.io",
@@ -34,7 +34,7 @@
"update:pkg:hugo": "npm install --save-dev --save-exact hugo-extended@latest"
},
"devDependencies": {
- "autoprefixer": "^10.4.19",
+ "autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
"hugo-extended": "0.125.4",
"postcss-cli": "^11.0.0"
diff --git a/micrometer-support/pom.xml b/micrometer-support/pom.xml
index d39a5fad8f..67fe0d4b4c 100644
--- a/micrometer-support/pom.xml
+++ b/micrometer-support/pom.xml
@@ -4,7 +4,7 @@
io.javaoperatorsdk
java-operator-sdk
- 5.0.3-SNAPSHOT
+ 5.0.4-SNAPSHOT
micrometer-support
diff --git a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java
index 07106d9b3c..26f149249b 100644
--- a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java
+++ b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java
@@ -89,8 +89,8 @@ public static MicrometerMetricsBuilder newMicrometerMetricsBuilder(MeterRegistry
* @return a MicrometerMetrics instance configured to not collect per-resource metrics
* @see PerResourceCollectingMicrometerMetricsBuilder
*/
- public static PerResourceCollectingMicrometerMetricsBuilder newPerResourceCollectingMicrometerMetricsBuilder(
- MeterRegistry registry) {
+ public static PerResourceCollectingMicrometerMetricsBuilder
+ newPerResourceCollectingMicrometerMetricsBuilder(MeterRegistry registry) {
return new PerResourceCollectingMicrometerMetricsBuilder(registry);
}
@@ -103,8 +103,8 @@ public static PerResourceCollectingMicrometerMetricsBuilder newPerResourceCollec
* @param cleaner the {@link Cleaner} to use
* @param collectingPerResourceMetrics whether to collect per resource metrics
*/
- private MicrometerMetrics(MeterRegistry registry, Cleaner cleaner,
- boolean collectingPerResourceMetrics) {
+ private MicrometerMetrics(
+ MeterRegistry registry, Cleaner cleaner, boolean collectingPerResourceMetrics) {
this.registry = registry;
this.cleaner = cleaner;
this.collectPerResourceMetrics = collectingPerResourceMetrics;
@@ -144,17 +144,17 @@ public T timeControllerExecution(ControllerExecution execution) {
.publishPercentileHistogram()
.register(registry);
try {
- final var result = timer.record(() -> {
- try {
- return execution.execute();
- } catch (Exception e) {
- throw new OperatorException(e);
- }
- });
+ final var result =
+ timer.record(
+ () -> {
+ try {
+ return execution.execute();
+ } catch (Exception e) {
+ throw new OperatorException(e);
+ }
+ });
final var successType = execution.successTypeName(result);
- registry
- .counter(execName + SUCCESS_SUFFIX, CONTROLLER, name, TYPE, successType)
- .increment();
+ registry.counter(execName + SUCCESS_SUFFIX, CONTROLLER, name, TYPE, successType).increment();
return result;
} catch (Exception e) {
final var exception = e.getClass().getSimpleName();
@@ -168,12 +168,16 @@ public T timeControllerExecution(ControllerExecution execution) {
@Override
public void receivedEvent(Event event, Map metadata) {
if (event instanceof ResourceEvent) {
- incrementCounter(event.getRelatedCustomResourceID(), EVENTS_RECEIVED,
+ incrementCounter(
+ event.getRelatedCustomResourceID(),
+ EVENTS_RECEIVED,
metadata,
Tag.of(EVENT, event.getClass().getSimpleName()),
Tag.of(ACTION, ((ResourceEvent) event).getAction().toString()));
} else {
- incrementCounter(event.getRelatedCustomResourceID(), EVENTS_RECEIVED,
+ incrementCounter(
+ event.getRelatedCustomResourceID(),
+ EVENTS_RECEIVED,
metadata,
Tag.of(EVENT, event.getClass().getSimpleName()));
}
@@ -187,14 +191,18 @@ public void cleanupDoneFor(ResourceID resourceID, Map metadata)
}
@Override
- public void reconcileCustomResource(HasMetadata resource, RetryInfo retryInfoNullable,
- Map metadata) {
+ public void reconcileCustomResource(
+ HasMetadata resource, RetryInfo retryInfoNullable, Map metadata) {
Optional retryInfo = Optional.ofNullable(retryInfoNullable);
- incrementCounter(ResourceID.fromResource(resource), RECONCILIATIONS_STARTED,
+ incrementCounter(
+ ResourceID.fromResource(resource),
+ RECONCILIATIONS_STARTED,
metadata,
- Tag.of(RECONCILIATIONS_RETRIES_NUMBER,
+ Tag.of(
+ RECONCILIATIONS_RETRIES_NUMBER,
String.valueOf(retryInfo.map(RetryInfo::getAttemptCount).orElse(0))),
- Tag.of(RECONCILIATIONS_RETRIES_LAST,
+ Tag.of(
+ RECONCILIATIONS_RETRIES_LAST,
String.valueOf(retryInfo.map(RetryInfo::isLastAttempt).orElse(true))));
var controllerQueueSize =
@@ -226,15 +234,18 @@ public void reconciliationExecutionFinished(HasMetadata resource, Map metadata) {
+ public void failedReconciliation(
+ HasMetadata resource, Exception exception, Map metadata) {
var cause = exception.getCause();
if (cause == null) {
cause = exception;
} else if (cause instanceof RuntimeException) {
cause = cause.getCause() != null ? cause.getCause() : cause;
}
- incrementCounter(ResourceID.fromResource(resource), RECONCILIATIONS_FAILED, metadata,
+ incrementCounter(
+ ResourceID.fromResource(resource),
+ RECONCILIATIONS_FAILED,
+ metadata,
Tag.of(EXCEPTION, cause.getClass().getSimpleName()));
}
@@ -243,9 +254,8 @@ public void failedReconciliation(HasMetadata resource, Exception exception,
return registry.gaugeMapSize(PREFIX + name + SIZE_SUFFIX, Collections.emptyList(), map);
}
-
- private void addMetadataTags(ResourceID resourceID, Map metadata,
- List tags, boolean prefixed) {
+ private void addMetadataTags(
+ ResourceID resourceID, Map metadata, List tags, boolean prefixed) {
if (collectPerResourceMetrics) {
addTag(NAME, resourceID.getName(), tags, prefixed);
addTagOmittingOnEmptyValue(NAMESPACE, resourceID.getNamespace().orElse(null), tags, prefixed);
@@ -261,8 +271,8 @@ private static void addTag(String name, String value, List tags, boolean pr
tags.add(Tag.of(getPrefixedMetadataTag(name, prefixed), value));
}
- private static void addTagOmittingOnEmptyValue(String name, String value, List tags,
- boolean prefixed) {
+ private static void addTagOmittingOnEmptyValue(
+ String name, String value, List tags, boolean prefixed) {
if (value != null && !value.isBlank()) {
addTag(name, value, tags, prefixed);
}
@@ -282,8 +292,8 @@ private static void addGVKTags(GroupVersionKind gvk, List tags, boolean pre
addTag(KIND, gvk.getKind(), tags, prefixed);
}
- private void incrementCounter(ResourceID id, String counterName, Map metadata,
- Tag... additionalTags) {
+ private void incrementCounter(
+ ResourceID id, String counterName, Map metadata, Tag... additionalTags) {
final var additionalTagsNb =
additionalTags != null && additionalTags.length > 0 ? additionalTags.length : 0;
final var metadataNb = metadata != null ? metadata.size() : 0;
@@ -314,8 +324,8 @@ private PerResourceCollectingMicrometerMetricsBuilder(MeterRegistry registry) {
/**
* @param cleaningThreadsNumber the maximal number of threads that can be assigned to the
- * removal of {@link Meter}s associated with deleted resources, defaults to 1 if not
- * specified or if the provided number is lesser or equal to 0
+ * removal of {@link Meter}s associated with deleted resources, defaults to 1 if not
+ * specified or if the provided number is lesser or equal to 0
*/
public PerResourceCollectingMicrometerMetricsBuilder withCleaningThreadNumber(
int cleaningThreadsNumber) {
@@ -325,11 +335,11 @@ public PerResourceCollectingMicrometerMetricsBuilder withCleaningThreadNumber(
/**
* @param cleanUpDelayInSeconds the number of seconds to wait before {@link Meter}s are removed
- * for deleted resources, defaults to 1 (meaning meters will be removed one second after
- * the associated resource is deleted) if not specified or if the provided number is
- * lesser than 0. Threading and the general interaction model of interacting with the API
- * server means that it's not possible to ensure that meters are immediately deleted in
- * all cases so a minimal delay of one second is always enforced
+ * for deleted resources, defaults to 1 (meaning meters will be removed one second after the
+ * associated resource is deleted) if not specified or if the provided number is lesser than
+ * 0. Threading and the general interaction model of interacting with the API server means
+ * that it's not possible to ensure that meters are immediately deleted in all cases so a
+ * minimal delay of one second is always enforced
*/
public PerResourceCollectingMicrometerMetricsBuilder withCleanUpDelayInSeconds(
int cleanUpDelayInSeconds) {
@@ -344,6 +354,7 @@ public MicrometerMetrics build() {
return new MicrometerMetrics(registry, cleaner, true);
}
}
+
public static class MicrometerMetricsBuilder {
protected final MeterRegistry registry;
private boolean collectingPerResourceMetrics = true;
@@ -352,9 +363,7 @@ private MicrometerMetricsBuilder(MeterRegistry registry) {
this.registry = registry;
}
- /**
- * Configures the instance to collect metrics on a per-resource basis.
- */
+ /** Configures the instance to collect metrics on a per-resource basis. */
@SuppressWarnings("unused")
public PerResourceCollectingMicrometerMetricsBuilder collectingMetricsPerResource() {
collectingPerResourceMetrics = true;
@@ -422,8 +431,8 @@ static class DelayedCleaner extends MicrometerMetrics.DefaultCleaner {
private final ScheduledExecutorService metersCleaner;
private final int cleanUpDelayInSeconds;
- private DelayedCleaner(MeterRegistry registry, int cleanUpDelayInSeconds,
- int cleaningThreadsNumber) {
+ private DelayedCleaner(
+ MeterRegistry registry, int cleanUpDelayInSeconds, int cleaningThreadsNumber) {
super(registry);
this.cleanUpDelayInSeconds = cleanUpDelayInSeconds;
this.metersCleaner = Executors.newScheduledThreadPool(cleaningThreadsNumber);
@@ -432,8 +441,8 @@ private DelayedCleaner(MeterRegistry registry, int cleanUpDelayInSeconds,
@Override
public void removeMetersFor(ResourceID resourceID) {
// schedule deletion of meters associated with ResourceID
- metersCleaner.schedule(() -> super.removeMetersFor(resourceID),
- cleanUpDelayInSeconds, TimeUnit.SECONDS);
+ metersCleaner.schedule(
+ () -> super.removeMetersFor(resourceID), cleanUpDelayInSeconds, TimeUnit.SECONDS);
}
}
}
diff --git a/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/AbstractMicrometerMetricsTestFixture.java b/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/AbstractMicrometerMetricsTestFixture.java
index 8575f07243..788253e5e8 100644
--- a/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/AbstractMicrometerMetricsTestFixture.java
+++ b/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/AbstractMicrometerMetricsTestFixture.java
@@ -25,7 +25,6 @@ public abstract class AbstractMicrometerMetricsTestFixture {
protected final MicrometerMetrics metrics = getMetrics();
protected static final String testResourceName = "micrometer-metrics-cr";
-
@RegisterExtension
LocallyRunOperatorExtension operator =
LocallyRunOperatorExtension.builder()
@@ -33,21 +32,23 @@ public abstract class AbstractMicrometerMetricsTestFixture {
.withReconciler(new MetricsCleaningTestReconciler())
.build();
-
protected abstract MicrometerMetrics getMetrics();
@Test
void properlyHandlesResourceDeletion() throws Exception {
- var testResource = new ConfigMapBuilder()
- .withNewMetadata()
- .withName(testResourceName)
- .endMetadata()
- .build();
+ var testResource =
+ new ConfigMapBuilder().withNewMetadata().withName(testResourceName).endMetadata().build();
final var created = operator.create(testResource);
// make sure the resource is created
- await().until(() -> !operator.get(ConfigMap.class, testResourceName)
- .getMetadata().getFinalizers().isEmpty());
+ await()
+ .until(
+ () ->
+ !operator
+ .get(ConfigMap.class, testResourceName)
+ .getMetadata()
+ .getFinalizers()
+ .isEmpty());
final var resourceID = ResourceID.fromResource(created);
final var meters = preDeleteChecks(resourceID);
diff --git a/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/DelayedMetricsCleaningOnDeleteIT.java b/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/DelayedMetricsCleaningOnDeleteIT.java
index 26dfe59f84..92929d5ddb 100644
--- a/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/DelayedMetricsCleaningOnDeleteIT.java
+++ b/micrometer-support/src/test/java/io/javaoperatorsdk/operator/monitoring/micrometer/DelayedMetricsCleaningOnDeleteIT.java
@@ -15,7 +15,9 @@ public class DelayedMetricsCleaningOnDeleteIT extends AbstractMicrometerMetricsT
@Override
protected MicrometerMetrics getMetrics() {
return MicrometerMetrics.newPerResourceCollectingMicrometerMetricsBuilder(registry)
- .withCleanUpDelayInSeconds(testDelay).withCleaningThreadNumber(2).build();
+ .withCleanUpDelayInSeconds(testDelay)
+ .withCleaningThreadNumber(2)
+ .build();
}
@Override
diff --git a/operator-framework-bom/pom.xml b/operator-framework-bom/pom.xml
index 779a9feac4..d0bae9c140 100644
--- a/operator-framework-bom/pom.xml
+++ b/operator-framework-bom/pom.xml
@@ -4,7 +4,7 @@
io.javaoperatorsdk
operator-framework-bom
- 5.0.3-SNAPSHOT
+ 5.0.4-SNAPSHOT
pom
Operator SDK - Bill of Materials
Java SDK for implementing Kubernetes operators
@@ -78,25 +78,34 @@
com.diffplug.spotless
spotless-maven-plugin
- ${spotless.version}
pom.xml
./**/pom.xml
-
+
+ false
+
-
- contributing/eclipse-google-style.xml
-
+
+ true
+
- contributing/eclipse.importorder
+ java,javax,org,io,com,,\#
-
+
+
+
+
+ apply
+
+ compile
+
+
diff --git a/operator-framework-core/pom.xml b/operator-framework-core/pom.xml
index 61e7d71e4c..a4dc87a3d3 100644
--- a/operator-framework-core/pom.xml
+++ b/operator-framework-core/pom.xml
@@ -4,7 +4,7 @@
io.javaoperatorsdk
java-operator-sdk
- 5.0.3-SNAPSHOT
+ 5.0.4-SNAPSHOT
../pom.xml
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java
index 2fdc80d606..611b92bf24 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java
@@ -24,9 +24,11 @@ public Map getAggregatedExceptions() {
@Override
public String getMessage() {
- return super.getMessage() + " " + causes.entrySet().stream()
- .map(entry -> entry.getKey() + " -> " + exceptionDescription(entry))
- .collect(Collectors.joining("\n - ", "Details:\n - ", ""));
+ return super.getMessage()
+ + " "
+ + causes.entrySet().stream()
+ .map(entry -> entry.getKey() + " -> " + exceptionDescription(entry))
+ .collect(Collectors.joining("\n - ", "Details:\n - ", ""));
}
private static String exceptionDescription(Entry entry) {
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/BuilderUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/BuilderUtils.java
index 8f33036b74..48e07e939d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/BuilderUtils.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/BuilderUtils.java
@@ -1,4 +1,3 @@
-
package io.javaoperatorsdk.operator;
import java.lang.reflect.Constructor;
@@ -15,8 +14,12 @@ public static B newBuilder(Class builderType, T item) {
try {
Constructor constructor = builderType.getDeclaredConstructor(builderTargetType);
return constructor.newInstance(item);
- } catch (NoSuchMethodException | SecurityException | InstantiationException
- | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ } catch (NoSuchMethodException
+ | SecurityException
+ | InstantiationException
+ | IllegalAccessException
+ | IllegalArgumentException
+ | InvocationTargetException e) {
throw new OperatorException(
"Failied to instantiate builder: " + builderType.getCanonicalName() + " using: " + item,
e);
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerManager.java
index a755e4db7e..2d6e4c91f0 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerManager.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerManager.java
@@ -23,6 +23,7 @@ class ControllerManager {
@SuppressWarnings("rawtypes")
private final Map controllers = new HashMap<>();
+
private boolean started = false;
private final ExecutorServiceManager executorServiceManager;
@@ -30,7 +31,6 @@ public ControllerManager(ExecutorServiceManager executorServiceManager) {
this.executorServiceManager = executorServiceManager;
}
-
public synchronized void shouldStart() {
if (started) {
return;
@@ -41,27 +41,36 @@ public synchronized void shouldStart() {
}
public synchronized void start(boolean startEventProcessor) {
- executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
- c.start(startEventProcessor);
- return null;
- }, c -> "Controller Starter for: " + c.getConfiguration().getName());
+ executorServiceManager.boundedExecuteAndWaitForAllToComplete(
+ controllers().stream(),
+ c -> {
+ c.start(startEventProcessor);
+ return null;
+ },
+ c -> "Controller Starter for: " + c.getConfiguration().getName());
started = true;
}
public synchronized void stop() {
- executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
- log.debug("closing {}", c);
- c.stop();
- return null;
- }, c -> "Controller Stopper for: " + c.getConfiguration().getName());
+ executorServiceManager.boundedExecuteAndWaitForAllToComplete(
+ controllers().stream(),
+ c -> {
+ log.debug("closing {}", c);
+ c.stop();
+ return null;
+ },
+ c -> "Controller Stopper for: " + c.getConfiguration().getName());
started = false;
}
public synchronized void startEventProcessing() {
- executorServiceManager.boundedExecuteAndWaitForAllToComplete(controllers().stream(), c -> {
- c.startEventProcessing();
- return null;
- }, c -> "Event processor starter for: " + c.getConfiguration().getName());
+ executorServiceManager.boundedExecuteAndWaitForAllToComplete(
+ controllers().stream(),
+ c -> {
+ c.startEventProcessing();
+ return null;
+ },
+ c -> "Event processor starter for: " + c.getConfiguration().getName());
}
@SuppressWarnings("rawtypes")
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java
index d6ee17a383..72f23d628e 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/LeaderElectionManager.java
@@ -39,8 +39,8 @@ public class LeaderElectionManager {
private String leaseNamespace;
private String leaseName;
- LeaderElectionManager(ControllerManager controllerManager,
- ConfigurationService configurationService) {
+ LeaderElectionManager(
+ ControllerManager controllerManager, ConfigurationService configurationService) {
this.controllerManager = controllerManager;
this.configurationService = configurationService;
}
@@ -52,8 +52,10 @@ public boolean isLeaderElectionEnabled() {
private void init(LeaderElectionConfiguration config) {
this.identity = identity(config);
leaseNamespace =
- config.getLeaseNamespace().orElseGet(
- () -> configurationService.getKubernetesClient().getConfiguration().getNamespace());
+ config
+ .getLeaseNamespace()
+ .orElseGet(
+ () -> configurationService.getKubernetesClient().getConfiguration().getNamespace());
if (leaseNamespace == null) {
final var message =
"Lease namespace is not set and cannot be inferred. Leader election cannot continue.";
@@ -62,25 +64,25 @@ private void init(LeaderElectionConfiguration config) {
}
leaseName = config.getLeaseName();
final var lock = new LeaseLock(leaseNamespace, leaseName, identity);
- leaderElector = new LeaderElectorBuilder(
- configurationService.getKubernetesClient(),
- configurationService.getExecutorServiceManager().cachingExecutorService())
- .withConfig(
- new LeaderElectionConfig(
- lock,
- config.getLeaseDuration(),
- config.getRenewDeadline(),
- config.getRetryPeriod(),
- leaderCallbacks(config),
- // this is required to be false to receive stop event in all cases, thus stopLeading
- // is called always when leadership is lost/cancelled
- false,
- leaseName))
- .build();
+ leaderElector =
+ new LeaderElectorBuilder(
+ configurationService.getKubernetesClient(),
+ configurationService.getExecutorServiceManager().cachingExecutorService())
+ .withConfig(
+ new LeaderElectionConfig(
+ lock,
+ config.getLeaseDuration(),
+ config.getRenewDeadline(),
+ config.getRetryPeriod(),
+ leaderCallbacks(config),
+ // this is required to be false to receive stop event in all cases, thus
+ // stopLeading
+ // is called always when leadership is lost/cancelled
+ false,
+ leaseName))
+ .build();
}
-
-
private LeaderCallbacks leaderCallbacks(LeaderElectionConfiguration config) {
return new LeaderCallbacks(
() -> {
@@ -141,25 +143,33 @@ private void checkLeaseAccess() {
review.setSpec(new SelfSubjectRulesReviewSpecBuilder().withNamespace(leaseNamespace).build());
var reviewResult = configurationService.getKubernetesClient().resource(review).create();
log.debug("SelfSubjectRulesReview result: {}", reviewResult);
- var verbsAllowed = reviewResult.getStatus().getResourceRules().stream()
- .filter(rule -> matchesValue(rule.getApiGroups(), COORDINATION_GROUP))
- .filter(rule -> matchesValue(rule.getResources(), LEASES_RESOURCE))
- .filter(rule -> rule.getResourceNames().isEmpty()
- || rule.getResourceNames().contains(leaseName))
- .map(ResourceRule::getVerbs)
- .flatMap(Collection::stream)
- .distinct()
- .collect(Collectors.toList());
+ var verbsAllowed =
+ reviewResult.getStatus().getResourceRules().stream()
+ .filter(rule -> matchesValue(rule.getApiGroups(), COORDINATION_GROUP))
+ .filter(rule -> matchesValue(rule.getResources(), LEASES_RESOURCE))
+ .filter(
+ rule ->
+ rule.getResourceNames().isEmpty()
+ || rule.getResourceNames().contains(leaseName))
+ .map(ResourceRule::getVerbs)
+ .flatMap(Collection::stream)
+ .distinct()
+ .collect(Collectors.toList());
if (verbsAllowed.contains(UNIVERSAL_VALUE) || verbsAllowed.containsAll(verbsRequired)) {
return;
}
- var missingVerbs = verbsRequired.stream()
- .filter(Predicate.not(verbsAllowed::contains))
- .collect(Collectors.toList());
-
- throw new OperatorException(NO_PERMISSION_TO_LEASE_RESOURCE_MESSAGE +
- " in namespace: " + leaseNamespace + "; missing required verbs: " + missingVerbs);
+ var missingVerbs =
+ verbsRequired.stream()
+ .filter(Predicate.not(verbsAllowed::contains))
+ .collect(Collectors.toList());
+
+ throw new OperatorException(
+ NO_PERMISSION_TO_LEASE_RESOURCE_MESSAGE
+ + " in namespace: "
+ + leaseNamespace
+ + "; missing required verbs: "
+ + missingVerbs);
}
private boolean matchesValue(Collection values, String match) {
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java
index 9680bc7e8d..22072bb696 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java
@@ -29,7 +29,6 @@ public class Operator implements LifecycleAware {
private final ConfigurationService configurationService;
private volatile boolean started = false;
-
public Operator() {
this((KubernetesClient) null);
}
@@ -39,12 +38,12 @@ public Operator() {
}
/**
- * Creates an Operator based on the configuration provided by the specified
- * {@link ConfigurationService}. If you intend to use different values than the default, you use
- * {@link Operator#Operator(Consumer)} instead to override the default with your intended setup.
+ * Creates an Operator based on the configuration provided by the specified {@link
+ * ConfigurationService}. If you intend to use different values than the default, you use {@link
+ * Operator#Operator(Consumer)} instead to override the default with your intended setup.
*
* @param configurationService a {@link ConfigurationService} providing the configuration for the
- * operator
+ * operator
*/
public Operator(ConfigurationService configurationService) {
this.configurationService = configurationService;
@@ -60,14 +59,14 @@ public Operator(ConfigurationService configurationService) {
* specified {@link ConfigurationServiceOverrider}.
*
* @param overrider a {@link ConfigurationServiceOverrider} consumer used to override the default
- * {@link ConfigurationService} values
+ * {@link ConfigurationService} values
*/
public Operator(Consumer overrider) {
this(initConfigurationService(null, overrider));
}
- private static ConfigurationService initConfigurationService(KubernetesClient client,
- Consumer overrider) {
+ private static ConfigurationService initConfigurationService(
+ KubernetesClient client, Consumer overrider) {
// initialize the client if the user didn't provide one
if (client == null) {
var configurationService = ConfigurationService.newOverriddenConfigurationService(overrider);
@@ -90,12 +89,12 @@ private static ConfigurationService initConfigurationService(KubernetesClient cl
* Adds a shutdown hook that automatically calls {@link #stop()} when the app shuts down. Note
* that graceful shutdown is usually not needed, but some {@link Reconciler} implementations might
* require it.
- *
- * Note that you might want to tune "terminationGracePeriodSeconds" for the Pod running the
+ *
+ *
Note that you might want to tune "terminationGracePeriodSeconds" for the Pod running the
* controller.
*
* @param gracefulShutdownTimeout timeout to wait for executor threads to complete actual
- * reconciliations
+ * reconciliations
*/
@SuppressWarnings("unused")
public void installShutdownHook(Duration gracefulShutdownTimeout) {
@@ -152,8 +151,8 @@ public void stop() throws OperatorException {
if (!started) {
return;
}
- log.info("Operator SDK {} is shutting down...",
- configurationService.getVersion().getSdkVersion());
+ log.info(
+ "Operator SDK {} is shutting down...", configurationService.getVersion().getSdkVersion());
controllerManager.stop();
configurationService.getExecutorServiceManager().stop(reconciliationTerminationTimeout);
@@ -182,8 +181,8 @@ public
RegisteredController
register(Reconciler
re
/**
* Add a registration requests for the specified reconciler with this operator, overriding its
- * default configuration by the specified one (usually created via
- * {@link io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider#override(ControllerConfiguration)},
+ * default configuration by the specified one (usually created via {@link
+ * io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider#override(ControllerConfiguration)},
* passing it the reconciler's original configuration. The effective registration of the
* reconciler is delayed till the operator is started.
*
@@ -193,19 +192,20 @@ public
RegisteredController
register(Reconciler
re
* @return registered controller
* @throws OperatorException if a problem occurred during the registration process
*/
- public
RegisteredController
register(Reconciler
reconciler,
- ControllerConfiguration
configuration)
- throws OperatorException {
+ public
RegisteredController
register(
+ Reconciler
reconciler, ControllerConfiguration
configuration) throws OperatorException {
if (started) {
throw new OperatorException("Operator already started. Register all the controllers before.");
}
if (configuration == null) {
throw new OperatorException(
- "Cannot register reconciler with name " + reconciler.getClass().getCanonicalName() +
- " reconciler named " + ReconcilerUtils.getNameFor(reconciler)
- + " because its configuration cannot be found.\n" +
- " Known reconcilers are: "
+ "Cannot register reconciler with name "
+ + reconciler.getClass().getCanonicalName()
+ + " reconciler named "
+ + ReconcilerUtils.getNameFor(reconciler)
+ + " because its configuration cannot be found.\n"
+ + " Known reconcilers are: "
+ configurationService.getKnownReconcilerNames());
}
@@ -214,8 +214,10 @@ public
RegisteredController
register(Reconciler
re
controllerManager.add(controller);
final var informerConfig = configuration.getInformerConfig();
- final var watchedNS = informerConfig.watchAllNamespaces() ? "[all namespaces]"
- : informerConfig.getEffectiveNamespaces(configuration);
+ final var watchedNS =
+ informerConfig.watchAllNamespaces()
+ ? "[all namespaces]"
+ : informerConfig.getEffectiveNamespaces(configuration);
log.info(
"Registered reconciler: '{}' for resource: '{}' for namespace(s): {}",
@@ -233,10 +235,9 @@ public
RegisteredController
register(Reconciler
re
* @return registered controller
* @param
the {@code HasMetadata} type associated with the reconciler
*/
- public
RegisteredController
register(Reconciler
reconciler,
- Consumer> configOverrider) {
- final var controllerConfiguration =
- configurationService.getConfigurationFor(reconciler);
+ public RegisteredController
register(
+ Reconciler
reconciler, Consumer> configOverrider) {
+ final var controllerConfiguration = configurationService.getConfigurationFor(reconciler);
var configToOverride = ControllerConfigurationOverrider.override(controllerConfiguration);
configOverrider.accept(configToOverride);
return register(reconciler, configToOverride.build());
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java
index c2241e4bbb..ea7c58acfb 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java
@@ -81,20 +81,26 @@ public static void checkIfCanAddOwnerReference(HasMetadata owner, HasMetadata re
if (owner instanceof Namespaced) {
if (!(resource instanceof Namespaced)) {
throw new OperatorException(
- "Cannot add owner reference from a cluster scoped to a namespace scoped resource." +
- resourcesIdentifierDescription(owner, resource));
- } else if (!Objects.equals(owner.getMetadata().getNamespace(),
- resource.getMetadata().getNamespace())) {
+ "Cannot add owner reference from a cluster scoped to a namespace scoped resource."
+ + resourcesIdentifierDescription(owner, resource));
+ } else if (!Objects.equals(
+ owner.getMetadata().getNamespace(), resource.getMetadata().getNamespace())) {
throw new OperatorException(
- "Cannot add owner reference between two resource in different namespaces." +
- resourcesIdentifierDescription(owner, resource));
+ "Cannot add owner reference between two resource in different namespaces."
+ + resourcesIdentifierDescription(owner, resource));
}
}
}
private static String resourcesIdentifierDescription(HasMetadata owner, HasMetadata resource) {
- return " Owner name: " + owner.getMetadata().getName() + " Kind: " + owner.getKind()
- + ", Resource name: " + resource.getMetadata().getName() + " Kind: " + resource.getKind();
+ return " Owner name: "
+ + owner.getMetadata().getName()
+ + " Kind: "
+ + owner.getKind()
+ + ", Resource name: "
+ + resource.getMetadata().getName()
+ + " Kind: "
+ + resource.getKind();
}
public static String getNameFor(Reconciler reconciler) {
@@ -153,10 +159,11 @@ public static Object setSpec(HasMetadata resource, Object spec) {
if (spec != null) {
setSpecMethod = resourceClass.getMethod(SET_SPEC, spec.getClass());
} else {
- setSpecMethod = Arrays.stream(resourceClass.getMethods())
- .filter(method -> SET_SPEC.equals(method.getName()))
- .findFirst()
- .orElseThrow(() -> noSpecException(resource, null));
+ setSpecMethod =
+ Arrays.stream(resourceClass.getMethods())
+ .filter(method -> SET_SPEC.equals(method.getName()))
+ .findFirst()
+ .orElseThrow(() -> noSpecException(resource, null));
}
return setSpecMethod.invoke(resource, spec);
@@ -165,17 +172,17 @@ public static Object setSpec(HasMetadata resource, Object spec) {
}
}
- private static IllegalStateException noSpecException(HasMetadata resource,
- ReflectiveOperationException e) {
- return new IllegalStateException("No spec found on resource " + resource.getClass().getName(),
- e);
+ private static IllegalStateException noSpecException(
+ HasMetadata resource, ReflectiveOperationException e) {
+ return new IllegalStateException(
+ "No spec found on resource " + resource.getClass().getName(), e);
}
public static T loadYaml(Class clazz, Class loader, String yaml) {
try (InputStream is = loader.getResourceAsStream(yaml)) {
if (Builder.class.isAssignableFrom(clazz)) {
- return BuilderUtils.newBuilder(clazz,
- Serialization.unmarshal(is, BuilderUtils.builderTargetType(clazz)));
+ return BuilderUtils.newBuilder(
+ clazz, Serialization.unmarshal(is, BuilderUtils.builderTargetType(clazz)));
}
return Serialization.unmarshal(is, clazz);
} catch (IOException ex) {
@@ -190,16 +197,16 @@ public static void handleKubernetesClientException(Exception e, String resourceT
if (e instanceof KubernetesClientException ke) {
// only throw MissingCRDException if the 404 error occurs on the target CRD
- if (404 == ke.getCode() &&
- (resourceTypeName.equals(ke.getFullResourceName())
+ if (404 == ke.getCode()
+ && (resourceTypeName.equals(ke.getFullResourceName())
|| matchesResourceType(resourceTypeName, ke))) {
throw new MissingCRDException(resourceTypeName, ke.getVersion(), e.getMessage(), e);
}
}
}
- private static boolean matchesResourceType(String resourceTypeName,
- KubernetesClientException exception) {
+ private static boolean matchesResourceType(
+ String resourceTypeName, KubernetesClientException exception) {
final var fullResourceName = exception.getFullResourceName();
if (fullResourceName != null) {
return resourceTypeName.equals(fullResourceName);
@@ -212,8 +219,8 @@ private static boolean matchesResourceType(String resourceTypeName,
if (group.endsWith(".")) {
group = group.substring(0, group.length() - 1);
}
- final var segments = Arrays.stream(group.split("/")).filter(Predicate.not(String::isEmpty))
- .toList();
+ final var segments =
+ Arrays.stream(group.split("/")).filter(Predicate.not(String::isEmpty)).toList();
if (segments.size() != 3) {
return false;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java
index 88cd0123b0..9db473260b 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java
@@ -10,5 +10,4 @@ public interface RegisteredController extends NamespaceCh
ControllerConfiguration
getConfiguration();
ControllerHealthInfo getControllerHealthInfo();
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java
index ee2f4d447e..b7fbce7f07 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java
@@ -38,7 +38,8 @@ public Set getRegisteredControllers() {
private void checkIfStarted() {
if (!isStarted()) {
log.warn(
- "Operator not started yet while accessing runtime info, this might lead to an unreliable behavior");
+ "Operator not started yet while accessing runtime info, this might lead to an unreliable"
+ + " behavior");
}
}
@@ -46,34 +47,36 @@ public boolean allEventSourcesAreHealthy() {
checkIfStarted();
return registeredControllers.stream()
.filter(rc -> !rc.getControllerHealthInfo().unhealthyEventSources().isEmpty())
- .findFirst().isEmpty();
+ .findFirst()
+ .isEmpty();
}
/**
* @return Aggregated Map with controller related event sources.
*/
-
public Map> unhealthyEventSources() {
checkIfStarted();
Map> res = new HashMap<>();
for (var rc : registeredControllers) {
- res.put(rc.getConfiguration().getName(),
- rc.getControllerHealthInfo().unhealthyEventSources());
+ res.put(
+ rc.getConfiguration().getName(), rc.getControllerHealthInfo().unhealthyEventSources());
}
return res;
}
/**
* @return Aggregated Map with controller related event sources that wraps an informer. Thus,
- * either a {@link ControllerEventSource} or an
- * {@link io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource}.
+ * either a {@link ControllerEventSource} or an {@link
+ * io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource}.
*/
- public Map> unhealthyInformerWrappingEventSourceHealthIndicator() {
+ public Map>
+ unhealthyInformerWrappingEventSourceHealthIndicator() {
checkIfStarted();
Map> res = new HashMap<>();
for (var rc : registeredControllers) {
- res.put(rc.getConfiguration().getName(), rc.getControllerHealthInfo()
- .unhealthyInformerEventSourceHealthIndicators());
+ res.put(
+ rc.getConfiguration().getName(),
+ rc.getControllerHealthInfo().unhealthyInformerEventSourceHealthIndicators());
}
return res;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
index f7ed42c577..5abe6a7d03 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
@@ -33,40 +33,43 @@ protected AbstractConfigurationService(Version version, Cloner cloner) {
* Creates a new {@link AbstractConfigurationService} with the specified parameters.
*
* @param client the {@link KubernetesClient} instance to use to connect to the cluster, if let
- * {@code null}, the client will be lazily instantiated with the default configuration
- * provided by {@link ConfigurationService#getKubernetesClient()} the first time
- * {@link #getKubernetesClient()} is called
+ * {@code null}, the client will be lazily instantiated with the default configuration
+ * provided by {@link ConfigurationService#getKubernetesClient()} the first time {@link
+ * #getKubernetesClient()} is called
* @param version the version information
- * @param cloner the {@link Cloner} to use, if {@code null} the default provided by
- * {@link ConfigurationService#getResourceCloner()} will be used
+ * @param cloner the {@link Cloner} to use, if {@code null} the default provided by {@link
+ * ConfigurationService#getResourceCloner()} will be used
* @param executorServiceManager the {@link ExecutorServiceManager} instance to be used, can be
- * {@code null} to lazily initialize one by default when
- * {@link #getExecutorServiceManager()} is called
+ * {@code null} to lazily initialize one by default when {@link #getExecutorServiceManager()}
+ * is called
*/
- public AbstractConfigurationService(Version version, Cloner cloner,
- ExecutorServiceManager executorServiceManager, KubernetesClient client) {
+ public AbstractConfigurationService(
+ Version version,
+ Cloner cloner,
+ ExecutorServiceManager executorServiceManager,
+ KubernetesClient client) {
this.version = version;
init(cloner, executorServiceManager, client);
}
/**
- * Subclasses can call this method to more easily initialize the {@link Cloner} and
- * {@link ExecutorServiceManager} associated with this ConfigurationService implementation. This
- * is useful in situations where the cloner depends on a mapper that might require additional
+ * Subclasses can call this method to more easily initialize the {@link Cloner} and {@link
+ * ExecutorServiceManager} associated with this ConfigurationService implementation. This is
+ * useful in situations where the cloner depends on a mapper that might require additional
* configuration steps before it's ready to be used.
*
* @param cloner the {@link Cloner} instance to be used, if {@code null}, the default provided by
- * {@link ConfigurationService#getResourceCloner()} will be used
+ * {@link ConfigurationService#getResourceCloner()} will be used
* @param executorServiceManager the {@link ExecutorServiceManager} instance to be used, can be
- * {@code null} to lazily initialize one by default when
- * {@link #getExecutorServiceManager()} is called
+ * {@code null} to lazily initialize one by default when {@link #getExecutorServiceManager()}
+ * is called
* @param client the {@link KubernetesClient} instance to use to connect to the cluster, if let
- * {@code null}, the client will be lazily instantiated with the default configuration
- * provided by {@link ConfigurationService#getKubernetesClient()} the first time
- * {@link #getKubernetesClient()} is called
+ * {@code null}, the client will be lazily instantiated with the default configuration
+ * provided by {@link ConfigurationService#getKubernetesClient()} the first time {@link
+ * #getKubernetesClient()} is called
*/
- protected void init(Cloner cloner, ExecutorServiceManager executorServiceManager,
- KubernetesClient client) {
+ protected void init(
+ Cloner cloner, ExecutorServiceManager executorServiceManager, KubernetesClient client) {
this.client = client;
this.cloner = cloner != null ? cloner : ConfigurationService.super.getResourceCloner();
this.executorServiceManager = executorServiceManager;
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java
index 4204cb6faf..438f7d91a9 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java
@@ -54,11 +54,9 @@ public BaseConfigurationService() {
@SuppressWarnings({"unchecked", "rawtypes"})
private static List dependentResources(
- Workflow annotation,
- ControllerConfiguration> controllerConfiguration) {
+ Workflow annotation, ControllerConfiguration> controllerConfiguration) {
final var dependents = annotation.dependents();
-
if (dependents == null || dependents.length == 0) {
return Collections.emptyList();
}
@@ -79,19 +77,21 @@ private static List dependentResources(
var eventSourceName = dependent.useEventSourceWithName();
eventSourceName = Constants.NO_VALUE_SET.equals(eventSourceName) ? null : eventSourceName;
final var context = Utils.contextFor(name, dependentType, null);
- spec = new DependentResourceSpec(dependentType, dependentName,
- Set.of(dependent.dependsOn()),
- Utils.instantiate(dependent.readyPostcondition(), Condition.class, context),
- Utils.instantiate(dependent.reconcilePrecondition(), Condition.class, context),
- Utils.instantiate(dependent.deletePostcondition(), Condition.class, context),
- Utils.instantiate(dependent.activationCondition(), Condition.class, context),
- eventSourceName);
+ spec =
+ new DependentResourceSpec(
+ dependentType,
+ dependentName,
+ Set.of(dependent.dependsOn()),
+ Utils.instantiate(dependent.readyPostcondition(), Condition.class, context),
+ Utils.instantiate(dependent.reconcilePrecondition(), Condition.class, context),
+ Utils.instantiate(dependent.deletePostcondition(), Condition.class, context),
+ Utils.instantiate(dependent.activationCondition(), Condition.class, context),
+ eventSourceName);
specsMap.put(dependentName, spec);
// extract potential configuration
- DependentResourceConfigurationResolver.configureSpecFromConfigured(spec,
- controllerConfiguration,
- dependentType);
+ DependentResourceConfigurationResolver.configureSpecFromConfigured(
+ spec, controllerConfiguration, dependentType);
specsMap.put(dependentName, spec);
}
@@ -106,8 +106,10 @@ private static T valueOrDefaultFromAnnotation(
String defaultMethodName) {
try {
if (controllerConfiguration == null) {
- return (T) io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class
- .getDeclaredMethod(defaultMethodName).getDefaultValue();
+ return (T)
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class
+ .getDeclaredMethod(defaultMethodName)
+ .getDefaultValue();
} else {
return mapper.apply(controllerConfiguration);
}
@@ -125,18 +127,19 @@ private static String getName(String name, Class extends DependentResource> de
}
@SuppressWarnings("unused")
- private static Configurator configuratorFor(Class instanceType,
- Class extends Reconciler>> reconcilerClass) {
+ private static Configurator configuratorFor(
+ Class instanceType, Class extends Reconciler>> reconcilerClass) {
return instance -> configureFromAnnotatedReconciler(instance, reconcilerClass);
}
@SuppressWarnings({"unchecked", "rawtypes"})
- private static void configureFromAnnotatedReconciler(Object instance,
- Class extends Reconciler>> reconcilerClass) {
+ private static void configureFromAnnotatedReconciler(
+ Object instance, Class extends Reconciler>> reconcilerClass) {
if (instance instanceof AnnotationConfigurable configurable) {
final Class extends Annotation> configurationClass =
- (Class extends Annotation>) Utils.getFirstTypeArgumentFromSuperClassOrInterface(
- instance.getClass(), AnnotationConfigurable.class);
+ (Class extends Annotation>)
+ Utils.getFirstTypeArgumentFromSuperClassOrInterface(
+ instance.getClass(), AnnotationConfigurable.class);
final var configAnnotation = reconcilerClass.getAnnotation(configurationClass);
if (configAnnotation != null) {
configurable.initFrom(configAnnotation);
@@ -146,7 +149,9 @@ private static void configureFromAnnotatedReconciler(Object instance,
@Override
protected void logMissingReconcilerWarning(String reconcilerKey, String reconcilersNameMessage) {
- logger.warn("Configuration for reconciler '{}' was not found. {}", reconcilerKey,
+ logger.warn(
+ "Configuration for reconciler '{}' was not found. {}",
+ reconcilerKey,
reconcilersNameMessage);
}
@@ -168,10 +173,11 @@ public ControllerConfiguration getConfigurationFor(
// create the configuration on demand and register it
config = configFor(reconciler);
register(config);
- getLogger().info(
- "Created configuration for reconciler {} with name {}",
- reconciler.getClass().getName(),
- config.getName());
+ getLogger()
+ .info(
+ "Created configuration for reconciler {} with name {}",
+ reconciler.getClass().getName(),
+ config.getName());
}
} else {
// check that we don't have a reconciler name collision
@@ -196,33 +202,34 @@ protected ResourceClassResolver getResourceClassResolver() {
protected ControllerConfiguration
configFor(Reconciler
reconciler) {
final Class extends Reconciler
> reconcilerClass =
(Class extends Reconciler
>) reconciler.getClass();
- final var controllerAnnotation = reconcilerClass.getAnnotation(
- io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class);
+ final var controllerAnnotation =
+ reconcilerClass.getAnnotation(
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class);
ResolvedControllerConfiguration
config =
controllerConfiguration(reconcilerClass, controllerAnnotation);
- final var workflowAnnotation = reconcilerClass.getAnnotation(
- io.javaoperatorsdk.operator.api.reconciler.Workflow.class);
+ final var workflowAnnotation =
+ reconcilerClass.getAnnotation(io.javaoperatorsdk.operator.api.reconciler.Workflow.class);
if (workflowAnnotation != null) {
final var specs = dependentResources(workflowAnnotation, config);
- WorkflowSpec workflowSpec = new WorkflowSpec() {
- @Override
- public List getDependentResourceSpecs() {
- return specs;
- }
-
- @Override
- public boolean isExplicitInvocation() {
- return workflowAnnotation.explicitInvocation();
- }
-
- @Override
- public boolean handleExceptionsInReconciler() {
- return workflowAnnotation.handleExceptionsInReconciler();
- }
-
- };
+ WorkflowSpec workflowSpec =
+ new WorkflowSpec() {
+ @Override
+ public List getDependentResourceSpecs() {
+ return specs;
+ }
+
+ @Override
+ public boolean isExplicitInvocation() {
+ return workflowAnnotation.explicitInvocation();
+ }
+
+ @Override
+ public boolean handleExceptionsInReconciler() {
+ return workflowAnnotation.handleExceptionsInReconciler();
+ }
+ };
config.setWorkflowSpec(workflowSpec);
}
@@ -236,31 +243,44 @@ private ResolvedControllerConfiguration
controllerCon
final var resourceClass = getResourceClassResolver().getPrimaryResourceClass(reconcilerClass);
final var name = ReconcilerUtils.getNameFor(reconcilerClass);
- final var generationAware = valueOrDefaultFromAnnotation(
- annotation,
- io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::generationAwareEventProcessing,
- "generationAwareEventProcessing");
+ final var generationAware =
+ valueOrDefaultFromAnnotation(
+ annotation,
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration
+ ::generationAwareEventProcessing,
+ "generationAwareEventProcessing");
final var associatedReconcilerClass =
ResolvedControllerConfiguration.getAssociatedReconcilerClassName(reconcilerClass);
final var context = Utils.contextFor(name);
final Class extends Retry> retryClass =
- valueOrDefaultFromAnnotation(annotation,
+ valueOrDefaultFromAnnotation(
+ annotation,
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::retry,
"retry");
- final var retry = Utils.instantiateAndConfigureIfNeeded(retryClass, Retry.class,
- context, configuratorFor(Retry.class, reconcilerClass));
+ final var retry =
+ Utils.instantiateAndConfigureIfNeeded(
+ retryClass, Retry.class, context, configuratorFor(Retry.class, reconcilerClass));
@SuppressWarnings("rawtypes")
- final Class extends RateLimiter> rateLimiterClass = valueOrDefaultFromAnnotation(annotation,
- io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::rateLimiter,
- "rateLimiter");
- final var rateLimiter = Utils.instantiateAndConfigureIfNeeded(rateLimiterClass,
- RateLimiter.class, context, configuratorFor(RateLimiter.class, reconcilerClass));
-
- final var reconciliationInterval = valueOrDefaultFromAnnotation(annotation,
- io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::maxReconciliationInterval,
- "maxReconciliationInterval");
+ final Class extends RateLimiter> rateLimiterClass =
+ valueOrDefaultFromAnnotation(
+ annotation,
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::rateLimiter,
+ "rateLimiter");
+ final var rateLimiter =
+ Utils.instantiateAndConfigureIfNeeded(
+ rateLimiterClass,
+ RateLimiter.class,
+ context,
+ configuratorFor(RateLimiter.class, reconcilerClass));
+
+ final var reconciliationInterval =
+ valueOrDefaultFromAnnotation(
+ annotation,
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration
+ ::maxReconciliationInterval,
+ "maxReconciliationInterval");
long interval = -1;
TimeUnit timeUnit = null;
if (reconciliationInterval != null && reconciliationInterval.interval() > 0) {
@@ -268,30 +288,36 @@ private
ResolvedControllerConfiguration
controllerCon
timeUnit = reconciliationInterval.timeUnit();
}
- var fieldManager = valueOrDefaultFromAnnotation(annotation,
- io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::fieldManager,
- "fieldManager");
+ var fieldManager =
+ valueOrDefaultFromAnnotation(
+ annotation,
+ io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::fieldManager,
+ "fieldManager");
final var dependentFieldManager =
- fieldManager.equals(CONTROLLER_NAME_AS_FIELD_MANAGER) ? name
- : fieldManager;
+ fieldManager.equals(CONTROLLER_NAME_AS_FIELD_MANAGER) ? name : fieldManager;
- InformerConfiguration
informerConfig = InformerConfiguration.builder(resourceClass)
- .initFromAnnotation(annotation != null ? annotation.informer() : null, context)
- .buildForController();
+ InformerConfiguration
informerConfig =
+ InformerConfiguration.builder(resourceClass)
+ .initFromAnnotation(annotation != null ? annotation.informer() : null, context)
+ .buildForController();
return new ResolvedControllerConfiguration
(
- name, generationAware,
- associatedReconcilerClass, retry, rateLimiter,
+ name,
+ generationAware,
+ associatedReconcilerClass,
+ retry,
+ rateLimiter,
ResolvedControllerConfiguration.getMaxReconciliationInterval(interval, timeUnit),
- valueOrDefaultFromAnnotation(annotation,
+ valueOrDefaultFromAnnotation(
+ annotation,
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::finalizerName,
"finalizerName"),
null,
dependentFieldManager,
- this, informerConfig);
+ this,
+ informerConfig);
}
-
protected boolean createIfNeeded() {
return true;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java
index 30b2cee0e9..08cccab6f7 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java
@@ -5,5 +5,4 @@
public interface Cloner {
R clone(R object);
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java
index 14a13bf0b6..3ffc913c5e 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java
@@ -36,37 +36,32 @@ public interface ConfigurationService {
Logger log = LoggerFactory.getLogger(ConfigurationService.class);
int DEFAULT_MAX_CONCURRENT_REQUEST = 512;
- /**
- * The default numbers of concurrent reconciliations
- */
+
+ /** The default numbers of concurrent reconciliations */
int DEFAULT_RECONCILIATION_THREADS_NUMBER = 50;
- /**
- * The default number of threads used to process dependent workflows
- */
+
+ /** The default number of threads used to process dependent workflows */
int DEFAULT_WORKFLOW_EXECUTOR_THREAD_NUMBER = DEFAULT_RECONCILIATION_THREADS_NUMBER;
/**
- * Creates a new {@link ConfigurationService} instance used to configure an
- * {@link io.javaoperatorsdk.operator.Operator} instance, starting from the specified base
- * configuration and overriding specific aspects according to the provided
- * {@link ConfigurationServiceOverrider} instance.
- *
- *
- * NOTE: This overriding mechanism should only be used before creating
- * your Operator instance as the configuration service is set at creation time and cannot be
- * subsequently changed. As a result, overriding values this way after the Operator has been
+ * Creates a new {@link ConfigurationService} instance used to configure an {@link
+ * io.javaoperatorsdk.operator.Operator} instance, starting from the specified base configuration
+ * and overriding specific aspects according to the provided {@link ConfigurationServiceOverrider}
+ * instance.
+ *
+ *
NOTE: This overriding mechanism should only be used before
+ * creating your Operator instance as the configuration service is set at creation time and cannot
+ * be subsequently changed. As a result, overriding values this way after the Operator has been
* configured will not take effect.
- *
*
* @param baseConfiguration the {@link ConfigurationService} to start from
* @param overrider the {@link ConfigurationServiceOverrider} used to change the values provided
- * by the base configuration
+ * by the base configuration
* @return a new {@link ConfigurationService} starting from the configuration provided as base but
- * with overridden values.
+ * with overridden values.
*/
static ConfigurationService newOverriddenConfigurationService(
- ConfigurationService baseConfiguration,
- Consumer overrider) {
+ ConfigurationService baseConfiguration, Consumer overrider) {
if (overrider != null) {
final var toOverride = new ConfigurationServiceOverrider(baseConfiguration);
overrider.accept(toOverride);
@@ -76,22 +71,20 @@ static ConfigurationService newOverriddenConfigurationService(
}
/**
- * Creates a new {@link ConfigurationService} instance used to configure an
- * {@link io.javaoperatorsdk.operator.Operator} instance, starting from the default configuration
- * and overriding specific aspects according to the provided {@link ConfigurationServiceOverrider}
+ * Creates a new {@link ConfigurationService} instance used to configure an {@link
+ * io.javaoperatorsdk.operator.Operator} instance, starting from the default configuration and
+ * overriding specific aspects according to the provided {@link ConfigurationServiceOverrider}
* instance.
*
- *
- * NOTE: This overriding mechanism should only be used before creating
- * your Operator instance as the configuration service is set at creation time and cannot be
- * subsequently changed. As a result, overriding values this way after the Operator has been
+ *
NOTE: This overriding mechanism should only be used before
+ * creating your Operator instance as the configuration service is set at creation time and cannot
+ * be subsequently changed. As a result, overriding values this way after the Operator has been
* configured will not take effect.
- *
*
* @param overrider the {@link ConfigurationServiceOverrider} used to change the values provided
- * by the default configuration
+ * by the default configuration
* @return a new {@link ConfigurationService} overriding the default values with the ones provided
- * by the specified {@link ConfigurationServiceOverrider}
+ * by the specified {@link ConfigurationServiceOverrider}
* @since 4.4.0
*/
static ConfigurationService newOverriddenConfigurationService(
@@ -104,18 +97,16 @@ static ConfigurationService newOverriddenConfigurationService(
*
* @param reconciler the reconciler we want the configuration of
* @param the {@code CustomResource} type associated with the specified reconciler
- * @return the {@link ControllerConfiguration} associated with the specified reconciler or
- * {@code null} if no configuration exists for the reconciler
+ * @return the {@link ControllerConfiguration} associated with the specified reconciler or {@code
+ * null} if no configuration exists for the reconciler
*/
ControllerConfiguration getConfigurationFor(Reconciler reconciler);
/**
* Used to clone custom resources.
*
- *
- * NOTE: It is strongly suggested that implementors override this method since the
+ *
NOTE: It is strongly suggested that implementors override this method since the
* default implementation creates a new {@link Cloner} instance each time this method is called.
- *
*
* @return the configured {@link Cloner}
*/
@@ -134,31 +125,28 @@ public R clone(R object) {
* take care of creating the required connections to watch the target resources (in particular,
* you do not need to worry about setting the namespace information in most cases).
*
- *
- * Previous versions of this class provided direct access to the serialization mechanism (via
+ *
Previous versions of this class provided direct access to the serialization mechanism (via
* {@link com.fasterxml.jackson.databind.ObjectMapper}) or the client's configuration. This was
* somewhat confusing, in particular with respect to changes made in the Fabric8 client
* serialization architecture made in 6.7. The proper way to configure these aspects is now to
* configure the Kubernetes client accordingly and the SDK will extract the information it needs
- * from this instance. The recommended way to do so is to create your operator with
- * {@link io.javaoperatorsdk.operator.Operator#Operator(Consumer)}, passing your custom instance
- * with {@link ConfigurationServiceOverrider#withKubernetesClient(KubernetesClient)}.
- *
+ * from this instance. The recommended way to do so is to create your operator with {@link
+ * io.javaoperatorsdk.operator.Operator#Operator(Consumer)}, passing your custom instance with
+ * {@link ConfigurationServiceOverrider#withKubernetesClient(KubernetesClient)}.
*
- *
- * NOTE: It is strongly suggested that implementors override this method since the
+ *
NOTE: It is strongly suggested that implementors override this method since the
* default implementation creates a new {@link KubernetesClient} instance each time this method is
* called.
- *
*
* @return the configured {@link KubernetesClient}
* @since 4.4.0
*/
default KubernetesClient getKubernetesClient() {
return new KubernetesClientBuilder()
- .withConfig(new ConfigBuilder(Config.autoConfigure(null))
- .withMaxConcurrentRequests(DEFAULT_MAX_CONCURRENT_REQUEST)
- .build())
+ .withConfig(
+ new ConfigBuilder(Config.autoConfigure(null))
+ .withMaxConcurrentRequests(DEFAULT_MAX_CONCURRENT_REQUEST)
+ .build())
.withKubernetesSerialization(new KubernetesSerialization())
.build();
}
@@ -178,13 +166,11 @@ default KubernetesClient getKubernetesClient() {
Version getVersion();
/**
- * Whether the operator should query the CRD to make sure it's deployed and validate
- * {@link CustomResource} implementations before attempting to register the associated
- * reconcilers.
+ * Whether the operator should query the CRD to make sure it's deployed and validate {@link
+ * CustomResource} implementations before attempting to register the associated reconcilers.
*
- *
- * Note that this might require elevating the privileges associated with the operator to gain read
- * access on the CRD resources.
+ *
Note that this might require elevating the privileges associated with the operator to gain
+ * read access on the CRD resources.
*
* @return {@code true} if CRDs should be checked (default), {@code false} otherwise
*/
@@ -226,7 +212,7 @@ default Metrics getMetrics() {
* handle concurrent reconciliations
*
* @return the {@link ExecutorService} implementation to use for concurrent reconciliation
- * processing
+ * processing
*/
default ExecutorService getExecutorService() {
return Executors.newFixedThreadPool(concurrentReconciliationThreads());
@@ -243,8 +229,8 @@ default ExecutorService getWorkflowExecutorService() {
}
/**
- * Determines whether the associated Kubernetes client should be closed when the associated
- * {@link io.javaoperatorsdk.operator.Operator} is stopped.
+ * Determines whether the associated Kubernetes client should be closed when the associated {@link
+ * io.javaoperatorsdk.operator.Operator} is stopped.
*
* @return {@code true} if the Kubernetes should be closed on stop, {@code false} otherwise
*/
@@ -264,9 +250,9 @@ default DependentResourceFactory dependentResourceFactory() {
}
/**
- * Retrieves the optional {@link LeaderElectionConfiguration} to specify how the associated
- * {@link io.javaoperatorsdk.operator.Operator} handles leader election to ensure only one
- * instance of the operator runs on the cluster at any given time
+ * Retrieves the optional {@link LeaderElectionConfiguration} to specify how the associated {@link
+ * io.javaoperatorsdk.operator.Operator} handles leader election to ensure only one instance of
+ * the operator runs on the cluster at any given time
*
* @return the {@link LeaderElectionConfiguration}
*/
@@ -275,15 +261,12 @@ default Optional getLeaderElectionConfiguration() {
}
/**
- *
- * if true, operator stops if there are some issues with informers
- * {@link io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource} or
- * {@link ControllerEventSource} on startup. Other event sources may also respect this flag.
- *
- *
- * if false, the startup will ignore recoverable errors, caused for example by RBAC issues, and
+ * if true, operator stops if there are some issues with informers {@link
+ * io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource} or {@link
+ * ControllerEventSource} on startup. Other event sources may also respect this flag.
+ *
+ *
if false, the startup will ignore recoverable errors, caused for example by RBAC issues, and
* will try to reconnect periodically in the background.
- *
*
* @return actual value described above
*/
@@ -320,26 +303,28 @@ default Duration reconciliationTerminationTimeout() {
* @return an optional InformerStopHandler
*/
default Optional getInformerStoppedHandler() {
- return Optional.of((informer, ex) -> {
- // hasSynced is checked to verify that informer already started. If not started, in case
- // of a fatal error the operator will stop, no need for explicit exit.
- if (ex != null && informer.hasSynced()) {
- log.error("Fatal error in informer: {}. Stopping the operator", informer, ex);
- System.exit(1);
- } else {
- log.debug(
- "Informer stopped: {}. Has synced: {}, Error: {}. This can happen as a result of " +
- "stopping the controller, or due to an error on startup." +
- "See also stopOnInformerErrorDuringStartup configuration.",
- informer, informer.hasSynced(), ex);
- }
- });
+ return Optional.of(
+ (informer, ex) -> {
+ // hasSynced is checked to verify that informer already started. If not started, in case
+ // of a fatal error the operator will stop, no need for explicit exit.
+ if (ex != null && informer.hasSynced()) {
+ log.error("Fatal error in informer: {}. Stopping the operator", informer, ex);
+ System.exit(1);
+ } else {
+ log.debug(
+ "Informer stopped: {}. Has synced: {}, Error: {}. This can happen as a result of "
+ + "stopping the controller, or due to an error on startup."
+ + "See also stopOnInformerErrorDuringStartup configuration.",
+ informer,
+ informer.hasSynced(),
+ ex);
+ }
+ });
}
/**
- * Override to provide a custom {@link ManagedWorkflowFactory} implementation to change how
- * {@link io.javaoperatorsdk.operator.processing.dependent.workflow.ManagedWorkflow} are
- * instantiated
+ * Override to provide a custom {@link ManagedWorkflowFactory} implementation to change how {@link
+ * io.javaoperatorsdk.operator.processing.dependent.workflow.ManagedWorkflow} are instantiated
*
* @return the custom {@link ManagedWorkflowFactory} implementation
*/
@@ -360,12 +345,12 @@ default ExecutorServiceManager getExecutorServiceManager() {
/**
* Allows to revert to the 4.3 behavior when it comes to creating, updating and matching
* Kubernetes Dependent Resources when set to {@code false}. The default approach how these
- * resources are created/updated and match was change to use
- * Server-Side
- * Apply (SSA) by default.
- *
- * SSA based create/update can be still used with the legacy matching, just overriding the match
- * method of Kubernetes Dependent Resource.
+ * resources are created/updated and match was change to use Server-Side Apply
+ * (SSA) by default.
+ *
+ *
SSA based create/update can be still used with the legacy matching, just overriding the
+ * match method of Kubernetes Dependent Resource.
*
* @return {@code true} if SSA should be used for dependent resources, {@code false} otherwise
* @since 4.4.0
@@ -387,7 +372,9 @@ default boolean ssaBasedCreateUpdateMatchForDependentResources() {
*/
default boolean shouldUseSSA(
KubernetesDependentResource dependentResource) {
- return shouldUseSSA(dependentResource.getClass(), dependentResource.resourceType(),
+ return shouldUseSSA(
+ dependentResource.getClass(),
+ dependentResource.resourceType(),
dependentResource.configuration().orElse(null));
}
@@ -399,19 +386,19 @@ default boolean shouldUseSSA(
* @param dependentResourceType the {@link KubernetesDependentResource} type under consideration
* @param resourceType the resource type associated with the considered dependent resource type
* @return {@code true} if SSA should be used for specified dependent resource type, {@code false}
- * otherwise
+ * otherwise
* @since 4.9.5
*/
@SuppressWarnings("rawtypes")
- default boolean shouldUseSSA(Class extends KubernetesDependentResource> dependentResourceType,
+ default boolean shouldUseSSA(
+ Class extends KubernetesDependentResource> dependentResourceType,
Class extends HasMetadata> resourceType,
KubernetesDependentResourceConfig extends HasMetadata> config) {
if (ResourceUpdaterMatcher.class.isAssignableFrom(dependentResourceType)) {
return false;
}
- Boolean useSSAConfig = Optional.ofNullable(config)
- .map(KubernetesDependentResourceConfig::useSSA)
- .orElse(null);
+ Boolean useSSAConfig =
+ Optional.ofNullable(config).map(KubernetesDependentResourceConfig::useSSA).orElse(null);
// don't use SSA for certain resources by default, only if explicitly overridden
if (useSSAConfig == null) {
if (defaultNonSSAResources().contains(resourceType)) {
@@ -426,12 +413,12 @@ default boolean shouldUseSSA(Class extends KubernetesDependentResource> depend
/**
* Returns the set of default resources for which Server-Side Apply (SSA) will not be used, even
- * if it is the default behavior for dependent resources as specified by
- * {@link #ssaBasedCreateUpdateMatchForDependentResources()}. The exception to this is in the case
- * where the use of SSA is explicitly enabled on the dependent resource directly using
- * {@link KubernetesDependent#useSSA()}.
- *
- * By default, SSA is disabled for {@link ConfigMap} and {@link Secret} resources.
+ * if it is the default behavior for dependent resources as specified by {@link
+ * #ssaBasedCreateUpdateMatchForDependentResources()}. The exception to this is in the case where
+ * the use of SSA is explicitly enabled on the dependent resource directly using {@link
+ * KubernetesDependent#useSSA()}.
+ *
+ *
By default, SSA is disabled for {@link ConfigMap} and {@link Secret} resources.
*
* @return The set of resource types for which SSA will not be used
*/
@@ -450,12 +437,11 @@ default Set> defaultNonSSAResource() {
/**
* If a javaoperatorsdk.io/previous annotation should be used so that the operator sdk can detect
* events from its own updates of dependent resources and then filter them.
- *
- * Disable this if you want to react to your own dependent resource updates
+ *
+ *
Disable this if you want to react to your own dependent resource updates
*
* @return if special annotation should be used for dependent resource to filter events
* @since 4.5.0
- *
* @return if special annotation should be used for dependent resource to filter events
*/
default boolean previousAnnotationForDependentResourcesEventFiltering() {
@@ -465,15 +451,14 @@ default boolean previousAnnotationForDependentResourcesEventFiltering() {
/**
* If the event logic should parse the resourceVersion to determine the ordering of dependent
* resource events. This is typically not needed.
- *
- * Disabled by default as Kubernetes does not support, and discourages, this interpretation of
+ *
+ *
Disabled by default as Kubernetes does not support, and discourages, this interpretation of
* resourceVersions. Enable only if your api server event processing seems to lag the operator
* logic, and you want to further minimize the amount of work done / updates issued by the
* operator.
*
* @return if resource version should be parsed (as integer)
* @since 4.5.0
- *
* @return if resource version should be parsed (as integer)
*/
default boolean parseResourceVersionsForEventFilteringAndCaching() {
@@ -486,7 +471,7 @@ default boolean parseResourceVersionsForEventFilteringAndCaching() {
* adding finalizers, patching resources and status.
*
* @return {@code true} if Server-Side Apply (SSA) should be used when patching the primary
- * resources, {@code false} otherwise
+ * resources, {@code false} otherwise
* @see ConfigurationServiceOverrider#withUseSSAToPatchPrimaryResource(boolean)
* @since 5.0.0
*/
@@ -495,25 +480,20 @@ default boolean useSSAToPatchPrimaryResource() {
}
/**
- *
- * Determines whether resources retrieved from caches such as via calls to
- * {@link Context#getSecondaryResource(Class)} should be defensively cloned first.
- *
+ * Determines whether resources retrieved from caches such as via calls to {@link
+ * Context#getSecondaryResource(Class)} should be defensively cloned first.
*
- *
- * Defensive cloning to prevent problematic cache modifications (modifying the resource would
+ *
Defensive cloning to prevent problematic cache modifications (modifying the resource would
* otherwise modify the stored copy in the cache) was transparently done in previous JOSDK
* versions. This might have performance consequences and, with the more prevalent use of
* Server-Side Apply, where you should create a new copy of your resource with only modified
* fields, such modifications of these resources are less likely to occur.
- *
*
* @return {@code true} if resources should be defensively cloned before returning them from
- * caches, {@code false} otherwise
+ * caches, {@code false} otherwise
* @since 5.0.0
*/
default boolean cloneSecondaryResourcesWhenGettingFromCache() {
return false;
}
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java
index 7de9bcda43..f420be0fff 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java
@@ -40,6 +40,7 @@ public class ConfigurationServiceOverrider {
private Boolean parseResourceVersions;
private Boolean useSSAToPatchPrimaryResource;
private Boolean cloneSecondaryResourcesWhenGettingFromCache;
+
@SuppressWarnings("rawtypes")
private DependentResourceFactory dependentResourceFactory;
@@ -98,8 +99,8 @@ public ConfigurationServiceOverrider withWorkflowExecutorService(
/**
* Replaces the default {@link KubernetesClient} instance by the specified one. This is the
* preferred mechanism to configure which client will be used to access the cluster.
- *
- * Note that when {@link Operator#stop()} is called, by default the client is closed even if
+ *
+ *
Note that when {@link Operator#stop()} is called, by default the client is closed even if
* explicitly provided with this method. Use {@link #withCloseClientOnStop(boolean)} to change
* this behavior.
*
@@ -151,8 +152,7 @@ public ConfigurationServiceOverrider withDefaultNonSSAResource(
return this;
}
- public ConfigurationServiceOverrider withPreviousAnnotationForDependentResources(
- boolean value) {
+ public ConfigurationServiceOverrider withPreviousAnnotationForDependentResources(boolean value) {
this.previousAnnotationForDependentResources = value;
return this;
}
@@ -161,8 +161,7 @@ public ConfigurationServiceOverrider withPreviousAnnotationForDependentResources
* @param value true if internal algorithms can use metadata.resourceVersion as a numeric value.
* @return this
*/
- public ConfigurationServiceOverrider withParseResourceVersions(
- boolean value) {
+ public ConfigurationServiceOverrider withParseResourceVersions(boolean value) {
this.parseResourceVersions = value;
return this;
}
@@ -173,8 +172,7 @@ public ConfigurationServiceOverrider withParseResourceVersions(
* @return this
*/
@Deprecated(forRemoval = true)
- public ConfigurationServiceOverrider wihtParseResourceVersions(
- boolean value) {
+ public ConfigurationServiceOverrider wihtParseResourceVersions(boolean value) {
this.parseResourceVersions = value;
return this;
}
@@ -197,28 +195,29 @@ public Set getKnownReconcilerNames() {
return original.getKnownReconcilerNames();
}
- private T overriddenValueOrDefault(T value,
- Function defaultValue) {
+ private T overriddenValueOrDefault(
+ T value, Function defaultValue) {
return value != null ? value : defaultValue.apply(original);
}
@Override
public boolean checkCRDAndValidateLocalModel() {
- return overriddenValueOrDefault(checkCR,
- ConfigurationService::checkCRDAndValidateLocalModel);
+ return overriddenValueOrDefault(
+ checkCR, ConfigurationService::checkCRDAndValidateLocalModel);
}
@SuppressWarnings("rawtypes")
@Override
public DependentResourceFactory dependentResourceFactory() {
- return overriddenValueOrDefault(dependentResourceFactory,
- ConfigurationService::dependentResourceFactory);
+ return overriddenValueOrDefault(
+ dependentResourceFactory, ConfigurationService::dependentResourceFactory);
}
@Override
public int concurrentReconciliationThreads() {
return Utils.ensureValid(
- overriddenValueOrDefault(concurrentReconciliationThreads,
+ overriddenValueOrDefault(
+ concurrentReconciliationThreads,
ConfigurationService::concurrentReconciliationThreads),
"maximum reconciliation threads",
1,
@@ -228,7 +227,8 @@ public int concurrentReconciliationThreads() {
@Override
public int concurrentWorkflowExecutorThreads() {
return Utils.ensureValid(
- overriddenValueOrDefault(concurrentWorkflowExecutorThreads,
+ overriddenValueOrDefault(
+ concurrentWorkflowExecutorThreads,
ConfigurationService::concurrentWorkflowExecutorThreads),
"maximum workflow execution threads",
1,
@@ -252,25 +252,28 @@ public ExecutorService getExecutorService() {
@Override
public ExecutorService getWorkflowExecutorService() {
- return overriddenValueOrDefault(workflowExecutorService,
- ConfigurationService::getWorkflowExecutorService);
+ return overriddenValueOrDefault(
+ workflowExecutorService, ConfigurationService::getWorkflowExecutorService);
}
@Override
public Optional getLeaderElectionConfiguration() {
- return leaderElectionConfiguration != null ? Optional.of(leaderElectionConfiguration)
+ return leaderElectionConfiguration != null
+ ? Optional.of(leaderElectionConfiguration)
: original.getLeaderElectionConfiguration();
}
@Override
public Optional getInformerStoppedHandler() {
- return informerStoppedHandler != null ? Optional.of(informerStoppedHandler)
+ return informerStoppedHandler != null
+ ? Optional.of(informerStoppedHandler)
: original.getInformerStoppedHandler();
}
@Override
public boolean stopOnInformerErrorDuringStartup() {
- return overriddenValueOrDefault(stopOnInformerErrorDuringStartup,
+ return overriddenValueOrDefault(
+ stopOnInformerErrorDuringStartup,
ConfigurationService::stopOnInformerErrorDuringStartup);
}
@@ -281,46 +284,50 @@ public Duration cacheSyncTimeout() {
@Override
public Duration reconciliationTerminationTimeout() {
- return overriddenValueOrDefault(reconciliationTerminationTimeout,
+ return overriddenValueOrDefault(
+ reconciliationTerminationTimeout,
ConfigurationService::reconciliationTerminationTimeout);
}
@Override
public boolean ssaBasedCreateUpdateMatchForDependentResources() {
- return overriddenValueOrDefault(ssaBasedCreateUpdateMatchForDependentResources,
+ return overriddenValueOrDefault(
+ ssaBasedCreateUpdateMatchForDependentResources,
ConfigurationService::ssaBasedCreateUpdateMatchForDependentResources);
}
@Override
public Set> defaultNonSSAResources() {
- return overriddenValueOrDefault(defaultNonSSAResource,
- ConfigurationService::defaultNonSSAResources);
+ return overriddenValueOrDefault(
+ defaultNonSSAResource, ConfigurationService::defaultNonSSAResources);
}
@Override
public boolean previousAnnotationForDependentResourcesEventFiltering() {
- return overriddenValueOrDefault(previousAnnotationForDependentResources,
+ return overriddenValueOrDefault(
+ previousAnnotationForDependentResources,
ConfigurationService::previousAnnotationForDependentResourcesEventFiltering);
}
@Override
public boolean parseResourceVersionsForEventFilteringAndCaching() {
- return overriddenValueOrDefault(parseResourceVersions,
+ return overriddenValueOrDefault(
+ parseResourceVersions,
ConfigurationService::parseResourceVersionsForEventFilteringAndCaching);
}
@Override
public boolean useSSAToPatchPrimaryResource() {
- return overriddenValueOrDefault(useSSAToPatchPrimaryResource,
- ConfigurationService::useSSAToPatchPrimaryResource);
+ return overriddenValueOrDefault(
+ useSSAToPatchPrimaryResource, ConfigurationService::useSSAToPatchPrimaryResource);
}
@Override
public boolean cloneSecondaryResourcesWhenGettingFromCache() {
- return overriddenValueOrDefault(cloneSecondaryResourcesWhenGettingFromCache,
+ return overriddenValueOrDefault(
+ cloneSecondaryResourcesWhenGettingFromCache,
ConfigurationService::cloneSecondaryResourcesWhenGettingFromCache);
}
};
}
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java
index e03cf5626e..2c18fa55d3 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java
@@ -18,9 +18,8 @@ public interface ControllerConfiguration extends Informab
@SuppressWarnings("rawtypes")
RateLimiter DEFAULT_RATE_LIMITER = LinearRateLimiter.deactivatedRateLimiter();
- /**
- * Will use the controller name as fieldManager if set.
- */
+
+ /** Will use the controller name as fieldManager if set. */
String CONTROLLER_NAME_AS_FIELD_MANAGER = "use_controller_name";
default String getName() {
@@ -42,7 +41,9 @@ static String ensureValidFinalizerName(String finalizer, String resourceTypeName
} else {
throw new IllegalArgumentException(
finalizer
- + " is not a valid finalizer. See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#finalizers for details");
+ + " is not a valid finalizer. See"
+ + " https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#finalizers"
+ + " for details");
}
} else {
return ReconcilerUtils.getDefaultFinalizerName(resourceTypeName);
@@ -80,9 +81,9 @@ default Set getEffectiveNamespaces() {
}
/**
- * Retrieves the name used to assign as field manager for
- * Server-Side
- * Apply (SSA) operations. If unset, the sanitized controller name will be used.
+ * Retrieves the name used to assign as field manager for Server-Side Apply
+ * (SSA) operations. If unset, the sanitized controller name will be used.
*
* @return the name used as field manager for SSA operations
*/
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java
index 3d3eef5990..d2e37a397d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java
@@ -17,7 +17,6 @@
import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;
import io.javaoperatorsdk.operator.processing.retry.Retry;
-
@SuppressWarnings({"rawtypes", "unused", "UnusedReturnValue"})
public class ControllerConfigurationOverrider {
@@ -150,13 +149,11 @@ public ControllerConfigurationOverrider withName(String name) {
return this;
}
- public ControllerConfigurationOverrider withFieldManager(
- String dependentFieldManager) {
+ public ControllerConfigurationOverrider withFieldManager(String dependentFieldManager) {
this.fieldManager = dependentFieldManager;
return this;
}
-
/**
* Sets a max page size limit when starting the informer. This will result in pagination while
* populating the cache. This means that longer lists will take multiple requests to fetch. See
@@ -164,20 +161,22 @@ public ControllerConfigurationOverrider withFieldManager(
*
* @param informerListLimit null (the default) results in no pagination
*/
- public ControllerConfigurationOverrider withInformerListLimit(
- Long informerListLimit) {
+ public ControllerConfigurationOverrider withInformerListLimit(Long informerListLimit) {
config.withInformerListLimit(informerListLimit);
return this;
}
- public ControllerConfigurationOverrider replacingNamedDependentResourceConfig(String name,
- Object dependentResourceConfig) {
+ public ControllerConfigurationOverrider replacingNamedDependentResourceConfig(
+ String name, Object dependentResourceConfig) {
final var specs = original.getWorkflowSpec().orElseThrow().getDependentResourceSpecs();
- final var spec = specs.stream()
- .filter(drs -> drs.getName().equals(name)).findFirst()
- .orElseThrow(
- () -> new IllegalArgumentException("Cannot find a DependentResource named: " + name));
+ final var spec =
+ specs.stream()
+ .filter(drs -> drs.getName().equals(name))
+ .findFirst()
+ .orElseThrow(
+ () ->
+ new IllegalArgumentException("Cannot find a DependentResource named: " + name));
if (configurations == null) {
configurations = new HashMap<>(specs.size());
@@ -189,9 +188,14 @@ public ControllerConfigurationOverrider replacingNamedDependentResourceConfig
public ControllerConfiguration build() {
return new ResolvedControllerConfiguration<>(
name,
- generationAware, original.getAssociatedReconcilerClassName(), retry, rateLimiter,
+ generationAware,
+ original.getAssociatedReconcilerClassName(),
+ retry,
+ rateLimiter,
reconciliationMaxInterval,
- finalizer, configurations, fieldManager,
+ finalizer,
+ configurations,
+ fieldManager,
original.getConfigurationService(),
config.buildForController(),
original.getWorkflowSpec().orElse(null));
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java
index cdd4c5540e..cf44b9890e 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java
@@ -9,7 +9,7 @@ public class DefaultResourceClassResolver implements ResourceClassResolver {
@Override
public Class getPrimaryResourceClass(
Class extends Reconciler> reconcilerClass) {
- return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(reconcilerClass,
- Reconciler.class);
+ return (Class)
+ Utils.getFirstTypeArgumentFromSuperClassOrInterface(reconcilerClass, Reconciler.class);
}
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java
index c35281e822..3cbf68d8fe 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java
@@ -41,39 +41,50 @@ public class ExecutorServiceManager {
* @param threadNamer for naming thread
* @param type
*/
- public void boundedExecuteAndWaitForAllToComplete(Stream stream,
- Function task, Function threadNamer) {
+ public void boundedExecuteAndWaitForAllToComplete(
+ Stream stream, Function task, Function threadNamer) {
executeAndWaitForAllToComplete(stream, task, threadNamer, cachingExecutorService());
}
- public static void executeAndWaitForAllToComplete(Stream stream,
- Function task, Function threadNamer,
+ public static void executeAndWaitForAllToComplete(
+ Stream stream,
+ Function task,
+ Function threadNamer,
ExecutorService executorService) {
final var instrumented = new InstrumentedExecutorService(executorService);
try {
- instrumented.invokeAll(stream.map(item -> (Callable) () -> {
- // change thread name for easier debugging
- final var thread = Thread.currentThread();
- final var name = thread.getName();
- thread.setName(threadNamer.apply(item));
- try {
- task.apply(item);
- return null;
- } finally {
- // restore original name
- thread.setName(name);
- }
- }).collect(Collectors.toList())).forEach(f -> {
- try {
- // to find out any exceptions
- f.get();
- } catch (ExecutionException e) {
- throw new OperatorException(e);
- } catch (InterruptedException e) {
- log.warn("Interrupted.", e);
- Thread.currentThread().interrupt();
- }
- });
+ instrumented
+ .invokeAll(
+ stream
+ .map(
+ item ->
+ (Callable)
+ () -> {
+ // change thread name for easier debugging
+ final var thread = Thread.currentThread();
+ final var name = thread.getName();
+ thread.setName(threadNamer.apply(item));
+ try {
+ task.apply(item);
+ return null;
+ } finally {
+ // restore original name
+ thread.setName(name);
+ }
+ })
+ .collect(Collectors.toList()))
+ .forEach(
+ f -> {
+ try {
+ // to find out any exceptions
+ f.get();
+ } catch (ExecutionException e) {
+ throw new OperatorException(e);
+ } catch (InterruptedException e) {
+ log.warn("Interrupted.", e);
+ Thread.currentThread().interrupt();
+ }
+ });
} catch (InterruptedException e) {
log.warn("Interrupted.", e);
Thread.currentThread().interrupt();
@@ -113,9 +124,11 @@ public void stop(Duration gracefulShutdownTimeout) {
try {
log.debug("Closing executor");
var parallelExec = Executors.newFixedThreadPool(3);
- parallelExec.invokeAll(List.of(shutdown(executor, gracefulShutdownTimeout),
- shutdown(workflowExecutor, gracefulShutdownTimeout),
- shutdown(cachingExecutorService, gracefulShutdownTimeout)));
+ parallelExec.invokeAll(
+ List.of(
+ shutdown(executor, gracefulShutdownTimeout),
+ shutdown(workflowExecutor, gracefulShutdownTimeout),
+ shutdown(cachingExecutorService, gracefulShutdownTimeout)));
workflowExecutor = null;
parallelExec.shutdownNow();
started = false;
@@ -125,16 +138,16 @@ public void stop(Duration gracefulShutdownTimeout) {
}
}
- private static Callable shutdown(ExecutorService executorService,
- Duration gracefulShutdownTimeout) {
+ private static Callable shutdown(
+ ExecutorService executorService, Duration gracefulShutdownTimeout) {
return () -> {
// workflow executor can be null
if (executorService == null) {
return null;
}
executorService.shutdown();
- if (!executorService.awaitTermination(gracefulShutdownTimeout.toMillis(),
- TimeUnit.MILLISECONDS)) {
+ if (!executorService.awaitTermination(
+ gracefulShutdownTimeout.toMillis(), TimeUnit.MILLISECONDS)) {
executorService.shutdownNow(); // if we timed out, waiting, cancel everything
}
return null;
@@ -203,8 +216,9 @@ public List> invokeAll(Collection extends Callable> tasks)
}
@Override
- public List> invokeAll(Collection extends Callable> tasks, long timeout,
- TimeUnit unit) throws InterruptedException {
+ public List> invokeAll(
+ Collection extends Callable> tasks, long timeout, TimeUnit unit)
+ throws InterruptedException {
return executor.invokeAll(tasks, timeout, unit);
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java
index 5b58836483..39272b2083 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java
@@ -1,6 +1,5 @@
package io.javaoperatorsdk.operator.api.config;
-
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java
index cfce453e14..49efa10b8d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java
@@ -28,7 +28,10 @@ public LeaderElectionConfiguration(String leaseName, String leaseNamespace, Stri
leaseNamespace,
LEASE_DURATION_DEFAULT_VALUE,
RENEW_DEADLINE_DEFAULT_VALUE,
- RETRY_PERIOD_DEFAULT_VALUE, identity, null, true);
+ RETRY_PERIOD_DEFAULT_VALUE,
+ identity,
+ null,
+ true);
}
public LeaderElectionConfiguration(String leaseName, String leaseNamespace) {
@@ -37,7 +40,10 @@ public LeaderElectionConfiguration(String leaseName, String leaseNamespace) {
leaseNamespace,
LEASE_DURATION_DEFAULT_VALUE,
RENEW_DEADLINE_DEFAULT_VALUE,
- RETRY_PERIOD_DEFAULT_VALUE, null, null, true);
+ RETRY_PERIOD_DEFAULT_VALUE,
+ null,
+ null,
+ true);
}
public LeaderElectionConfiguration(String leaseName) {
@@ -46,7 +52,10 @@ public LeaderElectionConfiguration(String leaseName) {
null,
LEASE_DURATION_DEFAULT_VALUE,
RENEW_DEADLINE_DEFAULT_VALUE,
- RETRY_PERIOD_DEFAULT_VALUE, null, null, true);
+ RETRY_PERIOD_DEFAULT_VALUE,
+ null,
+ null,
+ true);
}
public LeaderElectionConfiguration(
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java
index eda262f9eb..c4d4fc6190 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java
@@ -62,7 +62,14 @@ public LeaderElectionConfigurationBuilder withExitOnStopLeading(boolean exitOnSt
}
public LeaderElectionConfiguration build() {
- return new LeaderElectionConfiguration(leaseName, leaseNamespace, leaseDuration, renewDeadline,
- retryPeriod, identity, leaderCallbacks, exitOnStopLeading);
+ return new LeaderElectionConfiguration(
+ leaseName,
+ leaseNamespace,
+ leaseDuration,
+ renewDeadline,
+ retryPeriod,
+ identity,
+ leaderCallbacks,
+ exitOnStopLeading);
}
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java
index 426b179438..6e6d53f49f 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java
@@ -7,10 +7,9 @@
public interface NamespaceChangeable {
/**
- * If the controller and possibly registered
- * {@link io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource}
- * watches a set of namespaces this set can be adjusted dynamically, this when the operator is
- * running.
+ * If the controller and possibly registered {@link
+ * io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource} watches a set
+ * of namespaces this set can be adjusted dynamically, this when the operator is running.
*
* @param namespaces target namespaces to watch
*/
@@ -24,5 +23,4 @@ default void changeNamespaces(String... namespaces) {
default boolean allowsNamespaceChanges() {
return true;
}
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java
index 7e8415f584..3c26659ed2 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java
@@ -32,37 +32,61 @@ public class ResolvedControllerConfiguration
private WorkflowSpec workflowSpec;
public ResolvedControllerConfiguration(ControllerConfiguration
other) {
- this(other.getName(), other.isGenerationAware(),
- other.getAssociatedReconcilerClassName(), other.getRetry(), other.getRateLimiter(),
+ this(
+ other.getName(),
+ other.isGenerationAware(),
+ other.getAssociatedReconcilerClassName(),
+ other.getRetry(),
+ other.getRateLimiter(),
other.maxReconciliationInterval().orElse(null),
- other.getFinalizerName(), Collections.emptyMap(),
+ other.getFinalizerName(),
+ Collections.emptyMap(),
other.fieldManager(),
other.getConfigurationService(),
other.getInformerConfig(),
other.getWorkflowSpec().orElse(null));
}
- public ResolvedControllerConfiguration(String name,
- boolean generationAware, String associatedReconcilerClassName, Retry retry,
- RateLimiter rateLimiter, Duration maxReconciliationInterval,
+ public ResolvedControllerConfiguration(
+ String name,
+ boolean generationAware,
+ String associatedReconcilerClassName,
+ Retry retry,
+ RateLimiter rateLimiter,
+ Duration maxReconciliationInterval,
String finalizer,
Map configurations,
String fieldManager,
ConfigurationService configurationService,
InformerConfiguration informerConfig,
WorkflowSpec workflowSpec) {
- this(name, generationAware, associatedReconcilerClassName, retry, rateLimiter,
- maxReconciliationInterval, finalizer, configurations, fieldManager,
- configurationService, informerConfig);
+ this(
+ name,
+ generationAware,
+ associatedReconcilerClassName,
+ retry,
+ rateLimiter,
+ maxReconciliationInterval,
+ finalizer,
+ configurations,
+ fieldManager,
+ configurationService,
+ informerConfig);
setWorkflowSpec(workflowSpec);
}
- protected ResolvedControllerConfiguration(String name,
- boolean generationAware, String associatedReconcilerClassName, Retry retry,
- RateLimiter rateLimiter, Duration maxReconciliationInterval, String finalizer,
+ protected ResolvedControllerConfiguration(
+ String name,
+ boolean generationAware,
+ String associatedReconcilerClassName,
+ Retry retry,
+ RateLimiter rateLimiter,
+ Duration maxReconciliationInterval,
+ String finalizer,
Map configurations,
String fieldManager,
- ConfigurationService configurationService, InformerConfiguration informerConfig) {
+ ConfigurationService configurationService,
+ InformerConfiguration
informerConfig) {
this.informerConfig = informerConfig;
this.configurationService = configurationService;
this.name = ControllerConfiguration.ensureValidName(name, associatedReconcilerClassName);
@@ -77,10 +101,22 @@ protected ResolvedControllerConfiguration(String name,
this.fieldManager = fieldManager;
}
- protected ResolvedControllerConfiguration(Class
resourceClass, String name,
- Class extends Reconciler> reconcilerClas, ConfigurationService configurationService) {
- this(name, false, getAssociatedReconcilerClassName(reconcilerClas), null, null,
- null, null, null, null, configurationService,
+ protected ResolvedControllerConfiguration(
+ Class
resourceClass,
+ String name,
+ Class extends Reconciler> reconcilerClas,
+ ConfigurationService configurationService) {
+ this(
+ name,
+ false,
+ getAssociatedReconcilerClassName(reconcilerClas),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ configurationService,
InformerConfiguration.builder(resourceClass).buildForController());
}
@@ -136,7 +172,6 @@ public RateLimiter getRateLimiter() {
return rateLimiter;
}
-
@Override
public Optional getWorkflowSpec() {
return Optional.ofNullable(workflowSpec);
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java
index 001eb3e0de..b1d0af9263 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java
@@ -7,5 +7,4 @@ public interface ResourceClassResolver {
Class
getPrimaryResourceClass(
Class extends Reconciler
> reconcilerClass);
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
index ea776f3a6c..f11fc47eef 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
@@ -23,6 +23,7 @@ public class Utils {
private static final Logger log = LoggerFactory.getLogger(Utils.class);
public static final String CHECK_CRD_ENV_KEY = "JAVA_OPERATOR_SDK_CHECK_CRD";
public static final String DEBUG_THREAD_POOL_ENV_KEY = "JAVA_OPERATOR_SDK_DEBUG_THREAD_POOL";
+ public static final String USE_MDC_ENV_KEY = "JAVA_OPERATOR_SDK_USE_MDC";
public static final String GENERIC_PARAMETER_TYPE_ERROR_PREFIX =
"Couldn't retrieve generic parameter type from ";
@@ -61,9 +62,7 @@ private static Version loadFromProperties() {
log.debug("Couldn't parse git.build.time property", e);
builtTime = Date.from(Instant.EPOCH);
}
- return new Version(
- properties.getProperty("git.commit.id.abbrev", "unknown"),
- builtTime);
+ return new Version(properties.getProperty("git.commit.id.abbrev", "unknown"), builtTime);
}
public static int ensureValid(int value, String description, int minValue) {
@@ -76,8 +75,13 @@ public static int ensureValid(int value, String description, int minValue, int d
throw new IllegalArgumentException(
"Default value for " + description + " must be greater than " + minValue);
}
- log.warn("Requested {} should be greater than {}. Requested: {}, using {}{} instead",
- description, minValue, value, defaultValue, defaultValue == minValue ? "" : " (default)");
+ log.warn(
+ "Requested {} should be greater than {}. Requested: {}, using {}{} instead",
+ description,
+ minValue,
+ value,
+ defaultValue,
+ defaultValue == minValue ? "" : " (default)");
value = defaultValue;
}
return value;
@@ -97,7 +101,8 @@ public static boolean debugThreadPool() {
return getBooleanFromSystemPropsOrDefault(DEBUG_THREAD_POOL_ENV_KEY, false);
}
- static boolean getBooleanFromSystemPropsOrDefault(String propertyName, boolean defaultValue) {
+ public static boolean getBooleanFromSystemPropsOrDefault(
+ String propertyName, boolean defaultValue) {
var property = System.getProperty(propertyName);
if (property == null) {
return defaultValue;
@@ -120,20 +125,22 @@ public static Class> getTypeArgumentFromExtendedClassByIndex(Class> clazz, i
Type type = clazz.getGenericSuperclass();
return (Class>) ((ParameterizedType) type).getActualTypeArguments()[index];
} catch (Exception e) {
- throw new RuntimeException(GENERIC_PARAMETER_TYPE_ERROR_PREFIX
- + clazz.getSimpleName()
- + " because it doesn't extend a class that is parameterized with the type we want to retrieve",
+ throw new RuntimeException(
+ GENERIC_PARAMETER_TYPE_ERROR_PREFIX
+ + clazz.getSimpleName()
+ + " because it doesn't extend a class that is parameterized with the type we want to"
+ + " retrieve",
e);
}
}
- public static Class> getFirstTypeArgumentFromInterface(Class> clazz,
- Class> expectedImplementedInterface) {
+ public static Class> getFirstTypeArgumentFromInterface(
+ Class> clazz, Class> expectedImplementedInterface) {
return getTypeArgumentFromInterfaceByIndex(clazz, expectedImplementedInterface, 0);
}
- public static Class> getTypeArgumentFromInterfaceByIndex(Class> clazz,
- Class> expectedImplementedInterface, int index) {
+ public static Class> getTypeArgumentFromInterfaceByIndex(
+ Class> clazz, Class> expectedImplementedInterface, int index) {
if (expectedImplementedInterface.isAssignableFrom(clazz)) {
final var genericInterfaces = clazz.getGenericInterfaces();
@@ -148,50 +155,60 @@ public static Class> getTypeArgumentFromInterfaceByIndex(Class> clazz,
return getTypeArgumentFromInterfaceByIndex(parent, expectedImplementedInterface, index);
}
}
- throw new IllegalArgumentException(GENERIC_PARAMETER_TYPE_ERROR_PREFIX
- + clazz.getSimpleName() + " because it or its superclasses don't implement "
- + expectedImplementedInterface.getSimpleName());
+ throw new IllegalArgumentException(
+ GENERIC_PARAMETER_TYPE_ERROR_PREFIX
+ + clazz.getSimpleName()
+ + " because it or its superclasses don't implement "
+ + expectedImplementedInterface.getSimpleName());
}
- private static Optional extends Class>> extractType(Class> clazz,
- Class> expectedImplementedInterface, int index, Type[] genericInterfaces) {
+ private static Optional extends Class>> extractType(
+ Class> clazz, Class> expectedImplementedInterface, int index, Type[] genericInterfaces) {
Optional extends Class>> target = Optional.empty();
if (genericInterfaces.length > 0) {
// try to find the target interface among them
- target = Arrays.stream(genericInterfaces)
- .filter(type -> type.getTypeName().startsWith(expectedImplementedInterface.getName())
- && type instanceof ParameterizedType)
- .map(ParameterizedType.class::cast)
- .findFirst()
- .map(t -> {
- final Type argument = t.getActualTypeArguments()[index];
- if (argument instanceof Class) {
- return (Class>) argument;
- }
- // account for the case where the argument itself has parameters, which we will ignore
- // and just return the raw type
- if (argument instanceof ParameterizedType) {
- final var rawType = ((ParameterizedType) argument).getRawType();
- if (rawType instanceof Class) {
- return (Class>) rawType;
- }
- }
- throw new IllegalArgumentException(clazz.getSimpleName() + " implements "
- + expectedImplementedInterface.getSimpleName()
- + " but indirectly. Java type erasure doesn't allow to retrieve the generic type from it. Retrieved type was: "
- + argument);
- });
+ target =
+ Arrays.stream(genericInterfaces)
+ .filter(
+ type ->
+ type.getTypeName().startsWith(expectedImplementedInterface.getName())
+ && type instanceof ParameterizedType)
+ .map(ParameterizedType.class::cast)
+ .findFirst()
+ .map(
+ t -> {
+ final Type argument = t.getActualTypeArguments()[index];
+ if (argument instanceof Class) {
+ return (Class>) argument;
+ }
+ // account for the case where the argument itself has parameters, which we will
+ // ignore
+ // and just return the raw type
+ if (argument instanceof ParameterizedType) {
+ final var rawType = ((ParameterizedType) argument).getRawType();
+ if (rawType instanceof Class) {
+ return (Class>) rawType;
+ }
+ }
+ throw new IllegalArgumentException(
+ clazz.getSimpleName()
+ + " implements "
+ + expectedImplementedInterface.getSimpleName()
+ + " but indirectly. Java type erasure doesn't allow to retrieve the"
+ + " generic type from it. Retrieved type was: "
+ + argument);
+ });
}
return target;
}
- public static Class> getFirstTypeArgumentFromSuperClassOrInterface(Class> clazz,
- Class> expectedImplementedInterface) {
+ public static Class> getFirstTypeArgumentFromSuperClassOrInterface(
+ Class> clazz, Class> expectedImplementedInterface) {
return getTypeArgumentFromSuperClassOrInterfaceByIndex(clazz, expectedImplementedInterface, 0);
}
- public static Class> getTypeArgumentFromSuperClassOrInterfaceByIndex(Class> clazz,
- Class> expectedImplementedInterface, int index) {
+ public static Class> getTypeArgumentFromSuperClassOrInterfaceByIndex(
+ Class> clazz, Class> expectedImplementedInterface, int index) {
// first check super class if it exists
try {
final Class> superclass = clazz.getSuperclass();
@@ -204,8 +221,8 @@ public static Class> getTypeArgumentFromSuperClassOrInterfaceByIndex(Class>
return getTypeArgumentFromInterfaceByIndex(clazz, expectedImplementedInterface, index);
} catch (Exception ex) {
// try on the parent
- return getTypeArgumentFromSuperClassOrInterfaceByIndex(superclass,
- expectedImplementedInterface, index);
+ return getTypeArgumentFromSuperClassOrInterfaceByIndex(
+ superclass, expectedImplementedInterface, index);
}
}
}
@@ -215,8 +232,11 @@ public static Class> getTypeArgumentFromSuperClassOrInterfaceByIndex(Class>
}
}
- public static T instantiateAndConfigureIfNeeded(Class extends T> targetClass,
- Class expectedType, String context, Configurator configurator) {
+ public static T instantiateAndConfigureIfNeeded(
+ Class extends T> targetClass,
+ Class expectedType,
+ String context,
+ Configurator configurator) {
// if class to instantiate equals the expected interface, we cannot instantiate it so just
// return null as it means we passed on void-type default value
if (expectedType.equals(targetClass)) {
@@ -231,11 +251,18 @@ public static T instantiateAndConfigureIfNeeded(Class extends T> targetCla
}
return instance;
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException
+ } catch (InstantiationException
+ | IllegalAccessException
+ | InvocationTargetException
| IllegalStateException e) {
- throw new OperatorException("Couldn't instantiate " + expectedType.getSimpleName() + " '"
- + targetClass.getName() + "'."
- + (context != null ? " Context: " + context : ""), e);
+ throw new OperatorException(
+ "Couldn't instantiate "
+ + expectedType.getSimpleName()
+ + " '"
+ + targetClass.getName()
+ + "'."
+ + (context != null ? " Context: " + context : ""),
+ e);
}
}
@@ -251,8 +278,8 @@ public static Constructor getConstructor(Class targetClass) {
return constructor;
}
- public static T instantiate(Class extends T> toInstantiate, Class expectedType,
- String context) {
+ public static T instantiate(
+ Class extends T> toInstantiate, Class expectedType, String context) {
return instantiateAndConfigureIfNeeded(toInstantiate, expectedType, context, null);
}
@@ -262,7 +289,8 @@ public interface Configurator {
}
@SuppressWarnings("rawtypes")
- public static String contextFor(ControllerConfiguration> controllerConfiguration,
+ public static String contextFor(
+ ControllerConfiguration> controllerConfiguration,
Class extends DependentResource> dependentType,
Class extends Annotation> configurationAnnotation) {
return contextFor(controllerConfiguration.getName(), dependentType, configurationAnnotation);
@@ -273,11 +301,13 @@ public static String contextFor(String reconcilerName) {
}
@SuppressWarnings("rawtypes")
- public static String contextFor(String reconcilerName,
+ public static String contextFor(
+ String reconcilerName,
Class extends DependentResource> dependentType,
Class extends Annotation> configurationAnnotation) {
final var annotationName =
- configurationAnnotation != null ? configurationAnnotation.getSimpleName()
+ configurationAnnotation != null
+ ? configurationAnnotation.getSimpleName()
: io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class
.getSimpleName();
var context = "annotation: " + annotationName + ", ";
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
index d43d8aa1cf..571e389ecc 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
@@ -36,8 +36,8 @@ public String getCommit() {
/**
* Returns the date at which this SDK instance was built
*
- * @return the build time at which this SDK instance was built or the date corresponding to
- * {@link java.time.Instant#EPOCH} if the built time couldn't be retrieved
+ * @return the build time at which this SDK instance was built or the date corresponding to {@link
+ * java.time.Instant#EPOCH} if the built time couldn't be retrieved
*/
public Date getBuiltTime() {
return builtTime;
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java
index f0327514ae..beebc16239 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java
@@ -6,6 +6,8 @@
public interface ConfigurationConverter {
- C configFrom(A configAnnotation, DependentResourceSpec, ?, C> spec,
+ C configFrom(
+ A configAnnotation,
+ DependentResourceSpec, ?, C> spec,
ControllerConfiguration> parentConfiguration);
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfigurationResolver.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfigurationResolver.java
index 471b0f6a8e..837ff7fbb0 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfigurationResolver.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfigurationResolver.java
@@ -16,9 +16,8 @@ private DependentResourceConfigurationResolver() {}
private static final Map, ConverterAnnotationPair> converters =
new HashMap<>();
- private static final Map, ConfigurationConverter> knownConverters =
- new HashMap<>();
-
+ private static final Map, ConfigurationConverter>
+ knownConverters = new HashMap<>();
public static > void configureSpecFromConfigured(
DependentResourceSpec spec,
@@ -38,7 +37,9 @@ public static > void configureSpecFromConfi
if (converterAnnotationPair == null) {
final var configured = configuredClassPair.configured;
converterAnnotationPair =
- getOrCreateConverter(dependentResourceClass, parentConfiguration,
+ getOrCreateConverter(
+ dependentResourceClass,
+ parentConfiguration,
configured.converter(),
configured.by());
} else {
@@ -74,18 +75,22 @@ private static ConfiguredClassPair getConfigured(
return result;
}
- private static > ConverterAnnotationPair getOrCreateConverter(
- Class extends DependentResource> dependentResourceClass, C parentConfiguration,
- Class extends ConfigurationConverter> converterClass,
- Class extends Annotation> annotationClass) {
+ private static >
+ ConverterAnnotationPair getOrCreateConverter(
+ Class extends DependentResource> dependentResourceClass,
+ C parentConfiguration,
+ Class extends ConfigurationConverter> converterClass,
+ Class extends Annotation> annotationClass) {
var converterPair = converters.get(dependentResourceClass);
if (converterPair == null) {
// only instantiate a new converter if we haven't done so already for this converter type
var converter = knownConverters.get(converterClass);
if (converter == null) {
- converter = Utils.instantiate(converterClass,
- ConfigurationConverter.class,
- Utils.contextFor(parentConfiguration, dependentResourceClass, Configured.class));
+ converter =
+ Utils.instantiate(
+ converterClass,
+ ConfigurationConverter.class,
+ Utils.contextFor(parentConfiguration, dependentResourceClass, Configured.class));
knownConverters.put(converterClass, converter);
}
// record dependent class - converter association for faster future retrieval
@@ -102,13 +107,16 @@ static ConfigurationConverter getConverter(
}
@SuppressWarnings("unused")
- public static void registerConverter(Class extends DependentResource> dependentResourceClass,
- ConfigurationConverter converter) {
+ public static void registerConverter(
+ Class extends DependentResource> dependentResourceClass, ConfigurationConverter converter) {
var configured = getConfigured(dependentResourceClass);
if (configured == null) {
- throw new IllegalArgumentException("There is no @" + Configured.class.getSimpleName()
- + " annotation on " + dependentResourceClass.getName()
- + " or its superclasses and thus doesn't need to be associated with a converter");
+ throw new IllegalArgumentException(
+ "There is no @"
+ + Configured.class.getSimpleName()
+ + " annotation on "
+ + dependentResourceClass.getName()
+ + " or its superclasses and thus doesn't need to be associated with a converter");
}
// find the associated configuration annotation
@@ -134,8 +142,8 @@ private static class ConfiguredClassPair {
private final Configured configured;
private final Class extends DependentResource> annotatedClass;
- private ConfiguredClassPair(Configured configured,
- Class extends DependentResource> annotatedClass) {
+ private ConfiguredClassPair(
+ Configured configured, Class extends DependentResource> annotatedClass) {
this.configured = configured;
this.annotatedClass = annotatedClass;
}
@@ -150,8 +158,8 @@ private static class ConverterAnnotationPair {
private final ConfigurationConverter converter;
private final Class extends Annotation> annotationClass;
- private ConverterAnnotationPair(ConfigurationConverter converter,
- Class extends Annotation> annotationClass) {
+ private ConverterAnnotationPair(
+ ConfigurationConverter converter, Class extends Annotation> annotationClass) {
this.converter = converter;
this.annotationClass = annotationClass;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java
index accccb3f6e..8e79571e73 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java
@@ -20,10 +20,15 @@ public class DependentResourceSpec {
private final String useEventSourceWithName;
private C nullableConfiguration;
- public DependentResourceSpec(Class extends DependentResource> dependentResourceClass,
- String name, Set dependsOn, Condition, ?> readyCondition,
- Condition, ?> reconcileCondition, Condition, ?> deletePostCondition,
- Condition, ?> activationCondition, String useEventSourceWithName) {
+ public DependentResourceSpec(
+ Class extends DependentResource> dependentResourceClass,
+ String name,
+ Set dependsOn,
+ Condition, ?> readyCondition,
+ Condition, ?> reconcileCondition,
+ Condition, ?> deletePostCondition,
+ Condition, ?> activationCondition,
+ String useEventSourceWithName) {
this.dependentResourceClass = dependentResourceClass;
this.name = name;
this.dependsOn = dependsOn;
@@ -44,8 +49,11 @@ public String getName() {
@Override
public String toString() {
- return "DependentResourceSpec{ name='" + name +
- "', type=" + getDependentResourceClass().getCanonicalName() + '}';
+ return "DependentResourceSpec{ name='"
+ + name
+ + "', type="
+ + getDependentResourceClass().getCanonicalName()
+ + '}';
}
@Override
@@ -100,5 +108,4 @@ public Optional getConfiguration() {
protected void setNullableConfiguration(C configuration) {
this.nullableConfiguration = configuration;
}
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java
index cdbf07a5c1..80a025009d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java
@@ -27,18 +27,20 @@
* Specified which namespaces the associated informer monitors for custom resources events. If no
* namespace is specified then which namespaces the informer will monitor will depend on the
* context in which the informer is configured:
+ *
*
- * - all namespaces if configuring a controller informer
- * - the namespaces configured for the associated controller if configuring an event source
+ * - all namespaces if configuring a controller informer
+ *
- the namespaces configured for the associated controller if configuring an event source
*
*
* You can set a list of namespaces or use the following constants:
+ *
*
- * - {@link Constants#WATCH_ALL_NAMESPACES}
- * - {@link Constants#WATCH_CURRENT_NAMESPACE}
- * - {@link Constants#SAME_AS_CONTROLLER}
+ * - {@link Constants#WATCH_ALL_NAMESPACES}
+ *
- {@link Constants#WATCH_CURRENT_NAMESPACE}
+ *
- {@link Constants#SAME_AS_CONTROLLER}
*
- *
+ *
* @return the array of namespaces the associated informer monitors
*/
String[] namespaces() default {Constants.SAME_AS_CONTROLLER};
@@ -56,7 +58,7 @@
* Optional {@link OnAddFilter} to filter add events sent to the associated informer
*
* @return the {@link OnAddFilter} filter implementation to use, defaulting to the interface
- * itself if no value is set
+ * itself if no value is set
*/
Class extends OnAddFilter> onAddFilter() default OnAddFilter.class;
@@ -64,7 +66,7 @@
* Optional {@link OnUpdateFilter} to filter update events sent to the associated informer
*
* @return the {@link OnUpdateFilter} filter implementation to use, defaulting to the interface
- * itself if no value is set
+ * itself if no value is set
*/
Class extends OnUpdateFilter> onUpdateFilter() default OnUpdateFilter.class;
@@ -72,7 +74,7 @@
* Optional {@link OnDeleteFilter} to filter delete events sent to the associated informer
*
* @return the {@link OnDeleteFilter} filter implementation to use, defaulting to the interface
- * itself if no value is set
+ * itself if no value is set
*/
Class extends OnDeleteFilter> onDeleteFilter() default OnDeleteFilter.class;
@@ -80,7 +82,7 @@
* Optional {@link GenericFilter} to filter events sent to the associated informer
*
* @return the {@link GenericFilter} filter implementation to use, defaulting to the interface
- * itself if no value is set
+ * itself if no value is set
*/
Class extends GenericFilter> genericFilter() default GenericFilter.class;
@@ -96,14 +98,10 @@
* "https://github.com/fabric8io/kubernetes-client/blob/43b67939fde91046ab7fb0c362f500c2b46eb59e/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/DefaultSharedIndexInformer.java#L273">
* method in fabric8 client informer implementation.
*
- *
- * The main goal, is to be able to use limited caches or provide any custom implementation.
- *
+ * The main goal, is to be able to use limited caches or provide any custom implementation.
*
- *
- * See {@link BoundedItemStore} and See {@link BoundedItemStore} and CaffeinBoundedCache
- *
*
* @return the class of the {@link ItemStore} implementation to use
*/
@@ -115,5 +113,4 @@
* the informer cache.
*/
long informerListLimit() default NO_LONG_VALUE_SET;
-
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java
index 0c55353b86..958a2a7a6f 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java
@@ -21,7 +21,6 @@
import static io.javaoperatorsdk.operator.api.reconciler.Constants.*;
-
@SuppressWarnings("unused")
public class InformerConfiguration {
private final Builder builder = new Builder();
@@ -38,11 +37,18 @@ public class InformerConfiguration {
private ItemStore itemStore;
private Long informerListLimit;
- protected InformerConfiguration(Class resourceClass, String name, Set namespaces,
+ protected InformerConfiguration(
+ Class resourceClass,
+ String name,
+ Set namespaces,
boolean followControllerNamespaceChanges,
- String labelSelector, OnAddFilter super R> onAddFilter,
- OnUpdateFilter super R> onUpdateFilter, OnDeleteFilter super R> onDeleteFilter,
- GenericFilter super R> genericFilter, ItemStore itemStore, Long informerListLimit) {
+ String labelSelector,
+ OnAddFilter super R> onAddFilter,
+ OnUpdateFilter super R> onUpdateFilter,
+ OnDeleteFilter super R> onDeleteFilter,
+ GenericFilter super R> genericFilter,
+ ItemStore itemStore,
+ Long informerListLimit) {
this(resourceClass);
this.name = name;
this.namespaces = namespaces;
@@ -58,11 +64,13 @@ protected InformerConfiguration(Class resourceClass, String name, Set
private InformerConfiguration(Class resourceClass) {
this.resourceClass = resourceClass;
- this.resourceTypeName = resourceClass.isAssignableFrom(GenericKubernetesResource.class)
- // in general this is irrelevant now for secondary resources it is used just by controller
- // where GenericKubernetesResource now does not apply
- ? GenericKubernetesResource.class.getSimpleName()
- : ReconcilerUtils.getResourceTypeName(resourceClass);
+ this.resourceTypeName =
+ resourceClass.isAssignableFrom(GenericKubernetesResource.class)
+ // in general this is irrelevant now for secondary resources it is used just by
+ // controller
+ // where GenericKubernetesResource now does not apply
+ ? GenericKubernetesResource.class.getSimpleName()
+ : ReconcilerUtils.getResourceTypeName(resourceClass);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@@ -74,10 +82,19 @@ public static InformerConfiguration.Builder builder(
@SuppressWarnings({"rawtypes", "unchecked"})
public static InformerConfiguration.Builder builder(
InformerConfiguration original) {
- return new InformerConfiguration(original.resourceClass, original.name, original.namespaces,
- original.followControllerNamespaceChanges, original.labelSelector, original.onAddFilter,
- original.onUpdateFilter, original.onDeleteFilter, original.genericFilter,
- original.itemStore, original.informerListLimit).builder;
+ return new InformerConfiguration(
+ original.resourceClass,
+ original.name,
+ original.namespaces,
+ original.followControllerNamespaceChanges,
+ original.labelSelector,
+ original.onAddFilter,
+ original.onUpdateFilter,
+ original.onDeleteFilter,
+ original.genericFilter,
+ original.itemStore,
+ original.informerListLimit)
+ .builder;
}
public static String ensureValidLabelSelector(String labelSelector) {
@@ -97,8 +114,8 @@ public static boolean currentNamespaceWatched(Set namespaces) {
public static void failIfNotValid(Set namespaces) {
if (namespaces != null && !namespaces.isEmpty()) {
- final var present = namespaces.contains(WATCH_CURRENT_NAMESPACE)
- || namespaces.contains(WATCH_ALL_NAMESPACES);
+ final var present =
+ namespaces.contains(WATCH_CURRENT_NAMESPACE) || namespaces.contains(WATCH_ALL_NAMESPACES);
if (!present || namespaces.size() == 1) {
return;
}
@@ -107,7 +124,8 @@ public static void failIfNotValid(Set namespaces) {
"Must specify namespaces. To watch all namespaces, use only '"
+ WATCH_ALL_NAMESPACES
+ "'. To watch only the namespace in which the operator is deployed, use only '"
- + WATCH_CURRENT_NAMESPACE + "'");
+ + WATCH_CURRENT_NAMESPACE
+ + "'");
}
public static Set ensureValidNamespaces(Collection namespaces) {
@@ -165,11 +183,16 @@ public Set getEffectiveNamespaces(ControllerConfiguration> controllerC
var targetNamespaces = getNamespaces();
if (watchCurrentNamespace()) {
final String namespace =
- controllerConfiguration.getConfigurationService().getKubernetesClient().getConfiguration()
+ controllerConfiguration
+ .getConfigurationService()
+ .getKubernetesClient()
+ .getConfiguration()
.getNamespace();
if (namespace == null) {
throw new OperatorException(
- "Couldn't retrieve the currently connected namespace. Make sure it's correctly set in your ~/.kube/config file, using, e.g. 'kubectl config set-context --namespace='");
+ "Couldn't retrieve the currently connected namespace. Make sure it's correctly set in"
+ + " your ~/.kube/config file, using, e.g. 'kubectl config set-context --namespace='");
}
targetNamespaces = Collections.singleton(namespace);
}
@@ -190,9 +213,9 @@ public boolean getFollowControllerNamespaceChanges() {
/**
* Retrieves the label selector that is used to filter which resources are actually watched by the
- * associated informer. See the official documentation on the
- * topic
- * for more details on syntax.
+ * associated informer. See the official documentation on the topic for
+ * more details on syntax.
*
* @return the label selector filtering watched resources
*/
@@ -221,17 +244,13 @@ public GenericFilter super R> getGenericFilter() {
* "https://github.com/fabric8io/kubernetes-client/blob/43b67939fde91046ab7fb0c362f500c2b46eb59e/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/DefaultSharedIndexInformer.java#L273">method
* in fabric8 client informer implementation.
*
- *
- * The main goal, is to be able to use limited caches or provide any custom implementation.
- *
+ * The main goal, is to be able to use limited caches or provide any custom implementation.
*
- *
- * See {@link BoundedItemStore} and See {@link BoundedItemStore} and CaffeineBoundedCache
- *
*
* @return Optional {@link ItemStore} implementation. If present this item store will be used by
- * the informers.
+ * the informers.
*/
public ItemStore getItemStore() {
return itemStore;
@@ -245,7 +264,6 @@ public Long getInformerListLimit() {
return informerListLimit;
}
-
@SuppressWarnings("UnusedReturnValue")
public class Builder {
@@ -253,7 +271,8 @@ public class Builder {
public InformerConfiguration buildForController() {
// if the informer config uses the default "same as controller" value, reset the namespaces to
// the default set for controllers
- if (namespaces == null || namespaces.isEmpty()
+ if (namespaces == null
+ || namespaces.isEmpty()
|| inheritsNamespacesFromController(namespaces)) {
namespaces = Constants.DEFAULT_NAMESPACES_SET;
}
@@ -268,15 +287,14 @@ public InformerConfiguration build() {
namespaces = Constants.SAME_AS_CONTROLLER_NAMESPACES_SET;
}
if (followControllerNamespaceChanges == null) {
- followControllerNamespaceChanges =
- DEFAULT_FOLLOW_CONTROLLER_NAMESPACE_CHANGES;
+ followControllerNamespaceChanges = DEFAULT_FOLLOW_CONTROLLER_NAMESPACE_CHANGES;
}
return InformerConfiguration.this;
}
@SuppressWarnings({"unchecked"})
- public InformerConfiguration.Builder initFromAnnotation(Informer informerConfig,
- String context) {
+ public InformerConfiguration.Builder initFromAnnotation(
+ Informer informerConfig, String context) {
if (informerConfig != null) {
// override default name if more specific one is provided
@@ -291,24 +309,21 @@ public InformerConfiguration.Builder initFromAnnotation(Informer informerConf
var labelSelector = Constants.NO_VALUE_SET.equals(fromAnnotation) ? null : fromAnnotation;
withLabelSelector(labelSelector);
- withOnAddFilter(Utils.instantiate(informerConfig.onAddFilter(),
- OnAddFilter.class, context));
+ withOnAddFilter(
+ Utils.instantiate(informerConfig.onAddFilter(), OnAddFilter.class, context));
- withOnUpdateFilter(Utils.instantiate(informerConfig.onUpdateFilter(),
- OnUpdateFilter.class, context));
+ withOnUpdateFilter(
+ Utils.instantiate(informerConfig.onUpdateFilter(), OnUpdateFilter.class, context));
- withOnDeleteFilter(Utils.instantiate(informerConfig.onDeleteFilter(),
- OnDeleteFilter.class, context));
+ withOnDeleteFilter(
+ Utils.instantiate(informerConfig.onDeleteFilter(), OnDeleteFilter.class, context));
- withGenericFilter(Utils.instantiate(informerConfig.genericFilter(),
- GenericFilter.class,
- context));
+ withGenericFilter(
+ Utils.instantiate(informerConfig.genericFilter(), GenericFilter.class, context));
- withFollowControllerNamespacesChanges(
- informerConfig.followControllerNamespaceChanges());
+ withFollowControllerNamespacesChanges(informerConfig.followControllerNamespaceChanges());
- withItemStore(Utils.instantiate(informerConfig.itemStore(),
- ItemStore.class, context));
+ withItemStore(Utils.instantiate(informerConfig.itemStore(), ItemStore.class, context));
final var informerListLimitValue = informerConfig.informerListLimit();
final var informerListLimit =
@@ -324,8 +339,7 @@ public Builder withName(String name) {
}
public Builder withNamespaces(Set namespaces) {
- InformerConfiguration.this.namespaces =
- ensureValidNamespaces(namespaces);
+ InformerConfiguration.this.namespaces = ensureValidNamespaces(namespaces);
return this;
}
@@ -334,13 +348,13 @@ public Set namespaces() {
}
/**
- * Sets the initial set of namespaces to watch (typically extracted from the parent
- * {@link io.javaoperatorsdk.operator.processing.Controller}'s configuration), specifying
- * whether changes made to the parent controller configured namespaces should be tracked or not.
+ * Sets the initial set of namespaces to watch (typically extracted from the parent {@link
+ * io.javaoperatorsdk.operator.processing.Controller}'s configuration), specifying whether
+ * changes made to the parent controller configured namespaces should be tracked or not.
*
* @param namespaces the initial set of namespaces to watch
* @param followChanges {@code true} to follow the changes made to the parent controller
- * namespaces, {@code false} otherwise
+ * namespaces, {@code false} otherwise
* @return the builder instance so that calls can be chained fluently
*/
public Builder withNamespaces(Set namespaces, boolean followChanges) {
@@ -363,47 +377,40 @@ public Builder withWatchCurrentNamespace() {
return this;
}
-
/**
- * Whether the associated informer should track changes made to the parent
- * {@link io.javaoperatorsdk.operator.processing.Controller}'s namespaces configuration.
+ * Whether the associated informer should track changes made to the parent {@link
+ * io.javaoperatorsdk.operator.processing.Controller}'s namespaces configuration.
*
* @param followChanges {@code true} to reconfigure the associated informer when the parent
- * controller's namespaces are reconfigured, {@code false} otherwise
+ * controller's namespaces are reconfigured, {@code false} otherwise
* @return the builder instance so that calls can be chained fluently
*/
public Builder withFollowControllerNamespacesChanges(boolean followChanges) {
- InformerConfiguration.this.followControllerNamespaceChanges =
- followChanges;
+ InformerConfiguration.this.followControllerNamespaceChanges = followChanges;
return this;
}
public Builder withLabelSelector(String labelSelector) {
- InformerConfiguration.this.labelSelector =
- ensureValidLabelSelector(labelSelector);
+ InformerConfiguration.this.labelSelector = ensureValidLabelSelector(labelSelector);
return this;
}
- public Builder withOnAddFilter(
- OnAddFilter super R> onAddFilter) {
+ public Builder withOnAddFilter(OnAddFilter super R> onAddFilter) {
InformerConfiguration.this.onAddFilter = onAddFilter;
return this;
}
- public Builder withOnUpdateFilter(
- OnUpdateFilter super R> onUpdateFilter) {
+ public Builder withOnUpdateFilter(OnUpdateFilter super R> onUpdateFilter) {
InformerConfiguration.this.onUpdateFilter = onUpdateFilter;
return this;
}
- public Builder withOnDeleteFilter(
- OnDeleteFilter super R> onDeleteFilter) {
+ public Builder withOnDeleteFilter(OnDeleteFilter super R> onDeleteFilter) {
InformerConfiguration.this.onDeleteFilter = onDeleteFilter;
return this;
}
- public Builder withGenericFilter(
- GenericFilter super R> genericFilter) {
+ public Builder withGenericFilter(GenericFilter super R> genericFilter) {
InformerConfiguration.this.genericFilter = genericFilter;
return this;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java
index c3c2777049..9fb5ad4c82 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java
@@ -22,8 +22,7 @@
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_ALL_NAMESPACE_SET;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE_SET;
-public interface InformerEventSourceConfiguration
- extends Informable {
+public interface InformerEventSourceConfiguration extends Informable {
static Builder from(
Class resourceClass, Class extends HasMetadata> primaryResourceClass) {
@@ -55,7 +54,7 @@ default boolean followControllerNamespaceChanges() {
*
* @return the configured {@link SecondaryToPrimaryMapper}
* @see SecondaryToPrimaryMapper for more explanations on when using such a mapper is useful /
- * needed
+ * needed
*/
SecondaryToPrimaryMapper getSecondaryToPrimaryMapper();
@@ -135,19 +134,20 @@ class Builder {
private SecondaryToPrimaryMapper secondaryToPrimaryMapper;
private KubernetesClient kubernetesClient;
- private Builder(Class resourceClass,
- Class extends HasMetadata> primaryResourceClass) {
+ private Builder(Class resourceClass, Class extends HasMetadata> primaryResourceClass) {
this(resourceClass, primaryResourceClass, null);
}
@SuppressWarnings("unchecked")
- private Builder(GroupVersionKind groupVersionKind,
- Class extends HasMetadata> primaryResourceClass) {
+ private Builder(
+ GroupVersionKind groupVersionKind, Class extends HasMetadata> primaryResourceClass) {
this((Class) GenericKubernetesResource.class, primaryResourceClass, groupVersionKind);
}
- private Builder(Class resourceClass,
- Class extends HasMetadata> primaryResourceClass, GroupVersionKind groupVersionKind) {
+ private Builder(
+ Class resourceClass,
+ Class extends HasMetadata> primaryResourceClass,
+ GroupVersionKind groupVersionKind) {
this.resourceClass = resourceClass;
this.groupVersionKind = groupVersionKind;
this.primaryResourceClass = primaryResourceClass;
@@ -176,8 +176,7 @@ public Builder withSecondaryToPrimaryMapper(
* Use this is case want to create an InformerEventSource that handles resources from different
* cluster.
*/
- public Builder