diff --git a/sample-operators/leader-election/README.md b/sample-operators/leader-election/README.md
index 2a9a369a45..d74bad0b35 100644
--- a/sample-operators/leader-election/README.md
+++ b/sample-operators/leader-election/README.md
@@ -1,6 +1,10 @@
# Leader Election E2E Test
-The purpose of this module is to e2e test leader election feature.
+The purpose of this module is to e2e test leader election feature and to demonstrate contract-first CRDs.
The deployment is using directly pods in order to better control some aspects in test.
-In real life this would be a Deployment.
\ No newline at end of file
+In real life this would be a Deployment.
+
+The custom resource definition (CRD) is defined in YAML in the folder `src/main/resources/kubernetes`.
+Upon build, the [java-generator-maven-plugin](https://github.com/fabric8io/kubernetes-client/blob/master/doc/java-generation-from-CRD.md)
+generates the Java code under `target/generated-sources/java`.
diff --git a/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml b/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml
index 68e00d81ad..13724a911a 100644
--- a/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml
+++ b/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml
@@ -48,8 +48,8 @@ rules:
- apiGroups:
- "sample.javaoperatorsdk"
resources:
- - leaderelectiontestcustomresources
- - leaderelectiontestcustomresources/status
+ - leaderelections
+ - leaderelections/status
verbs:
- '*'
- apiGroups:
diff --git a/sample-operators/leader-election/k8s/operator.yaml b/sample-operators/leader-election/k8s/operator.yaml
index 00ed3e7273..9d289a2d6c 100644
--- a/sample-operators/leader-election/k8s/operator.yaml
+++ b/sample-operators/leader-election/k8s/operator.yaml
@@ -52,8 +52,8 @@ rules:
- apiGroups:
- "sample.javaoperatorsdk"
resources:
- - leaderelectiontestcustomresources
- - leaderelectiontestcustomresources/status
+ - leaderelections
+ - leaderelections/status
verbs:
- '*'
- apiGroups:
diff --git a/sample-operators/leader-election/pom.xml b/sample-operators/leader-election/pom.xml
index 87b346a818..bb417df67e 100644
--- a/sample-operators/leader-election/pom.xml
+++ b/sample-operators/leader-election/pom.xml
@@ -47,11 +47,6 @@
takes
1.21.1
-
- io.fabric8
- crd-generator-apt
- provided
-
org.awaitility
awaitility
@@ -88,6 +83,22 @@
maven-compiler-plugin
3.10.0
+
+
+ io.fabric8
+ java-generator-maven-plugin
+ ${fabric8-client.version}
+
+
+
+ generate
+
+
+
+
+ src/main/resources/kubernetes
+
+
diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java
deleted file mode 100644
index b440be4d18..0000000000
--- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.javaoperatorsdk.operator.sample;
-
-import io.fabric8.kubernetes.api.model.Namespaced;
-import io.fabric8.kubernetes.client.CustomResource;
-import io.fabric8.kubernetes.model.annotation.Group;
-import io.fabric8.kubernetes.model.annotation.ShortNames;
-import io.fabric8.kubernetes.model.annotation.Version;
-
-@Group("sample.javaoperatorsdk")
-@Version("v1")
-@ShortNames("le")
-public class LeaderElectionTestCustomResource
- extends CustomResource
- implements Namespaced {
-}
diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java
index f6231d0a52..4cd8627328 100644
--- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java
+++ b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java
@@ -1,15 +1,19 @@
package io.javaoperatorsdk.operator.sample;
import java.time.Duration;
+import java.util.ArrayList;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
+import javaoperatorsdk.sample.v1.LeaderElection;
+import javaoperatorsdk.sample.v1.LeaderElectionStatus;
+
@ControllerConfiguration()
public class LeaderElectionTestReconciler
- implements Reconciler {
+ implements Reconciler {
private final String reconcilerName;
@@ -18,12 +22,15 @@ public LeaderElectionTestReconciler(String reconcilerName) {
}
@Override
- public UpdateControl reconcile(
- LeaderElectionTestCustomResource resource,
- Context context) {
+ public UpdateControl reconcile(
+ LeaderElection resource,
+ Context context) {
if (resource.getStatus() == null) {
- resource.setStatus(new LeaderElectionTestStatus());
+ resource.setStatus(new LeaderElectionStatus());
+ }
+ if (resource.getStatus().getReconciledBy() == null) {
+ resource.getStatus().setReconciledBy(new ArrayList<>());
}
resource.getStatus().getReconciledBy().add(reconcilerName);
diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java
deleted file mode 100644
index 5a9e66e270..0000000000
--- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.javaoperatorsdk.operator.sample;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class LeaderElectionTestStatus {
-
- private List reconciledBy;
-
- public List getReconciledBy() {
- if (reconciledBy == null) {
- reconciledBy = new ArrayList<>();
- }
- return reconciledBy;
- }
-
- public LeaderElectionTestStatus setReconciledBy(List reconciledBy) {
- this.reconciledBy = reconciledBy;
- return this;
- }
-}
diff --git a/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml b/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml
new file mode 100644
index 0000000000..cc9d8c3fc6
--- /dev/null
+++ b/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml
@@ -0,0 +1,34 @@
+# Custom Resource Definition that will be used to generate the Java classes in target/generated-sources/java
+# See https://github.com/fabric8io/kubernetes-client/blob/master/doc/java-generation-from-CRD.md
+# The Java classes will then be used to recreate this CR in target/classes/META-INF/fabric8
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: leaderelections.sample.javaoperatorsdk
+spec:
+ group: sample.javaoperatorsdk
+ names:
+ kind: LeaderElection
+ singular: leaderelection
+ plural: leaderelections
+ shortNames:
+ - le
+ - les
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ status:
+ properties:
+ reconciledBy:
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java b/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java
index 9b4eb736db..5512f54fc1 100644
--- a/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java
+++ b/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java
@@ -27,6 +27,8 @@
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
+import javaoperatorsdk.sample.v1.LeaderElection;
+
import static io.javaoperatorsdk.operator.junit.AbstractOperatorExtension.CRD_READY_WAIT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
@@ -61,7 +63,7 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) {
await().pollDelay(Duration.ofSeconds(MINIMAL_SECONDS_FOR_RENEWAL))
.atMost(Duration.ofSeconds(MAX_WAIT_SECONDS))
.untilAsserted(() -> {
- var actualStatus = client.resources(LeaderElectionTestCustomResource.class)
+ var actualStatus = client.resources(LeaderElection.class)
.inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus();
assertThat(actualStatus).isNotNull();
@@ -71,14 +73,14 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) {
client.pods().inNamespace(namespace).withName(OPERATOR_1_POD_NAME).delete();
- var actualListSize = client.resources(LeaderElectionTestCustomResource.class)
+ var actualListSize = client.resources(LeaderElection.class)
.inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus().getReconciledBy()
.size();
await().pollDelay(Duration.ofSeconds(MINIMAL_SECONDS_FOR_RENEWAL))
.atMost(Duration.ofSeconds(240))
.untilAsserted(() -> {
- var actualStatus = client.resources(LeaderElectionTestCustomResource.class)
+ var actualStatus = client.resources(LeaderElection.class)
.inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus();
assertThat(actualStatus).isNotNull();
@@ -87,7 +89,7 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) {
});
assertReconciliations(
- client.resources(LeaderElectionTestCustomResource.class).inNamespace(namespace)
+ client.resources(LeaderElection.class).inNamespace(namespace)
.withName(TEST_RESOURCE_NAME).get().getStatus().getReconciledBy());
}
@@ -104,7 +106,7 @@ private void assertReconciliations(List reconciledBy) {
}
private void applyCustomResource() {
- var res = new LeaderElectionTestCustomResource();
+ var res = new LeaderElection();
res.setMetadata(new ObjectMetaBuilder()
.withName(TEST_RESOURCE_NAME)
.withNamespace(namespace)
@@ -150,7 +152,7 @@ private void deployOperatorsInOrder(String yamlFilePrefix) {
void applyCRD() {
String path =
- "./target/classes/META-INF/fabric8/leaderelectiontestcustomresources.sample.javaoperatorsdk-v1.yml";
+ "./src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml";
try (InputStream is = new FileInputStream(path)) {
final var crd = client.load(is);
crd.createOrReplace();