Skip to content

Commit 529102f

Browse files
authored
Merge pull request #5 from luismr/feature/ping-created-event-decoupled-from-model-to-use-ping-dto
Simplify PingCreatedEvent and Add Message Payload Documentation
2 parents 5541521 + a3d9b25 commit 529102f

File tree

8 files changed

+136
-141
lines changed

8 files changed

+136
-141
lines changed

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,68 @@ app:
293293
- `ReadWriteRoutingAspect`: Sets the context based on transaction type
294294
- `DbContextHolder`: Thread-local holder for the current context
295295

296+
## Message Payloads
297+
298+
The application uses two main DTOs for message communication:
299+
300+
### PingDTO
301+
Used to publish flight position updates to the flight-tracker-event-app via WebSocket.
302+
303+
```json
304+
{
305+
"id": "uuid",
306+
"aircraft": {
307+
"icao24": "string",
308+
"callsign": "string",
309+
"origin_country": "string",
310+
"last_contact": "timestamp",
311+
"squawk": "string",
312+
"spi": boolean,
313+
"sensors": [integer]
314+
},
315+
"vector": {
316+
"velocity": double,
317+
"true_track": double,
318+
"vertical_rate": double
319+
},
320+
"position": {
321+
"longitude": double,
322+
"latitude": double,
323+
"geo_altitude": double,
324+
"baro_altitude": double,
325+
"on_ground": boolean,
326+
"source": integer,
327+
"time": "timestamp"
328+
},
329+
"last_update": "timestamp"
330+
}
331+
```
332+
333+
### FlightDataDTO
334+
Used to subscribe to flight tracker data from the flight tracker producer via Kafka.
335+
336+
```json
337+
{
338+
"icao24": "string",
339+
"callsign": "string",
340+
"origin_country": "string",
341+
"last_contact": long,
342+
"time_position": long,
343+
"longitude": double,
344+
"latitude": double,
345+
"baro_altitude": double,
346+
"on_ground": boolean,
347+
"velocity": double,
348+
"true_track": double,
349+
"vertical_rate": double,
350+
"sensors": [integer],
351+
"geo_altitude": double,
352+
"squawk": "string",
353+
"spi": boolean,
354+
"position_source": integer
355+
}
356+
```
357+
296358
## Project Structure
297359

