Skip to content

Commit a5341a8

Browse files
✨ feat: Calendar | write slices: StartDay and FinishDay (#6)
1 parent 6262dc2 commit a5341a8

16 files changed

Lines changed: 513 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
import com.dddheroes.heroesofddd.calendar.write.finishday.CanOnlyFinishCurrentDay;
4+
import com.dddheroes.heroesofddd.calendar.write.finishday.DayFinished;
5+
import com.dddheroes.heroesofddd.calendar.write.finishday.FinishDay;
6+
import com.dddheroes.heroesofddd.calendar.write.startday.CannotSkipDays;
7+
import com.dddheroes.heroesofddd.calendar.write.startday.DayStarted;
8+
import com.dddheroes.heroesofddd.calendar.write.startday.StartDay;
9+
import org.axonframework.commandhandling.CommandHandler;
10+
import org.axonframework.eventsourcing.EventSourcingHandler;
11+
import org.axonframework.modelling.command.AggregateCreationPolicy;
12+
import org.axonframework.modelling.command.AggregateIdentifier;
13+
import org.axonframework.modelling.command.CreationPolicy;
14+
import org.axonframework.spring.stereotype.Aggregate;
15+
16+
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
17+
18+
@Aggregate
19+
class Calendar {
20+
21+
@AggregateIdentifier
22+
private CalendarId calendarId;
23+
private Month currentMonth;
24+
private Week currentWeek;
25+
private Day currentDay;
26+
27+
@CommandHandler
28+
@CreationPolicy(AggregateCreationPolicy.CREATE_IF_MISSING)
29+
// performance downside in comparison to constructor
30+
void handle(StartDay command) {
31+
new CannotSkipDays(command, currentMonth, currentWeek, currentDay).verify();
32+
33+
apply(
34+
DayStarted.event(
35+
command.calendarId(),
36+
command.month(),
37+
command.week(),
38+
command.day()
39+
)
40+
);
41+
}
42+
43+
@EventSourcingHandler
44+
void on(DayStarted event) {
45+
calendarId = new CalendarId(event.calendarId());
46+
currentMonth = new Month(event.month());
47+
currentWeek = new Week(event.week());
48+
currentDay = new Day(event.day());
49+
}
50+
51+
@CommandHandler
52+
void handle(FinishDay command) {
53+
new CanOnlyFinishCurrentDay(command, currentMonth, currentWeek, currentDay).verify();
54+
55+
apply(
56+
DayFinished.event(
57+
command.calendarId(),
58+
command.month(),
59+
command.week(),
60+
command.day()
61+
)
62+
);
63+
}
64+
65+
Calendar() {
66+
// required by Axon
67+
}
68+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
public interface CalendarCommand {
4+
5+
CalendarId calendarId();
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
public interface CalendarEvent {
4+
5+
String calendarId();
6+
7+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
import java.util.UUID;
4+
5+
public record CalendarId(String raw) {
6+
7+
public CalendarId {
8+
if (raw == null || raw.isBlank()) {
9+
throw new IllegalArgumentException("Calendar id cannot be null or empty");
10+
}
11+
}
12+
13+
public static CalendarId of(String raw) {
14+
return new CalendarId(raw);
15+
}
16+
17+
public static CalendarId random() {
18+
return new CalendarId(UUID.randomUUID().toString());
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return raw;
24+
}
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
public record Day(Integer raw) {
4+
5+
public Day {
6+
if (raw == null || raw < 1 || raw > 7) {
7+
throw new IllegalArgumentException("Day must be between 1 and 7");
8+
}
9+
}
10+
11+
public static Day of(Integer raw) {
12+
return new Day(raw);
13+
}
14+
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
public record Month(Integer raw) {
4+
5+
public Month {
6+
if (raw == null || raw < 1) {
7+
throw new IllegalArgumentException("Month must be greater than 0");
8+
}
9+
}
10+
11+
public static Month of(Integer raw) {
12+
return new Month(raw);
13+
}
14+
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.dddheroes.heroesofddd.calendar.write;
2+
3+
public record Week(Integer raw) {
4+
5+
public Week {
6+
if (raw == null || raw < 1 || raw > 4) {
7+
throw new IllegalArgumentException("Week must be between 1 and 4");
8+
}
9+
}
10+
11+
public static Week of(Integer raw) {
12+
return new Week(raw);
13+
}
14+
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.dddheroes.heroesofddd.calendar.write.finishday;
2+
3+
import com.dddheroes.heroesofddd.calendar.write.Day;
4+
import com.dddheroes.heroesofddd.calendar.write.Month;
5+
import com.dddheroes.heroesofddd.calendar.write.Week;
6+
import com.dddheroes.heroesofddd.shared.DomainRule;
7+
8+
public record CanOnlyFinishCurrentDay(
9+
FinishDay command,
10+
Month currentMonth,
11+
Week currentWeek,
12+
Day currentDay
13+
) implements DomainRule {
14+
15+
@Override
16+
public boolean isViolated() {
17+
boolean isCurrentDay = command.month().equals(currentMonth)
18+
&& command.week().equals(currentWeek)
19+
&& command.day().equals(currentDay);
20+
return !isCurrentDay;
21+
}
22+
23+
@Override
24+
public String message() {
25+
return "Can only finish current day";
26+
}
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.dddheroes.heroesofddd.calendar.write.finishday;
2+
3+
import com.dddheroes.heroesofddd.calendar.write.CalendarEvent;
4+
import com.dddheroes.heroesofddd.calendar.write.CalendarId;
5+
import com.dddheroes.heroesofddd.calendar.write.Day;
6+
import com.dddheroes.heroesofddd.calendar.write.Month;
7+
import com.dddheroes.heroesofddd.calendar.write.Week;
8+
9+
public record DayFinished(
10+
String calendarId,
11+
Integer month,
12+
Integer week,
13+
Integer day
14+
) implements CalendarEvent {
15+
16+
public static DayFinished event(CalendarId calendarId, Month month, Week week, Day day) {
17+
return new DayFinished(calendarId.raw(), month.raw(), week.raw(), day.raw());
18+
}
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.dddheroes.heroesofddd.calendar.write.finishday;
2+
3+
import com.dddheroes.heroesofddd.calendar.write.CalendarCommand;
4+
import com.dddheroes.heroesofddd.calendar.write.CalendarId;
5+
import com.dddheroes.heroesofddd.calendar.write.Day;
6+
import com.dddheroes.heroesofddd.calendar.write.Month;
7+
import com.dddheroes.heroesofddd.calendar.write.Week;
8+
import org.axonframework.modelling.command.TargetAggregateIdentifier;
9+
10+
public record FinishDay(
11+
@TargetAggregateIdentifier
12+
CalendarId calendarId,
13+
Month month,
14+
Week week,
15+
Day day
16+
) implements CalendarCommand {
17+
18+
public static FinishDay command(String calendarId, Integer month, Integer week, Integer day) {
19+
return new FinishDay(CalendarId.of(calendarId), Month.of(month), Week.of(week), Day.of(day));
20+
}
21+
}

0 commit comments

Comments
 (0)