From d54f00f34141f8a98cf5b98a73981a316df2ac28 Mon Sep 17 00:00:00 2001 From: Hanjaemo <110653660+Hanjaemo@users.noreply.github.com> Date: Fri, 20 Sep 2024 00:54:13 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=B5=EA=B3=B5=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EA=B8=B0=EB=8A=A5=EC=9D=98=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20(#129)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 패키지 정리 * style: 사용되지 않는 코드 제거 * feat: 반복적인 개별 저장을 일괄 저장 방식으로 개선 * feat: @Transactional 추가 * refactor: 코드 구조 개선 --- .../global/exception/ErrorCode.java | 8 +- .../repository/CollectingBoxRepository.java | 10 --- .../publicdata/PublicDataApiController.java | 80 ------------------- .../{ => application}/PublicDataService.java | 73 +++++++++-------- .../{ => domain}/AddressInfoMapper.java | 5 +- .../{ => domain}/KakaoApiManager.java | 3 +- .../publicdata/domain/OpenDataApiManager.java | 46 +++++++++++ .../{ => domain}/PublicDataApiInfo.java | 2 +- .../PublicDataApiInfoRepository.java | 2 +- .../{ => domain}/PublicDataExtract.java | 30 +++---- .../publicdata/{ => dto}/AddressInfoDto.java | 9 ++- .../{ => dto}/LoadCsvPublicDataRequest.java | 2 +- .../{ => dto}/LoadPublicDataRequest.java | 2 +- .../SavePublicDataApiInfoRequest.java | 3 +- .../presentation/PublicDataApiController.java | 42 ++++++++++ 15 files changed, 164 insertions(+), 153 deletions(-) delete mode 100644 src/main/java/contest/collectingbox/module/publicdata/PublicDataApiController.java rename src/main/java/contest/collectingbox/module/publicdata/{ => application}/PublicDataService.java (59%) rename src/main/java/contest/collectingbox/module/publicdata/{ => domain}/AddressInfoMapper.java (89%) rename src/main/java/contest/collectingbox/module/publicdata/{ => domain}/KakaoApiManager.java (95%) create mode 100644 src/main/java/contest/collectingbox/module/publicdata/domain/OpenDataApiManager.java rename src/main/java/contest/collectingbox/module/publicdata/{ => domain}/PublicDataApiInfo.java (91%) rename src/main/java/contest/collectingbox/module/publicdata/{ => domain}/PublicDataApiInfoRepository.java (74%) rename src/main/java/contest/collectingbox/module/publicdata/{ => domain}/PublicDataExtract.java (86%) rename src/main/java/contest/collectingbox/module/publicdata/{ => dto}/AddressInfoDto.java (91%) rename src/main/java/contest/collectingbox/module/publicdata/{ => dto}/LoadCsvPublicDataRequest.java (82%) rename src/main/java/contest/collectingbox/module/publicdata/{ => dto}/LoadPublicDataRequest.java (88%) rename src/main/java/contest/collectingbox/module/publicdata/{ => dto}/SavePublicDataApiInfoRequest.java (81%) create mode 100644 src/main/java/contest/collectingbox/module/publicdata/presentation/PublicDataApiController.java diff --git a/src/main/java/contest/collectingbox/global/exception/ErrorCode.java b/src/main/java/contest/collectingbox/global/exception/ErrorCode.java index 0d0eebc..fc84795 100644 --- a/src/main/java/contest/collectingbox/global/exception/ErrorCode.java +++ b/src/main/java/contest/collectingbox/global/exception/ErrorCode.java @@ -4,8 +4,7 @@ import lombok.Getter; import org.springframework.http.HttpStatus; -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.*; @Getter @AllArgsConstructor @@ -25,11 +24,10 @@ public enum ErrorCode { NOT_FOUND_COLLECTING_BOX(NOT_FOUND, "해당 수거함이 존재하지 않습니다."), // 임시 - NOT_FOUND_TAG(NOT_FOUND, "해당 이름과 일치하는 수거함 태그가 없습니다."); - - // 409 + NOT_FOUND_TAG(NOT_FOUND, "해당 이름과 일치하는 수거함 태그가 없습니다."), // 500 + UNEXPECTED_ERROR_EXTERNAL_API(INTERNAL_SERVER_ERROR, "외부 API 호출 시 알 수 없는 예외가 발생했습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/contest/collectingbox/module/collectingbox/domain/repository/CollectingBoxRepository.java b/src/main/java/contest/collectingbox/module/collectingbox/domain/repository/CollectingBoxRepository.java index 6557096..ad56c38 100644 --- a/src/main/java/contest/collectingbox/module/collectingbox/domain/repository/CollectingBoxRepository.java +++ b/src/main/java/contest/collectingbox/module/collectingbox/domain/repository/CollectingBoxRepository.java @@ -1,17 +1,7 @@ package contest.collectingbox.module.collectingbox.domain.repository; import contest.collectingbox.module.collectingbox.domain.CollectingBox; -import contest.collectingbox.module.collectingbox.domain.Tag; -import contest.collectingbox.module.location.domain.DongInfo; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; public interface CollectingBoxRepository extends JpaRepository, CollectingBoxRepositoryCustom { - - @Query("select c from CollectingBox c join c.location l where l.dongInfo = :dongInfo and c.tag in :tags") - List findAllByDongInfoAndTags(@Param("dongInfo") DongInfo dongInfo, - @Param("tags") List tags); } diff --git a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiController.java b/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiController.java deleted file mode 100644 index a6f6f6c..0000000 --- a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiController.java +++ /dev/null @@ -1,80 +0,0 @@ -package contest.collectingbox.module.publicdata; - -import contest.collectingbox.global.common.ApiResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpMethod; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.List; - -@Slf4j -@RestController -@RequiredArgsConstructor -public class PublicDataApiController { - - private static final String TOTAL_COUNT_KEY = "totalCount"; - - private final PublicDataService publicDataService; - - @Value("${public-data.api.key}") - private String apiKey; - - @PostMapping("/public-data/info") - public ApiResponse savePublicDataApiInfo(@RequestBody List requests) { - publicDataService.savePublicDataApiInfo(requests); - return ApiResponse.ok(requests.size()); - } - - @PostMapping("/public-data/load") - public ApiResponse loadPublicData(@RequestBody List requests) { - long loadedDataCount = 0; - for (LoadPublicDataRequest request : requests) { - try { - System.out.printf("======= %s - %s =======%n", request.getSigungu(), request.getTag().getLabel()); - int totalCount = getTotalCountOfPublicData(request); - loadedDataCount += publicDataService.loadPublicData(callPublicDataApi(request, totalCount), - request.getSigungu(), - request.getTag()); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - return ApiResponse.ok(loadedDataCount); - } - - @PostMapping("/public-data/csv") - public ApiResponse loadCsvPublicData(@RequestBody List requests) { - long loadedDataCount = 0; - for (LoadCsvPublicDataRequest request : requests) { - loadedDataCount += publicDataService.loadCsvPublicData(request); - } - return ApiResponse.ok(loadedDataCount); - } - - private JSONObject callPublicDataApi(LoadPublicDataRequest request, int perPage) throws IOException { - URL url = new URL(request.getUrlWithPerPage(apiKey, perPage)); - HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setRequestMethod(HttpMethod.GET.name()); - urlConnection.setRequestProperty("Content-type", "application/json"); - - BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)); - return new JSONObject(br.readLine()); - } - - private int getTotalCountOfPublicData(LoadPublicDataRequest request) throws IOException { - return Integer.parseInt(callPublicDataApi(request, 1).get(TOTAL_COUNT_KEY).toString()); - } -} diff --git a/src/main/java/contest/collectingbox/module/publicdata/PublicDataService.java b/src/main/java/contest/collectingbox/module/publicdata/application/PublicDataService.java similarity index 59% rename from src/main/java/contest/collectingbox/module/publicdata/PublicDataService.java rename to src/main/java/contest/collectingbox/module/publicdata/application/PublicDataService.java index e4621df..4590667 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/PublicDataService.java +++ b/src/main/java/contest/collectingbox/module/publicdata/application/PublicDataService.java @@ -1,15 +1,21 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.application; import com.opencsv.CSVReader; import com.opencsv.exceptions.CsvValidationException; -import contest.collectingbox.module.collectingbox.domain.repository.CollectingBoxRepository; import contest.collectingbox.module.collectingbox.domain.Tag; +import contest.collectingbox.module.collectingbox.domain.repository.CollectingBoxRepository; import contest.collectingbox.module.location.domain.repository.DongInfoRepository; +import contest.collectingbox.module.publicdata.domain.*; +import contest.collectingbox.module.publicdata.dto.AddressInfoDto; +import contest.collectingbox.module.publicdata.dto.LoadCsvPublicDataRequest; +import contest.collectingbox.module.publicdata.dto.LoadPublicDataRequest; +import contest.collectingbox.module.publicdata.dto.SavePublicDataApiInfoRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONObject; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.io.InputStreamReader; @@ -24,59 +30,62 @@ public class PublicDataService { private static final String CSV_FILE_PATH = "csv/"; + private final PublicDataApiInfoRepository publicDataApiInfoRepository; + private final OpenDataApiManager openDataApiManager; private final PublicDataExtract publicDataExtract; private final KakaoApiManager kakaoApiManager; private final CollectingBoxRepository collectingBoxRepository; private final DongInfoRepository dongInfoRepository; + @Transactional public void savePublicDataApiInfo(List requests) { - for (SavePublicDataApiInfoRequest request : requests) { - publicDataApiInfoRepository.save(request.toEntity()); - } + publicDataApiInfoRepository.saveAll(getEntities(requests)); } - public long loadPublicData(JSONObject jsonObject, String sigungu, Tag tag) { - long loadedDataCount = 0; - JSONArray jsonArray = (JSONArray) jsonObject.get("data"); + private List getEntities(List requests) { + return requests.stream() + .map(SavePublicDataApiInfoRequest::toEntity) + .toList(); + } - Set querySet = new HashSet<>(); - for (Object o : jsonArray) { - JSONObject object = (JSONObject) o; - querySet.add(publicDataExtract.extractQuery(object, sigungu, tag)); - } + @Transactional + public long loadPublicData(List requests) { + long loadedDataCount = 0; + for (LoadPublicDataRequest request : requests) { + log.info("======= {} - {} =======", request.getSigungu(), request.getTag().getLabel()); - for (String query : querySet) { - // 검색 키워드 null 체크 - if (query == null) { - continue; - } + String sigungu = request.getSigungu(); + Tag tag = request.getTag(); - // 카카오 주소 검색 API 호출 - AddressInfoDto addressInfo = kakaoApiManager.fetchAddressInfo(query, tag); + int totalCount = openDataApiManager.fetchTotalCount(request.getCallAddress()); + JSONArray jsonArray = openDataApiManager.fetchOpenData(request.getCallAddress(), totalCount); - // 카카오 주소 검색 API 응답 null 체크 - if (addressInfo == null) { - continue; + Set querySet = new HashSet<>(); + for (Object o : jsonArray) { + publicDataExtract.extractQuery((JSONObject) o, sigungu, tag) + .ifPresent(querySet::add); } - if (addressInfo.hasNull()) { - throw new RuntimeException("kakao API response has null"); - } + for (String query : querySet) { + // 카카오 주소 검색 API 호출 + AddressInfoDto addressInfo = kakaoApiManager.fetchAddressInfo(query, tag); - // 카카오 주소 검색 API 응답 출력 - log.info("query = {}, response = {}", query, addressInfo); + // 카카오 주소 검색 API 응답 출력 + log.info("query = {}, response = {}", query, addressInfo); - // insert DB - if (equals(addressInfo.getSigungu(), sigungu)) { - loadedDataCount++; - collectingBoxRepository.save(addressInfo.toCollectingBox(dongInfoRepository)); + // insert DB + if (addressInfo != null && addressInfo.isSigunguEquals(sigungu)) { + collectingBoxRepository.save(addressInfo.toCollectingBox(dongInfoRepository)); + loadedDataCount++; + } } } return loadedDataCount; } + @Transactional public long loadCsvPublicData(LoadCsvPublicDataRequest request) { String fileName = CSV_FILE_PATH + request.getFileName(); try { diff --git a/src/main/java/contest/collectingbox/module/publicdata/AddressInfoMapper.java b/src/main/java/contest/collectingbox/module/publicdata/domain/AddressInfoMapper.java similarity index 89% rename from src/main/java/contest/collectingbox/module/publicdata/AddressInfoMapper.java rename to src/main/java/contest/collectingbox/module/publicdata/domain/AddressInfoMapper.java index 0e898bb..d7ff0f1 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/AddressInfoMapper.java +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/AddressInfoMapper.java @@ -1,11 +1,12 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.domain; import contest.collectingbox.module.collectingbox.domain.Tag; +import contest.collectingbox.module.publicdata.dto.AddressInfoDto; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.json.JSONObject; -import static contest.collectingbox.module.publicdata.AddressInfoDto.*; +import static contest.collectingbox.module.publicdata.dto.AddressInfoDto.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class AddressInfoMapper { diff --git a/src/main/java/contest/collectingbox/module/publicdata/KakaoApiManager.java b/src/main/java/contest/collectingbox/module/publicdata/domain/KakaoApiManager.java similarity index 95% rename from src/main/java/contest/collectingbox/module/publicdata/KakaoApiManager.java rename to src/main/java/contest/collectingbox/module/publicdata/domain/KakaoApiManager.java index c07aae3..99f9783 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/KakaoApiManager.java +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/KakaoApiManager.java @@ -1,6 +1,7 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.domain; import contest.collectingbox.module.collectingbox.domain.Tag; +import contest.collectingbox.module.publicdata.dto.AddressInfoDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; diff --git a/src/main/java/contest/collectingbox/module/publicdata/domain/OpenDataApiManager.java b/src/main/java/contest/collectingbox/module/publicdata/domain/OpenDataApiManager.java new file mode 100644 index 0000000..390d7df --- /dev/null +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/OpenDataApiManager.java @@ -0,0 +1,46 @@ +package contest.collectingbox.module.publicdata.domain; + +import contest.collectingbox.global.exception.CollectingBoxException; +import org.json.JSONArray; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import static contest.collectingbox.global.exception.ErrorCode.UNEXPECTED_ERROR_EXTERNAL_API; + +@Component +public class OpenDataApiManager { + + private static final String API_URL = "https://api.odcloud.kr/api%s?serviceKey=%s&perPage=%d"; + + @Value("${public-data.api.key}") + private String apiKey; + + public int fetchTotalCount(String callAddress) { + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.getForEntity(getUrl(callAddress, 1), String.class); + if (isError(response)) { + throw new CollectingBoxException(UNEXPECTED_ERROR_EXTERNAL_API); + } + return new JSONObject(response.getBody()).getInt("totalCount"); + } + + public JSONArray fetchOpenData(String callAddress, int perPage) { + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.getForEntity(getUrl(callAddress, perPage), String.class); + if (isError(response)) { + throw new CollectingBoxException(UNEXPECTED_ERROR_EXTERNAL_API); + } + return new JSONObject(response.getBody()).getJSONArray("data"); + } + + private String getUrl(String callAddress, int perPage) { + return String.format(API_URL, callAddress, apiKey, perPage); + } + + private boolean isError(ResponseEntity response) { + return response.getStatusCode().isError(); + } +} diff --git a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfo.java b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfo.java similarity index 91% rename from src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfo.java rename to src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfo.java index 467d36a..00ef879 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfo.java +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfo.java @@ -1,4 +1,4 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.domain; import contest.collectingbox.module.collectingbox.domain.Tag; import jakarta.persistence.*; diff --git a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfoRepository.java b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfoRepository.java similarity index 74% rename from src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfoRepository.java rename to src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfoRepository.java index adae97b..555edbd 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/PublicDataApiInfoRepository.java +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataApiInfoRepository.java @@ -1,4 +1,4 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.domain; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/contest/collectingbox/module/publicdata/PublicDataExtract.java b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataExtract.java similarity index 86% rename from src/main/java/contest/collectingbox/module/publicdata/PublicDataExtract.java rename to src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataExtract.java index 2497127..6417c9c 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/PublicDataExtract.java +++ b/src/main/java/contest/collectingbox/module/publicdata/domain/PublicDataExtract.java @@ -1,38 +1,45 @@ -package contest.collectingbox.module.publicdata; - -import static contest.collectingbox.module.collectingbox.domain.Tag.*; +package contest.collectingbox.module.publicdata.domain; import contest.collectingbox.module.collectingbox.domain.Tag; -import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; import org.springframework.stereotype.Component; +import java.util.Optional; import java.util.Set; +import static contest.collectingbox.module.collectingbox.domain.Tag.TRASH; + @Slf4j @Component public class PublicDataExtract { private static final String[] KEYWORDS = {"도로", "지번", "주소", "소재지", "위치", "장소"}; - public String extractQuery(JSONObject jsonObject, String sigungu, Tag tag) { + public Optional extractQuery(JSONObject jsonObject, String sigungu, Tag tag) { Optional specialValue = extractSpecialCaseValue(jsonObject, sigungu, tag); if (specialValue.isPresent()) { - return specialValue.get(); + return specialValue; } Set keySet = jsonObject.keySet(); for (String keyword : KEYWORDS) { for (String key : keySet) { if (key.contains(keyword) && !jsonObject.isNull(key)) { - return jsonObject.get(key).toString(); + return Optional.ofNullable(jsonObject.get(key).toString()); } } } log.warn("Not contains anything in {}", jsonObject); - return null; + return Optional.empty(); + } + + private Optional extractSpecialCaseValue(JSONObject jsonObject, String sigungu, Tag tag) { + if (sigungu.equals("강북구") && tag == TRASH) { + return Optional.of(jsonObject.optString("세부 위치")); + } + return Optional.empty(); } public int extractCsvQueryIndex(String[] columnNames, String sigungu, Tag tag) { @@ -52,13 +59,6 @@ public int extractCsvQueryIndex(String[] columnNames, String sigungu, Tag tag) { return -1; } - private Optional extractSpecialCaseValue(JSONObject jsonObject, String sigungu, Tag tag) { - if (sigungu.equals("강북구") && tag == TRASH) { - return Optional.of(jsonObject.optString("세부 위치")); - } - return Optional.empty(); - } - private int extractSpecialCaseIndex(String sigungu, Tag tag) { if (sigungu.equals("구로구") && tag == TRASH) { return 1; // 소재지가로명주소 diff --git a/src/main/java/contest/collectingbox/module/publicdata/AddressInfoDto.java b/src/main/java/contest/collectingbox/module/publicdata/dto/AddressInfoDto.java similarity index 91% rename from src/main/java/contest/collectingbox/module/publicdata/AddressInfoDto.java rename to src/main/java/contest/collectingbox/module/publicdata/dto/AddressInfoDto.java index 4e92ba8..f6ef292 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/AddressInfoDto.java +++ b/src/main/java/contest/collectingbox/module/publicdata/dto/AddressInfoDto.java @@ -1,13 +1,12 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.dto; import contest.collectingbox.global.utils.GeometryUtil; import contest.collectingbox.module.collectingbox.domain.CollectingBox; import contest.collectingbox.module.collectingbox.domain.Tag; -import contest.collectingbox.module.location.domain.repository.DongInfoRepository; import contest.collectingbox.module.location.domain.Location; +import contest.collectingbox.module.location.domain.repository.DongInfoRepository; import lombok.*; - @ToString @Getter @Builder @@ -40,6 +39,10 @@ public boolean hasEmptyValue() { || tag.name().isEmpty(); } + public boolean isSigunguEquals(String sigungu) { + return this.sigungu.equals(sigungu); + } + public CollectingBox toCollectingBox(DongInfoRepository repository) { Location location = Location.builder() .dongInfo(repository.findBySigunguNmAndDongNm(sigungu, dong)) diff --git a/src/main/java/contest/collectingbox/module/publicdata/LoadCsvPublicDataRequest.java b/src/main/java/contest/collectingbox/module/publicdata/dto/LoadCsvPublicDataRequest.java similarity index 82% rename from src/main/java/contest/collectingbox/module/publicdata/LoadCsvPublicDataRequest.java rename to src/main/java/contest/collectingbox/module/publicdata/dto/LoadCsvPublicDataRequest.java index 44afef3..975811d 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/LoadCsvPublicDataRequest.java +++ b/src/main/java/contest/collectingbox/module/publicdata/dto/LoadCsvPublicDataRequest.java @@ -1,4 +1,4 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.dto; import contest.collectingbox.module.collectingbox.domain.Tag; import lombok.Getter; diff --git a/src/main/java/contest/collectingbox/module/publicdata/LoadPublicDataRequest.java b/src/main/java/contest/collectingbox/module/publicdata/dto/LoadPublicDataRequest.java similarity index 88% rename from src/main/java/contest/collectingbox/module/publicdata/LoadPublicDataRequest.java rename to src/main/java/contest/collectingbox/module/publicdata/dto/LoadPublicDataRequest.java index e5852e1..114c317 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/LoadPublicDataRequest.java +++ b/src/main/java/contest/collectingbox/module/publicdata/dto/LoadPublicDataRequest.java @@ -1,4 +1,4 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.dto; import contest.collectingbox.module.collectingbox.domain.Tag; import lombok.Data; diff --git a/src/main/java/contest/collectingbox/module/publicdata/SavePublicDataApiInfoRequest.java b/src/main/java/contest/collectingbox/module/publicdata/dto/SavePublicDataApiInfoRequest.java similarity index 81% rename from src/main/java/contest/collectingbox/module/publicdata/SavePublicDataApiInfoRequest.java rename to src/main/java/contest/collectingbox/module/publicdata/dto/SavePublicDataApiInfoRequest.java index 8907866..a473618 100644 --- a/src/main/java/contest/collectingbox/module/publicdata/SavePublicDataApiInfoRequest.java +++ b/src/main/java/contest/collectingbox/module/publicdata/dto/SavePublicDataApiInfoRequest.java @@ -1,6 +1,7 @@ -package contest.collectingbox.module.publicdata; +package contest.collectingbox.module.publicdata.dto; import contest.collectingbox.module.collectingbox.domain.Tag; +import contest.collectingbox.module.publicdata.domain.PublicDataApiInfo; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/contest/collectingbox/module/publicdata/presentation/PublicDataApiController.java b/src/main/java/contest/collectingbox/module/publicdata/presentation/PublicDataApiController.java new file mode 100644 index 0000000..a9c76c6 --- /dev/null +++ b/src/main/java/contest/collectingbox/module/publicdata/presentation/PublicDataApiController.java @@ -0,0 +1,42 @@ +package contest.collectingbox.module.publicdata.presentation; + +import contest.collectingbox.global.common.ApiResponse; +import contest.collectingbox.module.publicdata.application.PublicDataService; +import contest.collectingbox.module.publicdata.dto.LoadCsvPublicDataRequest; +import contest.collectingbox.module.publicdata.dto.LoadPublicDataRequest; +import contest.collectingbox.module.publicdata.dto.SavePublicDataApiInfoRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class PublicDataApiController { + + private final PublicDataService publicDataService; + + @PostMapping("/public-data/info") + public ApiResponse savePublicDataApiInfo(@RequestBody List requests) { + publicDataService.savePublicDataApiInfo(requests); + return ApiResponse.ok(requests.size()); + } + + @PostMapping("/public-data/load") + public ApiResponse loadPublicData(@RequestBody List requests) { + return ApiResponse.ok(publicDataService.loadPublicData(requests)); + } + + @PostMapping("/public-data/csv") + public ApiResponse loadCsvPublicData(@RequestBody List requests) { + long loadedDataCount = 0; + for (LoadCsvPublicDataRequest request : requests) { + loadedDataCount += publicDataService.loadCsvPublicData(request); + } + return ApiResponse.ok(loadedDataCount); + } +}