Skip to content
Snippets Groups Projects
Commit aa41248e authored by Diana Gulčíková's avatar Diana Gulčíková
Browse files

Merge branch 'race_extended_functionality' into 'milestone_2'

Race extended functionality

See merge request !41
parents a53078c9 9a41c428
No related branches found
No related tags found
2 merge requests!60Docker,!41Race extended functionality
Pipeline #
Showing
with 195 additions and 83 deletions
...@@ -32,24 +32,6 @@ ...@@ -32,24 +32,6 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>fi.muni</groupId>
<artifactId>car</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>fi.muni</groupId>
<artifactId>driver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>fi.muni</groupId>
<artifactId>component</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
......
package cz.muni.pa165.race; package cz.muni.pa165.race;
import cz.muni.pa165.car.data.model.Car;
import cz.muni.pa165.common_library.client.ClientConfig; import cz.muni.pa165.common_library.client.ClientConfig;
import cz.muni.pa165.common_library.exception.RestExceptionHandler; import cz.muni.pa165.common_library.exception.RestExceptionHandler;
import cz.muni.pa165.component.data.model.CarComponent;
import cz.muni.pa165.driver.data.model.Driver;
import cz.muni.pa165.race.data.model.Race; import cz.muni.pa165.race.data.model.Race;
import cz.muni.pa165.race.data.model.Season; import cz.muni.pa165.race.data.model.Season;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
...@@ -20,8 +18,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; ...@@ -20,8 +18,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication @SpringBootApplication
@EnableJpaRepositories(basePackages = "cz.muni.pa165.race.data.repository") @EnableJpaRepositories(basePackages = "cz.muni.pa165.race.data.repository")
@EnableTransactionManagement @EnableTransactionManagement
@EntityScan(basePackageClasses = {Race.class, Season.class, Car.class, Driver.class, @EntityScan(basePackageClasses = {Race.class, Season.class})
CarComponent.class})
@Import({RestExceptionHandler.class, ClientConfig.class}) @Import({RestExceptionHandler.class, ClientConfig.class})
public class App { public class App {
......
package cz.muni.pa165.race.data.model; package cz.muni.pa165.race.data.model;
import cz.muni.pa165.car.data.model.Car;
import cz.muni.pa165.common_library.dtos.Location; import cz.muni.pa165.common_library.dtos.Location;
import cz.muni.pa165.driver.data.model.Driver;
import jakarta.persistence.CascadeType; import jakarta.persistence.CascadeType;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.EnumType; import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated; import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType; import jakarta.persistence.GenerationType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Max;
......
package cz.muni.pa165.race.data.repository;
import cz.muni.pa165.car.data.model.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Repository for car.
*/
@Repository
public interface CarRepository extends JpaRepository<Car, Long> {
}
package cz.muni.pa165.race.data.repository;
import cz.muni.pa165.driver.data.model.Driver;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Driver repository.
*/
@Repository
public interface DriverRepository extends JpaRepository<Driver, Long> {
}
...@@ -21,4 +21,9 @@ public interface RaceRepository extends JpaRepository<Race, Long> { ...@@ -21,4 +21,9 @@ public interface RaceRepository extends JpaRepository<Race, Long> {
+ "WHERE ri.location = :location AND (do.id = :driverId OR dt.id = :driverId)") + "WHERE ri.location = :location AND (do.id = :driverId OR dt.id = :driverId)")
List<Race> findAllRacesOfDriverInLocation(@Param("location") Location raceLocation, List<Race> findAllRacesOfDriverInLocation(@Param("location") Location raceLocation,
@Param("driverId") long driverId); @Param("driverId") long driverId);
@Query("SELECT r FROM Race r"
+ " JOIN r.raceInfo ri "
+ "WHERE ri.location = :location")
List<Race> findRacesByLocation(@Param("location") Location raceLocation);
} }
package cz.muni.pa165.race.rest; package cz.muni.pa165.race.rest;
import cz.muni.pa165.common_library.dtos.Location;
import cz.muni.pa165.common_library.dtos.RaceDto; import cz.muni.pa165.common_library.dtos.RaceDto;
import cz.muni.pa165.race.service.RaceService; import cz.muni.pa165.race.service.RaceServiceI;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Set;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -26,9 +28,9 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -26,9 +28,9 @@ import org.springframework.web.bind.annotation.RestController;
@Validated @Validated
public class RaceController { public class RaceController {
RaceService raceService; RaceServiceI raceService;
public RaceController(RaceService raceService) { public RaceController(RaceServiceI raceService) {
this.raceService = raceService; this.raceService = raceService;
} }
...@@ -64,8 +66,8 @@ public class RaceController { ...@@ -64,8 +66,8 @@ public class RaceController {
@PatchMapping(path = "/assignDriverOne", @PatchMapping(path = "/assignDriverOne",
produces = MediaType.APPLICATION_JSON_VALUE) produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<RaceDto> assignDriverOne(@RequestParam Long driverOneId, public ResponseEntity<RaceDto> assignDriverOne(@RequestParam Long driverOneId,
@RequestParam Long raceId, @RequestParam Long raceId,
@RequestParam Long carId) { @RequestParam Long carId) {
return ResponseEntity.ok(raceService.assignDriverOne(driverOneId, raceId, carId)); return ResponseEntity.ok(raceService.assignDriverOne(driverOneId, raceId, carId));
} }
...@@ -73,8 +75,31 @@ public class RaceController { ...@@ -73,8 +75,31 @@ public class RaceController {
@PatchMapping(path = "/assignDriverTwo", @PatchMapping(path = "/assignDriverTwo",
produces = MediaType.APPLICATION_JSON_VALUE) produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<RaceDto> assignDriverTwo(@RequestParam Long driverTwoId, public ResponseEntity<RaceDto> assignDriverTwo(@RequestParam Long driverTwoId,
@RequestParam Long raceId, @RequestParam Long raceId,
@RequestParam Long carId) { @RequestParam Long carId) {
return ResponseEntity.ok(raceService.assignDriverTwo(driverTwoId, raceId, carId)); return ResponseEntity.ok(raceService.assignDriverTwo(driverTwoId, raceId, carId));
} }
@Operation(summary = "Assign position for driver two")
@PatchMapping(path = "/assignPointsDriverTwo",
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<RaceDto> assignPositionDriverTwo(@RequestParam Long raceId,
@RequestParam Integer position) {
return ResponseEntity.ok(raceService.assignPositionForDriverTwo(raceId, position));
}
@Operation(summary = "Assign position for driver two")
@PatchMapping(path = "/assignPointsDriverOne",
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<RaceDto> assignPositionDriverOne(@RequestParam Long raceId,
@RequestParam Integer position) {
return ResponseEntity.ok(raceService.assignPositionForDriverOne(raceId, position));
}
@Operation(summary = "get races")
@GetMapping(path = "/findMostSuitableDriversForLocation")
public ResponseEntity<Set<Long>> getMostSuitableDriversForLocation(
@RequestParam Location location) {
return ResponseEntity.ok(raceService.findMostSuitableDriver(location));
}
} }
package cz.muni.pa165.race.rest; package cz.muni.pa165.race.rest;
import cz.muni.pa165.common_library.dtos.SeasonDto; import cz.muni.pa165.common_library.dtos.SeasonDto;
import cz.muni.pa165.race.service.SeasonServiceInterface; import cz.muni.pa165.race.service.SeasonServiceI;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List; import java.util.List;
...@@ -25,9 +25,9 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -25,9 +25,9 @@ import org.springframework.web.bind.annotation.RestController;
@Validated @Validated
public class SeasonController { public class SeasonController {
SeasonServiceInterface seasonService; SeasonServiceI seasonService;
public SeasonController(SeasonServiceInterface seasonService) { public SeasonController(SeasonServiceI seasonService) {
this.seasonService = seasonService; this.seasonService = seasonService;
} }
......
package cz.muni.pa165.race.service;
import java.util.HashMap;
import java.util.Map;
/**
* Utility for points per position.
*/
public class PointsUtil {
/**
* Map with position and corresponding points.
*/
public Map<Integer, Integer> points;
/**
* Constructor.
*/
public PointsUtil() {
points = new HashMap<>();
points.put(1, 25);
points.put(2, 18);
points.put(3, 15);
points.put(4, 12);
points.put(5, 10);
points.put(6, 8);
points.put(7, 6);
points.put(8, 4);
points.put(9, 2);
points.put(10, 1);
}
}
package cz.muni.pa165.race.service; package cz.muni.pa165.race.service;
import cz.muni.pa165.car.data.model.Car; import cz.muni.pa165.common_library.dtos.CarResponseDto;
import cz.muni.pa165.common_library.dtos.DriverDto;
import cz.muni.pa165.common_library.dtos.Location;
import cz.muni.pa165.common_library.dtos.RaceDriverCarDto; import cz.muni.pa165.common_library.dtos.RaceDriverCarDto;
import cz.muni.pa165.common_library.dtos.RaceDto; import cz.muni.pa165.common_library.dtos.RaceDto;
import cz.muni.pa165.common_library.exception.BadRequestException; import cz.muni.pa165.common_library.exception.BadRequestException;
import cz.muni.pa165.common_library.exception.DatabaseException; import cz.muni.pa165.common_library.exception.DatabaseException;
import cz.muni.pa165.driver.data.model.Driver;
import cz.muni.pa165.race.data.model.Race; import cz.muni.pa165.race.data.model.Race;
import cz.muni.pa165.race.data.repository.CarRepository;
import cz.muni.pa165.race.data.repository.DriverRepository;
import cz.muni.pa165.race.data.repository.RaceRepository; import cz.muni.pa165.race.data.repository.RaceRepository;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
...@@ -21,20 +25,17 @@ import org.springframework.web.client.RestTemplate; ...@@ -21,20 +25,17 @@ import org.springframework.web.client.RestTemplate;
*/ */
// TODO chybnú hlášku spraviť konštantu // TODO chybnú hlášku spraviť konštantu
@Service @Service
public class RaceService { public class RaceService implements RaceServiceI {
PointsUtil pointsUtil = new PointsUtil();
RaceRepository raceRepository; RaceRepository raceRepository;
CarRepository carRepository;
DriverRepository driverRepository;
@Autowired @Autowired
RestTemplate client; RestTemplate client;
RaceService(RaceRepository raceRepository, CarRepository carRepository, RaceService(RaceRepository raceRepository) {
DriverRepository driverRepository) {
this.raceRepository = raceRepository; this.raceRepository = raceRepository;
this.carRepository = carRepository;
this.driverRepository = driverRepository;
} }
/** /**
...@@ -97,7 +98,8 @@ public class RaceService { ...@@ -97,7 +98,8 @@ public class RaceService {
race.getDriver2().setDriverId(driver.getId()); race.getDriver2().setDriverId(driver.getId());
race.getDriver2().setCarId(car.getId()); race.getDriver2().setCarId(car.getId());
return convertRace(raceRepository.save(race)); var a = convertRace(raceRepository.save(race));
return a;
} }
/** /**
...@@ -121,6 +123,75 @@ public class RaceService { ...@@ -121,6 +123,75 @@ public class RaceService {
return raceRepository.findAll().stream().map(this::convertRace).toList(); return raceRepository.findAll().stream().map(this::convertRace).toList();
} }
/**
* Assigns positions for driver number two.
*
* @param raceId race id.
* @param position position of driver two.
* @return updated race.
*/
public RaceDto assignPositionForDriverTwo(Long raceId, Integer position) {
var race =
raceRepository.findById(raceId).orElseThrow(() -> new DatabaseException("Race not found"));
race.getDriver2().setFinalPosition(position);
return convertRace(raceRepository.save(race));
}
/**
* Assigns positions for driver number one.
*
* @param raceId race id.
* @param position position of driver one.
* @return updated race.
*/
public RaceDto assignPositionForDriverOne(Long raceId, Integer position) {
var race =
raceRepository.findById(raceId).orElseThrow(() -> new DatabaseException("Race not found"));
race.getDriver2().setFinalPosition(position);
return convertRace(raceRepository.save(race));
}
/**
* Finds most suitable drivers for given location.
*
* @param location location of the race.
* @return set if ids of most suitable drivers for given location.
*/
public Set<Long> findMostSuitableDriver(Location location) {
var races = raceRepository.findRacesByLocation(location);
Map<Long, Integer> driverWithPoints = new HashMap<>();
for (Race race : races) {
updatePointsForDriver(race.getDriver1(), driverWithPoints);
updatePointsForDriver(race.getDriver2(), driverWithPoints);
}
var max = Collections.max(driverWithPoints.values());
Set<Long> drivers = new HashSet<>();
for (Map.Entry<Long, Integer> entry : driverWithPoints.entrySet()) {
if (Objects.equals(entry.getValue(), max)) {
drivers.add(entry.getKey());
}
}
return drivers;
}
private void updatePointsForDriver(Race.RaceDriverinfo driverinfo,
Map<Long, Integer> driverWithPoints) {
if (driverinfo == null || driverinfo.getDriverId() == null) {
return;
}
Integer points;
if (driverinfo.getFinalPosition() != null) {
points = pointsUtil.points.get(driverinfo.getFinalPosition());
} else {
points = 0;
}
driverWithPoints.merge(driverinfo.getDriverId(), points, Integer::sum);
}
private Race convertRaceDto(RaceDto raceDto) { private Race convertRaceDto(RaceDto raceDto) {
var race = Race.builder() var race = Race.builder()
.id(raceDto.getId()) .id(raceDto.getId())
...@@ -176,20 +247,21 @@ public class RaceService { ...@@ -176,20 +247,21 @@ public class RaceService {
if (race.getDriver2() != null) { if (race.getDriver2() != null) {
raceDto.setDriverTwo(RaceDriverCarDto.builder() raceDto.setDriverTwo(RaceDriverCarDto.builder()
.carId(race.getDriver2().getCarId()) .carId(race.getDriver2().getCarId())
.driverId(race.getDriver2().getCarId()) .driverId(race.getDriver2().getDriverId())
.build()); .build());
} }
return raceDto; return raceDto;
} }
private Driver getDriver(Long driverId) { private DriverDto getDriver(Long driverId) {
var response = var response =
client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, Driver.class); client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, DriverDto.class);
return response.getBody(); return response.getBody();
} }
private Car getCar(Long carId) { private CarResponseDto getCar(Long carId) {
var response = client.getForEntity("http://localhost:8082/car/id=" + carId, Car.class); var response =
client.getForEntity("http://localhost:8082/car/?carId=" + carId, CarResponseDto.class);
return response.getBody(); return response.getBody();
} }
} }
package cz.muni.pa165.race.service;
import cz.muni.pa165.common_library.dtos.Location;
import cz.muni.pa165.common_library.dtos.RaceDto;
import java.util.List;
import java.util.Set;
/**
* Race service interface.
*/
public interface RaceServiceI {
RaceDto postRace(RaceDto raceDto);
RaceDto findRaceById(Long raceId);
List<RaceDto> findRaces();
String deleteRace(Long raceId);
RaceDto assignDriverOne(Long driverId, Long raceId, Long carId);
RaceDto assignDriverTwo(Long driverId, Long raceId, Long carId);
Set<Long> findMostSuitableDriver(Location location);
RaceDto assignPositionForDriverTwo(Long raceId, Integer position);
RaceDto assignPositionForDriverOne(Long raceId, Integer position);
}
...@@ -15,7 +15,7 @@ import org.springframework.stereotype.Service; ...@@ -15,7 +15,7 @@ import org.springframework.stereotype.Service;
* Season service. * Season service.
*/ */
@Service @Service
public class SeasonService implements SeasonServiceInterface { public class SeasonService implements SeasonServiceI {
@Autowired @Autowired
SeasonRepository seasonRepository; SeasonRepository seasonRepository;
......
...@@ -6,7 +6,7 @@ import java.util.List; ...@@ -6,7 +6,7 @@ import java.util.List;
/** /**
* Interface for season service. * Interface for season service.
*/ */
public interface SeasonServiceInterface { public interface SeasonServiceI {
SeasonDto postSeason(SeasonDto seasonDto); SeasonDto postSeason(SeasonDto seasonDto);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment