Compare commits

...

15 Commits

22 changed files with 214 additions and 88 deletions

View File

@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Database Container" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="sourceFilePath" value="src/main/resources/compose.yaml" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

8
.run/Set up DB.run.xml Normal file
View File

@@ -0,0 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Set up DB" type="DatabaseScript">
<script-file value="$PROJECT_DIR$/build/generated/sources/annotationProcessor/java/main/ddl_Team.sql" />
<script-mode>FILE</script-mode>
<data-source id="0d777779-ef1b-44ea-a12b-5ae628beebd4" namespace="schema/&quot;jpa&quot;" />
<method v="2" />
</configuration>
</component>

View File

@@ -11,6 +11,7 @@
<method v="2"> <method v="2">
<option name="RunConfigurationTask" enabled="false" run_configuration_name="Database Container" run_configuration_type="docker-deploy" /> <option name="RunConfigurationTask" enabled="false" run_configuration_name="Database Container" run_configuration_type="docker-deploy" />
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Set up DB" run_configuration_type="DatabaseScript" />
</method> </method>
</configuration> </configuration>
</component> </component>

View File

@@ -3,10 +3,12 @@ package de.pnreichmuth.timekeep_backend.controllers;
import de.pnreichmuth.timekeep_backend.entities.Racer; import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.entities.Team; import de.pnreichmuth.timekeep_backend.entities.Team;
import de.pnreichmuth.timekeep_backend.exceptions.RacerExistsException; import de.pnreichmuth.timekeep_backend.exceptions.RacerExistsException;
import de.pnreichmuth.timekeep_backend.exceptions.RacerNotFoundException;
import de.pnreichmuth.timekeep_backend.exceptions.TeamNotFoundException; import de.pnreichmuth.timekeep_backend.exceptions.TeamNotFoundException;
import de.pnreichmuth.timekeep_backend.services.RacerService; import de.pnreichmuth.timekeep_backend.services.RacerService;
import de.pnreichmuth.timekeep_backend.services.TeamService; import de.pnreichmuth.timekeep_backend.services.TeamService;
import de.pnreichmuth.timekeep_backend.wsto.RacerWSTO; import de.pnreichmuth.timekeep_backend.wsto.RacerWSTO;
import de.pnreichmuth.timekeep_backend.wsto.TeamWSTO;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -16,7 +18,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.UUID;
@RestController @RestController
@RequestMapping("/racers") @RequestMapping("/racers")
@@ -28,7 +29,8 @@ public class RacerRestController {
private final TeamService teamService; private final TeamService teamService;
// ///////////////////////////////////////////////BEGIN POST MAPPINGS/////////////////////////////////////////////////// // ///////////////////////////////////////////////BEGIN POST MAPPINGS///////////////////////////////////////////////////
@PostMapping("createRacer") @PostMapping("createRacer")
public ResponseEntity<@NonNull RacerWSTO> createRacer(@RequestBody Racer racer) { public ResponseEntity<@NonNull RacerWSTO> createRacer(@RequestBody RacerWSTO racerWSTO) {
Racer racer = RacerWSTO.toEntity(racerWSTO);
try { try {
racerService.updateRacer(racer); racerService.updateRacer(racer);
return new ResponseEntity<>(RacerWSTO.of(racer), HttpStatus.CREATED); return new ResponseEntity<>(RacerWSTO.of(racer), HttpStatus.CREATED);
@@ -49,31 +51,28 @@ public class RacerRestController {
} }
@GetMapping("singleRacer") @GetMapping("singleRacer")
public ResponseEntity<@NonNull RacerWSTO> getSingleRacers(@RequestParam Racer requestRacer){ public ResponseEntity<@NonNull RacerWSTO> getSingleRacers(@RequestBody RacerWSTO requestRacerWSTO){
Racer actualRacer = racerService.getRacer(requestRacer.getFirstName(), requestRacer.getLastName()); try{
if (actualRacer == null){ Racer actualRacer = racerService.getRacer(RacerWSTO.toEntity(requestRacerWSTO));
return ResponseEntity.of(
ProblemDetail.forStatusAndDetail(
HttpStatus.NOT_FOUND,
String.format("Racer with name %s %s not found",
requestRacer.getFirstName(), requestRacer.getLastName()
)
)
).build();
}
return ResponseEntity.ok(RacerWSTO.of(actualRacer)); return ResponseEntity.ok(RacerWSTO.of(actualRacer));
} }
catch (RacerNotFoundException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage())).build();
}
catch (IllegalArgumentException e) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build();
}
}
@GetMapping("byTeam") @GetMapping("byTeam")
public ResponseEntity<@NonNull List<RacerWSTO>> getByTeam(@RequestParam Team requestTeam){ public ResponseEntity<@NonNull List<RacerWSTO>> getByTeam(@RequestBody TeamWSTO requestTeamWSTO){
UUID teamID = requestTeam.getId();
String teamName = requestTeam.getTeamName();
Team dbTeam; Team dbTeam;
try { try {
if (teamID != null) dbTeam = teamService.getTeam(teamID); dbTeam = teamService.getTeam(TeamWSTO.toEntity(requestTeamWSTO));
else if (teamName != null) dbTeam = teamService.getTeam(teamName);
else return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "Must provide either id or name")).build();
} catch (TeamNotFoundException e) { } catch (TeamNotFoundException e) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage())).build();
}
catch (IllegalArgumentException e) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build(); return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build();
} }
List<RacerWSTO> returnList = List.copyOf(dbTeam.getMembers().stream().map(RacerWSTO::of).toList()); List<RacerWSTO> returnList = List.copyOf(dbTeam.getMembers().stream().map(RacerWSTO::of).toList());
@@ -81,6 +80,18 @@ public class RacerRestController {
} }
// ////////////////////////////////////////////////BEGIN DELETE MAPPINGS/////////////////////////////////////////////////// // ////////////////////////////////////////////////BEGIN DELETE MAPPINGS///////////////////////////////////////////////////
@DeleteMapping("/removeRacer")
public ResponseEntity<?> removeRacer(@RequestBody RacerWSTO racerWSTO){
Racer racer = RacerWSTO.toEntity(racerWSTO);
try {
racerService.deleteRacer(racer);
return ResponseEntity.ok(racer);
}
catch (IllegalArgumentException e) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build();
} catch (RacerNotFoundException e) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage())).build();
}
}
} }

