Skip to content

Commit f0bd796

Browse files
✨ feat: handle gameId on metadata level (#11)
1 parent a49c648 commit f0bd796

19 files changed

Lines changed: 171 additions & 44 deletions

File tree

.github/workflows/maven.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ on:
99
pull_request:
1010
branches: [ "master" ]
1111

12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
14+
cancel-in-progress: true
15+
1216
jobs:
1317
build:
1418

1519
runs-on: ubuntu-latest
1620

21+
timeout-minutes: 10
22+
1723
steps:
1824
- name: 🛎️ Checkout repository
1925
uses: actions/checkout@v4
@@ -31,8 +37,8 @@ jobs:
3137
- name: 🧪 Run tests
3238
run: mvn -B test --file pom.xml
3339

34-
- name: 📦 Package application
35-
run: mvn -B package --file pom.xml
40+
# - name: 📦 Package application
41+
# run: mvn -B package --file pom.xml
3642

3743
# Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
3844
# - name: 📈 Update dependency graph

src/main/java/com/dddheroes/heroesofddd/astrologers/automation/whenweekstartedthenproclaimweeksymbol/WhenWeekStartedThenProclaimWeekSymbolProcessor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@
44
import com.dddheroes.heroesofddd.astrologers.write.MonthWeek;
55
import com.dddheroes.heroesofddd.astrologers.write.proclaimweeksymbol.ProclaimWeekSymbol;
66
import com.dddheroes.heroesofddd.calendar.write.startday.DayStarted;
7+
import com.dddheroes.heroesofddd.shared.GameMetaData;
78
import org.axonframework.commandhandling.gateway.CommandGateway;
89
import org.axonframework.config.ProcessingGroup;
910
import org.axonframework.eventhandling.DisallowReplay;
1011
import org.axonframework.eventhandling.EventHandler;
12+
import org.axonframework.messaging.annotation.MetaDataValue;
1113
import org.springframework.stereotype.Component;
1214

1315
@ProcessingGroup("Automation_WhenWeekStartedThenProclaimWeekSymbol_Processor")
1416
@DisallowReplay
1517
@Component
1618
class WhenWeekStartedThenProclaimWeekSymbolProcessor {
1719

20+
public static final int FIRST_DAY_OF_THE_WEEK = 1;
21+
1822
private final CommandGateway commandGateway;
1923
private final WeekSymbolCalculator weekSymbolCalculator;
2024

@@ -27,8 +31,8 @@ class WhenWeekStartedThenProclaimWeekSymbolProcessor {
2731
}
2832

2933
@EventHandler
30-
void react(DayStarted event) {
31-
var isWeekStarted = event.day() == 1;
34+
void react(DayStarted event, @MetaDataValue(GameMetaData.KEY) String gameId) {
35+
var isWeekStarted = event.day() == FIRST_DAY_OF_THE_WEEK;
3236
if (isWeekStarted) {
3337
var weekSymbol = weekSymbolCalculator.apply(MonthWeek.of(event.month(), event.week()));
3438
var command = ProclaimWeekSymbol.command(
@@ -38,7 +42,7 @@ void react(DayStarted event) {
3842
weekSymbol.weekOf().raw(),
3943
weekSymbol.growth()
4044
);
41-
commandGateway.sendAndWait(command);
45+
commandGateway.sendAndWait(command, GameMetaData.withId(gameId));
4246
}
4347
}
4448
}

src/main/java/com/dddheroes/heroesofddd/astrologers/automation/whenweeksymbolproclaimedthenincreasedwellingavailablecreatures/WhenWeekSymbolProclaimedThenIncreaseDwellingAvailableCreaturesProcessor.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import com.dddheroes.heroesofddd.creaturerecruitment.read.DwellingReadModel;
55
import com.dddheroes.heroesofddd.creaturerecruitment.read.getalldwellings.GetAllDwellings;
66
import com.dddheroes.heroesofddd.creaturerecruitment.write.changeavailablecreatures.IncreaseAvailableCreatures;
7+
import com.dddheroes.heroesofddd.shared.GameMetaData;
78
import org.axonframework.commandhandling.gateway.CommandGateway;
89
import org.axonframework.config.ProcessingGroup;
910
import org.axonframework.eventhandling.DisallowReplay;
1011
import org.axonframework.eventhandling.EventHandler;
12+
import org.axonframework.messaging.annotation.MetaDataValue;
1113
import org.axonframework.queryhandling.QueryGateway;
1214
import org.springframework.stereotype.Component;
1315

@@ -28,14 +30,14 @@ class WhenWeekSymbolProclaimedThenIncreaseDwellingAvailableCreaturesProcessor {
2830
}
2931

3032
@EventHandler
31-
void react(WeekSymbolProclaimed event) {
33+
void react(WeekSymbolProclaimed event, @MetaDataValue(GameMetaData.KEY) String gameId) {
3234
// todo: separate dwelling per game. Now we read all of them
3335
// I want be consistent here. With DBC it'd be nice to query all types and by tags like game.
3436
// use EventStore, @SequenceNumber long sequenceNumber
3537

3638
var creature = event.weekOf();
3739
var increaseBy = event.growth();
38-
var toProcess = queryGateway.query(GetAllDwellings.query(), GetAllDwellings.Result.class);
40+
var toProcess = queryGateway.query(GetAllDwellings.query(gameId), GetAllDwellings.Result.class);
3941
toProcess.thenAccept(r -> r.dwellings()
4042
.stream().filter(dwelling -> dwelling.getCreatureId().equals(creature))
4143
.forEach(dwelling -> increaseAvailableCreatures(dwelling, increaseBy)));
@@ -47,6 +49,6 @@ private void increaseAvailableCreatures(DwellingReadModel dwelling, Integer incr
4749
dwelling.getCreatureId(),
4850
increaseBy
4951
);
50-
commandGateway.sendAndWait(command);
52+
commandGateway.sendAndWait(command, GameMetaData.withId(dwelling.getGameId()));
5153
}
5254
}

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/automation/WhenCreatureRecruitedThenAddToArmyProcessor.java

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

33
import com.dddheroes.heroesofddd.armies.write.addcreature.AddCreatureToArmy;
44
import com.dddheroes.heroesofddd.creaturerecruitment.write.recruitcreature.CreatureRecruited;
5+
import com.dddheroes.heroesofddd.shared.GameMetaData;
56
import org.axonframework.commandhandling.gateway.CommandGateway;
67
import org.axonframework.config.ProcessingGroup;
78
import org.axonframework.eventhandling.DisallowReplay;
89
import org.axonframework.eventhandling.EventHandler;
10+
import org.axonframework.messaging.annotation.MetaDataValue;
911
import org.springframework.stereotype.Component;
1012

1113
@ProcessingGroup("Automation_WhenCreatureRecruitedThenAddToArmy_Processor")
@@ -20,13 +22,13 @@ class WhenCreatureRecruitedThenAddToArmyProcessor {
2022
}
2123

2224
@EventHandler
23-
void react(CreatureRecruited event) {
25+
void react(CreatureRecruited event, @MetaDataValue(GameMetaData.KEY) String gameId) {
2426
var command = AddCreatureToArmy.command(
2527
event.toArmy(),
2628
event.creatureId(),
2729
event.quantity()
2830
);
2931

30-
commandGateway.sendAndWait(command);
32+
commandGateway.sendAndWait(command, GameMetaData.withId(gameId));
3133
}
3234
}

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/read/DwellingReadModel.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import jakarta.persistence.Column;
44
import jakarta.persistence.Entity;
55
import jakarta.persistence.Id;
6+
import jakarta.persistence.Index;
67
import jakarta.persistence.Table;
78
import org.hibernate.annotations.JdbcTypeCode;
89
import org.hibernate.type.SqlTypes;
@@ -11,9 +12,11 @@
1112
import java.util.Objects;
1213

1314
@Entity
14-
@Table(name = "read_model_dwelling")
15+
@Table(name = "read_model_dwelling", indexes = @Index(name = "idx_game_id", columnList = "gameId"))
1516
public class DwellingReadModel {
1617

18+
private String gameId;
19+
1720
@Id
1821
private String dwellingId;
1922

@@ -25,11 +28,14 @@ public class DwellingReadModel {
2528

2629
private Integer availableCreatures;
2730

28-
public DwellingReadModel(String dwellingId,
29-
String creatureId,
30-
Map<String, Integer> costPerTroop,
31-
Integer availableCreatures
31+
public DwellingReadModel(
32+
String gameId,
33+
String dwellingId,
34+
String creatureId,
35+
Map<String, Integer> costPerTroop,
36+
Integer availableCreatures
3237
) {
38+
this.gameId = gameId;
3339
this.dwellingId = dwellingId;
3440
this.creatureId = creatureId;
3541
this.costPerTroop = costPerTroop;
@@ -46,6 +52,10 @@ DwellingReadModel withAvailableCreaturesDecreasedBy(Integer decreasedBy) {
4652
return this;
4753
}
4854

55+
public String getGameId() {
56+
return gameId;
57+
}
58+
4959
public String getDwellingId() {
5060
return dwellingId;
5161
}

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/read/DwellingReadModelProjector.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.dddheroes.heroesofddd.creaturerecruitment.write.builddwelling.DwellingBuilt;
44
import com.dddheroes.heroesofddd.creaturerecruitment.write.changeavailablecreatures.AvailableCreaturesChanged;
55
import com.dddheroes.heroesofddd.creaturerecruitment.write.recruitcreature.CreatureRecruited;
6+
import com.dddheroes.heroesofddd.shared.GameMetaData;
67
import org.axonframework.config.ProcessingGroup;
78
import org.axonframework.eventhandling.EventHandler;
9+
import org.axonframework.messaging.annotation.MetaDataValue;
810
import org.springframework.stereotype.Component;
911

1012
@ProcessingGroup("ReadModel_Dwelling")
@@ -18,8 +20,9 @@ class DwellingReadModelProjector {
1820
}
1921

2022
@EventHandler
21-
void on(DwellingBuilt event) {
23+
void on(DwellingBuilt event, @MetaDataValue(GameMetaData.KEY) String gameId) {
2224
var state = new DwellingReadModel(
25+
gameId,
2326
event.dwellingId(),
2427
event.creatureId(),
2528
event.costPerTroop(),

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/read/DwellingReadModelRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import org.springframework.data.jpa.repository.JpaRepository;
44
import org.springframework.stereotype.Repository;
55

6+
import java.util.List;
7+
68
@Repository
79
public interface DwellingReadModelRepository extends JpaRepository<DwellingReadModel, String> {
810

11+
List<DwellingReadModel> findAllByGameId(String gameId);
12+
913
}

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/read/getalldwellings/GetAllDwellings.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.dddheroes.heroesofddd.creaturerecruitment.read.getalldwellings;
22

33
import com.dddheroes.heroesofddd.creaturerecruitment.read.DwellingReadModel;
4+
import com.dddheroes.heroesofddd.shared.GameId;
45

56
import java.util.List;
67

7-
public record GetAllDwellings() {
8+
public record GetAllDwellings(GameId gameId) {
89

9-
public static GetAllDwellings query() {
10-
return new GetAllDwellings();
10+
public static GetAllDwellings query(String gameId) {
11+
return new GetAllDwellings(GameId.of(gameId));
1112
}
1213

1314
public record Result(List<DwellingReadModel> dwellings) {

src/main/java/com/dddheroes/heroesofddd/creaturerecruitment/read/getalldwellings/GetAllDwellingsQueryHandler.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import com.dddheroes.heroesofddd.creaturerecruitment.read.DwellingReadModel;
44
import com.dddheroes.heroesofddd.creaturerecruitment.read.DwellingReadModelRepository;
55
import com.dddheroes.heroesofddd.creaturerecruitment.write.builddwelling.DwellingBuilt;
6+
import com.dddheroes.heroesofddd.shared.GameMetaData;
67
import com.google.common.collect.Streams;
78
import org.axonframework.config.ProcessingGroup;
89
import org.axonframework.eventhandling.EventHandler;
10+
import org.axonframework.messaging.annotation.MetaDataValue;
911
import org.axonframework.queryhandling.QueryHandler;
1012
import org.springframework.stereotype.Component;
1113

@@ -24,20 +26,30 @@ class GetAllDwellingsQueryHandler {
2426

2527
@QueryHandler
2628
GetAllDwellings.Result handle(GetAllDwellings query) {
27-
var dwellings = dwellingReadModelRepository.findAll();
28-
var result = Streams.concat(dwellings.stream(), cache.stream()) // todo: check ordering
29+
var gameId = query.gameId().raw();
30+
var dwellings = dwellingReadModelRepository.findAllByGameId(gameId);
31+
var result = Streams.concat(
32+
dwellings.stream(),
33+
cache.stream().filter(it -> it.getGameId().equals(gameId))
34+
) // todo: check ordering
2935
.distinct()
3036
.toList();
3137
return new GetAllDwellings.Result(result);
3238
}
3339

3440
@EventHandler
35-
void evolve(DwellingBuilt event) {
41+
void evolve(DwellingBuilt event, @MetaDataValue(GameMetaData.KEY) String gameId) {
3642
while (cache.size() > 20) {
3743
cache.pollFirst();
3844
}
39-
var item = new DwellingReadModel(event.dwellingId(), event.creatureId(), event.costPerTroop(), 0);
40-
if (!cache.contains(item)) { // todo: check concurrency issues
45+
var item = new DwellingReadModel(
46+
gameId,
47+
event.dwellingId(),
48+
event.creatureId(),
49+
event.costPerTroop(),
50+
0
51+
);
52+
if (!cache.contains(item)) { // todo: check if there are any concurrency issues
4153
cache.push(item);
4254
}
4355
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.dddheroes.heroesofddd.creaturerecruitment.read.getdwellingbyid;
22

33
import com.dddheroes.heroesofddd.creaturerecruitment.write.DwellingId;
4+
import com.dddheroes.heroesofddd.shared.GameId;
45

5-
public record GetDwellingById(DwellingId dwellingId) {
6+
public record GetDwellingById(GameId gameId, DwellingId dwellingId) {
67

7-
public static GetDwellingById query(String dwellingId) {
8-
return new GetDwellingById(DwellingId.of(dwellingId));
8+
public static GetDwellingById query(String gameId, String dwellingId) {
9+
return new GetDwellingById(GameId.of(gameId), DwellingId.of(dwellingId));
910
}
1011

1112
}

0 commit comments

Comments
 (0)