Skip to content

Commit 012ad6d

Browse files
committed
improvements on imple, fixes, unit tests
Signed-off-by: Attila Mészáros <csviri@gmail.com>
1 parent 4879c5c commit 012ad6d

File tree

6 files changed

+82
-29
lines changed

6 files changed

+82
-29
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public <R> List<ResourceEventSource<R, P>> getResourceEventSourcesFor(Class<R> d
210210
@Override
211211
public EventSource dynamicallyRegisterEventSource(EventSource eventSource) {
212212
synchronized (this) {
213-
var actual = eventSources.existing(eventSource);
213+
var actual = eventSources.existingEventSourceOfSameNameAndType(eventSource);
214214
if (actual != null) {
215215
eventSource = actual;
216216
} else {

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java

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

3-
import java.util.Collections;
4-
import java.util.HashMap;
5-
import java.util.List;
6-
import java.util.Map;
7-
import java.util.Objects;
3+
import java.util.*;
84
import java.util.concurrent.ConcurrentNavigableMap;
95
import java.util.concurrent.ConcurrentSkipListMap;
106
import java.util.stream.Collectors;
@@ -19,9 +15,6 @@
1915

2016
class EventSources<R extends HasMetadata> {
2117

22-
public static final String RETRY_RESCHEDULE_TIMER_EVENT_SOURCE_NAME =
23-
"RetryAndRescheduleTimerEventSource";
24-
2518
private final ConcurrentNavigableMap<String, Map<String, EventSource>> sources =
2619
new ConcurrentSkipListMap<>();
2720
private final TimerEventSource<R> retryAndRescheduleTimerEventSource = new TimerEventSource<>();
@@ -60,26 +53,42 @@ public void clear() {
6053
sources.clear();
6154
}
6255

63-
public EventSource existing(EventSource source) {
56+
public EventSource existingEventSourceOfSameNameAndType(EventSource source) {
6457
final var eventSources = sources.get(keyFor(source));
65-
if (eventSources == null || eventSources.isEmpty()) {
58+
if (eventSources == null) {
6659
return null;
6760
}
6861
return eventSources.get(source.name());
6962
}
7063

64+
65+
public Map<String, EventSource> existingEventSourceOfSameType(EventSource source) {
66+
final var eventSources = sources.get(keyFor(source));
67+
if (eventSources == null) {
68+
return Collections.emptyMap();
69+
}
70+
return eventSources;
71+
}
72+
7173
public void add(EventSource eventSource) {
7274
final var name = eventSource.name();
73-
final var existing = existing(eventSource);
74-
if (existing != null && !eventSource.scopeEquals(existing)) {
75+
final var existing = existingEventSourceOfSameType(eventSource);
76+
if (existing.get(name) != null) {
77+
throw new IllegalArgumentException("Event source " + existing
78+
+ " is already registered with name: " + name);
79+
}
80+
if (existing.values().stream().anyMatch(eventSource::scopeEquals)) {
7581
throw new IllegalArgumentException("Event source " + existing
7682
+ " is already registered for the "
7783
+ keyAsString(getResourceType(eventSource), name)
78-
+ " class/name combination");
84+
+ " with same scope");
7985
}
80-
sources.computeIfAbsent(keyFor(existing), k -> new HashMap<>()).put(name, eventSource);
86+
87+
sources.computeIfAbsent(keyFor(eventSource), k -> new HashMap<>()).put(name, eventSource);
8188
}
8289

90+
91+
8392
@SuppressWarnings("rawtypes")
8493
private Class<?> getResourceType(EventSource source) {
8594
return source instanceof ResourceEventSource

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/AbstractEventSource.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.javaoperatorsdk.operator.processing.event.source;
22

3+
34
import io.javaoperatorsdk.operator.OperatorException;
45
import io.javaoperatorsdk.operator.processing.event.EventHandler;
56

@@ -41,4 +42,5 @@ public AbstractEventSource setEventSourcePriority(
4142
this.eventSourceStartPriority = eventSourceStartPriority;
4243
return this;
4344
}
45+
4446
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ default String name() {
3333
return getClass().getSimpleName();
3434
}
3535

36-
// todo maybe different special method name?
36+
/**
37+
* todo do not implement here? Check if targets the same resources as the current event source.
38+
*/
3739
default boolean scopeEquals(EventSource es) {
3840
return this == es;
3941
}
4042

43+
4144
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void retrievingEventSourceForClassShouldWork() {
9292
}
9393

9494
@Test
95-
void shouldNotBePossibleToAddEventSourcesForSameTypeAndName() {
95+
void notPossibleAddEventSourcesForSameName() {
9696
EventSourceManager manager = initManager();
9797
final var name = "name1";
9898

@@ -103,25 +103,48 @@ void shouldNotBePossibleToAddEventSourcesForSameTypeAndName() {
103103

104104
eventSource = mock(ManagedInformerEventSource.class);
105105
when(eventSource.resourceType()).thenReturn(TestCustomResource.class);
106+
when(eventSource.name()).thenReturn(name);
106107
final var source = eventSource;
107108

108109
final var exception = assertThrows(OperatorException.class,
109110
() -> manager.registerEventSource(source));
110111
final var cause = exception.getCause();
111112
assertInstanceOf(IllegalArgumentException.class, cause);
112-
assertThat(cause.getMessage()).contains(
113-
"is already registered for the (io.javaoperatorsdk.operator.sample.simple.TestCustomResource, "
114-
+ name + ") class/name combination");
113+
assertThat(cause.getMessage()).contains("is already registered with name");
115114
}
116115

117116
@Test
118-
void retrievingAnEventSourceWhenMultipleAreRegisteredForATypeShouldRequireAQualifier() {
117+
void notPossibleToAddEventSourceWithSameScopeButDifferentName() {
119118
EventSourceManager manager = initManager();
119+
final var name = "name1";
120120

121121
ManagedInformerEventSource eventSource = mock(ManagedInformerEventSource.class);
122+
when(eventSource.name()).thenReturn("name1");
122123
when(eventSource.resourceType()).thenReturn(TestCustomResource.class);
123124
manager.registerEventSource(eventSource);
125+
126+
eventSource = mock(ManagedInformerEventSource.class);
127+
when(eventSource.resourceType()).thenReturn(TestCustomResource.class);
128+
when(eventSource.name()).thenReturn("name2");
129+
when(eventSource.scopeEquals(any())).thenReturn(true);
130+
final var source = eventSource;
131+
132+
final var exception = assertThrows(OperatorException.class,
133+
() -> manager.registerEventSource(source));
134+
final var cause = exception.getCause();
135+
assertInstanceOf(IllegalArgumentException.class, cause);
136+
assertThat(cause.getMessage()).contains("with same scope");
137+
}
138+
139+
@Test
140+
void retrievingAnEventSourceWhenMultipleAreRegisteredForATypeShouldRequireAQualifier() {
141+
EventSourceManager manager = initManager();
142+
143+
ManagedInformerEventSource eventSource = mock(ManagedInformerEventSource.class);
144+
when(eventSource.resourceType()).thenReturn(TestCustomResource.class);
124145
when(eventSource.name()).thenReturn("name1");
146+
manager.registerEventSource(eventSource);
147+
125148

126149
ManagedInformerEventSource eventSource2 = mock(ManagedInformerEventSource.class);
127150
when(eventSource2.name()).thenReturn("name2");

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourcesTest.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import static org.junit.jupiter.api.Assertions.assertEquals;
1818
import static org.junit.jupiter.api.Assertions.assertNotNull;
1919
import static org.junit.jupiter.api.Assertions.assertThrows;
20+
import static org.mockito.ArgumentMatchers.any;
2021
import static org.mockito.Mockito.mock;
2122
import static org.mockito.Mockito.when;
2223

@@ -33,25 +34,39 @@ void cannotAddTwoDifferentEventSourcesWithSameName() {
3334
var es2 = mock(EventSource.class);
3435
when(es2.name()).thenReturn(EVENT_SOURCE_NAME);
3536

37+
eventSources.add(es1);
3638
assertThrows(IllegalArgumentException.class, () -> {
37-
eventSources.add(es1);
3839
eventSources.add(es2);
3940
});
4041
}
4142

4243
@Test
43-
void cannotAddTwoEventSourcesWithSameNameUnlessTheyAreEqual() {
44+
void cannotAddTwoEventSourcesWithSame() {
4445
final var eventSources = new EventSources();
4546
final var source = mock(EventSource.class);
4647
when(source.name()).thenReturn("name");
48+
when(source.scopeEquals(any())).thenCallRealMethod();
4749

4850
eventSources.add(source);
49-
eventSources.add(source);
50-
51-
assertThat(eventSources.flatMappedSources())
52-
.containsExactly(source);
51+
assertThrows(IllegalArgumentException.class, () -> eventSources.add(source));
5352
}
5453

54+
@Test
55+
void cannotAddEventSourceWithDifferentNameSameScope() {
56+
final var es1 = mock(EventSource.class);
57+
when(es1.name()).thenReturn("name1");
58+
59+
final var es2 = mock(EventSource.class);
60+
when(es2.name()).thenReturn("name2");
61+
when(es2.scopeEquals(any())).thenReturn(true);
62+
63+
final var eventSources = new EventSources();
64+
eventSources.add(es1);
65+
66+
assertThrows(IllegalArgumentException.class, () -> {
67+
eventSources.add(es2);
68+
});
69+
}
5570

5671
@Test
5772
void eventSourcesStreamShouldNotReturnControllerEventSource() {
@@ -133,15 +148,16 @@ void getShouldWork() {
133148
eventSourceMockWithName(ResourceEventSource.class, "name1", HasMetadata.class);
134149
final var mock2 =
135150
eventSourceMockWithName(ResourceEventSource.class, "name2", HasMetadata.class);
151+
when(mock2.scopeEquals(any())).thenCallRealMethod();
136152
final var mock3 = eventSourceMockWithName(ResourceEventSource.class, "name2", ConfigMap.class);
137153

138154
eventSources.add(mock1);
139-
140-
eventSources.add(mock2);
141155
eventSources.add(mock2);
156+
eventSources.add(mock3);
142157

143158
assertEquals(mock1, eventSources.get(HasMetadata.class, "name1"));
144159
assertEquals(mock2, eventSources.get(HasMetadata.class, "name2"));
160+
// todo this should not work?! according new rules
145161
assertEquals(mock3, eventSources.get(ConfigMap.class, "name2"));
146162
assertEquals(mock3, eventSources.get(ConfigMap.class, null));
147163

0 commit comments

Comments
 (0)