Skip to content

Commit f46ca07

Browse files
committed
Merge branch 'master' into event-sources
# Conflicts: # operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java # operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java # operator-framework/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java # operator-framework/src/test/java/io/javaoperatorsdk/operator/EventDispatcherTest.java # operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSchedulerTest.java
2 parents c26f157 + bc65b1c commit f46ca07

File tree

11 files changed

+59
-32
lines changed

11 files changed

+59
-32
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Set up Minikube
3030
uses: manusa/[email protected]
3131
with:
32-
minikube version: 'v1.15.0'
32+
minikube version: 'v1.15.1'
3333
kubernetes version: ${{ matrix.kubernetes }}
3434
driver: 'docker'
3535
- name: Run integration tests

operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,27 @@
1616
public class ControllerUtils {
1717

1818
private final static double JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version"));
19-
20-
private final static Logger log = LoggerFactory.getLogger(ControllerUtils.class);
19+
private static final String FINALIZER_NAME_SUFFIX = "/finalizer";
2120

2221
// this is just to support testing, this way we don't try to create class multiple times in memory with same name.
2322
// note that other solution is to add a random string to doneable class name
2423
private static Map<Class<? extends CustomResource>, Class<? extends CustomResourceDoneable<? extends CustomResource>>>
2524
doneableClassCache = new HashMap<>();
2625

27-
public static String getDefaultFinalizer(ResourceController controller) {
28-
return getAnnotation(controller).finalizerName();
26+
static String getFinalizer(ResourceController controller) {
27+
final String annotationFinalizerName = getAnnotation(controller).finalizerName();
28+
if (!Controller.NULL.equals(annotationFinalizerName)) {
29+
return annotationFinalizerName;
30+
}
31+
final String crdName = getAnnotation(controller).crdName() + FINALIZER_NAME_SUFFIX;
32+
return crdName;
2933
}
3034

3135
public static boolean getGenerationEventProcessing(ResourceController controller) {
3236
return getAnnotation(controller).generationAwareEventProcessing();
3337
}
3438

35-
public static <R extends CustomResource> Class<R> getCustomResourceClass(ResourceController controller) {
39+
static <R extends CustomResource> Class<R> getCustomResourceClass(ResourceController<R> controller) {
3640
return (Class<R>) getAnnotation(controller).customResourceClass();
3741
}
3842

@@ -79,10 +83,7 @@ private static Controller getAnnotation(ResourceController controller) {
7983
return controller.getClass().getAnnotation(Controller.class);
8084
}
8185

82-
public static boolean hasDefaultFinalizer(CustomResource resource, String finalizer) {
83-
if (resource.getMetadata().getFinalizers() != null) {
84-
return resource.getMetadata().getFinalizers().contains(finalizer);
85-
}
86-
return false;
86+
public static boolean hasGivenFinalizer(CustomResource resource, String finalizer) {
87+
return resource.getMetadata().getFinalizers() != null && resource.getMetadata().getFinalizers().contains(finalizer);
8788
}
8889
}

operator-framework/src/main/java/io/javaoperatorsdk/operator/Operator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ private <R extends CustomResource> void registerController(ResourceController<R>
5151
Class<R> resClass = getCustomResourceClass(controller);
5252
CustomResourceDefinitionContext crd = getCustomResourceDefinitionForController(controller);
5353
KubernetesDeserializer.registerCustomKind(crd.getVersion(), crd.getKind(), resClass);
54-
String finalizer = getDefaultFinalizer(controller);
55-
MixedOperation client = k8sClient.customResources(crd, resClass, CustomResourceList.class, getCustomResourceDoneableClass(controller));
54+
String finalizer = ControllerUtils.getFinalizer(controller);
55+
MixedOperation client = k8sClient.customResources(crd, resClass, CustomResourceList.class, ControllerUtils.getCustomResourceDoneableClass(controller));
5656
EventDispatcher eventDispatcher = new EventDispatcher(controller,
5757
finalizer, new EventDispatcher.CustomResourceFacade(client), ControllerUtils.getGenerationEventProcessing(controller));
5858

operator-framework/src/main/java/io/javaoperatorsdk/operator/api/Controller.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
@Retention(RetentionPolicy.RUNTIME)
1111
@Target({ElementType.TYPE})
1212
public @interface Controller {
13-
14-
String DEFAULT_FINALIZER = "operator.default.finalizer";
13+
String NULL = "";
1514

1615
String crdName();
1716

1817
Class<? extends CustomResource> customResourceClass();
1918

20-
String finalizerName() default DEFAULT_FINALIZER;
19+
/**
20+
* Optional finalizer name, if it is not,
21+
* the crdName will be used as the name of the finalizer too.
22+
*/
23+
String finalizerName() default NULL;
2124

2225
/**
2326
* If true, will dispatch new event to the controller if generation increased since the last processing, otherwise will

operator-framework/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public interface ResourceController<R extends CustomResource> {
66

77
/**
88
* The implementation should delete the associated component(s). Note that this is method is called when an object
9-
* is marked for deletion. After its executed the default finalizer is automatically removed by the framework;
9+
* is marked for deletion. After its executed the custom resource finalizer is automatically removed by the framework;
1010
* unless the return value is false - note that this is almost never the case.
1111
* Its important to have the implementation also idempotent, in the current implementation to cover all edge cases
1212
* actually will be executed mostly twice.
@@ -27,5 +27,4 @@ public interface ResourceController<R extends CustomResource> {
2727
* <b>However we will always call an update if there is no finalizer on object and its not marked for deletion.</b>
2828
*/
2929
UpdateControl<R> createOrUpdateResource(R resource, Context<R> context);
30-
3130
}

operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
2222
public class ControllerExecutionIT {
2323

24-
private final static Logger log = LoggerFactory.getLogger(ControllerExecutionIT.class);
2524
public static final String TEST_CUSTOM_RESOURCE_NAME = "test-custom-resource";
2625
private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
2726

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,46 @@
11
package io.javaoperatorsdk.operator;
22

3-
import io.javaoperatorsdk.operator.sample.TestCustomResource;
4-
import io.javaoperatorsdk.operator.sample.TestCustomResourceController;
53
import io.fabric8.kubernetes.client.CustomResourceDoneable;
4+
import io.javaoperatorsdk.operator.api.Context;
65
import io.javaoperatorsdk.operator.api.Controller;
6+
import io.javaoperatorsdk.operator.api.ResourceController;
7+
import io.javaoperatorsdk.operator.api.UpdateControl;
8+
import io.javaoperatorsdk.operator.sample.TestCustomResource;
9+
import io.javaoperatorsdk.operator.sample.TestCustomResourceController;
710
import org.junit.jupiter.api.Assertions;
811
import org.junit.jupiter.api.Test;
912

10-
import static org.junit.jupiter.api.Assertions.assertEquals;
11-
import static org.junit.jupiter.api.Assertions.assertTrue;
13+
import static org.junit.jupiter.api.Assertions.*;
1214

1315
class ControllerUtilsTest {
1416

17+
public static final String CUSTOM_FINALIZER_NAME = "a.custom/finalizer";
18+
1519
@Test
1620
public void returnsValuesFromControllerAnnotationFinalizer() {
17-
Assertions.assertEquals(Controller.DEFAULT_FINALIZER, ControllerUtils.getDefaultFinalizer(new TestCustomResourceController(null)));
21+
Assertions.assertEquals(TestCustomResourceController.CRD_NAME + "/finalizer", ControllerUtils.getFinalizer(new TestCustomResourceController(null)));
1822
assertEquals(TestCustomResource.class, ControllerUtils.getCustomResourceClass(new TestCustomResourceController(null)));
1923
Assertions.assertEquals(TestCustomResourceController.CRD_NAME, ControllerUtils.getCrdName(new TestCustomResourceController(null)));
20-
assertEquals(false, ControllerUtils.getGenerationEventProcessing(new TestCustomResourceController(null)));
24+
assertFalse(ControllerUtils.getGenerationEventProcessing(new TestCustomResourceController(null)));
2125
assertTrue(CustomResourceDoneable.class.isAssignableFrom(ControllerUtils.getCustomResourceDoneableClass(new TestCustomResourceController(null))));
2226
}
27+
28+
@Controller(crdName = "test.crd", customResourceClass = TestCustomResource.class, finalizerName = CUSTOM_FINALIZER_NAME)
29+
static class TestCustomFinalizerController implements ResourceController<TestCustomResource> {
30+
31+
@Override
32+
public boolean deleteResource(TestCustomResource resource, Context<TestCustomResource> context) {
33+
return false;
34+
}
35+
36+
@Override
37+
public UpdateControl<TestCustomResource> createOrUpdateResource(TestCustomResource resource, Context<TestCustomResource> context) {
38+
return null;
39+
}
40+
}
41+
42+
@Test
43+
public void returnCustomerFinalizerNameIfSet() {
44+
assertEquals(CUSTOM_FINALIZER_NAME, ControllerUtils.getFinalizer(new TestCustomFinalizerController()));
45+
}
2346
}

operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void initialize(KubernetesClient k8sClient, ResourceController controller
5353
}
5454
operator = new Operator(k8sClient);
5555
operator.registerController(controller, TEST_NAMESPACE);
56-
log.info("Operator is running with TestCustomeResourceController");
56+
log.info("Operator is running with {}", controller.getClass().getCanonicalName());
5757
}
5858

5959
public CustomResourceDefinition loadCRDAndApplyToCluster(String classPathYaml) {
@@ -107,7 +107,7 @@ public void teardownIfSuccess(TestRun test) {
107107
if (namespace.getStatus().getPhase().equals("Active")) {
108108
k8sClient.namespaces().withName(TEST_NAMESPACE).delete();
109109
}
110-
await("namespace deleted").atMost(30, TimeUnit.SECONDS)
110+
await("namespace deleted").atMost(45, TimeUnit.SECONDS)
111111
.until(() -> k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null);
112112
} catch (Exception e) {
113113
throw new IllegalStateException(e);

operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void ifNoFinalizerPresentFirstAddsTheFinalizerThenExecutesControllerAgain
6868
* If this would not happen (no optimistic locking on status sub-resource) we could receive and store an event
6969
* while processing the controller method. But this event would always fail since its resource version is outdated
7070
* already.
71-
* */
71+
*/
7272
@Test
7373
public void updateCustomResourceAfterSubResourceChange() {
7474
integrationTestSupport.teardownIfSuccess(() -> {
@@ -104,7 +104,7 @@ public SubResourceTestCustomResource createTestCustomResource(String id) {
104104
resource.setMetadata(new ObjectMetaBuilder()
105105
.withName("subresource-" + id)
106106
.withNamespace(TEST_NAMESPACE)
107-
.withFinalizers(Controller.DEFAULT_FINALIZER)
107+
.withFinalizers(SubResourceTestCustomResourceController.FINALIZER_NAME)
108108
.build());
109109
resource.setKind("SubresourceSample");
110110
resource.setSpec(new SubResourceTestCustomResourceSpec());

operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/TestCustomResourceController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class TestCustomResourceController implements ResourceController<TestCust
2222
private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class);
2323

2424
public static final String CRD_NAME = "customservices.sample.javaoperatorsdk";
25+
public static final String FINALIZER_NAME = CRD_NAME + "/finalizer";
2526

2627
private final KubernetesClient kubernetesClient;
2728
private final boolean updateStatus;
@@ -52,7 +53,7 @@ public DeleteControl deleteResource(TestCustomResource resource, Context<TestCus
5253
public UpdateControl<TestCustomResource> createOrUpdateResource(TestCustomResource resource,
5354
Context<TestCustomResource> context) {
5455
numberOfExecutions.addAndGet(1);
55-
if (!resource.getMetadata().getFinalizers().contains(Controller.DEFAULT_FINALIZER)) {
56+
if (!resource.getMetadata().getFinalizers().contains(FINALIZER_NAME)) {
5657
throw new IllegalStateException("Finalizer is not present.");
5758
}
5859

0 commit comments

Comments
 (0)