View File

@@ -0,0 +1,59 @@
package de.pnreichmuth.timekeep_backend.controllers;
import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.entities.Team;
import de.pnreichmuth.timekeep_backend.exceptions.ExistsException;
import de.pnreichmuth.timekeep_backend.exceptions.NotFoundException;
import de.pnreichmuth.timekeep_backend.services.TeamService;
import de.pnreichmuth.timekeep_backend.wsto.RacerWSTO;
import de.pnreichmuth.timekeep_backend.wsto.TeamWSTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/members")
@Slf4j
@RequiredArgsConstructor
public class TeamMemberRestController {
private final TeamService teamService;
// ///////////////////////////////////////////////BEGIN GET MAPPINGS///////////////////////////////////////////////////
// ///////////////////////////////////////////////BEGIN POST MAPPINGS///////////////////////////////////////////////////
@PostMapping("/addMemberToTeam")
public ResponseEntity<?> addMemberToTeam(@RequestParam("teamName") String teamName, @RequestBody RacerWSTO racerWsto) {
Team mockTeam = new Team();
mockTeam.setTeamName(teamName);
Racer racer = RacerWSTO.toEntity(racerWsto);
try{
this.teamService.addMember(mockTeam,racer);
}
catch(NotFoundException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage())).build();
}
catch (ExistsException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build();
}
return ResponseEntity.ok(TeamWSTO.of(teamService.getTeam(mockTeam)));
}
// ///////////////////////////////////////////////BEGIN DELETE MAPPINGS///////////////////////////////////////////////////
@DeleteMapping("/removeMemberFromTeam")
public ResponseEntity<?> removeMemberFromTeam(@RequestParam("teamName") String teamName, @RequestBody RacerWSTO racerWsto) {
Team mockTeam = new Team();
mockTeam.setTeamName(teamName);
Racer racer = RacerWSTO.toEntity(racerWsto);
try{
this.teamService.removeMember(mockTeam,racer);
}
catch(NotFoundException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage())).build();
}
catch (ExistsException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage())).build();
}
return ResponseEntity.ok(TeamWSTO.of(teamService.getTeam(mockTeam)));
}
}

