Skip to content

Commit 7d36549

Browse files
committed
feat(open-multi-domain-api): Allow use any domain as source or destination
1 parent 5ef0ad1 commit 7d36549

File tree

15 files changed

+297
-275
lines changed

15 files changed

+297
-275
lines changed

async/async-commons-api/src/main/java/org/reactivecommons/async/api/HandlerRegistry.java

Lines changed: 86 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,29 @@
1111
import org.reactivecommons.async.api.handlers.DomainEventHandler;
1212
import org.reactivecommons.async.api.handlers.QueryHandler;
1313
import org.reactivecommons.async.api.handlers.QueryHandlerDelegate;
14+
import org.reactivecommons.async.api.handlers.RawCommandHandler;
1415
import org.reactivecommons.async.api.handlers.RawEventHandler;
1516
import org.reactivecommons.async.api.handlers.registered.RegisteredCommandHandler;
17+
import org.reactivecommons.async.api.handlers.registered.RegisteredDomainHandlers;
1618
import org.reactivecommons.async.api.handlers.registered.RegisteredEventListener;
1719
import org.reactivecommons.async.api.handlers.registered.RegisteredQueryHandler;
1820

1921
import java.lang.reflect.ParameterizedType;
20-
import java.util.List;
21-
import java.util.Map;
22-
import java.util.concurrent.ConcurrentHashMap;
2322
import java.util.concurrent.CopyOnWriteArrayList;
2423

