-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor: 부산, 서울 응답값에 JsonIgnoreProperties 추가 * test: 부산, 서울 변환 로직 테스트 추가 * refactor: 조회 로직 수정 및 EqualsAndHashCode 추가 * feat: 전국 주차장 데이터 추가 * refactor: 요청 url 및 URI 생성 방식 변경 * refactor: URI 생성 방식 변경 * refactor: 커낵션 타임아웃 설정 * fix: 좌표가 없는 데이터만 좌표를 가져오도록 수정 * fix: Location에서 제공되지 않는 값 public 상수로 변경 * refactor: SearchingCondition 도메인 서비스 패키지로 이동 * refactor: 어플리케이션단에서 Enum 컬랙션을 List 대신 Set 사용하도록 변경
- Loading branch information
Showing
51 changed files
with
3,743 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
...ler/src/main/java/com/parkingcomestrue/external/parkingapi/korea/KoreaParkingAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package com.parkingcomestrue.external.parkingapi.korea; | ||
|
||
import com.parkingcomestrue.common.domain.parking.BaseInformation; | ||
import com.parkingcomestrue.common.domain.parking.Fee; | ||
import com.parkingcomestrue.common.domain.parking.FeePolicy; | ||
import com.parkingcomestrue.common.domain.parking.FreeOperatingTime; | ||
import com.parkingcomestrue.common.domain.parking.Location; | ||
import com.parkingcomestrue.common.domain.parking.OperatingTime; | ||
import com.parkingcomestrue.common.domain.parking.OperationType; | ||
import com.parkingcomestrue.common.domain.parking.Parking; | ||
import com.parkingcomestrue.common.domain.parking.ParkingType; | ||
import com.parkingcomestrue.common.domain.parking.PayType; | ||
import com.parkingcomestrue.common.domain.parking.Space; | ||
import com.parkingcomestrue.common.domain.parking.TimeInfo; | ||
import com.parkingcomestrue.common.domain.parking.TimeUnit; | ||
import java.time.DateTimeException; | ||
import java.time.LocalTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import org.apache.logging.log4j.util.Strings; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class KoreaParkingAdapter { | ||
|
||
private static final String NO_PROVIDE = "-1"; | ||
private static final String FREE = "무료"; | ||
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); | ||
private static final String HOURS_24 = "23:59"; | ||
private static final String HOURS_00 = "00:00"; | ||
|
||
public List<Parking> convert(KoreaParkingResponse response) { | ||
return response.getResponse().getBody().getItems().stream() | ||
.map(this::toParking) | ||
.toList(); | ||
} | ||
|
||
private Parking toParking(KoreaParkingResponse.Response.Body.Item item) { | ||
return new Parking( | ||
getBaseInformation(item), | ||
getLocation(item), | ||
getSpace(item), | ||
getFreeOperatingTime(item), | ||
getOperatingTime(item), | ||
getFeePolicy(item) | ||
); | ||
} | ||
|
||
private BaseInformation getBaseInformation(KoreaParkingResponse.Response.Body.Item item) { | ||
return new BaseInformation( | ||
item.getParkingName(), | ||
item.getTel(), | ||
filterAddress(item), | ||
toPayTypes(item), | ||
ParkingType.find(item.getParkingType()), | ||
OperationType.find(item.getOperationType()) | ||
); | ||
} | ||
|
||
private String filterAddress(KoreaParkingResponse.Response.Body.Item item) { | ||
if (Strings.isBlank(item.getOldAddress())) { | ||
return item.getNewAddress(); | ||
} | ||
return item.getOldAddress(); | ||
} | ||
|
||
private Set<PayType> toPayTypes(KoreaParkingResponse.Response.Body.Item item) { | ||
Set<PayType> payTypes = new HashSet<>(); | ||
for (PayType payType : PayType.values()) { | ||
if (item.getPayType().contains(payType.getDescription())) { | ||
payTypes.add(payType); | ||
} | ||
} | ||
if (payTypes.isEmpty()) { | ||
return Set.of(PayType.NO_INFO); | ||
} | ||
return payTypes; | ||
} | ||
|
||
private Location getLocation(KoreaParkingResponse.Response.Body.Item item) { | ||
return Location.of(item.getLongitude(), item.getLatitude()); | ||
} | ||
|
||
private Space getSpace(KoreaParkingResponse.Response.Body.Item item) { | ||
return Space.of(item.getCapacity(), NO_PROVIDE); | ||
} | ||
|
||
private FreeOperatingTime getFreeOperatingTime(KoreaParkingResponse.Response.Body.Item item) { | ||
if (item.getFeeInfo().equals(FREE)) { | ||
return FreeOperatingTime.ALWAYS_FREE; | ||
} | ||
return FreeOperatingTime.ALWAYS_PAY; | ||
} | ||
|
||
private OperatingTime getOperatingTime(KoreaParkingResponse.Response.Body.Item item) { | ||
return new OperatingTime( | ||
toTimeInfo(item.getWeekDayBeginTime(), item.getWeekdayEndTime()), | ||
toTimeInfo(item.getSaturdayBeginTime(), item.getSaturdayEndTime()), | ||
toTimeInfo(item.getHolidayBeginTime(), item.getHolidayEndTime()) | ||
); | ||
} | ||
|
||
private TimeInfo toTimeInfo(String beginTime, String endTime) { | ||
if (HOURS_00.equals(beginTime) && HOURS_24.equals(endTime)) { | ||
return TimeInfo.ALL_DAY; | ||
} | ||
if (HOURS_00.equals(beginTime) && HOURS_00.equals(endTime)) { | ||
return TimeInfo.CLOSED; | ||
} | ||
return new TimeInfo(parsingOperationTime(beginTime), parsingOperationTime(endTime)); | ||
} | ||
|
||
private LocalTime parsingOperationTime(String time) { | ||
if (time.equals(HOURS_24)) { | ||
return LocalTime.MAX; | ||
} | ||
try { | ||
return LocalTime.parse(time, TIME_FORMATTER); | ||
} catch (DateTimeException e) { | ||
return null; | ||
} | ||
} | ||
|
||
private FeePolicy getFeePolicy(KoreaParkingResponse.Response.Body.Item item) { | ||
return new FeePolicy( | ||
Fee.from(item.getBaseFee()), | ||
Fee.from(item.getExtraFee()), | ||
TimeUnit.from(item.getBaseTimeUnit()), | ||
TimeUnit.from(item.getExtraTimeUnit()), | ||
Fee.from(item.getDayMaximumFee()) | ||
); | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
.../src/main/java/com/parkingcomestrue/external/parkingapi/korea/KoreaParkingApiService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.parkingcomestrue.external.parkingapi.korea; | ||
|
||
import com.parkingcomestrue.common.domain.parking.Parking; | ||
import com.parkingcomestrue.external.parkingapi.ParkingApiService; | ||
import java.net.URI; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.RestTemplate; | ||
import org.springframework.web.util.DefaultUriBuilderFactory; | ||
|
||
@Component | ||
public class KoreaParkingApiService implements ParkingApiService { | ||
|
||
private static final String URL = "http://api.data.go.kr/openapi/tn_pubr_prkplce_info_api"; | ||
private static final String RESULT_TYPE = "json"; | ||
private static final int SIZE = 250; | ||
private static final String NORMAL_RESULT_CODE = "00"; | ||
|
||
@Value("${korea-parking-key}") | ||
private String API_KEY; | ||
|
||
private final KoreaParkingAdapter adapter; | ||
private final RestTemplate restTemplate; | ||
|
||
public KoreaParkingApiService(KoreaParkingAdapter adapter, | ||
@Qualifier("parkingApiRestTemplate") RestTemplate restTemplate) { | ||
this.adapter = adapter; | ||
this.restTemplate = restTemplate; | ||
} | ||
|
||
@Override | ||
public List<Parking> read() throws Exception { | ||
Set<KoreaParkingResponse> result = new HashSet<>(); | ||
for (int pageNumber = 1; ; pageNumber++) { | ||
KoreaParkingResponse response = call(pageNumber, SIZE); | ||
String resultCode = response.getResponse().getHeader().getResultCode(); | ||
if (NORMAL_RESULT_CODE.equals(resultCode)) { | ||
result.add(response); | ||
continue; | ||
} | ||
break; | ||
} | ||
return result.stream() | ||
.flatMap(response -> adapter.convert(response).stream()) | ||
.toList(); | ||
} | ||
|
||
private KoreaParkingResponse call(int startIndex, int size) { | ||
URI uri = makeUri(startIndex, size); | ||
ResponseEntity<KoreaParkingResponse> response = restTemplate.getForEntity(uri, KoreaParkingResponse.class); | ||
return response.getBody(); | ||
} | ||
|
||
private URI makeUri(int startIndex, int size) { | ||
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(URL); | ||
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY); | ||
return factory.builder() | ||
.queryParam("serviceKey", API_KEY) | ||
.queryParam("pageNo", startIndex) | ||
.queryParam("numOfRows", size) | ||
.queryParam("type", RESULT_TYPE) | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.