1
1
package io .javaoperatorsdk .operator .processing .event ;
2
2
3
- import java .util .*;
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 ;
4
8
import java .util .concurrent .ConcurrentNavigableMap ;
5
9
import java .util .concurrent .ConcurrentSkipListMap ;
6
10
import java .util .stream .Collectors ;
@@ -20,15 +24,14 @@ class EventSources<R extends HasMetadata> {
20
24
public static final String RETRY_RESCHEDULE_TIMER_EVENT_SOURCE_NAME =
21
25
"RetryAndRescheduleTimerEventSource" ;
22
26
23
- private final ConcurrentNavigableMap <String , Map <String , EventSource >> sources =
27
+ private final ConcurrentNavigableMap <String , Map <String , NamedEventSource >> sources =
24
28
new ConcurrentSkipListMap <>();
25
29
private final TimerEventSource <R > retryAndRescheduleTimerEventSource = new TimerEventSource <>();
26
30
private ControllerResourceEventSource <R > controllerResourceEventSource ;
27
31
28
32
29
- ControllerResourceEventSource < R > initControllerEventSource (Controller <R > controller ) {
33
+ void initControllerEventSource (Controller <R > controller ) {
30
34
controllerResourceEventSource = new ControllerResourceEventSource <>(controller );
31
- return controllerResourceEventSource ;
32
35
}
33
36
34
37
ControllerResourceEventSource <R > controllerResourceEventSource () {
@@ -49,7 +52,7 @@ public Stream<NamedEventSource> additionalNamedEventSources() {
49
52
Stream <EventSource > additionalEventSources () {
50
53
return Stream .concat (
51
54
Stream .of (retryEventSource ()).filter (Objects ::nonNull ),
52
- sources . values ().stream (). flatMap ( c -> c . values (). stream () ));
55
+ flatMappedSources ().map ( NamedEventSource :: original ));
53
56
}
54
57
55
58
NamedEventSource namedControllerResourceEventSource () {
@@ -58,29 +61,32 @@ NamedEventSource namedControllerResourceEventSource() {
58
61
}
59
62
60
63
Stream <NamedEventSource > flatMappedSources () {
61
- return sources .values ().stream ().flatMap (c -> c .entrySet ().stream ()
62
- .map (esEntry -> new NamedEventSource (esEntry .getValue (), esEntry .getKey ())));
64
+ return sources .values ().stream ().flatMap (c -> c .values ().stream ());
63
65
}
64
66
65
67
public void clear () {
66
68
sources .clear ();
67
69
}
68
70
69
- public boolean contains (String name , EventSource source ) {
71
+ private NamedEventSource existing (String name , EventSource source ) {
70
72
final var eventSources = sources .get (keyFor (source ));
71
73
if (eventSources == null || eventSources .isEmpty ()) {
72
- return false ;
74
+ return null ;
73
75
}
74
- return eventSources .containsKey (name );
76
+ return eventSources .get (name );
75
77
}
76
78
77
- public void add (String name , EventSource eventSource ) {
78
- if (contains (name , eventSource )) {
79
- throw new IllegalArgumentException ("An event source is already registered for the "
80
- + keyAsString (getResourceType (eventSource ), name )
79
+ public void add (NamedEventSource eventSource ) {
80
+ final var name = eventSource .name ();
81
+ final var original = eventSource .original ();
82
+ final var existing = existing (name , original );
83
+ if (existing != null && !eventSource .equals (existing )) {
84
+ throw new IllegalArgumentException ("Event source " + existing .original ()
85
+ + " is already registered for the "
86
+ + keyAsString (getResourceType (original ), name )
81
87
+ " class/name combination" );
82
88
}
83
- sources .computeIfAbsent (keyFor (eventSource ), k -> new HashMap <>()).put (name , eventSource );
89
+ sources .computeIfAbsent (keyFor (original ), k -> new HashMap <>()).put (name , eventSource );
84
90
}
85
91
86
92
@ SuppressWarnings ("rawtypes" )
@@ -91,6 +97,10 @@ private Class<?> getResourceType(EventSource source) {
91
97
}
92
98
93
99
private String keyFor (EventSource source ) {
100
+ if (source instanceof NamedEventSource ) {
101
+ source = ((NamedEventSource ) source ).original ();
102
+ }
103
+
94
104
return keyFor (getResourceType (source ));
95
105
}
96
106
@@ -100,16 +110,20 @@ private String keyFor(Class<?> dependentType) {
100
110
101
111
@ SuppressWarnings ("unchecked" )
102
112
public <S > ResourceEventSource <S , R > get (Class <S > dependentType , String name ) {
113
+ if (dependentType == null ) {
114
+ throw new IllegalArgumentException ("Must pass a dependent type to retrieve event sources" );
115
+ }
116
+
103
117
final var sourcesForType = sources .get (keyFor (dependentType ));
104
118
if (sourcesForType == null || sourcesForType .isEmpty ()) {
105
119
throw new IllegalArgumentException (
106
120
"There is no event source found for class:" + dependentType .getName ());
107
121
}
108
122
109
123
final var size = sourcesForType .size ();
110
- final EventSource source ;
124
+ NamedEventSource source ;
111
125
if (size == 1 && name == null ) {
112
- source = sourcesForType .values ().stream ().findFirst ().orElse ( null );
126
+ source = sourcesForType .values ().stream ().findFirst ().orElseThrow ( );
113
127
} else {
114
128
if (name == null || name .isBlank ()) {
115
129
throw new IllegalArgumentException ("There are multiple EventSources registered for type "
@@ -125,15 +139,16 @@ public <S> ResourceEventSource<S, R> get(Class<S> dependentType, String name) {
125
139
}
126
140
}
127
141
128
- if (!(source instanceof ResourceEventSource )) {
142
+ EventSource original = source .original ();
143
+ if (!(original instanceof ResourceEventSource )) {
129
144
throw new IllegalArgumentException (source + " associated with "
130
145
+ keyAsString (dependentType , name ) + " is not a "
131
146
+ ResourceEventSource .class .getSimpleName ());
132
147
}
133
- final var res = (ResourceEventSource <S , R >) source ;
148
+ final var res = (ResourceEventSource <S , R >) original ;
134
149
final var resourceClass = res .resourceType ();
135
150
if (!resourceClass .isAssignableFrom (dependentType )) {
136
- throw new IllegalArgumentException (source + " associated with "
151
+ throw new IllegalArgumentException (original + " associated with "
137
152
+ keyAsString (dependentType , name )
138
153
+ " is handling " + resourceClass .getName () + " resources but asked for "
139
154
+ dependentType .getName ());
@@ -151,7 +166,12 @@ private String keyAsString(Class dependentType, String name) {
151
166
@ SuppressWarnings ("unchecked" )
152
167
public <S > List <ResourceEventSource <S , R >> getEventSources (Class <S > dependentType ) {
153
168
final var sourcesForType = sources .get (keyFor (dependentType ));
169
+ if (sourcesForType == null ) {
170
+ return Collections .emptyList ();
171
+ }
172
+
154
173
return sourcesForType .values ().stream ()
174
+ .map (NamedEventSource ::original )
155
175
.filter (ResourceEventSource .class ::isInstance )
156
176
.map (es -> (ResourceEventSource <S , R >) es )
157
177
.collect (Collectors .toList ());
0 commit comments