2524
@Getter
2625
@NoArgsConstructor(access = AccessLevel.PACKAGE)
2726
public final class HandlerRegistry {
2827
public static final String DEFAULT_DOMAIN = "app";
29-
private final Map<String, List<RegisteredEventListener<?, ?>>> domainEventListeners = new ConcurrentHashMap<>();
30-
private final List<RegisteredEventListener<?, ?>> dynamicEventHandlers = new CopyOnWriteArrayList<>();
31-
private final List<RegisteredEventListener<?, ?>> eventNotificationListener = new CopyOnWriteArrayList<>();
32-
private final List<RegisteredQueryHandler<?, ?>> handlers = new CopyOnWriteArrayList<>();
33-
private final List<RegisteredCommandHandler<?, ?>> commandHandlers = new CopyOnWriteArrayList<>();
28+
private final RegisteredDomainHandlers<RegisteredEventListener<?, ?>> domainEventListeners =
29+
new RegisteredDomainHandlers<>();
30+
private final RegisteredDomainHandlers<RegisteredEventListener<?, ?>> dynamicEventHandlers =
31+
new RegisteredDomainHandlers<>();
32+
private final RegisteredDomainHandlers<RegisteredEventListener<?, ?>> eventNotificationListener =
33+
new RegisteredDomainHandlers<>();
34+
private final RegisteredDomainHandlers<RegisteredQueryHandler<?, ?>> handlers = new RegisteredDomainHandlers<>();
35+
private final RegisteredDomainHandlers<RegisteredCommandHandler<?, ?>> commandHandlers =
36+
new RegisteredDomainHandlers<>();
3437

3538

3639
public static HandlerRegistry register() {
@@ -39,90 +42,136 @@ public static HandlerRegistry register() {
3942
return instance;
4043
}
4144

45+
//events: DomainEvent
46+
public <T> HandlerRegistry listenEvent(String eventName, DomainEventHandler<T> handler, Class<T> eventClass) {
47+
return listenDomainEvent(DEFAULT_DOMAIN, eventName, handler, eventClass);
48+
}
49+
4250
public <T> HandlerRegistry listenDomainEvent(String domain, String eventName, DomainEventHandler<T> handler,
4351
Class<T> eventClass) {
44-
domainEventListeners.computeIfAbsent(domain, ignored -> new CopyOnWriteArrayList<>())
45-
.add(new RegisteredEventListener<>(eventName, handler, eventClass));
52+
domainEventListeners.add(domain, new RegisteredEventListener<>(eventName, handler, eventClass));
4653
return this;
4754
}
4855

49-
public HandlerRegistry listenDomainCloudEvent(String domain, String eventName, CloudEventHandler handler) {
50-
domainEventListeners.computeIfAbsent(domain, ignored -> new CopyOnWriteArrayList<>())
51-
.add(new RegisteredEventListener<>(eventName, handler, CloudEvent.class));
52-
return this;
56+
// events: CloudEvent
57+
public HandlerRegistry listenCloudEvent(String eventName, CloudEventHandler handler) {
58+
return listenDomainCloudEvent(DEFAULT_DOMAIN, eventName, handler);
5359
}
5460

55-
public HandlerRegistry listenDomainRawEvent(String domain, String eventName, RawEventHandler<?> handler) {
56-
domainEventListeners.computeIfAbsent(domain, ignored -> new CopyOnWriteArrayList<>())
57-
.add(new RegisteredEventListener<>(eventName, handler, RawMessage.class));
61+
public HandlerRegistry listenDomainCloudEvent(String domain, String eventName, CloudEventHandler handler) {
62+
domainEventListeners.add(domain, new RegisteredEventListener<>(eventName, handler, CloudEvent.class));
5863
return this;
5964
}
6065

61-
public <T> HandlerRegistry listenEvent(String eventName, DomainEventHandler<T> handler, Class<T> eventClass) {
62-
domainEventListeners.computeIfAbsent(DEFAULT_DOMAIN, ignored -> new CopyOnWriteArrayList<>())
63-
.add(new RegisteredEventListener<>(eventName, handler, eventClass));
64-
return this;
66+
// events: RawMessage
67+
public HandlerRegistry listenRawEvent(String eventName, RawEventHandler<?> handler) {
68+
return listenDomainRawEvent(DEFAULT_DOMAIN, eventName, handler);
6569
}
6670

67-
public HandlerRegistry listenCloudEvent(String eventName, CloudEventHandler handler) {
68-
domainEventListeners.computeIfAbsent(DEFAULT_DOMAIN, ignored -> new CopyOnWriteArrayList<>())
69-
.add(new RegisteredEventListener<>(eventName, handler, CloudEvent.class));
71+
public HandlerRegistry listenDomainRawEvent(String domain, String eventName, RawEventHandler<?> handler) {
72+
domainEventListeners.add(domain, new RegisteredEventListener<>(eventName, handler, RawMessage.class));
7073
return this;
7174
}
7275

76+
// notifications: DomainEvent
7377
public <T> HandlerRegistry listenNotificationEvent(String eventName, DomainEventHandler<T> handler,
7478
Class<T> eventClass) {
75-
eventNotificationListener.add(new RegisteredEventListener<>(eventName, handler, eventClass));
79+
return listenNotificationEvent(DEFAULT_DOMAIN, eventName, handler, eventClass);
80+
}
81+
82+
public <T> HandlerRegistry listenNotificationEvent(String domain, String eventName, DomainEventHandler<T> handler,
83+
Class<T> eventClass) {
84+
eventNotificationListener.add(domain, new RegisteredEventListener<>(eventName, handler, eventClass));
7685
return this;
7786
}
7887

88+
// notifications: CloudEvent
7989
public HandlerRegistry listenNotificationCloudEvent(String eventName, CloudEventHandler handler) {
80-
eventNotificationListener.add(new RegisteredEventListener<>(eventName, handler, CloudEvent.class));
90+
return listenNotificationCloudEvent(DEFAULT_DOMAIN, eventName, handler);
91+
}
92+
93+
public HandlerRegistry listenNotificationCloudEvent(String domain, String eventName, CloudEventHandler handler) {
94+
eventNotificationListener.add(domain, new RegisteredEventListener<>(eventName, handler, CloudEvent.class));
95+
return this;
96+
}
97+
98+
// notifications: RawMessage
99+
public HandlerRegistry listenNotificationRawEvent(String eventName, RawEventHandler<?> handler) {
100+
return listenDomainRawEvent(DEFAULT_DOMAIN, eventName, handler);
101+
}
102+
103+
public HandlerRegistry listenNotificationRawEvent(String domain, String eventName, RawEventHandler<?> handler) {
104+
eventNotificationListener.add(domain, new RegisteredEventListener<>(eventName, handler, RawMessage.class));
81105
return this;
82106
}
83107

108+
// dynamic: DomainEvent supported only for default domain
84109
public <T> HandlerRegistry handleDynamicEvents(String eventNamePattern, DomainEventHandler<T> handler,
85110
Class<T> eventClass) {
86-
dynamicEventHandlers.add(new RegisteredEventListener<>(eventNamePattern, handler, eventClass));
111+
dynamicEventHandlers.add(DEFAULT_DOMAIN, new RegisteredEventListener<>(eventNamePattern, handler, eventClass));
87112
return this;
88113
}
89114

115+
// dynamic: CloudEvent supported only for default domain
90116
public HandlerRegistry handleDynamicCloudEvents(String eventNamePattern, CloudEventHandler handler) {
91-
dynamicEventHandlers.add(new RegisteredEventListener<>(eventNamePattern, handler, CloudEvent.class));
117+
dynamicEventHandlers.add(DEFAULT_DOMAIN, new RegisteredEventListener<>(eventNamePattern, handler,
118+
CloudEvent.class));
92119
return this;
93120
}
94121

122+
// commands: Command
95123
public <T> HandlerRegistry handleCommand(String commandName, DomainCommandHandler<T> fn, Class<T> commandClass) {
96-
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, commandClass));
124+
return handleCommand(DEFAULT_DOMAIN, commandName, fn, commandClass);
125+
}
126+
127+
public <T> HandlerRegistry handleCommand(String domain, String commandName, DomainCommandHandler<T> fn,
128+
Class<T> commandClass) {
129+
commandHandlers.add(domain, new RegisteredCommandHandler<>(commandName, fn, commandClass));
97130
return this;
98131
}
99132

133+
// commands: CloudEvent
100134
public HandlerRegistry handleCloudEventCommand(String commandName, CloudCommandHandler handler) {
101-
commandHandlers.add(new RegisteredCommandHandler<>(commandName, handler, CloudEvent.class));
135+
return handleCloudEventCommand(DEFAULT_DOMAIN, commandName, handler);
136+
}
137+
138+
public HandlerRegistry handleCloudEventCommand(String domain, String commandName, CloudCommandHandler handler) {
139+
commandHandlers.add(domain, new RegisteredCommandHandler<>(commandName, handler, CloudEvent.class));
140+
return this;
141+
}
142+
143+
// commands: RawMessage
144+
public HandlerRegistry handleRawCommand(String commandName, RawCommandHandler<?> handler) {
145+
return handleRawCommand(DEFAULT_DOMAIN, commandName, handler);
146+
}
147+
148+
public HandlerRegistry handleRawCommand(String domain, String commandName, RawCommandHandler<?> handler) {
149+
commandHandlers.add(domain, new RegisteredCommandHandler<>(commandName, handler, RawMessage.class));
102150
return this;
103151
}
104152

153+
// queries: Query
105154
public <T, R> HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler, Class<R> queryClass) {
106-
handlers.add(new RegisteredQueryHandler<>(resource, (ignored, message) ->
155+
handlers.add(DEFAULT_DOMAIN, new RegisteredQueryHandler<>(resource, (ignored, message) ->
107156
handler.handle(message), queryClass
108157
));
109158
return this;
110159
}
111160

112161
public <R> HandlerRegistry serveQuery(String resource, QueryHandlerDelegate<Void, R> handler, Class<R> queryClass) {
113-
handlers.add(new RegisteredQueryHandler<>(resource, handler, queryClass));
162+
handlers.add(DEFAULT_DOMAIN, new RegisteredQueryHandler<>(resource, handler, queryClass));
114163
return this;
115164
}
116165

117166
public <R> HandlerRegistry serveCloudEventQuery(String resource, QueryHandler<R, CloudEvent> handler) {
118-
handlers.add(new RegisteredQueryHandler<>(resource, (ignored, message) ->
167+
handlers.add(DEFAULT_DOMAIN, new RegisteredQueryHandler<>(resource, (ignored, message) ->
119168
handler.handle(message), CloudEvent.class
120169
));
121170
return this;
122171
}
123172

124-
public <R> HandlerRegistry serveCloudEventQuery(String resource, QueryHandlerDelegate<Void, CloudEvent> handler) {
125-
handlers.add(new RegisteredQueryHandler<>(resource, handler, CloudEvent.class));
173+
public HandlerRegistry serveCloudEventQuery(String resource, QueryHandlerDelegate<Void, CloudEvent> handler) {
174+
handlers.add(DEFAULT_DOMAIN, new RegisteredQueryHandler<>(resource, handler, CloudEvent.class));
126175
return this;
127176
}
128177

@@ -139,7 +188,8 @@ public <T> HandlerRegistry handleDynamicEvents(String eventNamePattern, DomainEv
139188

140189
@Deprecated(forRemoval = true)
141190
public <T> HandlerRegistry handleCommand(String commandName, DomainCommandHandler<T> handler) {
142-
commandHandlers.add(new RegisteredCommandHandler<>(commandName, handler, inferGenericParameterType(handler)));
191+
commandHandlers.add(DEFAULT_DOMAIN, new RegisteredCommandHandler<>(commandName, handler,
192+
inferGenericParameterType(handler)));
143193
return this;
144194
}
145195

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.reactivecommons.async.api.handlers;
2+
3+
import org.reactivecommons.api.domain.RawMessage;
4+
5+
public interface RawCommandHandler<T extends RawMessage> extends CommandHandler<T> {
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.reactivecommons.async.api.handlers.registered;
2+
3+
import java.util.List;
4+
import java.util.concurrent.ConcurrentHashMap;
5+
import java.util.concurrent.CopyOnWriteArrayList;
6+
7+
public class RegisteredDomainHandlers<T> extends ConcurrentHashMap<String, List<T>> {
8+
private static final String DEFAULT_DOMAIN = "app";
9+
10+
public RegisteredDomainHandlers() {
11+
super();
12+
put(DEFAULT_DOMAIN, new CopyOnWriteArrayList<>());
13+
}
14+
15+
public void add(String domain, T handler) {
16+
computeIfAbsent(domain, ignored -> new CopyOnWriteArrayList<>()).add(handler);
17+
}
18+
}

async/async-commons-api/src/test/java/org/reactivecommons/async/api/HandlerRegistryTest.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,14 @@ void shouldRegisterPatternEventHandler() {
120120
@Test
121121
void shouldRegisterNotificationEventListener() {
122122
registry.listenNotificationEvent(name, message -> Mono.empty(), SomeDataClass.class);
123-
assertThat(registry.getEventNotificationListener())
123+
assertThat(registry.getEventNotificationListener().get(DEFAULT_DOMAIN))
124124
.anySatisfy(listener -> assertThat(listener.getPath()).isEqualTo(name));
125125
}
126126

127127
@Test
128128
void shouldRegisterNotificationCloudEventListener() {
129129
registry.listenNotificationCloudEvent(name, message -> Mono.empty());
130-
assertThat(registry.getEventNotificationListener())
130+
assertThat(registry.getEventNotificationListener().get(DEFAULT_DOMAIN))
131131
.anySatisfy(listener -> assertThat(listener.getPath()).isEqualTo(name));
132132
}
133133

@@ -151,7 +151,7 @@ void shouldListenDynamicEvent() {
151151

152152
registry.handleDynamicEvents(name, eventHandler, SomeDataClass.class);
153153

154-
assertThat(registry.getDynamicEventHandlers())
154+
assertThat(registry.getDynamicEventHandlers().get(DEFAULT_DOMAIN))
155155
.anySatisfy(registered -> assertThat(registered)
156156
.extracting(RegisteredEventListener::getPath, RegisteredEventListener::getInputClass,
157157
RegisteredEventListener::getHandler
@@ -165,7 +165,7 @@ void shouldListenDynamicCloudEvent() {
165165

166166
registry.handleDynamicCloudEvents(name, eventHandler);
167167

168-
assertThat(registry.getDynamicEventHandlers())
168+
assertThat(registry.getDynamicEventHandlers().get(DEFAULT_DOMAIN))
169169
.anySatisfy(registered -> assertThat(registered)
170170
.extracting(RegisteredEventListener::getPath, RegisteredEventListener::getInputClass,
171171
RegisteredEventListener::getHandler
@@ -179,7 +179,7 @@ void handleDomainCommand() {
179179

180180
registry.handleCommand(name, handler, SomeDataClass.class);
181181

182-
assertThat(registry.getCommandHandlers())
182+
assertThat(registry.getCommandHandlers().get(DEFAULT_DOMAIN))
183183
.anySatisfy(registered -> assertThat(registered)
184184
.extracting(RegisteredCommandHandler::getPath, RegisteredCommandHandler::getInputClass,
185185
RegisteredCommandHandler::getHandler
@@ -193,7 +193,7 @@ void handleCloudEventCommand() {
193193

194194
registry.handleCloudEventCommand(name, cloudCommandHandler);
195195

196-
assertThat(registry.getCommandHandlers())
196+
assertThat(registry.getCommandHandlers().get(DEFAULT_DOMAIN))
197197
.anySatisfy(registered -> assertThat(registered)
198198
.extracting(RegisteredCommandHandler::getPath, RegisteredCommandHandler::getInputClass,
199199
RegisteredCommandHandler::getHandler
@@ -207,7 +207,7 @@ void shouldServerCloudEventQuery() {
207207

208208
registry.serveCloudEventQuery(name, queryHandler);
209209

210-
assertThat(registry.getHandlers())
210+
assertThat(registry.getHandlers().get(DEFAULT_DOMAIN))
211211
.anySatisfy(registered -> assertThat(registered)
212212
.extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
213213
.containsExactly(name, CloudEvent.class)).hasSize(1);
@@ -217,7 +217,7 @@ void shouldServerCloudEventQuery() {
217217
void handleCommandWithLambda() {
218218
registry.handleCommand(name, (Command<SomeDataClass> message) -> Mono.empty(), SomeDataClass.class);
219219

220-
assertThat(registry.getCommandHandlers())
220+
assertThat(registry.getCommandHandlers().get(DEFAULT_DOMAIN))
221221
.anySatisfy(registered -> assertThat(registered)
222222
.extracting(RegisteredCommandHandler::getPath, RegisteredCommandHandler::getInputClass)
223223
.containsExactly(name, SomeDataClass.class)).hasSize(1);
@@ -227,7 +227,7 @@ void handleCommandWithLambda() {
227227
@Test
228228
void serveQueryWithLambda() {
229229
registry.serveQuery(name, message -> Mono.empty(), SomeDataClass.class);
230-
assertThat(registry.getHandlers())
230+
assertThat(registry.getHandlers().get(DEFAULT_DOMAIN))
231231
.anySatisfy(registered -> assertThat(registered)
232232
.extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
233233
.containsExactly(name, SomeDataClass.class)).hasSize(1);
@@ -237,7 +237,7 @@ void serveQueryWithLambda() {
237237
void serveQueryWithTypeInference() {
238238
QueryHandler<SomeDataClass, SomeDataClass> handler = new SomeQueryHandler();
239239
registry.serveQuery(name, handler, SomeDataClass.class);
240-
assertThat(registry.getHandlers()).anySatisfy(registered -> {
240+
assertThat(registry.getHandlers().get(DEFAULT_DOMAIN)).anySatisfy(registered -> {
241241
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
242242
.containsExactly(name, SomeDataClass.class);
243243
assertThat(registered).extracting(RegisteredQueryHandler::getHandler)
@@ -249,7 +249,7 @@ void serveQueryWithTypeInference() {
249249
void serveQueryDelegate() {
250250
QueryHandlerDelegate<Void, SomeDataClass> handler = new SomeQueryHandlerDelegate();
251251
registry.serveQuery(name, handler, SomeDataClass.class);
252-
assertThat(registry.getHandlers()).anySatisfy(registered -> {
252+
assertThat(registry.getHandlers().get(DEFAULT_DOMAIN)).anySatisfy(registered -> {
253253
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
254254
.containsExactly(name, SomeDataClass.class);
255255
}).hasSize(1);
@@ -258,7 +258,7 @@ void serveQueryDelegate() {
258258
@Test
259259
void serveQueryDelegateWithLambda() {
260260
registry.serveQuery(name, (from, message) -> Mono.empty(), SomeDataClass.class);
261-
assertThat(registry.getHandlers()).anySatisfy(registered -> {
261+
assertThat(registry.getHandlers().get(DEFAULT_DOMAIN)).anySatisfy(registered -> {
262262
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
263263
.containsExactly(name, SomeDataClass.class);
264264
}).hasSize(1);

async/async-commons/src/main/java/org/reactivecommons/async/commons/HandlerResolver.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ public class HandlerResolver {
2525

2626
private final Matcher matcher = new KeyMatcher();
2727

28+
public boolean hasNotificationListeners() {
29+
return !eventNotificationListeners.isEmpty();
30+
}
31+
32+
public boolean hasCommandHandlers() {
33+
return !commandHandlers.isEmpty();
34+
}
35+
36+
public boolean hasQueryHandlers() {
37+
return !queryHandlers.isEmpty();
38+
}
39+
2840
@SuppressWarnings("unchecked")
2941
public <T, M> RegisteredQueryHandler<T, M> getQueryHandler(String path) {
3042
return (RegisteredQueryHandler<T, M>) queryHandlers
@@ -74,7 +86,8 @@ public void addEventListener(RegisteredEventListener<?, ?> listener) {
7486

7587
public void addQueryHandler(RegisteredQueryHandler<?, ?> handler) {
7688
if (handler.getPath().contains("*") || handler.getPath().contains("#")) {
77-
throw new RuntimeException("avoid * or # in dynamic handlers, make sure you have no conflicts with cached patterns");
89+
throw new RuntimeException("avoid * or # in dynamic handlers, make sure you have no conflicts with cached" +
90+
" patterns");
7891
}
7992
queryHandlers.put(handler.getPath(), handler);
8093
}

0 commit comments

Comments
 (0)