Skip to content

Commit

Permalink
EnsembleTimer and Rotation now store Member objects instead of just M…
Browse files Browse the repository at this point in the history
…emberIds. This will make the Adapter transformers easier, since they won't have to keep fetching the Member objects from the MemberRepository every time they want to render the member's name.

This is OK from "don't hold onto one Aggregate from within another" as EnsembleTimer (and therefore Rotation) are transient Value Objects.
  • Loading branch information
tedyoung committed Mar 14, 2024
1 parent 315494f commit 25b3aa1
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public EnsembleService createEnsembleService(EnsembleRepository ensembleReposito
}

@Bean
public EnsembleTimerHolder createEnsembleTimerHolder(EnsembleRepository ensembleRepository, Broadcaster broadcaster) {
public EnsembleTimerHolder createEnsembleTimerHolder(EnsembleRepository ensembleRepository, MemberRepository memberRepository, Broadcaster broadcaster) {
return new EnsembleTimerHolder(ensembleRepository,
memberRepository,
broadcaster,
new ScheduledExecutorSecondsTicker());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public String viewTimer(@PathVariable("ensembleId") Long id, Model model) {
EnsembleTimer ensembleTimer = ensembleTimerHolder.timerFor(EnsembleId.of(id));
model.addAttribute("ensembleId", id);
model.addAttribute("ensembleName", ensembleTimer.ensembleName());
model.addAttribute("rolesToNames", ParticipantsTransformer.participantsToRolesAndNames(memberRepository, ensembleTimer));
model.addAttribute("rolesToNames", ParticipantsTransformer.participantsToRolesAndNames(ensembleTimer));
return "ensemble-timer";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
package com.jitterted.mobreg.adapter.in.web.admin;

import com.jitterted.mobreg.application.port.MemberRepository;
import com.jitterted.mobreg.domain.EnsembleTimer;
import com.jitterted.mobreg.domain.Member;
import com.jitterted.mobreg.domain.MemberId;
import com.jitterted.mobreg.domain.Rotation;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParticipantsTransformer {
public static Map<String, List<String>> participantsToRolesAndNames(MemberRepository memberRepository, EnsembleTimer ensembleTimer) {
public static Map<String, List<String>> participantsToRolesAndNames(EnsembleTimer ensembleTimer) {
Map<String, List<String>> rolesToNames = new HashMap<>();
Rotation rotation = ensembleTimer.rotation();
mapRoleToNames("Driver", List.of(rotation.driver()), rolesToNames, memberRepository);
mapRoleToNames("Navigator", List.of(rotation.navigator()), rolesToNames, memberRepository);
mapRoleToNames("Next Driver", List.of(rotation.nextDriver()), rolesToNames, memberRepository);
mapRoleToNames("Participant", rotation.restOfParticipants(), rolesToNames, memberRepository);
mapRoleToNames("Driver", List.of(rotation.driver()), rolesToNames);
mapRoleToNames("Navigator", List.of(rotation.navigator()), rolesToNames);
mapRoleToNames("Next Driver", List.of(rotation.nextDriver()), rolesToNames);
mapRoleToNames("Participant", rotation.restOfParticipants(), rolesToNames);
return rolesToNames;
}

private static void mapRoleToNames(String roleName,
List<MemberId> memberIds,
Map<String, List<String>> rolesToNames,
MemberRepository memberRepository) {
List<String> memberNames = memberIds.stream()
.map(memberId -> memberRepository
.findById(memberId)
.orElseThrow())
.map(Member::firstName)
.toList();
List<Member> members,
Map<String, List<String>> rolesToNames) {
List<String> memberNames = members.stream()
.map(Member::firstName)
.toList();
rolesToNames.put(roleName, memberNames);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,38 @@

import com.jitterted.mobreg.application.port.Broadcaster;
import com.jitterted.mobreg.application.port.EnsembleRepository;
import com.jitterted.mobreg.application.port.MemberRepository;
import com.jitterted.mobreg.application.port.SecondsTicker;
import com.jitterted.mobreg.domain.Ensemble;
import com.jitterted.mobreg.domain.EnsembleId;
import com.jitterted.mobreg.domain.EnsembleTimer;
import com.jitterted.mobreg.domain.Member;
import org.jetbrains.annotations.NotNull;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;

public class EnsembleTimerHolder implements EnsembleTimerTickHandler {
private final EnsembleRepository ensembleRepository;
private final MemberRepository memberRepository;
private final Broadcaster broadcaster;
private final SingleEntryHashMap<EnsembleId, EnsembleTimer> ensembleTimers = new SingleEntryHashMap<>();
private final SecondsTicker secondsTicker;

public EnsembleTimerHolder(EnsembleRepository ensembleRepository, Broadcaster broadcaster, SecondsTicker secondsTicker) {
public EnsembleTimerHolder(EnsembleRepository ensembleRepository,
MemberRepository memberRepository,
Broadcaster broadcaster,
SecondsTicker secondsTicker) {
this.ensembleRepository = ensembleRepository;
this.memberRepository = memberRepository;
this.broadcaster = broadcaster;
this.secondsTicker = secondsTicker;
}

public static EnsembleTimerHolder createNull(EnsembleRepository ensembleRepository) {
public static EnsembleTimerHolder createNull(EnsembleRepository ensembleRepository, MemberRepository memberRepository) {
return new EnsembleTimerHolder(ensembleRepository,
memberRepository,
ensembleTimer -> {},
new DoNothingSecondsTicker());
}
Expand All @@ -43,12 +52,18 @@ public EnsembleTimer createTimerFor(EnsembleId ensembleId) {
.orElseThrow();
EnsembleTimer ensembleTimer = new EnsembleTimer(ensembleId,
ensemble.name(),
ensemble.participants().toList());
membersFrom(ensemble));
ensembleTimers.put(ensembleId, ensembleTimer);
broadcaster.sendCurrentTimer(ensembleTimer);
return ensembleTimer;
}

private List<Member> membersFrom(Ensemble ensemble) {
return ensemble.participants()
.map(memberId -> memberRepository.findById(memberId).orElseThrow())
.toList();
}

public boolean hasTimerFor(EnsembleId ensembleId) {
return ensembleTimers.containsKey(ensembleId);
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/jitterted/mobreg/domain/EnsembleTimer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class EnsembleTimer {

private final EnsembleId ensembleId;
private final String ensembleName;
private final List<MemberId> participants;
private final List<Member> participants;
private final Rotation rotation;

private TimerState currentState;
Expand All @@ -23,27 +23,27 @@ public class EnsembleTimer {

public EnsembleTimer(EnsembleId ensembleId,
String ensembleName,
List<MemberId> participants) {
List<Member> participants) {
this(ensembleId, ensembleName, participants, DEFAULT_TIMER_DURATION);
}

public EnsembleTimer(EnsembleId ensembleId,
String ensembleName,
List<MemberId> participants,
List<Member> participants,
Duration timerDuration) {
this.ensembleId = ensembleId;
this.ensembleName = ensembleName;
this.participants = participants;
this.timerDuration = timerDuration;
this.currentState = TimerState.WAITING_TO_START;
rotation = new Rotation(participants);
this.rotation = new Rotation(participants);
}

public EnsembleId ensembleId() {
return ensembleId;
}

public Stream<MemberId> participants() {
public Stream<Member> participants() {
return participants.stream();
}

Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/jitterted/mobreg/domain/Rotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@

@SuppressWarnings("SequencedCollectionMethodCanBeUsed")
public class Rotation {
private final List<MemberId> participants;
private final List<Member> participants;

public Rotation(List<MemberId> participants) {
public Rotation(List<Member> participants) {
requireThreeOrMoreParticipants(participants);
this.participants = new ArrayList<>(participants);
}

private void requireThreeOrMoreParticipants(List<MemberId> participants) {
private void requireThreeOrMoreParticipants(List<Member> participants) {
if (participants.size() < 3) {
throw new NotEnoughParticipants("%d is too few participants, requires minimum of 3 participants."
.formatted(participants.size()));
}
}

public MemberId nextDriver() {
public Member nextDriver() {
return participants.get(0);
}

public MemberId driver() {
public Member driver() {
return participants.get(1);
}

public MemberId navigator() {
public Member navigator() {
return participants.get(2);
}

public List<MemberId> restOfParticipants() {
public List<Member> restOfParticipants() {
return participants.stream().skip(3).toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public EnsembleService createEnsembleService(EnsembleRepository ensembleReposito
}

@Bean
public EnsembleTimerHolder createEnsembleTimerHolder(EnsembleRepository ensembleRepository) {
public EnsembleTimerHolder createEnsembleTimerHolder(EnsembleRepository ensembleRepository, MemberRepository memberRepository) {
// TODO: enable real broadcaster when feature is ready
return EnsembleTimerHolder.createNull(ensembleRepository);
return EnsembleTimerHolder.createNull(ensembleRepository, memberRepository);
}

// TODO: remove this once member registration works
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.jitterted.mobreg.application.EnsembleTimerHolder;
import com.jitterted.mobreg.application.TestEnsembleServiceBuilder;
import com.jitterted.mobreg.application.port.EnsembleRepository;
import com.jitterted.mobreg.application.port.MemberRepository;
import com.jitterted.mobreg.domain.Ensemble;
import com.jitterted.mobreg.domain.EnsembleBuilder;
import com.jitterted.mobreg.domain.EnsembleId;
Expand Down Expand Up @@ -36,6 +37,9 @@ class EnsembleTimerControllerMvcTest {
@Autowired
EnsembleRepository ensembleRepository;

@Autowired
MemberRepository memberRepository;

@Autowired
EnsembleTimerHolder ensembleTimerHolder;

Expand Down Expand Up @@ -85,6 +89,7 @@ private void createAndSaveEnsembleInRepositoryForId(long ensembleId) {
.build();
new TestEnsembleServiceBuilder()
.withEnsembleRepository(ensembleRepository)
.withMemberRepository(memberRepository)
.saveEnsemble(ensemble)
.withThreeParticipants();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.jitterted.mobreg.domain.EnsembleId;
import com.jitterted.mobreg.domain.EnsembleTimer;
import com.jitterted.mobreg.domain.EnsembleTimerFactory;
import com.jitterted.mobreg.domain.MemberId;
import com.jitterted.mobreg.domain.Member;
import org.junit.jupiter.api.Test;
import org.springframework.ui.ConcurrentModel;
import org.springframework.ui.Model;
Expand All @@ -30,7 +30,7 @@ void createAndRedirectToTimerSessionForSpecificEnsemble() {
TestEnsembleServiceBuilder builder = new TestEnsembleServiceBuilder()
.saveEnsemble(ensemble)
.withThreeParticipants();
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository());
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository(), builder.memberRepository());
EnsembleTimerController ensembleTimerController = new EnsembleTimerController(ensembleTimerHolder, new InMemoryMemberRepository());

String redirectPage = ensembleTimerController.createTimerView(87L);
Expand All @@ -49,7 +49,7 @@ void viewTimerHasParticipantsInTheViewModelFromTheSpecifiedEnsembleAndTimerNotSt
.saveMemberAndAccept("Jane", "ghjane")
.saveMemberAndAccept("Paul", "ghpaul")
.saveMemberAndAccept("Sally", "ghsally");
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository());
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository(), builder.memberRepository());
EnsembleTimerController ensembleTimerController = new EnsembleTimerController(ensembleTimerHolder, builder.memberRepository());
ensembleTimerController.createTimerView(153L);

Expand All @@ -64,7 +64,6 @@ void viewTimerHasParticipantsInTheViewModelFromTheSpecifiedEnsembleAndTimerNotSt
assertThat((Map<String, List<String>>) model.getAttribute("rolesToNames"))
.containsExactlyInAnyOrderEntriesOf(
ParticipantsTransformer.participantsToRolesAndNames(
builder.memberRepository(),
ensembleTimerHolder.timerFor(EnsembleId.of(153))));
assertThat(ensembleTimerHolder.isTimerRunningFor(EnsembleId.of(153L)))
.isFalse();
Expand All @@ -78,7 +77,7 @@ void startTimerStartsTheSpecifiedEnsembleTimer() {
TestEnsembleServiceBuilder builder = new TestEnsembleServiceBuilder()
.saveEnsemble(ensemble)
.withThreeParticipants();
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository());
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository(), builder.memberRepository());
EnsembleTimerController ensembleTimerController = new EnsembleTimerController(ensembleTimerHolder, new InMemoryMemberRepository());
ensembleTimerController.createTimerView(279L);

Expand All @@ -96,9 +95,9 @@ public void rotateTimerRotatesParticipantsForFinishedEnsembleTimer() throws Exce
TestEnsembleServiceBuilder builder = new TestEnsembleServiceBuilder()
.saveEnsemble(ensemble)
.withThreeParticipants();
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository());
EnsembleTimerHolder ensembleTimerHolder = EnsembleTimerHolder.createNull(builder.ensembleRepository(), builder.memberRepository());
EnsembleTimer ensembleTimer = ensembleTimerHolder.createTimerFor(EnsembleId.of(279));
MemberId nextDriverBeforeRotation = ensembleTimer.rotation().nextDriver();
Member nextDriverBeforeRotation = ensembleTimer.rotation().nextDriver();
EnsembleTimerFactory.pushTimerToFinishedState(ensembleTimer);
EnsembleTimerController ensembleTimerController = new EnsembleTimerController(ensembleTimerHolder, new InMemoryMemberRepository());

Expand Down
Loading

0 comments on commit 25b3aa1

Please sign in to comment.