Skip to content

Commit 101db14

Browse files
metacosmadam-sandor
authored andcommitted
fix: restart event handler (#632)
Properly start event handler when starting the event source. Minor clean-ups. Fixes #630 Co-authored-by: csviri <[email protected]>
1 parent 1be67dd commit 101db14

File tree

6 files changed

+71
-3
lines changed

6 files changed

+71
-3
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static void close() {
4646
public static ExecutorServiceManager instance() {
4747
if (instance == null) {
4848
throw new IllegalStateException(
49-
"ExecutorServiceManager hasn't been started. Call start method before using!");
49+
"ExecutorServiceManager hasn't been started. Call init method before using!");
5050
}
5151
return instance;
5252
}

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,15 @@ public DefaultEventHandler(ConfiguredController<R> controller) {
6060
controller.getConfiguration().getConfigurationService().getMetrics().getEventMonitor());
6161
}
6262

63-
DefaultEventHandler(EventDispatcher<R> eventDispatcher, String relatedControllerName,
63+
public DefaultEventHandler(EventDispatcher<R> eventDispatcher, String relatedControllerName,
6464
Retry retry) {
6565
this(null, relatedControllerName, eventDispatcher, retry, null);
6666
}
6767

68+
public boolean isRunning() {
69+
return running;
70+
}
71+
6872
private DefaultEventHandler(ExecutorService executor, String relatedControllerName,
6973
EventDispatcher<R> eventDispatcher, Retry retry, EventMonitor monitor) {
7074
this.running = true;
@@ -142,6 +146,15 @@ public void handleEvent(Event event) {
142146
}
143147
}
144148

149+
public void start() {
150+
try {
151+
lock.lock();
152+
this.running = true;
153+
} finally {
154+
lock.unlock();
155+
}
156+
}
157+
145158
@Override
146159
public void close() {
147160
try {

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java

+2
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ public interface EventHandler extends Closeable {
99

1010
@Override
1111
default void close() throws IOException {}
12+
13+
default void start() {}
1214
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public CustomResourceEventSource(ConfiguredController<T> controller) {
4848

4949
@Override
5050
public void start() {
51+
eventHandler.start();
52+
5153
final var configuration = controller.getConfiguration();
5254
final var targetNamespaces = configuration.getEffectiveNamespaces();
5355
final var client = controller.getCRClient();

Diff for: operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public void setup() {
6363
// todo: remove
6464
when(defaultEventSourceManagerMock.getCache()).thenReturn(customResourceCache);
6565
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResource(any());
66-
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResource(any());
6766
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResources(any());
6867
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResourceUids(any());
6968
doCallRealMethod().when(defaultEventSourceManagerMock).cacheResource(any(), any());

Diff for: operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java

+52
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
package io.javaoperatorsdk.operator.processing.event.internal;
22

3+
import java.io.IOException;
34
import java.time.LocalDateTime;
45
import java.util.List;
56

67
import org.junit.jupiter.api.BeforeEach;
78
import org.junit.jupiter.api.Test;
89

910
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
11+
import io.fabric8.kubernetes.api.model.ListOptions;
12+
import io.fabric8.kubernetes.client.Watch;
1013
import io.fabric8.kubernetes.client.Watcher;
14+
import io.fabric8.kubernetes.client.dsl.FilterWatchListMultiDeletable;
1115
import io.fabric8.kubernetes.client.dsl.MixedOperation;
1216
import io.fabric8.kubernetes.client.dsl.Resource;
1317
import io.javaoperatorsdk.operator.Metrics;
1418
import io.javaoperatorsdk.operator.TestUtils;
1519
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1620
import io.javaoperatorsdk.operator.api.config.DefaultControllerConfiguration;
1721
import io.javaoperatorsdk.operator.processing.ConfiguredController;
22+
import io.javaoperatorsdk.operator.processing.CustomResourceCache;
23+
import io.javaoperatorsdk.operator.processing.DefaultEventHandler;
24+
import io.javaoperatorsdk.operator.processing.EventDispatcher;
25+
import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager;
1826
import io.javaoperatorsdk.operator.processing.event.EventHandler;
1927
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
2028

29+
import static org.junit.jupiter.api.Assertions.assertFalse;
30+
import static org.junit.jupiter.api.Assertions.assertTrue;
2131
import static org.mockito.Mockito.any;
32+
import static org.mockito.Mockito.doCallRealMethod;
2233
import static org.mockito.Mockito.mock;
34+
import static org.mockito.Mockito.timeout;
2335
import static org.mockito.Mockito.times;
2436
import static org.mockito.Mockito.verify;
2537
import static org.mockito.Mockito.when;
@@ -102,6 +114,46 @@ public void eventNotMarkedForLastGenerationIfNoFinalizer() {
102114
verify(eventHandler, times(2)).handleEvent(any());
103115
}
104116

117+
@Test
118+
public void restartingShouldResumeEventHandling() throws IOException {
119+
final var cr = TestUtils.testCustomResource();
120+
121+
CustomResourceCache customResourceCache = new CustomResourceCache();
122+
customResourceCache.cacheResource(cr);
123+
DefaultEventSourceManager defaultEventSourceManagerMock =
124+
mock(DefaultEventSourceManager.class);
125+
EventDispatcher eventDispatcherMock = mock(EventDispatcher.class);
126+
DefaultEventHandler local = new DefaultEventHandler(eventDispatcherMock, "Test",
127+
null);
128+
local.setEventSourceManager(defaultEventSourceManagerMock);
129+
when(defaultEventSourceManagerMock.getCache()).thenReturn(customResourceCache);
130+
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResource(any());
131+
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResources(any());
132+
doCallRealMethod().when(defaultEventSourceManagerMock).getLatestResourceUids(any());
133+
doCallRealMethod().when(defaultEventSourceManagerMock).cacheResource(any(), any());
134+
135+
final var mock = mock(FilterWatchListMultiDeletable.class);
136+
when(mock.watch((ListOptions) any(), any())).thenReturn(mock(Watch.class));
137+
when(client.inAnyNamespace()).thenReturn(mock);
138+
139+
customResourceEventSource.setEventHandler(local);
140+
141+
customResourceEventSource.eventReceived(Watcher.Action.MODIFIED, cr);
142+
verify(eventDispatcherMock, timeout(50).times(1)).handleExecution(any());
143+
144+
customResourceEventSource.close();
145+
assertFalse(local.isRunning());
146+
customResourceEventSource.eventReceived(Watcher.Action.MODIFIED, cr);
147+
// mockito times method is not reset and keeps increasing so here we stay at 1 call
148+
verify(eventDispatcherMock, timeout(50).times(1)).handleExecution(any());
149+
150+
customResourceEventSource.start();
151+
assertTrue(local.isRunning());
152+
customResourceEventSource.eventReceived(Watcher.Action.MODIFIED, cr);
153+
// we're expecting another call to the dispatcher, so total number of calls should now be 2
154+
verify(eventDispatcherMock, timeout(50).times(2)).handleExecution(any());
155+
}
156+
105157
private static class TestConfiguredController extends ConfiguredController<TestCustomResource> {
106158

107159
public TestConfiguredController(boolean generationAware) {

0 commit comments

Comments
 (0)