Skip to content

Commit 5f5e8f1

Browse files
author
Daniel Bustamante Ospina
authored
Merge pull request #46 from juancgalvis/query_delegate
Implement Query delegate
2 parents c10d99e + 5c5a2fc commit 5f5e8f1

File tree

27 files changed

+554
-158
lines changed

27 files changed

+554
-158
lines changed

.github/workflows/main.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ on:
44
push:
55
branches:
66
- master
7-
7+
88
pull_request:
99
branches:
1010
- master
11-
11+
1212
release:
1313
types: [created]
1414

@@ -49,12 +49,26 @@ jobs:
4949
# - name: Execute jacocoTestReport
5050
# run: ./gradlew test jacocoTestReport && cp build/reports/jacoco/report.xml jacoco.xml || echo "Code coverage failed"
5151
- name: Build with Gradle
52-
run: ./gradlew build --refresh-dependencies --no-daemon --continue
52+
run: ./gradlew build asciidoctor --refresh-dependencies --no-daemon --continue
53+
- name: Generate Changelog
54+
uses: heinrichreimer/[email protected]
55+
with:
56+
token: ${{ secrets.GITHUB_TOKEN }}
57+
- name: Push Docs and Changelog
58+
uses: github-actions-x/[email protected]
59+
with:
60+
github-token: ${{ secrets.GITHUB_TOKEN }}
61+
push-branch: 'master'
62+
commit-message: 'Automatic docs and changelog generation'
63+
force-add: 'true'
64+
files: CHANGELOG.md docs/
65+
name: ${{ github.actor }}
66+
email: ${{ github.actor }}@users.noreply.github.com
5367
# - name: Push codeCoverage to Codecov
5468
# run: bash <(curl -s https://codecov.io/bash)
5569
- name: Echo credentials
5670
run: echo "bintrayUser=${{secrets.BINTRAY_USER}}" >> gradle.properties
5771
- name: Echo credentials Key
58-
run: echo "bintrayApiKey=${{secrets.BINTRAY_KEY}}" >> gradle.properties && cat gradle.properties
72+
run: echo "bintrayApiKey=${{secrets.BINTRAY_KEY}}" >> gradle.properties && cat gradle.properties
5973
- name: Publish plugin
6074
run: ./gradlew bintrayUpload

async/async-commons-api/async-commons-api.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ bintray {
7373

7474
dependencies {
7575
compile project(":domain-events-api")
76-
implementation 'io.projectreactor:reactor-core'
76+
compileOnly 'io.projectreactor:reactor-core'
7777
testImplementation 'io.projectreactor:reactor-test'
78-
}
78+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
public interface DirectAsyncGateway {
77
<T> Mono<Void> sendCommand(Command<T> command, String targetName);
88
<T, R> Mono<R> requestReply(AsyncQuery<T> query, String targetName, Class<R> type);
9+
<T> Mono<Void> reply(T response, From from);
910
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.reactivecommons.async.api;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class From {
7+
private String replyID;
8+
private String correlationID;
9+
}

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

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import org.reactivecommons.async.api.handlers.CommandHandler;
77
import org.reactivecommons.async.api.handlers.EventHandler;
88
import org.reactivecommons.async.api.handlers.QueryHandler;
9+
import org.reactivecommons.async.api.handlers.QueryHandlerDelegate;
910
import org.reactivecommons.async.api.handlers.registered.RegisteredCommandHandler;
1011
import org.reactivecommons.async.api.handlers.registered.RegisteredEventListener;
1112
import org.reactivecommons.async.api.handlers.registered.RegisteredQueryHandler;
13+
import reactor.core.publisher.Mono;
1214

1315
import java.lang.reflect.ParameterizedType;
1416
import java.util.List;
@@ -18,82 +20,86 @@
1820
@NoArgsConstructor(access = AccessLevel.PACKAGE)
1921
public class HandlerRegistry {
2022

21-
public static HandlerRegistry register(){
22-
return new HandlerRegistry();
23-
}
24-
25-
private final List<RegisteredQueryHandler<?, ?>> handlers = new CopyOnWriteArrayList<>();
23+
private final List<RegisteredQueryHandler> handlers = new CopyOnWriteArrayList<>();
2624
private final List<RegisteredEventListener> eventListeners = new CopyOnWriteArrayList<>();
2725
private final List<RegisteredCommandHandler> commandHandlers = new CopyOnWriteArrayList<>();
2826
private final List<RegisteredEventListener> eventNotificationListener = new CopyOnWriteArrayList<>();
2927

30-
public <T> HandlerRegistry listenEvent(String eventName, EventHandler<T> fn, Class<T> eventClass){
31-
eventListeners.add(new RegisteredEventListener<>(eventName, fn, eventClass));
28+
public static HandlerRegistry register() {
29+
return new HandlerRegistry();
30+
}
31+
32+
public <T> HandlerRegistry listenEvent(String eventName, EventHandler<T> fn, Class<T> eventClass) {
33+
eventListeners.add(new RegisteredEventListener<>(eventName, fn, eventClass));
3234
return this;
3335
}
3436

35-
public <T> HandlerRegistry listenEvent(String eventName, EventHandler<T> handler){
36-
eventListeners.add(new RegisteredEventListener<>(eventName, handler, inferGenericParameterType(handler)));
37+
public <T> HandlerRegistry listenEvent(String eventName, EventHandler<T> handler) {
38+
eventListeners.add(new RegisteredEventListener<>(eventName, handler, inferGenericParameterType(handler)));
3739
return this;
3840
}
3941

40-
public <T> HandlerRegistry listenNotificationEvent(String eventName, EventHandler<T> fn, Class<T> eventClass){
41-
eventNotificationListener.add(new RegisteredEventListener<>(eventName, fn, eventClass));
42+
public <T> HandlerRegistry listenNotificationEvent(String eventName, EventHandler<T> fn, Class<T> eventClass) {
43+
eventNotificationListener.add(new RegisteredEventListener<>(eventName, fn, eventClass));
4244
return this;
4345
}
4446

45-
public <T> HandlerRegistry handleCommand(String commandName, CommandHandler<T> fn, Class<T> commandClass){
46-
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, commandClass));
47+
public <T> HandlerRegistry handleCommand(String commandName, CommandHandler<T> fn, Class<T> commandClass) {
48+
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, commandClass));
4749
return this;
4850
}
4951

50-
public <T> HandlerRegistry handleCommand(String commandName, CommandHandler<T> fn){
51-
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, inferGenericParameterType(fn)));
52+
public <T> HandlerRegistry handleCommand(String commandName, CommandHandler<T> fn) {
53+
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, inferGenericParameterType(fn)));
5254
return this;
5355
}
5456

