Skip to content

Commit 02e99bd

Browse files
committed
Event loop, signalix objects
1 parent 16808a3 commit 02e99bd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1146
-113
lines changed

README.md

+18-10
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ Add the following dependency to your project:
1010
<dependency>
1111
<groupId>org.exploit</groupId>
1212
<artifactId>signalix</artifactId>
13-
<version>0.1.1</version>
13+
<version>0.1.3</version>
1414
</dependency>
1515
```
1616

1717
### Gradle
1818
```groovy
19-
implementation("org.exploit:signalix:0.1.1")
19+
implementation("org.exploit:signalix:0.1.3")
2020
```
2121

2222
### Usage
@@ -58,7 +58,7 @@ public class MyListener implements Listener {
5858
You can also define event listener in a functional way:
5959
```java
6060
public static void main(String[] args) {
61-
EventScope scope = new EventScope();
61+
var scope = new EventScope();
6262

6363
scope.registerEvent(MyEvent.class, (e) -> {
6464
System.out.println("Handling event: " + e.getSampleData());
@@ -67,7 +67,8 @@ public static void main(String[] args) {
6767
```
6868

6969
#### Calling events
70-
Finally, we need to create an instance of `EventScope`, register the listener, and call our event.
70+
Finally, we need to create an instance of `EventScope`, register the listener, and call our event. All events are called in a non-blocking manner in a single event loop thread.
71+
7172
```java
7273
import org.exploit.signalix.manager.EventScope;
7374

@@ -81,12 +82,6 @@ public class Main {
8182
}
8283
```
8384

84-
To call event in a async way, use `callAsync`
85-
```java
86-
CompletableFuture<Void> call = scope.callAsync(new MyEvent(""));
87-
```
88-
___
89-
9085
You can handle the same event in multiple methods.
9186
Event Handler's order can be controlled by priority, an event can extend `Cancellable` to stop further handlers execution.
9287

@@ -145,5 +140,18 @@ public class MyListener implements Listener {
145140
}
146141
```
147142

143+
## Error handling
144+
In case of event execution error, `EventExecutionException` will be called as event:
145+
To handle the exception, simply define event handlers for `EventExecutionException`.
146+
```java
147+
@EventHandler
148+
public void onException(EventExecutionException exceptionEvent) {
149+
var event = exceptionEvent.getEvent();
150+
var exception = exceptionEvent.getException();
151+
152+
// Handle exception
153+
}
154+
```
155+
148156
## License
149157
Signalix is distributed under the [BSD 2-Clause License](LICENSE.md)

build.gradle

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ repositories {
99
mavenCentral()
1010
}
1111

12+
tasks.withType(JavaCompile) {
13+
options.compilerArgs << "-parameters"
14+
}
15+
1216
dependencies {
1317
testImplementation platform('org.junit:junit-bom:5.9.1')
1418
testImplementation 'org.junit.jupiter:junit-jupiter'
@@ -39,7 +43,7 @@ allprojects {
3943
}
4044

4145
group = 'org.exploit'
42-
version = '0.1.1'
46+
version = '0.1.3'
4347

4448
afterEvaluate { p ->
4549
publishing {

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
rootProject.name = 'signalix'
22
include 'signalix-kafka'
3+
include 'signalix-objects'
34

signalix-kafka/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ First add following dependency to your project:
88
<dependency>
99
<groupId>org.exploit</groupId>
1010
<artifactId>signalix-kafka</artifactId>
11-
<version>0.1</version>
11+
<version>0.1.3</version>
1212
</dependency>
1313
```
1414

1515
### Gradle
1616
```groovy
17-
implementation("org.exploit:signalix-kafka:0.1")
17+
implementation("org.exploit:signalix-kafka:0.1.3")
1818
```
1919

2020
## Usage
@@ -60,7 +60,7 @@ Now simply register it as default listener:
6060
```java
6161
public static void main(String[] args) {
6262
Map<String, String> kafkaProperties = new HashMap<String, String>();
63-
KafkaEventScope kafkaEventScope = new KafkaEventScope(kafkaProperties);
63+
var kafkaEventScope = new KafkaEventScope(kafkaProperties);
6464

6565
kafkaEventScope.registerListener(new MyKafkaListener());
6666
}
@@ -101,7 +101,7 @@ Now you can call your event from KafkaEventScope:
101101
```java
102102
public static void main(String[] args) {
103103
Map<String, String> kafkaProperties = new HashMap<String, String>();
104-
KafkaEventScope kafkaEventScope = new KafkaEventScope(kafkaProperties);
104+
var kafkaEventScope = new KafkaEventScope(kafkaProperties);
105105

106106
kafkaEventScope.call(new MyEvent("Hello World!"));
107107
}

signalix-kafka/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dependencies {
1919

2020
compileOnly project(":")
2121

22-
implementation 'org.apache.kafka:kafka-clients:3.5.0'
22+
implementation 'org.apache.kafka:kafka-clients:3.7.1'
2323
implementation 'org.slf4j:slf4j-api:2.0.12'
2424
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
2525
}

signalix-kafka/src/main/java/org/exploit/signalix/KafkaEventScope.java

+30-14
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
import org.exploit.signalix.annotation.KafkaEvent;
44
import org.exploit.signalix.annotation.KafkaEventListener;
5+
import org.exploit.signalix.core.KafkaEventManager;
56
import org.exploit.signalix.event.listener.ConsumerEventListener;
67
import org.exploit.signalix.event.listener.EventListener;
78
import org.exploit.signalix.event.listener.ReflectedEventListener;
8-
import org.exploit.signalix.core.KafkaEventManager;
9-
import org.exploit.signalix.model.KafkaEventMeta;
10-
import org.exploit.signalix.utils.EventObjectMapper;
9+
import org.exploit.signalix.exception.EventExecutionException;
1110
import org.exploit.signalix.manager.EventScope;
1211
import org.exploit.signalix.marker.Event;
1312
import org.exploit.signalix.marker.Listener;
13+
import org.exploit.signalix.model.KafkaEventMeta;
14+
import org.exploit.signalix.model.KafkaWiredEvent;
1415
import org.exploit.signalix.utils.EventConsumer;
16+
import org.exploit.signalix.utils.EventObjectMapper;
1517
import org.jetbrains.annotations.NotNull;
1618

1719
import java.util.List;
@@ -32,16 +34,6 @@ public KafkaEventScope(Map<String, String> properties) {
3234
this(convertToProperties(properties));
3335
}
3436

35-
@Override
36-
public <T extends Event> void call(T event) {
37-
var eventClass = event.getClass();
38-
39-
extractAnnotation(eventClass, KafkaEvent.class).ifPresentOrElse(
40-
meta -> kafkaEventManager.call(event, new KafkaEventMeta(meta)),
41-
() -> innerCall(event)
42-
);
43-
}
44-
4537
public <T extends Event> void call(String topic, T event) {
4638
extractAnnotation(event.getClass(), KafkaEvent.class).ifPresentOrElse(
4739
annotation -> {
@@ -52,8 +44,19 @@ public <T extends Event> void call(String topic, T event) {
5244
);
5345
}
5446

47+
@Override
48+
public void call(Event event) {
49+
extractAnnotation(event.getClass(), KafkaEvent.class).ifPresentOrElse(
50+
annotation -> {
51+
var meta = new KafkaEventMeta(annotation.topic(), annotation.partition(), List.of(annotation.headers()));
52+
call(meta, event);
53+
},
54+
() -> super.call(event)
55+
);
56+
}
57+
5558
public <T extends Event> void call(KafkaEventMeta meta, T event) {
56-
kafkaEventManager.call(event, meta);
59+
eventLoop.callEvent(new KafkaWiredEvent(event, meta));
5760
}
5861

5962
public <T extends Event> void innerCall(T event) {
@@ -104,6 +107,19 @@ public void registerEventListener(EventListener listener) {
104107
kafkaEventManager.getEventObjectMapper().registerEvents(listener);
105108
}
106109

110+
@Override
111+
protected void dispatchEvent(Event event) {
112+
if (event instanceof KafkaWiredEvent kafkaEvent) {
113+
try {
114+
kafkaEventManager.call(kafkaEvent);
115+
} catch (Exception e) {
116+
call(new EventExecutionException(e, kafkaEvent.event()));
117+
}
118+
} else {
119+
super.dispatchEvent(event);
120+
}
121+
}
122+
107123
@Override
108124
public void close() {
109125
super.close();

signalix-kafka/src/main/java/org/exploit/signalix/core/KafkaEventConsumer.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package org.exploit.signalix.core;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4-
import org.exploit.signalix.annotation.KafkaEventListener;
5-
import org.exploit.signalix.event.DeserializationFailureEvent;
6-
import org.exploit.signalix.utils.UtilityMethods;
7-
import org.exploit.signalix.marker.Event;
84
import org.apache.kafka.clients.consumer.ConsumerConfig;
95
import org.apache.kafka.clients.consumer.KafkaConsumer;
106
import org.apache.kafka.common.errors.WakeupException;
7+
import org.exploit.signalix.annotation.KafkaEventListener;
8+
import org.exploit.signalix.event.DeserializationFailureEvent;
9+
import org.exploit.signalix.marker.Event;
10+
import org.exploit.signalix.utils.UtilityMethods;
1111
import org.slf4j.Logger;
1212
import org.slf4j.LoggerFactory;
1313

signalix-kafka/src/main/java/org/exploit/signalix/core/KafkaEventManager.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
import org.exploit.signalix.KafkaEventScope;
44
import org.exploit.signalix.annotation.KafkaEventListener;
5-
import org.exploit.signalix.model.KafkaEventMeta;
5+
import org.exploit.signalix.model.KafkaWiredEvent;
66
import org.exploit.signalix.utils.EventObjectMapper;
7-
import org.exploit.signalix.marker.Event;
87

98
import java.io.Closeable;
109
import java.util.Properties;
@@ -28,8 +27,8 @@ public KafkaEventManager(Properties properties, KafkaEventScope eventScope) {
2827
this.eventProducer = new KafkaEventProducer(this);
2928
}
3029

31-
public <T extends Event> void call(T event, KafkaEventMeta meta) {
32-
eventProducer.sendEvent(event, meta);
30+
public void call(KafkaWiredEvent e) {
31+
eventProducer.sendEvent(e);
3332
}
3433

3534
public void registerKafkaListener(Class<?> clazz, KafkaEventListener meta) {
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package org.exploit.signalix.core;
22

3-
import org.exploit.signalix.exception.EventExecutionException;
4-
import org.exploit.signalix.model.KafkaEventMeta;
5-
import org.exploit.signalix.utils.UtilityMethods;
6-
import org.exploit.signalix.marker.Event;
73
import org.apache.kafka.clients.producer.KafkaProducer;
84
import org.apache.kafka.clients.producer.ProducerRecord;
5+
import org.exploit.signalix.model.KafkaWiredEvent;
6+
import org.exploit.signalix.utils.UtilityMethods;
97

108
public class KafkaEventProducer extends KafkaProducer<String, String> {
119
private final KafkaEventManager eventManager;
@@ -15,8 +13,11 @@ public KafkaEventProducer(KafkaEventManager eventManager) {
1513
this.eventManager = eventManager;
1614
}
1715

18-
public <T extends Event> void sendEvent(T event, KafkaEventMeta meta) {
16+
public void sendEvent(KafkaWiredEvent e) {
1917
try {
18+
var event = e.event();
19+
var meta = e.meta();
20+
2021
var topic = meta.topic();
2122
var name = event.getClass().getName();
2223
var value = eventManager.getEventObjectMapper().writeValueAsString(event);
@@ -25,8 +26,8 @@ public <T extends Event> void sendEvent(T event, KafkaEventMeta meta) {
2526
var headers = UtilityMethods.extractHeaders(meta);
2627

2728
send(new ProducerRecord<>(topic, partition, name, value, headers));
28-
} catch (Exception e) {
29-
throw new EventExecutionException(e.getMessage());
29+
} catch (Exception exception) {
30+
throw new IllegalStateException("Couldn't produce kafka event", exception);
3031
}
3132
}
3233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.exploit.signalix.model;
2+
3+
import org.exploit.signalix.marker.Event;
4+
5+
public record KafkaWiredEvent(Event event, KafkaEventMeta meta) implements Event {
6+
}

signalix-kafka/src/main/java/org/exploit/signalix/utils/UtilityMethods.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.exploit.signalix.utils;
22

3-
import org.exploit.signalix.model.KafkaEventMeta;
43
import org.apache.kafka.common.header.internals.RecordHeaders;
4+
import org.exploit.signalix.model.KafkaEventMeta;
55

66
import java.lang.annotation.Annotation;
77
import java.util.*;

signalix-kafka/src/test/java/org/exploit/signalix/kafka/test/WireSerializationTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ public void init() {
2121

2222
@Test
2323
public void testSerialize() throws JsonProcessingException {
24-
String expected = "{\"_name\":\"SampleEvent\",\"foo\":\"Hello world\"}";
25-
String result = objectMapper.writeValueAsString(new SampleEvent("Hello world"));
24+
var expected = "{\"_name\":\"SampleEvent\",\"foo\":\"Hello world\"}";
25+
var result = objectMapper.writeValueAsString(new SampleEvent("Hello world"));
2626

2727
assertEquals(expected, result);
2828
}
2929

3030
@Test
3131
public void testDeserialize() throws JsonProcessingException {
32-
String serialized = "{\"_name\":\"SampleEvent\",\"foo\":\"Hello world\"}";
33-
Event event = objectMapper.readValue(serialized, Event.class);
32+
var serialized = "{\"_name\":\"SampleEvent\",\"foo\":\"Hello world\"}";
33+
var event = objectMapper.readValue(serialized, Event.class);
3434

3535
assertEquals(event.getClass(), SampleEvent.class);
3636
}

0 commit comments

Comments
 (0)