298360
```

src/main/java/dev/luismachadoreis/flighttracker/server/ping/domain/Ping.java

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package dev.luismachadoreis.flighttracker.server.ping.domain;
22

3-
import dev.luismachadoreis.flighttracker.server.ping.domain.event.PingCreated;
4-
import jakarta.persistence.*;
5-
import lombok.Getter;
6-
import lombok.NoArgsConstructor;
7-
import org.springframework.data.domain.AbstractAggregateRoot;
8-
93
import java.time.Instant;
10-
import java.util.UUID;
114
import java.util.Arrays;
5+
import java.util.UUID;
6+
7+
import org.springframework.data.domain.AbstractAggregateRoot;
8+
9+
import jakarta.persistence.AttributeConverter;
10+
import jakarta.persistence.Column;
11+
import jakarta.persistence.Convert;
12+
import jakarta.persistence.Converter;
13+
import jakarta.persistence.Embeddable;
14+
import jakarta.persistence.Embedded;
15+
import jakarta.persistence.Entity;
16+
import jakarta.persistence.Id;
17+
import lombok.Getter;
18+
import lombok.NoArgsConstructor;
1219

1320
@Entity
1421
@Getter
@@ -131,19 +138,7 @@ public Integer[] convertToEntityAttribute(String dbData) {
131138
* Register the PingCreated event.
132139
*/
133140
public void registerPingCreated() {
134-
registerEvent(new PingCreated(
135-
this.id,
136-
this.aircraft.icao24(),
137-
this.aircraft.callsign(),
138-
this.position.latitude(),
139-
this.position.longitude(),
140-
this.vector.trueTrack(),
141-
this.position.geoAltitude(),
142-
this.position.baroAltitude(),
143-
this.position.onGround(),
144-
this.vector.velocity(),
145-
this.vector.verticalRate(),
146-
this.lastUpdate
147-
));
141+
registerEvent(new PingCreatedEvent(this, this.lastUpdate));
148142
}
143+
149144
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dev.luismachadoreis.flighttracker.server.ping.domain;
2+
3+
import java.time.Instant;
4+
public record PingCreatedEvent (
5+
Ping ping,
6+
Instant timestamp
7+
) {}

src/main/java/dev/luismachadoreis/flighttracker/server/ping/domain/event/PingCreated.java

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,37 @@
11
package dev.luismachadoreis.flighttracker.server.ping.infrastructure.pubsub;
22

3-
import dev.luismachadoreis.flighttracker.server.common.utils.JsonUtils;
4-
import dev.luismachadoreis.flighttracker.server.ping.domain.event.PingCreated;
5-
import dev.luismachadoreis.flighttracker.server.ping.infrastructure.websocket.MapUpdatesHandler;
6-
import lombok.extern.slf4j.Slf4j;
73
import org.springframework.stereotype.Component;
84
import org.springframework.transaction.event.TransactionPhase;
95
import org.springframework.transaction.event.TransactionalEventListener;
106

7+
import dev.luismachadoreis.flighttracker.server.common.utils.JsonUtils;
8+
import dev.luismachadoreis.flighttracker.server.ping.application.dto.PingDTO;
9+
import dev.luismachadoreis.flighttracker.server.ping.application.dto.PingMapper;
10+
import dev.luismachadoreis.flighttracker.server.ping.domain.PingCreatedEvent;
11+
import dev.luismachadoreis.flighttracker.server.ping.infrastructure.websocket.MapUpdatesHandler;
12+
import lombok.AllArgsConstructor;
13+
import lombok.extern.slf4j.Slf4j;
14+
1115
/**
1216
* Publishes PingCreated events to the MapUpdatesHandler.
1317
*/
1418
@Slf4j
1519
@Component
20+
@AllArgsConstructor
1621
public class PingEventPublisher {
1722

23+
private final PingMapper pingMapper;
1824
private final MapUpdatesHandler mapUpdatesHandler;
1925
private final JsonUtils jsonUtils;
2026

21-
/**
22-
* Constructor for PingEventPublisher.
23-
* @param mapUpdatesHandler the MapUpdatesHandler to publish to
24-
* @param jsonUtils the JsonUtils to use for serialization
25-
*/
26-
public PingEventPublisher(MapUpdatesHandler mapUpdatesHandler, JsonUtils jsonUtils) {
27-
this.mapUpdatesHandler = mapUpdatesHandler;
28-
this.jsonUtils = jsonUtils;
29-
}
30-
3127
/**
3228
* Handles PingCreated events.
3329
* @param event the PingCreated event
3430
*/
3531
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
36-
public void handlePingCreated(PingCreated event) {
37-
mapUpdatesHandler.sendMessage(jsonUtils.toJson(event));
32+
public void handlePingCreated(PingCreatedEvent event) {
33+
PingDTO pingDTO = pingMapper.toDTO(event.ping());
34+
mapUpdatesHandler.sendMessage(jsonUtils.toJson(pingDTO));
3835
}
3936

4037
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dev.luismachadoreis.flighttracker.server.ping.domain;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.time.Instant;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
class PingCreatedEventTest {
10+
11+
@Test
12+
void shouldCreatePingCreatedEvent() {
13+
// Given
14+
var aircraft = new Ping.Aircraft("ABC123", "FL123", "US", Instant.now(), "7700", true, new Integer[]{1, 2});
15+
var vector = new Ping.Vector(500.0, 180.0, 0.0);
16+
var position = new Ping.Position(10.0, 20.0, 30000.0, 29000.0, false, 1, Instant.now());
17+
var ping = new Ping(aircraft, vector, position);
18+
var timestamp = Instant.now();
19+
20+
// When
21+
var event = new PingCreatedEvent(ping, timestamp);
22+
23+
// Then
24+
assertThat(event.ping()).isEqualTo(ping);
25+
assertThat(event.timestamp()).isEqualTo(timestamp);
26+
}
27+
}

src/test/java/dev/luismachadoreis/flighttracker/server/ping/domain/PingTest.java

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package dev.luismachadoreis.flighttracker.server.ping.domain;
22

3-
import dev.luismachadoreis.flighttracker.server.ping.domain.event.PingCreated;
4-
import org.junit.jupiter.api.Test;
5-
import org.springframework.test.util.ReflectionTestUtils;
3+
import static org.assertj.core.api.Assertions.assertThat;
64

75
import java.time.Instant;
86
import java.util.Collection;
7+
import java.util.Optional;
98

10-
import static org.assertj.core.api.Assertions.assertThat;
9+
import org.junit.jupiter.api.Test;
10+
import org.springframework.test.util.ReflectionTestUtils;
1111

1212
class PingTest {
1313

@@ -42,24 +42,17 @@ void shouldRegisterPingCreatedEvent() {
4242

4343
// Then
4444
@SuppressWarnings("unchecked")
45-
Collection<Object> events = (Collection<Object>) ReflectionTestUtils.getField(ping, "domainEvents");
45+
var events = Optional.ofNullable(
46+
(Collection<Object>) ReflectionTestUtils.getField(ping, "domainEvents")
47+
).orElseThrow(() -> new IllegalStateException("Domain events collection is null"));
48+
4649
assertThat(events)
4750
.hasSize(1)
4851
.first()
49-
.isInstanceOf(PingCreated.class);
52+
.isInstanceOf(PingCreatedEvent.class);
5053

51-
var event = (PingCreated) events.iterator().next();
52-
assertThat(event.pingId()).isEqualTo(ping.getId());
53-
assertThat(event.icao24()).isEqualTo(aircraft.icao24());
54-
assertThat(event.callsign()).isEqualTo(aircraft.callsign());
55-
assertThat(event.latitude()).isEqualTo(position.latitude());
56-
assertThat(event.longitude()).isEqualTo(position.longitude());
57-
assertThat(event.trueTrack()).isEqualTo(vector.trueTrack());
58-
assertThat(event.geoAltitude()).isEqualTo(position.geoAltitude());
59-
assertThat(event.baroAltitude()).isEqualTo(position.baroAltitude());
60-
assertThat(event.onGround()).isEqualTo(position.onGround());
61-
assertThat(event.velocity()).isEqualTo(vector.velocity());
62-
assertThat(event.verticalRate()).isEqualTo(vector.verticalRate());
54+
var event = (PingCreatedEvent) events.stream().findFirst().orElseThrow(() -> new IllegalStateException("No event found"));
55+
assertThat(event.ping()).isEqualTo(ping);
6356
assertThat(event.timestamp()).isEqualTo(ping.getLastUpdate());
6457
}
6558
}

src/test/java/dev/luismachadoreis/flighttracker/server/ping/domain/event/PingCreatedTest.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)