Skip to content

Commit 8e9300e

Browse files
csvirimetacosmiocaneldependabot[bot]lburgazzoli
authored
Refined Interface of EventSource and EventSourceManager (#597)
* WIP * Addressing Custom Resource by Name and Namespace refactor + Informer Cache WIP * fix: DefaultEventHandler init from EventSourceManager * fix: custom resource selector test improvement * fix: wip test imrpovements * fix: test improvements * fix: further improvements * fix: build * feature: add mvn jar to gitignore * Exposing CustomResourceEventSource and informers * fix: cleanup * fix: remove caching optimization since it not possible anymore with informer * fix: formatting * refactor: make name/namespace final * feature: Simple label selector support * fix: formatting * fix: code inspection reports * fix: merge from v2 * fix: removed most deprecated apis * chore: renaming vars named k8sClient to kubernetsClient * chore(deps): bump jandex-maven-plugin from 1.1.1 to 1.2.1 (#592) Bumps [jandex-maven-plugin](https://github.com/wildfly/jandex-maven-plugin) from 1.1.1 to 1.2.1. - [Release notes](https://github.com/wildfly/jandex-maven-plugin/releases) - [Commits](wildfly/jandex-maven-plugin@1.1.1...1.2.1) --- updated-dependencies: - dependency-name: org.jboss.jandex:jandex-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump mockito-core from 3.12.4 to 4.0.0 (#591) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.12.4 to 4.0.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](mockito/mockito@v3.12.4...v4.0.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feature: Build PR on v2 * chore(ci): use Java 17 * chore(ci): use only Temurin distribution * fix: Updated informer mapping to CustomResourceID * chore: add generics to PostExecutionControl to reduce IDEs noise (#594) * chore: polish the junit5 extension (#593) * fix: EventSourceManager API wip * fix: code review fixes * fix: improvements of Event Source related APIs * fix: remarks from code review Co-authored-by: Chris Laprun <[email protected]> Co-authored-by: Ioannis Canellos <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Luca Burgazzoli <[email protected]>
1 parent 6e01001 commit 8e9300e

File tree

10 files changed

+50
-124
lines changed

10 files changed

+50
-124
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ private RetryExecution getOrInitRetryExecution(ExecutionScope<R> executionScope)
271271
}
272272

273273
private void cleanupAfterDeletedEvent(CustomResourceID customResourceUid) {
274-
eventSourceManager.cleanup(customResourceUid);
274+
eventSourceManager.cleanupForCustomResource(customResourceUid);
275275
eventBuffer.cleanup(customResourceUid);
276276
}
277277

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

3-
import java.io.IOException;
4-
import java.util.Collections;
5-
import java.util.Map;
6-
import java.util.Objects;
7-
import java.util.Optional;
8-
import java.util.concurrent.ConcurrentHashMap;
3+
import java.util.*;
94
import java.util.concurrent.locks.ReentrantLock;
105

116
import org.slf4j.Logger;
@@ -22,119 +17,81 @@
2217
public class DefaultEventSourceManager<R extends CustomResource<?, ?>>
2318
implements EventSourceManager {
2419

25-
public static final String RETRY_TIMER_EVENT_SOURCE_NAME = "retry-timer-event-source";
26-
public static final String CUSTOM_RESOURCE_EVENT_SOURCE_NAME = "custom-resource-event-source";
2720
private static final Logger log = LoggerFactory.getLogger(DefaultEventSourceManager.class);
2821

2922
private final ReentrantLock lock = new ReentrantLock();
30-
private final Map<String, EventSource> eventSources = new ConcurrentHashMap<>();
23+
private final Set<EventSource> eventSources = Collections.synchronizedSet(new HashSet<>());
3124
private DefaultEventHandler<R> defaultEventHandler;
3225
private TimerEventSource<R> retryTimerEventSource;
26+
private CustomResourceEventSource customResourceEventSource;
3327

3428
DefaultEventSourceManager(DefaultEventHandler<R> defaultEventHandler) {
3529
init(defaultEventHandler);
3630
}
3731

3832
public DefaultEventSourceManager(ConfiguredController<R> controller) {
39-
CustomResourceEventSource customResourceEventSource =
40-
new CustomResourceEventSource<>(controller);
33+
customResourceEventSource = new CustomResourceEventSource<>(controller);
4134
init(new DefaultEventHandler<>(controller, customResourceEventSource));
42-
registerEventSource(CUSTOM_RESOURCE_EVENT_SOURCE_NAME, customResourceEventSource);
35+
registerEventSource(customResourceEventSource);
4336
}
4437

4538
private void init(DefaultEventHandler<R> defaultEventHandler) {
4639
this.defaultEventHandler = defaultEventHandler;
4740
defaultEventHandler.setEventSourceManager(this);
4841

4942
this.retryTimerEventSource = new TimerEventSource<>();
50-
registerEventSource(RETRY_TIMER_EVENT_SOURCE_NAME, retryTimerEventSource);
43+
registerEventSource(retryTimerEventSource);
5144
}
5245

5346
@Override
5447
public void close() {
48+
lock.lock();
5549
try {
56-
lock.lock();
57-
5850
try {
5951
defaultEventHandler.close();
6052
} catch (Exception e) {
6153
log.warn("Error closing event handler", e);
6254
}
63-
64-
for (var entry : eventSources.entrySet()) {
55+
log.debug("Closing event sources.");
56+
for (var eventSource : eventSources) {
6557
try {
66-
log.debug("Closing {} -> {}", entry.getKey(), entry.getValue());
67-
entry.getValue().close();
58+
eventSource.close();
6859
} catch (Exception e) {
69-
log.warn("Error closing {} -> {}", entry.getKey(), entry.getValue(), e);
60+
log.warn("Error closing {} -> {}", eventSource);
7061
}
7162
}
72-
7363
eventSources.clear();
7464
} finally {
7565
lock.unlock();
7666
}
7767
}
7868

7969
@Override
80-
public final void registerEventSource(String name, EventSource eventSource)
70+
public final void registerEventSource(EventSource eventSource)
8171
throws OperatorException {
8272
Objects.requireNonNull(eventSource, "EventSource must not be null");
83-
73+
lock.lock();
8474
try {
85-
lock.lock();
86-
if (eventSources.containsKey(name)) {
87-
throw new IllegalStateException(
88-
"Event source with name already registered. Event source name: " + name);
89-
}
90-
eventSources.put(name, eventSource);
75+
eventSources.add(eventSource);
9176
eventSource.setEventHandler(defaultEventHandler);
9277
eventSource.start();
9378
} catch (Throwable e) {
9479
if (e instanceof IllegalStateException || e instanceof MissingCRDException) {
9580
// leave untouched
9681
throw e;
9782
}
98-
throw new OperatorException("Couldn't register event source named '" + name + "'", e);
99-
} finally {
100-
lock.unlock();
101-
}
102-
}
103-
104-
@Override
105-
public Optional<EventSource> deRegisterEventSource(String name) {
106-
try {
107-
lock.lock();
108-
EventSource currentEventSource = eventSources.remove(name);
109-
if (currentEventSource != null) {
110-
try {
111-
currentEventSource.close();
112-
} catch (IOException e) {
113-
throw new RuntimeException(e);
114-
}
115-
}
116-
117-
return Optional.ofNullable(currentEventSource);
83+
throw new OperatorException(
84+
"Couldn't register event source: " + eventSource.getClass().getName(), e);
11885
} finally {
11986
lock.unlock();
12087
}
12188
}
12289

123-
@Override
124-
public Optional<EventSource> deRegisterCustomResourceFromEventSource(
125-
String eventSourceName, CustomResourceID customResourceUid) {
90+
public void cleanupForCustomResource(CustomResourceID customResourceUid) {
91+
lock.lock();
12692
try {
127-
lock.lock();
128-
EventSource eventSource = this.eventSources.get(eventSourceName);
129-
if (eventSource == null) {
130-
log.warn(
131-
"Event producer: {} not found for custom resource: {}",
132-
eventSourceName,
133-
customResourceUid);
134-
return Optional.empty();
135-
} else {
136-
eventSource.eventSourceDeRegisteredForResource(customResourceUid);
137-
return Optional.of(eventSource);
93+
for (EventSource eventSource : this.eventSources) {
94+
eventSource.cleanupForCustomResource(customResourceUid);
13895
}
13996
} finally {
14097
lock.unlock();
@@ -146,19 +103,13 @@ public TimerEventSource getRetryTimerEventSource() {
146103
}
147104

148105
@Override
149-
public Map<String, EventSource> getRegisteredEventSources() {
150-
return Collections.unmodifiableMap(eventSources);
106+
public Set<EventSource> getRegisteredEventSources() {
107+
return Collections.unmodifiableSet(eventSources);
151108
}
152109

153110
@Override
154111
public CustomResourceEventSource getCustomResourceEventSource() {
155-
return (CustomResourceEventSource) getRegisteredEventSources()
156-
.get(CUSTOM_RESOURCE_EVENT_SOURCE_NAME);
112+
return customResourceEventSource;
157113
}
158114

159-
public void cleanup(CustomResourceID customResourceUid) {
160-
getRegisteredEventSources()
161-
.keySet()
162-
.forEach(k -> deRegisterCustomResourceFromEventSource(k, customResourceUid));
163-
}
164115
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,10 @@ default void close() throws IOException {}
2020

2121
void setEventHandler(EventHandler eventHandler);
2222

23-
default void eventSourceDeRegisteredForResource(CustomResourceID customResourceUid) {}
23+
/**
24+
* Automatically called when a custom resource is deleted from the cluster.
25+
*
26+
* @param customResourceUid - id of custom resource
27+
*/
28+
default void cleanupForCustomResource(CustomResourceID customResourceUid) {}
2429
}

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

+3-18
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
import java.io.Closeable;
44
import java.io.IOException;
5-
import java.util.Map;
6-
import java.util.Optional;
5+
import java.util.Set;
76

87
import io.fabric8.kubernetes.client.CustomResource;
98
import io.javaoperatorsdk.operator.OperatorException;
@@ -14,29 +13,15 @@ public interface EventSourceManager<T extends CustomResource<?, ?>> extends Clos
1413
/**
1514
* Add the {@link EventSource} identified by the given <code>name</code> to the event manager.
1615
*
17-
* @param name the name of the {@link EventSource} to add
1816
* @param eventSource the {@link EventSource} to register
1917
* @throws IllegalStateException if an {@link EventSource} with the same name is already
2018
* registered.
2119
* @throws OperatorException if an error occurred during the registration process
2220
*/
23-
void registerEventSource(String name, EventSource eventSource)
21+
void registerEventSource(EventSource eventSource)
2422
throws IllegalStateException, OperatorException;
2523

26-
/**
27-
* Remove the {@link EventSource} identified by the given <code>name</code> from the event
28-
* manager.
29-
*
30-
* @param name the name of the {@link EventSource} to remove
31-
* @return an optional {@link EventSource} which would be empty if no {@link EventSource} have
32-
* been registered with the given name.
33-
*/
34-
Optional<EventSource> deRegisterEventSource(String name);
35-
36-
Optional<EventSource> deRegisterCustomResourceFromEventSource(
37-
String name, CustomResourceID customResourceUid);
38-
39-
Map<String, EventSource> getRegisteredEventSources();
24+
Set<EventSource> getRegisteredEventSources();
4025

4126
CustomResourceEventSource<T> getCustomResourceEventSource();
4227

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void scheduleOnce(R customResource, long delay) {
5050
}
5151

5252
@Override
53-
public void eventSourceDeRegisteredForResource(CustomResourceID customResourceUid) {
53+
public void cleanupForCustomResource(CustomResourceID customResourceUid) {
5454
cancelSchedule(customResourceUid);
5555
cancelOnceSchedule(customResourceUid);
5656
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public void cleanUpAfterDeleteEvent() {
119119

120120
waitMinimalTime();
121121
verify(defaultEventSourceManagerMock, times(1))
122-
.cleanup(CustomResourceID.fromResource(customResource));
122+
.cleanupForCustomResource(CustomResourceID.fromResource(customResource));
123123
}
124124

125125
@Test
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.javaoperatorsdk.operator.processing.event;
22

33
import java.io.IOException;
4-
import java.util.Map;
4+
import java.util.Set;
55

66
import org.junit.jupiter.api.Test;
77

@@ -10,16 +10,13 @@
1010
import io.javaoperatorsdk.operator.processing.DefaultEventHandler;
1111

1212
import static org.assertj.core.api.Assertions.assertThat;
13-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
1413
import static org.mockito.Mockito.eq;
1514
import static org.mockito.Mockito.mock;
1615
import static org.mockito.Mockito.times;
1716
import static org.mockito.Mockito.verify;
1817

1918
class DefaultEventSourceManagerTest {
2019

21-
public static final String CUSTOM_EVENT_SOURCE_NAME = "CustomEventSource";
22-
2320
private DefaultEventHandler defaultEventHandlerMock = mock(DefaultEventHandler.class);
2421
private DefaultEventSourceManager defaultEventSourceManager =
2522
new DefaultEventSourceManager(defaultEventHandlerMock);
@@ -28,12 +25,12 @@ class DefaultEventSourceManagerTest {
2825
public void registersEventSource() {
2926
EventSource eventSource = mock(EventSource.class);
3027

31-
defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME, eventSource);
28+
defaultEventSourceManager.registerEventSource(eventSource);
3229

33-
Map<String, EventSource> registeredSources =
30+
Set<EventSource> registeredSources =
3431
defaultEventSourceManager.getRegisteredEventSources();
35-
assertThat(registeredSources.entrySet()).hasSize(2);
36-
assertThat(registeredSources.get(CUSTOM_EVENT_SOURCE_NAME)).isEqualTo(eventSource);
32+
assertThat(registeredSources).hasSize(2);
33+
3734
verify(eventSource, times(1)).setEventHandler(eq(defaultEventHandlerMock));
3835
verify(eventSource, times(1)).start();
3936
}
@@ -42,37 +39,25 @@ public void registersEventSource() {
4239
public void closeShouldCascadeToEventSources() throws IOException {
4340
EventSource eventSource = mock(EventSource.class);
4441
EventSource eventSource2 = mock(EventSource.class);
45-
defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME, eventSource);
46-
defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME + "2", eventSource2);
42+
defaultEventSourceManager.registerEventSource(eventSource);
43+
defaultEventSourceManager.registerEventSource(eventSource2);
4744

4845
defaultEventSourceManager.close();
4946

5047
verify(eventSource, times(1)).close();
5148
verify(eventSource2, times(1)).close();
5249
}
5350

54-
@Test
55-
public void throwExceptionIfRegisteringEventSourceWithSameName() {
56-
EventSource eventSource = mock(EventSource.class);
57-
EventSource eventSource2 = mock(EventSource.class);
58-
59-
defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME, eventSource);
60-
assertThatExceptionOfType(IllegalStateException.class)
61-
.isThrownBy(
62-
() -> defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME,
63-
eventSource2));
64-
}
65-
6651
@Test
6752
public void deRegistersEventSources() {
6853
CustomResource customResource = TestUtils.testCustomResource();
6954
EventSource eventSource = mock(EventSource.class);
70-
defaultEventSourceManager.registerEventSource(CUSTOM_EVENT_SOURCE_NAME, eventSource);
55+
defaultEventSourceManager.registerEventSource(eventSource);
7156

72-
defaultEventSourceManager.deRegisterCustomResourceFromEventSource(
73-
CUSTOM_EVENT_SOURCE_NAME, CustomResourceID.fromResource(customResource));
57+
defaultEventSourceManager
58+
.cleanupForCustomResource(CustomResourceID.fromResource(customResource));
7459

7560
verify(eventSource, times(1))
76-
.eventSourceDeRegisteredForResource(eq(CustomResourceID.fromResource(customResource)));
61+
.cleanupForCustomResource(eq(CustomResourceID.fromResource(customResource)));
7762
}
7863
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void deRegistersPeriodicalEventSources() {
6161
untilAsserted(() -> assertThat(eventHandlerMock.events).hasSizeGreaterThan(1));
6262

6363
timerEventSource
64-
.eventSourceDeRegisteredForResource(CustomResourceID.fromResource(customResource));
64+
.cleanupForCustomResource(CustomResourceID.fromResource(customResource));
6565

6666
int size = eventHandlerMock.events.size();
6767
untilAsserted(() -> assertThat(eventHandlerMock.events).hasSize(size));
@@ -103,7 +103,7 @@ public void deRegistersOnceEventSources() {
103103

104104
timerEventSource.scheduleOnce(customResource, PERIOD);
105105
timerEventSource
106-
.eventSourceDeRegisteredForResource(CustomResourceID.fromResource(customResource));
106+
.cleanupForCustomResource(CustomResourceID.fromResource(customResource));
107107

108108
untilAsserted(() -> assertThat(eventHandlerMock.events).isEmpty());
109109
}

Diff for: operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class EventSourceTestCustomResourceController
3232

3333
@Override
3434
public void init(EventSourceManager eventSourceManager) {
35-
eventSourceManager.registerEventSource("Timer", timerEventSource);
35+
eventSourceManager.registerEventSource(timerEventSource);
3636
}
3737

3838
@Override

Diff for: operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomResourceController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class InformerEventSourceTestCustomResourceController implements
3737
public void init(EventSourceManager eventSourceManager) {
3838
eventSource = new InformerEventSource<>(kubernetesClient, ConfigMap.class,
3939
Mappers.fromAnnotation(RELATED_RESOURCE_UID));
40-
eventSourceManager.registerEventSource("configmap", eventSource);
40+
eventSourceManager.registerEventSource(eventSource);
4141
}
4242

4343
@Override

0 commit comments

Comments
 (0)