-
Notifications
You must be signed in to change notification settings - Fork 209
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: API to check if next reconciliation is imminent (#2272)
Signed-off-by: Attila Mészáros <csviri@gmail.com>
- Loading branch information
Showing
7 changed files
with
180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
...tor-framework/src/test/java/io/javaoperatorsdk/operator/NextReconciliationImminentIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package io.javaoperatorsdk.operator; | ||
|
||
import java.time.Duration; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; | ||
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension; | ||
import io.javaoperatorsdk.operator.sample.nextreconciliationimminent.NextReconciliationImminentCustomResource; | ||
import io.javaoperatorsdk.operator.sample.nextreconciliationimminent.NextReconciliationImminentReconciler; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.awaitility.Awaitility.await; | ||
|
||
public class NextReconciliationImminentIT { | ||
|
||
private static final Logger log = | ||
LoggerFactory.getLogger(NextReconciliationImminentIT.class); | ||
|
||
public static final int WAIT_FOR_EVENT = 300; | ||
public static final String TEST_RESOURCE_NAME = "test1"; | ||
|
||
@RegisterExtension | ||
LocallyRunOperatorExtension extension = | ||
LocallyRunOperatorExtension.builder() | ||
.withReconciler(new NextReconciliationImminentReconciler()) | ||
.build(); | ||
|
||
@Test | ||
void skippingStatusUpdateWithNextReconciliationImminent() throws InterruptedException { | ||
var resource = extension.create(testResource()); | ||
|
||
var reconciler = extension.getReconcilerOfType(NextReconciliationImminentReconciler.class); | ||
await().untilAsserted(() -> assertThat(reconciler.isReconciliationWaiting()).isTrue()); | ||
Thread.sleep(WAIT_FOR_EVENT); | ||
|
||
resource.getMetadata().getAnnotations().put("trigger", "" + System.currentTimeMillis()); | ||
extension.replace(resource); | ||
Thread.sleep(WAIT_FOR_EVENT); | ||
log.info("Made change to trigger event"); | ||
|
||
reconciler.allowReconciliationToProceed(); | ||
Thread.sleep(WAIT_FOR_EVENT); | ||
// second event arrived | ||
await().untilAsserted(() -> assertThat(reconciler.isReconciliationWaiting()).isTrue()); | ||
reconciler.allowReconciliationToProceed(); | ||
|
||
await().pollDelay(Duration.ofMillis(WAIT_FOR_EVENT)).untilAsserted(() -> { | ||
assertThat(extension.get(NextReconciliationImminentCustomResource.class, TEST_RESOURCE_NAME) | ||
.getStatus().getUpdateNumber()).isEqualTo(1); | ||
}); | ||
} | ||
|
||
|
||
NextReconciliationImminentCustomResource testResource() { | ||
var res = new NextReconciliationImminentCustomResource(); | ||
res.setMetadata(new ObjectMetaBuilder() | ||
.withName(TEST_RESOURCE_NAME) | ||
.build()); | ||
return res; | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
.../operator/sample/nextreconciliationimminent/NextReconciliationImminentCustomResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.javaoperatorsdk.operator.sample.nextreconciliationimminent; | ||
|
||
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("nri") | ||
public class NextReconciliationImminentCustomResource | ||
extends CustomResource<Void, NextReconciliationImminentStatus> | ||
implements Namespaced { | ||
|
||
|
||
|
||
} |
58 changes: 58 additions & 0 deletions
58
...rsdk/operator/sample/nextreconciliationimminent/NextReconciliationImminentReconciler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package io.javaoperatorsdk.operator.sample.nextreconciliationimminent; | ||
|
||
import java.util.concurrent.SynchronousQueue; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
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; | ||
|
||
@ControllerConfiguration(generationAwareEventProcessing = false) | ||
public class NextReconciliationImminentReconciler | ||
implements Reconciler<NextReconciliationImminentCustomResource> { | ||
|
||
private static final Logger log = | ||
LoggerFactory.getLogger(NextReconciliationImminentReconciler.class); | ||
|
||
private final SynchronousQueue<Boolean> queue = new SynchronousQueue<>(); | ||
private volatile boolean reconciliationWaiting = false; | ||
|
||
@Override | ||
public UpdateControl<NextReconciliationImminentCustomResource> reconcile( | ||
NextReconciliationImminentCustomResource resource, | ||
Context<NextReconciliationImminentCustomResource> context) throws InterruptedException { | ||
log.info("started reconciliation"); | ||
reconciliationWaiting = true; | ||
// wait long enough to get manually allowed | ||
queue.poll(120, TimeUnit.SECONDS); | ||
log.info("Continue after wait"); | ||
reconciliationWaiting = false; | ||
|
||
if (context.isNextReconciliationImminent()) { | ||
return UpdateControl.noUpdate(); | ||
} else { | ||
if (resource.getStatus() == null) { | ||
resource.setStatus(new NextReconciliationImminentStatus()); | ||
} | ||
resource.getStatus().setUpdateNumber(resource.getStatus().getUpdateNumber() + 1); | ||
log.info("Patching status"); | ||
return UpdateControl.patchStatus(resource); | ||
} | ||
} | ||
|
||
public void allowReconciliationToProceed() { | ||
try { | ||
queue.put(true); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public boolean isReconciliationWaiting() { | ||
return reconciliationWaiting; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...ratorsdk/operator/sample/nextreconciliationimminent/NextReconciliationImminentStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.javaoperatorsdk.operator.sample.nextreconciliationimminent; | ||
|
||
public class NextReconciliationImminentStatus { | ||
|
||
private int updateNumber; | ||
|
||
public int getUpdateNumber() { | ||
return updateNumber; | ||
} | ||
|
||
public void setUpdateNumber(int updateNumber) { | ||
this.updateNumber = updateNumber; | ||
} | ||
} |