View File

@@ -29,12 +29,13 @@ public class TeamRestController {
/** /**
* Creates a team with the information provided via the /teams/createTeam endpoint * Creates a team with the information provided via the /teams/createTeam endpoint
* @param team * @param team Team object with the information to be used on creation
* @return a ResponseEntity, * @return a ResponseEntity,
* either containing a TeamWSTO if a team was successfully created or a HttpStatus.CONFLICT if the team already existed beforehand * either containing a TeamWSTO if a team was successfully created or a HttpStatus.CONFLICT if the team already existed beforehand
*/ */
@PostMapping("createTeam") @PostMapping("createTeam")
public ResponseEntity<@NonNull TeamWSTO> createTeam(@RequestBody Team team){ public ResponseEntity<@NonNull TeamWSTO> createTeam(@RequestBody TeamWSTO teamwsto){
Team team = TeamWSTO.toEntity(teamwsto);
try { try {
teamService.createTeam(team); teamService.createTeam(team);
return new ResponseEntity<>(TeamWSTO.of(team), HttpStatus.CREATED); return new ResponseEntity<>(TeamWSTO.of(team), HttpStatus.CREATED);
@@ -65,28 +66,25 @@ public class TeamRestController {
/** /**
* Gets all the information pertaining to a given team via the API * Gets all the information pertaining to a given team via the API
* @param reqTeam the team to query all information about with either a name or an id field set * @param reqTeamWSTO the teamWSTO to query all information about with either a name or an id field set
* @return a ResponseEntity containing the team in WSTO form, or a ResponseEntity containing either BAD_REQUEST or NOT_FOUND. * @return a ResponseEntity containing the team in WSTO form, or a ResponseEntity containing either BAD_REQUEST or NOT_FOUND.
*/ */
@GetMapping("single-team") @GetMapping("single-team")
public ResponseEntity<@NonNull TeamWSTO> getSingleTeam(@RequestBody Team reqTeam){ public ResponseEntity<@NonNull TeamWSTO> getSingleTeam(@RequestBody TeamWSTO reqTeamWSTO){
Team reqTeam = TeamWSTO.toEntity(reqTeamWSTO);
UUID id = reqTeam.getId(); UUID id = reqTeam.getId();
String name = reqTeam.getTeamName(); String name = reqTeam.getTeamName();
Team actualTeam; Team actualTeam;
try{ try{
if(id != null){ actualTeam = teamService.getTeam(reqTeam);
actualTeam = teamService.getTeam(id); //prefer uuid over name, as it is the most reliable way to find a JPA object
}
else if (name != null){
actualTeam = teamService.getTeam(name);
}
else return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "Must provide either id or name")).build();
return new ResponseEntity<>(TeamWSTO.of(actualTeam), HttpStatus.OK); return new ResponseEntity<>(TeamWSTO.of(actualTeam), HttpStatus.OK);
} }
catch(TeamNotFoundException e){ catch(TeamNotFoundException e){
if(id != null) return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND,"Team with id "+ id +" not found")).build(); if(id != null) return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND,"Team with id "+ id +" not found")).build();
if (name != null) return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND,"Team with name "+ name +" not found")).build(); else return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND,"Team with name "+ name +" not found")).build();
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "Must provide either id or name.")).build(); }
catch (IllegalArgumentException e){
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST,e.getMessage())).build();
} }
} }
@@ -104,12 +102,13 @@ public class TeamRestController {
/** /**
* Deletes a team via its name or id * Deletes a team via its name or id
* @param team the team to query all information about with either a name or an id field set * @param teamWSTO the teamWSTO to query all information about with either a name or an id field set
* @return a ResponseEntity containing HttpStatus.OK if deletion was successful, * @return a ResponseEntity containing HttpStatus.OK if deletion was successful,
* or a ResponseEntity containing either BAD_REQUEST or NOT_FOUND. * or a ResponseEntity containing either BAD_REQUEST or NOT_FOUND.
*/ */
@DeleteMapping("single-team") @DeleteMapping("single-team")
public ResponseEntity<@NonNull String> deleteTeam(@RequestBody Team team){ public ResponseEntity<@NonNull String> deleteTeam(@RequestBody TeamWSTO teamWSTO){
Team team = TeamWSTO.toEntity(teamWSTO);
String name = team.getTeamName(); String name = team.getTeamName();
UUID id = team.getId(); UUID id = team.getId();
try { try {

View File

@@ -26,7 +26,7 @@ public class Station {
private Set<Team> passedTeams; private Set<Team> passedTeams;
@ElementCollection @ElementCollection
private Map<Team, LocalDate> passingTimes; private Map<UUID, LocalDate> passingTimes;
public Station(String name, String location){ public Station(String name, String location){
this.name = name; this.name = name;
@@ -40,13 +40,13 @@ public class Station {
if(!passedTeams.add(team)){ if(!passedTeams.add(team)){
throw new TeamExistsException("Team %s was already seen at this Station: %s".formatted(team.getTeamName(), this.location), team); throw new TeamExistsException("Team %s was already seen at this Station: %s".formatted(team.getTeamName(), this.location), team);
} }
passingTimes.put(team, LocalDate.now()); passingTimes.put(team.getId(), LocalDate.now());
} }
public void removePassedTeam(Team team){ public void removePassedTeam(Team team){
if (!passedTeams.contains(team)) throw new TeamNotFoundException("Team %s was never seen at this station: %s".formatted(team.getTeamName(), this.location)); if (!passedTeams.contains(team)) throw new TeamNotFoundException("Team %s was never seen at this station: %s".formatted(team.getTeamName(), this.location));
passedTeams.remove(team); passedTeams.remove(team);
passingTimes.remove(team); passingTimes.remove(team.getId());
} }
public String setPasswordHash(String passwordHash){ public String setPasswordHash(String passwordHash){

View File

@@ -68,13 +68,11 @@ public class Team {
/** /**
* Removes a member from the team by name * Removes a member from the team by name
* @param firstName the first name of the racer to be removed * @param killableMember the Racer object to be removed from the team
* @param lastName the last name of the racer to be removed
*/ */
public void removeMember(String firstName, String lastName){ public void removeMember(Racer killableMember){
this.members.forEach(racer ->{ this.members.remove(killableMember);
if(firstName.equals(racer.getFirstName()) && lastName.equals(racer.getLastName())) members.remove(racer); killableMember.setMemberTeam(null);
});
this.checkFirstSemesterTeam(); this.checkFirstSemesterTeam();
} }
} }

View File

@@ -0,0 +1,7 @@
package de.pnreichmuth.timekeep_backend.exceptions;
public class ExistsException extends RuntimeException {
public ExistsException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package de.pnreichmuth.timekeep_backend.exceptions;
public class NotFoundException extends RuntimeException {
public NotFoundException(String message) {
super(message);
}
}

View File

@@ -1,11 +1,10 @@
package de.pnreichmuth.timekeep_backend.exceptions; package de.pnreichmuth.timekeep_backend.exceptions;
import de.pnreichmuth.timekeep_backend.entities.Racer; import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.entities.Team;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class RacerExistsException extends RuntimeException { public class RacerExistsException extends ExistsException {
public RacerExistsException(String message, Racer racer) { public RacerExistsException(String message, Racer racer) {
super(message); super(message);
log.warn(message, racer.getFirstName(), racer.getLastName()); log.warn(message, racer.getFirstName(), racer.getLastName());

View File

@@ -1,11 +1,9 @@
package de.pnreichmuth.timekeep_backend.exceptions; package de.pnreichmuth.timekeep_backend.exceptions;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@Slf4j @Slf4j
public class RacerNotFoundException extends RuntimeException { public class RacerNotFoundException extends NotFoundException {
public RacerNotFoundException(String message) { public RacerNotFoundException(String message) {
super(message); super(message);
log.error(message); log.error(message);

View File

@@ -4,7 +4,7 @@ import de.pnreichmuth.timekeep_backend.entities.Station;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class StationExistsException extends RuntimeException { public class StationExistsException extends ExistsException {
public StationExistsException(String message, Station station) { public StationExistsException(String message, Station station) {
super(message); super(message);
log.warn(message, station.getName(), station.getLocation()); log.warn(message, station.getName(), station.getLocation());

View File

@@ -3,7 +3,7 @@ package de.pnreichmuth.timekeep_backend.exceptions;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class StationNotFoundException extends RuntimeException { public class StationNotFoundException extends NotFoundException {
public StationNotFoundException(String message) { public StationNotFoundException(String message) {
super(message); super(message);
log.error(message); log.error(message);

View File

@@ -2,11 +2,9 @@ package de.pnreichmuth.timekeep_backend.exceptions;
import de.pnreichmuth.timekeep_backend.entities.Team; import de.pnreichmuth.timekeep_backend.entities.Team;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@Slf4j @Slf4j
public class TeamExistsException extends RuntimeException { public class TeamExistsException extends ExistsException {
public TeamExistsException(String message, Team team) { public TeamExistsException(String message, Team team) {
super(message); super(message);
log.warn(message, team.getTeamName()); log.warn(message, team.getTeamName());

View File

@@ -1,11 +1,9 @@
package de.pnreichmuth.timekeep_backend.exceptions; package de.pnreichmuth.timekeep_backend.exceptions;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@Slf4j @Slf4j
public class TeamNotFoundException extends RuntimeException { public class TeamNotFoundException extends NotFoundException {
public TeamNotFoundException(String message) { public TeamNotFoundException(String message) {
super(message); super(message);
log.error(message); log.error(message);

View File

@@ -1,12 +1,10 @@
package de.pnreichmuth.timekeep_backend.repositories; package de.pnreichmuth.timekeep_backend.repositories;
import de.pnreichmuth.timekeep_backend.entities.Racer; import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.entities.Team;
import lombok.NonNull; import lombok.NonNull;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;

View File

@@ -3,6 +3,7 @@ package de.pnreichmuth.timekeep_backend.services;
import de.pnreichmuth.timekeep_backend.entities.Racer; import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.exceptions.RacerExistsException; import de.pnreichmuth.timekeep_backend.exceptions.RacerExistsException;
import de.pnreichmuth.timekeep_backend.exceptions.RacerNotFoundException; import de.pnreichmuth.timekeep_backend.exceptions.RacerNotFoundException;
import de.pnreichmuth.timekeep_backend.exceptions.TeamNotFoundException;
import de.pnreichmuth.timekeep_backend.repositories.RacerRepository; import de.pnreichmuth.timekeep_backend.repositories.RacerRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -52,6 +53,18 @@ public class RacerService {
return racer; return racer;
} }
public Racer getRacer(Racer racer) throws RacerNotFoundException {
Racer dbRacer;
if(racer.getRacerID() != null) dbRacer = racerRepository.getRacerByRacerID(racer.getRacerID()).orElse(null);
else if(racer.getFirstName() != null && racer.getLastName() != null) dbRacer = racerRepository.getRacerByFirstNameAndLastName(racer.getFirstName(),racer.getLastName()).orElse(null);
else throw new IllegalArgumentException("Must provide either Racer ID or full Racer name");
if (dbRacer == null){
if(racer.getRacerID() != null) throw new TeamNotFoundException("Racer with id "+racer.getRacerID()+" not found");
else throw new TeamNotFoundException("Racer with name "+racer.getFirstName()+" "+ racer.getLastName()+" not found");
}
return dbRacer;
}
public UUID getRacerIdByName(String firstName, String lastName) throws RacerNotFoundException { public UUID getRacerIdByName(String firstName, String lastName) throws RacerNotFoundException {
Racer racer = racerRepository.getRacerByFirstNameAndLastName(firstName,lastName).orElse(null); Racer racer = racerRepository.getRacerByFirstNameAndLastName(firstName,lastName).orElse(null);
if(racer == null) throw new RacerNotFoundException(String.format("Racer with name %s %s not found", firstName, lastName)); if(racer == null) throw new RacerNotFoundException(String.format("Racer with name %s %s not found", firstName, lastName));
@@ -72,9 +85,13 @@ public class RacerService {
return racerRepository.save(racer); return racerRepository.save(racer);
} }
public void deleteRacer(UUID id) throws RacerNotFoundException { public void deleteRacer(Racer racer) throws RacerNotFoundException {
Racer racer = racerRepository.findById(id).orElse(null); Racer dbRacer;
if(racer == null) throw new RacerNotFoundException("Racer not found"); if(racer.getRacerID() != null) dbRacer = racerRepository.getRacerByRacerID(racer.getRacerID()).orElse(null);
else if(racer.getFirstName() != null && racer.getLastName() != null) dbRacer = racerRepository.getRacerByFirstNameAndLastName(racer.getFirstName(),racer.getLastName()).orElse(null);
else throw new IllegalArgumentException("Must provide either Racer ID or full Racer name");
if(dbRacer == null) throw new RacerNotFoundException("Racer not found");
racerRepository.delete(dbRacer);
} }
public void updateRacer(Racer racer) throws RacerExistsException{ public void updateRacer(Racer racer) throws RacerExistsException{

View File

@@ -9,7 +9,6 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
@Service @Service
@Slf4j @Slf4j

View File

@@ -1,9 +1,10 @@
package de.pnreichmuth.timekeep_backend.services; package de.pnreichmuth.timekeep_backend.services;
import de.pnreichmuth.timekeep_backend.entities.Racer;
import de.pnreichmuth.timekeep_backend.entities.Team; import de.pnreichmuth.timekeep_backend.entities.Team;
import de.pnreichmuth.timekeep_backend.exceptions.RacerExistsException;
import de.pnreichmuth.timekeep_backend.exceptions.TeamExistsException; import de.pnreichmuth.timekeep_backend.exceptions.TeamExistsException;
import de.pnreichmuth.timekeep_backend.exceptions.TeamNotFoundException; import de.pnreichmuth.timekeep_backend.exceptions.TeamNotFoundException;
import de.pnreichmuth.timekeep_backend.repositories.RacerRepository;
import de.pnreichmuth.timekeep_backend.repositories.TeamRepository; import de.pnreichmuth.timekeep_backend.repositories.TeamRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -19,6 +20,7 @@ import java.util.UUID;
@RequiredArgsConstructor @RequiredArgsConstructor
public class TeamService { public class TeamService {
private final TeamRepository teamRepository; private final TeamRepository teamRepository;
private final RacerService racerService;
private void checkTeamIsDuplicate(Team team) throws TeamExistsException { private void checkTeamIsDuplicate(Team team) throws TeamExistsException {
List<Team> teams = teamRepository.findAll(); List<Team> teams = teamRepository.findAll();
@@ -27,16 +29,17 @@ public class TeamService {
} }
} }
public Team getTeam(UUID id){ public Team getTeam(Team team){
Team team = teamRepository.findById(id).orElse(null); Team dbTeam;
if(team == null) throw new TeamNotFoundException("Team with id "+id+" not found"); if(team.getId()!=null) dbTeam = teamRepository.findById(team.getId()).orElse(null);
return team; else if (team.getTeamName() != null) dbTeam = teamRepository.getTeamByTeamName(team.getTeamName()).orElse(null);
} else throw new IllegalArgumentException("Must provide either team id or team name");
public Team getTeam(String name){ if (dbTeam == null){
Team team = teamRepository.getTeamByTeamName(name).orElse(null); if(team.getId() != null) throw new TeamNotFoundException("Team with id "+team.getId()+" not found");
if(team == null) throw new TeamNotFoundException("Team with name "+name+" not found"); else throw new TeamNotFoundException("Team with name "+team.getTeamName()+" not found");
return team; }
return dbTeam;
} }
public List<Team> getTeams(){ public List<Team> getTeams(){
@@ -69,9 +72,33 @@ public class TeamService {
public void updateTeam(Team team) throws TeamNotFoundException { public void updateTeam(Team team) throws TeamNotFoundException {
Objects.requireNonNull(team, "Can't update null team."); Objects.requireNonNull(team, "Can't update null team.");
checkTeamIsDuplicate(team);
teamRepository.save(team); teamRepository.save(team);
} }
/**
* Adds a new member to the given team
* @param team team object to add the member to
* @param newMember racer object to be added as a member
*/
public void addMember(Team team,Racer newMember){
Team dbTeam = this.getTeam(team);
Racer dbRacer = racerService.getRacer(newMember);
if(dbTeam.getMembers().stream().anyMatch(e -> e.equals(dbRacer))){
throw new RacerExistsException("%s %s is already a member".formatted(dbRacer.getFirstName(),dbRacer.getLastName()), newMember);
}
dbTeam.addMember(dbRacer);
this.updateTeam(dbTeam);
}
public void removeMember(Team team, Racer newMember){
Team dbTeam = this.getTeam(team);
Racer dbRacer = racerService.getRacer(newMember);
if(dbTeam.getMembers().stream().noneMatch(e -> e.equals(dbRacer))){
throw new RacerExistsException("%s %s is not a member".formatted(dbRacer.getFirstName(),dbRacer.getLastName()), newMember);
}
dbTeam.removeMember(dbRacer);
this.updateTeam(dbTeam);
}
/** /**
* DANGER ZONE * DANGER ZONE
*/ */

View File

@@ -8,7 +8,7 @@ package de.pnreichmuth.timekeep_backend.spring_configs;
// //
// //
//@Configuration //@Configuration
////@EnableWebSecurity //@EnableWebSecurity
//public class TimekeepBackendSecurityConfig { //public class TimekeepBackendSecurityConfig {
// @Bean // @Bean
// public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

View File

@@ -20,14 +20,10 @@ public record TeamWSTO(String teamName,
public static TeamWSTO of(Team team){ public static TeamWSTO of(Team team){
List<RacerWSTO> tempMemberList = new ArrayList<>(); List<RacerWSTO> tempMemberList = new ArrayList<>();
team.getMembers().forEach(member -> { team.getMembers().forEach(member -> tempMemberList.add(RacerWSTO.of(member)));
tempMemberList.add(RacerWSTO.of(member));
});
List<StationWSTO> tempStationList = new ArrayList<>(); List<StationWSTO> tempStationList = new ArrayList<>();
team.getPassedStations().forEach(passedStation -> { team.getPassedStations().forEach(passedStation -> tempStationList.add(StationWSTO.of(passedStation)));
tempStationList.add(StationWSTO.of(passedStation));
});
return new TeamWSTO( return new TeamWSTO(
team.getTeamName(), team.getTeamName(),
@@ -39,14 +35,10 @@ public record TeamWSTO(String teamName,
public static Team toEntity(TeamWSTO teamWSTO){ public static Team toEntity(TeamWSTO teamWSTO){
List<Racer> tempMemberList = new ArrayList<>(); List<Racer> tempMemberList = new ArrayList<>();
teamWSTO.teamMembers().forEach(member -> { teamWSTO.teamMembers().forEach(member -> tempMemberList.add(RacerWSTO.toEntity(member)));
tempMemberList.add(RacerWSTO.toEntity(member));
});
List<Station> tempStationList = new ArrayList<>(); List<Station> tempStationList = new ArrayList<>();
teamWSTO.passedStations().forEach(passedStation -> { teamWSTO.passedStations().forEach(passedStation -> tempStationList.add(StationWSTO.toEntity(passedStation)));
tempStationList.add(StationWSTO.toEntity(passedStation));
});
return new Team( return new Team(
teamWSTO.teamName(), teamWSTO.teamName(),