diff --git a/backend/src/main/java/com/carffeine/carffeine/controller/chargerStation/dto/CongestionResponse.java b/backend/src/main/java/com/carffeine/carffeine/controller/chargerStation/dto/CongestionResponse.java index f63a1b319..3116454e3 100644 --- a/backend/src/main/java/com/carffeine/carffeine/controller/chargerStation/dto/CongestionResponse.java +++ b/backend/src/main/java/com/carffeine/carffeine/controller/chargerStation/dto/CongestionResponse.java @@ -3,6 +3,6 @@ import java.util.List; import java.util.Map; -public record CongestionResponse(Map> STANDARD, - Map> QUICK) { +public record CongestionResponse(Map> standard, + Map> quick) { } diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/Charger.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/Charger.java index 40f18e71a..cde2caad7 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/Charger.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/Charger.java @@ -28,6 +28,7 @@ @Entity @Table(name = "charger") public class Charger { + private static final BigDecimal OUTPUT_THRESHOLD = BigDecimal.valueOf(50); @Id @Column(name = "station_id") @@ -62,4 +63,11 @@ public class Charger { public boolean isAvailable() { return chargerStatus.isAvailable(); } + + public boolean isQuick() { + if (capacity == null) { + return false; + } + return capacity.compareTo(OUTPUT_THRESHOLD) >= 0; + } } diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerRepository.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerRepository.java index 37f7a9cbe..2b234f741 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerRepository.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerRepository.java @@ -5,5 +5,6 @@ import java.util.List; public interface ChargerRepository extends Repository { + List findAllByStationId(String stationId); } diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerState.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerState.java index aeded7bd5..c6cfbbb08 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerState.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerState.java @@ -4,19 +4,17 @@ public enum ChargerState { - COMMUNICATION_ERROR(1, "1"), - STANDBY(2, "2"), - CHARGING_IN_PROGRESS(3, "3"), - OPERATION_SUSPENDED(4, "4"), - UNDER_INSPECTION(5, "5"), - STATUS_UNKNOWN(9, "9"); + COMMUNICATION_ERROR(1), + STANDBY(2), + CHARGING_IN_PROGRESS(3), + OPERATION_SUSPENDED(4), + UNDER_INSPECTION(5), + STATUS_UNKNOWN(9); private final int value; - private final String valueString; - ChargerState(int value, String valueString) { + ChargerState(int value) { this.value = value; - this.valueString = valueString; } public static ChargerState from(int input) { @@ -28,7 +26,7 @@ public static ChargerState from(int input) { public static ChargerState from(String input) { return Arrays.stream(ChargerState.values()) - .filter(it -> it.valueString.equals(input)) + .filter(it -> it.value == input.charAt(0) - '0') .findAny() .orElse(STATUS_UNKNOWN); } diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerStatus.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerStatus.java index 227a82f0f..f7f3de9c7 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerStatus.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/charger/ChargerStatus.java @@ -19,7 +19,7 @@ @ToString @Getter @Builder -@AllArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) @IdClass(ChargerId.class) @Entity diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/PeriodicCongestion.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/PeriodicCongestion.java index 79d97b9ac..c8777e786 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/PeriodicCongestion.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/PeriodicCongestion.java @@ -33,10 +33,10 @@ public class PeriodicCongestion { private double congestion; @ManyToOne - @JoinColumns({ - @JoinColumn(name = "station_id", referencedColumnName = "station_id", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT)), - @JoinColumn(name = "charger_id", referencedColumnName = "charger_id", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT)) - }) + @JoinColumns(value = { + @JoinColumn(name = "station_id", referencedColumnName = "station_id", insertable = false, updatable = false), + @JoinColumn(name = "charger_id", referencedColumnName = "charger_id", insertable = false, updatable = false) + }, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT)) private Charger charger; @Column(name = "station_id") diff --git a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/RequestPeriod.java b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/RequestPeriod.java index 5d920ce15..b6fa5208c 100644 --- a/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/RequestPeriod.java +++ b/backend/src/main/java/com/carffeine/carffeine/domain/chargestation/congestion/RequestPeriod.java @@ -12,10 +12,11 @@ public enum RequestPeriod { ZERO(0), TWELVE(1200); + private static final int UNIT = 100; private static final List periods = Arrays.stream(values()) .sorted(Comparator.comparingInt(RequestPeriod::getSection)) .toList(); - private static final int UNIT = 100; + private final int section; RequestPeriod(int section) { diff --git a/backend/src/main/java/com/carffeine/carffeine/infra/api/RestTemplateChargeStationRequester.java b/backend/src/main/java/com/carffeine/carffeine/infra/api/RestTemplateChargeStationRequester.java index 9664b3871..da77fc2a1 100644 --- a/backend/src/main/java/com/carffeine/carffeine/infra/api/RestTemplateChargeStationRequester.java +++ b/backend/src/main/java/com/carffeine/carffeine/infra/api/RestTemplateChargeStationRequester.java @@ -47,7 +47,7 @@ public ChargeStationRequest requestChargeStationRequest(int pageNo) { } @Override - public ChargerStateUpdateRequest requestChargerStatusUpdateRequest(int pageNo) { + public ChargerStateUpdateRequest requestChargerStatusUpdate(int pageNo) { while (true) { try { ChargerStateUpdateRequest result = requestChargeStateUpdateRequestWithRetry(pageNo); diff --git a/backend/src/main/java/com/carffeine/carffeine/infra/repository/ChargerStatusCustomRepositoryImpl.java b/backend/src/main/java/com/carffeine/carffeine/infra/repository/ChargerStatusCustomRepositoryImpl.java index 025728887..f7fa67611 100644 --- a/backend/src/main/java/com/carffeine/carffeine/infra/repository/ChargerStatusCustomRepositoryImpl.java +++ b/backend/src/main/java/com/carffeine/carffeine/infra/repository/ChargerStatusCustomRepositoryImpl.java @@ -1,8 +1,7 @@ package com.carffeine.carffeine.infra.repository; -import com.carffeine.carffeine.domain.chargestation.charger.ChargerState; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatus; import com.carffeine.carffeine.service.chargerstation.ChargerStatusCustomRepository; -import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateRequest; import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; @@ -10,8 +9,6 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.List; @RequiredArgsConstructor @@ -22,30 +19,21 @@ public class ChargerStatusCustomRepositoryImpl implements ChargerStatusCustomRep @Override @Transactional - public void saveAll(List item) { + public void saveAll(List chargerStatuses) { String sql = "INSERT INTO charger_status (station_id, charger_id, latest_update_time, charger_state) " + "VALUES (:stationId, :chargerId, :latestUpdateTime, :chargerState) " + "ON DUPLICATE KEY UPDATE latest_update_time = :latestUpdateTime, charger_state = :chargerState"; - SqlParameterSource[] sqlParameterSources = item.stream() + SqlParameterSource[] sqlParameterSources = chargerStatuses.stream() .map(this::changeToSqlParameterSource) .toArray(SqlParameterSource[]::new); namedParameterJdbcTemplate.batchUpdate(sql, sqlParameterSources); } - private MapSqlParameterSource changeToSqlParameterSource(ChargerStateRequest item) { + private MapSqlParameterSource changeToSqlParameterSource(ChargerStatus item) { return new MapSqlParameterSource() - .addValue("stationId", item.statId()) - .addValue("chargerId", item.chgerId()) - .addValue("latestUpdateTime", parseDateTimeFromString(item.statUpdDt())) - .addValue("chargerState", ChargerState.from(item.stat()).name()); - } - - private LocalDateTime parseDateTimeFromString(String input) { - if (input == null || input.length() != 14) { - return null; - } - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); - return LocalDateTime.parse(input, formatter); + .addValue("stationId", item.getStationId()) + .addValue("chargerId", item.getChargerId()) + .addValue("latestUpdateTime", item.getLatestUpdateTime()) + .addValue("chargerState", item.getChargerState().name()); } } diff --git a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateRequester.java b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateRequester.java index e098e77f2..ce523a2b4 100644 --- a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateRequester.java +++ b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateRequester.java @@ -4,5 +4,5 @@ public interface ChargerStateRequester { - ChargerStateUpdateRequest requestChargerStatusUpdateRequest(int pageNo); + ChargerStateUpdateRequest requestChargerStatusUpdate(int pageNo); } diff --git a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateUpdateService.java b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateUpdateService.java index 45477868b..b5f2306f5 100644 --- a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateUpdateService.java +++ b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStateUpdateService.java @@ -1,5 +1,6 @@ package com.carffeine.carffeine.service.chargerstation; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatus; import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateRequest; import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateUpdateRequest; import lombok.RequiredArgsConstructor; @@ -25,8 +26,11 @@ public void update() { } private void updateChargerState(int pageNo) { - ChargerStateUpdateRequest chargerStateUpdateRequest = chargerStateRequester.requestChargerStatusUpdateRequest(pageNo); + ChargerStateUpdateRequest chargerStateUpdateRequest = chargerStateRequester.requestChargerStatusUpdate(pageNo); List chargerStateRequests = chargerStateUpdateRequest.items().item(); - chargerStatusCustomRepository.saveAll(chargerStateRequests); + List chargerStatuses = chargerStateRequests.stream() + .map(ChargerStateRequest::toChargerStatus) + .toList(); + chargerStatusCustomRepository.saveAll(chargerStatuses); } } diff --git a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStatusCustomRepository.java b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStatusCustomRepository.java index 4fd32af06..a7abf5b86 100644 --- a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStatusCustomRepository.java +++ b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/ChargerStatusCustomRepository.java @@ -1,10 +1,10 @@ package com.carffeine.carffeine.service.chargerstation; -import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateRequest; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatus; import java.util.List; public interface ChargerStatusCustomRepository { - void saveAll(List item); + void saveAll(List item); } diff --git a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/CongestionService.java b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/CongestionService.java index 65d427684..74fd2aa3c 100644 --- a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/CongestionService.java +++ b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/CongestionService.java @@ -46,7 +46,7 @@ public StatisticsResponse calculateCongestion(StatisticsRequest statisticsReques private Map> calculateQuick(List congestions, List chargers) { List quickChargerIds = chargers.stream() - .filter(it -> it.getCapacity().intValue() >= OUTPUT_THRESHOLD) + .filter(Charger::isQuick) .map(Charger::getChargerId) .toList(); @@ -55,7 +55,7 @@ private Map> calculateQuick(List> calculateStandard(List congestions, List chargers) { List standardChargerIds = chargers.stream() - .filter(it -> it.getCapacity().intValue() < OUTPUT_THRESHOLD) + .filter(it -> !it.isQuick()) .map(Charger::getChargerId) .toList(); diff --git a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/dto/ChargerStateRequest.java b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/dto/ChargerStateRequest.java index 8dba6465e..8e5d46ef5 100644 --- a/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/dto/ChargerStateRequest.java +++ b/backend/src/main/java/com/carffeine/carffeine/service/chargerstation/dto/ChargerStateRequest.java @@ -1,5 +1,11 @@ package com.carffeine.carffeine.service.chargerstation.dto; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerState; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatus; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + public record ChargerStateRequest( String busiId, String statId, @@ -9,4 +15,23 @@ public record ChargerStateRequest( String lastTsdt, String lastTedt, String nowTsdt) { + + private static final int DATETIME_LENGTH = 14; + + public ChargerStatus toChargerStatus() { + return ChargerStatus.builder() + .stationId(statId) + .chargerId(chgerId) + .latestUpdateTime(parseDateTimeFromString(statUpdDt)) + .chargerState(ChargerState.from(stat)) + .build(); + } + + private LocalDateTime parseDateTimeFromString(String input) { + if (input == null || input.length() != DATETIME_LENGTH) { + return null; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + return LocalDateTime.parse(input, formatter); + } } diff --git a/backend/src/test/java/com/carffeine/carffeine/infra/repository/ChargerStatusRepositoryImplTest.java b/backend/src/test/java/com/carffeine/carffeine/infra/repository/ChargerStatusRepositoryImplTest.java index df70dd4bc..71d898ef9 100644 --- a/backend/src/test/java/com/carffeine/carffeine/infra/repository/ChargerStatusRepositoryImplTest.java +++ b/backend/src/test/java/com/carffeine/carffeine/infra/repository/ChargerStatusRepositoryImplTest.java @@ -1,17 +1,16 @@ package com.carffeine.carffeine.infra.repository; +import com.carffeine.carffeine.domain.chargestation.charger.ChargerState; import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatus; import com.carffeine.carffeine.domain.chargestation.charger.ChargerStatusRepository; import com.carffeine.carffeine.service.chargerstation.ChargerStatusCustomRepository; -import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateRequest; -import com.carffeine.carffeine.service.chargerstation.dto.ChargerStateUpdateRequest; -import com.carffeine.carffeine.service.chargerstation.dto.ChargersStateRequest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import java.time.LocalDateTime; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -20,8 +19,13 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class ChargerStatusRepositoryImplTest { - private final ChargerStateUpdateRequest request = new ChargerStateUpdateRequest( - 3, new ChargersStateRequest(List.of(new ChargerStateRequest("ME", "13", "45", "2", "updateDate", "lastTsdt", "lastTedt", "nowTsdt"))), 1, "3", 5 + private static final List chargerStatuses = List.of( + new ChargerStatus( + "stationId", + "chargerId", + LocalDateTime.of(2021, 1, 1, 0, 0, 0), + ChargerState.CHARGING_IN_PROGRESS + ) ); private ChargerStatusCustomRepository chargerStatusCustomRepository; @@ -34,8 +38,8 @@ void setUp(NamedParameterJdbcTemplate namedParameterJdbcTemplate, ChargerStatusR } @Test - void 저장() { - chargerStatusCustomRepository.saveAll(request.items().item()); + void 상태를_저장한다() { + chargerStatusCustomRepository.saveAll(chargerStatuses); List result = chargerStatusRepository.findAll(); diff --git a/backend/src/test/java/com/carffeine/carffeine/service/chargerstation/CongestionServiceTest.java b/backend/src/test/java/com/carffeine/carffeine/service/chargerstation/CongestionServiceTest.java index 0b1b85290..288a7b6fd 100644 --- a/backend/src/test/java/com/carffeine/carffeine/service/chargerstation/CongestionServiceTest.java +++ b/backend/src/test/java/com/carffeine/carffeine/service/chargerstation/CongestionServiceTest.java @@ -6,7 +6,6 @@ import com.carffeine.carffeine.domain.chargestation.charger.ChargerRepository; import com.carffeine.carffeine.domain.chargestation.congestion.PeriodicCongestionRepository; import com.carffeine.carffeine.service.chargerstation.dto.StatisticsRequest; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; import org.junit.jupiter.api.Test; @@ -17,6 +16,8 @@ import java.util.List; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; + @DisplayNameGeneration(ReplaceUnderscores.class) @SuppressWarnings("NonAsciiCharacters") @DataJpaTest @@ -30,13 +31,13 @@ void setCongestionService(PeriodicCongestionRepository periodicCongestionReposit } @Test - void 혼잡도_계산() { + void 상태값이_없는_데이터일_경우_음수가_반환된다() { StatisticsRequest statisticsRequest = new StatisticsRequest("ME174003"); StatisticsResponse statisticsResponse = congestionService.calculateCongestion(statisticsRequest); CongestionResponse expected = getExpected(); - Assertions.assertThat(expected).usingRecursiveComparison() + assertThat(expected).usingRecursiveComparison() .isEqualTo(statisticsResponse.congestion()); }