55-
public <T, R> HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler){
57+
public <T, R> HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler) {
5658
return serveQuery(resource, handler, inferGenericParameterType(handler));
5759
}
5860

59-
public <T, R> HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler, Class<R> queryClass){
61+
public <T, R> HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler, Class<R> queryClass) {
62+
handlers.add(new RegisteredQueryHandler<>(resource, (ignored, message) -> handler.handle(message), queryClass));
63+
return this;
64+
}
65+
66+
public <R> HandlerRegistry serveQuery(String resource, QueryHandlerDelegate<Void, R> handler, Class<R> queryClass) {
6067
handlers.add(new RegisteredQueryHandler<>(resource, handler, queryClass));
6168
return this;
6269
}
6370

6471

6572
@SuppressWarnings("unchecked")
66-
private <T, R> Class<R> inferGenericParameterType(QueryHandler<T, R> handler){
67-
try{
73+
private <T, R> Class<R> inferGenericParameterType(QueryHandler<T, R> handler) {
74+
try {
6875
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
69-
return (Class<R>) genericSuperclass.getActualTypeArguments()[1];
70-
}catch (Exception e){
71-
throw new RuntimeException("Fail to infer generic Query class, please use serveQuery(path, handler, class) instead");
76+
return (Class<R>) genericSuperclass.getActualTypeArguments()[1];
77+
} catch (Exception e) {
78+
throw new RuntimeException("Fail to infer generic Query class, please use serveQuery(path, handler, " +
79+
"class) instead");
7280
}
7381
}
7482

7583
@SuppressWarnings("unchecked")
76-
private <T> Class<T> inferGenericParameterType(CommandHandler<T> handler){
77-
try{
84+
private <T> Class<T> inferGenericParameterType(CommandHandler<T> handler) {
85+
try {
7886
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
79-
return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
80-
}catch (Exception e){
81-
throw new RuntimeException("Fail to infer generic Command class, please use handleCommand(path, handler, class) instead");
87+
return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
88+
} catch (Exception e) {
89+
throw new RuntimeException("Fail to infer generic Command class, please use handleCommand(path, handler, " +
90+
"class) instead");
8291
}
8392
}
8493

85-
private <T> Class<T> inferGenericParameterType(EventHandler<T> handler){
86-
try{
94+
private <T> Class<T> inferGenericParameterType(EventHandler<T> handler) {
95+
try {
8796
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
88-
return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
89-
}catch (Exception e){
90-
throw new RuntimeException("Fail to infer generic Query class, please use listenEvent(eventName, handler, class) instead");
97+
return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
98+
} catch (Exception e) {
99+
throw new RuntimeException("Fail to infer generic Query class, please use listenEvent(eventName, handler," +
100+
" class) instead");
91101
}
92102
}
93-
94-
95-
96-
97103
}
98104

99105

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.reactivecommons.async.api.handlers;
2+
3+
import org.reactivecommons.async.api.From;
4+
import reactor.core.publisher.Mono;
5+
6+
public interface QueryHandlerDelegate<T, M> {
7+
Mono<T> handle(From from, M message);
8+
}

async/async-commons-api/src/main/java/org/reactivecommons/async/api/handlers/registered/RegisteredQueryHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
import lombok.Getter;
44
import lombok.RequiredArgsConstructor;
5-
import org.reactivecommons.async.api.handlers.QueryHandler;
5+
import org.reactivecommons.async.api.handlers.QueryHandlerDelegate;
66

77
@RequiredArgsConstructor
88
@Getter
9-
public class RegisteredQueryHandler<T, R> {
9+
public class RegisteredQueryHandler<T, C> {
1010
private final String path;
11-
private final QueryHandler<T, R> handler;
12-
private final Class<R> queryClass;
11+
private final QueryHandlerDelegate<T, C> handler;
12+
private final Class<C> queryClass;
1313
}

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

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
package org.reactivecommons.async.api;
22

3-
import static org.assertj.core.api.Assertions.*;
4-
import static org.mockito.Mockito.*;
5-
63
import lombok.Data;
74
import org.junit.Test;
85
import org.reactivecommons.api.domain.Command;
96
import org.reactivecommons.api.domain.DomainEvent;
107
import org.reactivecommons.async.api.handlers.CommandHandler;
118
import org.reactivecommons.async.api.handlers.EventHandler;
129
import org.reactivecommons.async.api.handlers.QueryHandler;
10+
import org.reactivecommons.async.api.handlers.QueryHandlerDelegate;
1311
import org.reactivecommons.async.api.handlers.registered.RegisteredCommandHandler;
1412
import org.reactivecommons.async.api.handlers.registered.RegisteredEventListener;
1513
import org.reactivecommons.async.api.handlers.registered.RegisteredQueryHandler;
1614
import reactor.core.publisher.Mono;
1715

16+
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.mockito.Mockito.mock;
18+
1819
public class HandlerRegistryTest {
1920

2021
private HandlerRegistry registry = HandlerRegistry.register();
2122
private String name = "some.event";
2223

2324
@Test
24-
public void shouldListenEventWithTypeInferenceWhenClassInstanceIsUsed(){
25+
public void shouldListenEventWithTypeInferenceWhenClassInstanceIsUsed() {
2526
SomeEventHandler eventHandler = new SomeEventHandler();
2627

2728
registry.listenEvent(name, eventHandler);
2829

2930
assertThat(registry.getEventListeners()).anySatisfy(registered -> {
30-
assertThat(registered).extracting(RegisteredEventListener::getPath, RegisteredEventListener::getInputClass, RegisteredEventListener::getHandler)
31-
.containsExactly(name, SomeDataClass.class, eventHandler);
31+
assertThat(registered).extracting(RegisteredEventListener::getPath,
32+
RegisteredEventListener::getInputClass, RegisteredEventListener::getHandler)
33+
.containsExactly(name, SomeDataClass.class, eventHandler);
3234
}).hasSize(1);
3335
}
3436

@@ -39,8 +41,9 @@ public void listenEvent() {
3941
registry.listenEvent(name, handler, SomeDataClass.class);
4042

4143
assertThat(registry.getEventListeners()).anySatisfy(registered -> {
42-
assertThat(registered).extracting(RegisteredEventListener::getPath, RegisteredEventListener::getInputClass, RegisteredEventListener::getHandler)
43-
.containsExactly(name, SomeDataClass.class, handler);
44+
assertThat(registered).extracting(RegisteredEventListener::getPath,
45+
RegisteredEventListener::getInputClass, RegisteredEventListener::getHandler)
46+
.containsExactly(name, SomeDataClass.class, handler);
4447
}).hasSize(1);
4548
}
4649

@@ -51,8 +54,9 @@ public void handleCommandWithTypeInference() {
5154
registry.handleCommand(name, handler);
5255

5356
assertThat(registry.getCommandHandlers()).anySatisfy(registered -> {
54-
assertThat(registered).extracting(RegisteredCommandHandler::getPath, RegisteredCommandHandler::getInputClass, RegisteredCommandHandler::getHandler)
55-
.containsExactly(name, SomeDataClass.class, handler);
57+
assertThat(registered).extracting(RegisteredCommandHandler::getPath,
58+
RegisteredCommandHandler::getInputClass, RegisteredCommandHandler::getHandler)
59+
.containsExactly(name, SomeDataClass.class, handler);
5660
}).hasSize(1);
5761
}
5862

@@ -76,8 +80,9 @@ public void handleCommandWithLambda() {
7680
registry.handleCommand(name, (Command<SomeDataClass> message) -> Mono.empty(), SomeDataClass.class);
7781

7882
assertThat(registry.getCommandHandlers()).anySatisfy(registered -> {
79-
assertThat(registered).extracting(RegisteredCommandHandler::getPath, RegisteredCommandHandler::getInputClass)
80-
.containsExactly(name, SomeDataClass.class);
83+
assertThat(registered).extracting(RegisteredCommandHandler::getPath,
84+
RegisteredCommandHandler::getInputClass)
85+
.containsExactly(name, SomeDataClass.class);
8186
}).hasSize(1);
8287
}
8388

@@ -87,7 +92,7 @@ public void serveQueryWithLambda() {
8792
registry.serveQuery(name, message -> Mono.empty(), SomeDataClass.class);
8893
assertThat(registry.getHandlers()).anySatisfy(registered -> {
8994
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
90-
.containsExactly(name, SomeDataClass.class);
95+
.containsExactly(name, SomeDataClass.class);
9196
}).hasSize(1);
9297
}
9398

@@ -96,11 +101,38 @@ public void serveQueryWithTypeInference() {
96101
QueryHandler<SomeDataClass, SomeDataClass> handler = new SomeQueryHandler();
97102
registry.serveQuery(name, handler);
98103
assertThat(registry.getHandlers()).anySatisfy(registered -> {
99-
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass, RegisteredQueryHandler::getHandler)
100-
.containsExactly(name, SomeDataClass.class, handler);
104+
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
105+
.containsExactly(name, SomeDataClass.class);
106+
assertThat(registered).extracting(RegisteredQueryHandler::getHandler).isInstanceOf(QueryHandlerDelegate.class);
107+
}).hasSize(1);
108+
}
109+
110+
@Test
111+
public void serveQueryDelegate() {
112+
QueryHandlerDelegate<Void, SomeDataClass> handler = new SomeQueryHandlerDelegate();
113+
registry.serveQuery(name, handler, SomeDataClass.class);
114+
assertThat(registry.getHandlers()).anySatisfy(registered -> {
115+
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
116+
.containsExactly(name, SomeDataClass.class);
117+
}).hasSize(1);
118+
}
119+
120+
@Test
121+
public void serveQueryDelegateWithLambda() {
122+
registry.serveQuery(name, (from, message) -> Mono.empty(), SomeDataClass.class);
123+
assertThat(registry.getHandlers()).anySatisfy(registered -> {
124+
assertThat(registered).extracting(RegisteredQueryHandler::getPath, RegisteredQueryHandler::getQueryClass)
125+
.containsExactly(name, SomeDataClass.class);
101126
}).hasSize(1);
102127
}
103128

129+
private static class SomeQueryHandlerDelegate implements QueryHandlerDelegate<Void, SomeDataClass> {
130+
@Override
131+
public Mono<Void> handle(From from, SomeDataClass message) {
132+
return Mono.empty();
133+
}
134+
}
135+
104136
private static class SomeEventHandler implements EventHandler<SomeDataClass> {
105137
@Override
106138
public Mono<Void> handle(DomainEvent<SomeDataClass> message) {
@@ -129,4 +161,4 @@ private static class SomeDataClass {
129161
private Integer someProp2;
130162
}
131163

132-
}
164+
}

async/async-commons-starter/async-commons-starter.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ bintray {
7474

7575
dependencies {
7676
compile project(":async-commons")
77-
api('org.springframework.boot:spring-boot-starter')
77+
compileOnly('org.springframework.boot:spring-boot-starter')
7878

7979
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
8080

async/async-commons/async-commons.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ dependencies {
7575
compile project(":async-commons-api")
7676
compile project(":domain-events-api")
7777

78-
api 'io.projectreactor:reactor-core'
78+
compileOnly 'io.projectreactor:reactor-core'
7979
api ("io.projectreactor.rabbitmq:reactor-rabbitmq")
8080
api 'com.fasterxml.jackson.core:jackson-databind'
8181
testImplementation 'io.projectreactor:reactor-test'

0 commit comments

Comments
 (0)