diff --git a/src/main/java/com/kustacks/kuring/category/domain/Category.java b/src/main/java/com/kustacks/kuring/category/domain/Category.java index bb9b3bb7..22e502a7 100644 --- a/src/main/java/com/kustacks/kuring/category/domain/Category.java +++ b/src/main/java/com/kustacks/kuring/category/domain/Category.java @@ -1,5 +1,6 @@ package com.kustacks.kuring.category.domain; +import com.kustacks.kuring.kuapi.CategoryName; import com.kustacks.kuring.notice.domain.Notice; import com.kustacks.kuring.user.domain.UserCategory; import lombok.AccessLevel; @@ -33,6 +34,10 @@ public Category(String name) { this.name = name; } + public boolean isSameName(CategoryName categoryName) { + return this.name.equals(categoryName); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/com/kustacks/kuring/config/MappedBeanConfig.java b/src/main/java/com/kustacks/kuring/config/MappedBeanConfig.java index 4de1ad99..e5b34d09 100644 --- a/src/main/java/com/kustacks/kuring/config/MappedBeanConfig.java +++ b/src/main/java/com/kustacks/kuring/config/MappedBeanConfig.java @@ -1,7 +1,8 @@ package com.kustacks.kuring.config; import com.kustacks.kuring.kuapi.CategoryName; -import com.kustacks.kuring.kuapi.api.notice.NoticeAPIClient; +import com.kustacks.kuring.kuapi.api.notice.NoticeApiClient; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -9,26 +10,25 @@ import java.util.Map; @Configuration +@RequiredArgsConstructor public class MappedBeanConfig { - private final NoticeAPIClient kuisNoticeAPIClient; - private final NoticeAPIClient libraryNoticeAPIClient; + private final NoticeApiClient kuisNoticeApiClient; - public MappedBeanConfig(NoticeAPIClient kuisNoticeAPIClient, NoticeAPIClient libraryNoticeAPIClient) { - this.kuisNoticeAPIClient = kuisNoticeAPIClient; - this.libraryNoticeAPIClient = libraryNoticeAPIClient; - } + private final NoticeApiClient libraryNoticeApiClient; @Bean - public Map noticeAPIClientMap() { - HashMap map = new HashMap<>(); + public Map noticeApiClientMap() { + HashMap map = new HashMap<>(); + for (CategoryName categoryName : CategoryName.values()) { if(categoryName.equals(CategoryName.LIBRARY)) { - map.put(categoryName, libraryNoticeAPIClient); + map.put(categoryName, libraryNoticeApiClient); } else { - map.put(categoryName, kuisNoticeAPIClient); + map.put(categoryName, kuisNoticeApiClient); } } + return map; } } diff --git a/src/main/java/com/kustacks/kuring/config/RestConfig.java b/src/main/java/com/kustacks/kuring/config/RestTemplateConfig.java similarity index 96% rename from src/main/java/com/kustacks/kuring/config/RestConfig.java rename to src/main/java/com/kustacks/kuring/config/RestTemplateConfig.java index e520fe81..c61e7b85 100644 --- a/src/main/java/com/kustacks/kuring/config/RestConfig.java +++ b/src/main/java/com/kustacks/kuring/config/RestTemplateConfig.java @@ -8,7 +8,7 @@ import org.springframework.web.client.RestTemplate; @Configuration -public class RestConfig { +public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { diff --git a/src/main/java/com/kustacks/kuring/kuapi/CategoryName.java b/src/main/java/com/kustacks/kuring/kuapi/CategoryName.java index d7b4d6a8..be45f3e8 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/CategoryName.java +++ b/src/main/java/com/kustacks/kuring/kuapi/CategoryName.java @@ -24,6 +24,10 @@ public enum CategoryName { this.korName = korName; } + public boolean isSameName(String name) { + return this.name.equals(name); + } + public boolean isSameShortName(String shortName) { return this.shortName.equals(shortName); } diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/APIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/ApiClient.java similarity index 59% rename from src/main/java/com/kustacks/kuring/kuapi/api/APIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/ApiClient.java index fab5259f..c85e71bf 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/APIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/ApiClient.java @@ -1,4 +1,4 @@ package com.kustacks.kuring.kuapi.api; -public interface APIClient { +public interface ApiClient { } diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClient.java similarity index 97% rename from src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClient.java index 26cd372f..35c22306 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClient.java @@ -24,7 +24,7 @@ @Slf4j @Component -public class KuisNoticeAPIClient implements NoticeAPIClient { +public class KuisNoticeApiClient implements NoticeApiClient { @Value("${notice.referer}") private String noticeReferer; @@ -37,7 +37,7 @@ public class KuisNoticeAPIClient implements NoticeAPIClient { private final KuisAuthManager kuisAuthManager; private final Map noticeRequestBodies; - public KuisNoticeAPIClient(KuisAuthManager parsingKuisAuthManager, + public KuisNoticeApiClient(KuisAuthManager parsingKuisAuthManager, KuisNoticeDTOToCommonFormatDTOConverter dtoConverter, BachelorKuisNoticeRequestBody bachelorNoticeRequestBody, diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeAPIClient.java deleted file mode 100644 index f183cce0..00000000 --- a/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeAPIClient.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.kustacks.kuring.kuapi.api.notice; - -import com.kustacks.kuring.common.error.ErrorCode; -import com.kustacks.kuring.common.error.InternalLogicException; -import com.kustacks.kuring.kuapi.CategoryName; -import com.kustacks.kuring.kuapi.notice.dto.response.CommonNoticeFormatDTO; -import com.kustacks.kuring.kuapi.notice.dto.response.LibraryNoticeDTO; -import com.kustacks.kuring.kuapi.notice.dto.response.LibraryNoticeResponseDTO; -import com.kustacks.kuring.common.utils.converter.DTOConverter; -import com.kustacks.kuring.common.utils.converter.LibraryNoticeDTOToCommonFormatDTOConverter; -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.UriComponentsBuilder; - -import java.util.LinkedList; -import java.util.List; - -@Component -public class LibraryNoticeAPIClient implements NoticeAPIClient { - - @Value("${library.request-url}") - private String libraryUrl; - - private final DTOConverter dtoConverter; - private final RestTemplate restTemplate; - - public LibraryNoticeAPIClient(LibraryNoticeDTOToCommonFormatDTOConverter dtoConverter, RestTemplate restTemplate) { - this.dtoConverter = dtoConverter; - this.restTemplate = restTemplate; - } - - /* - 도서관 공지 갱신 - */ - - @Override - public List getNotices(CategoryName categoryName) throws InternalLogicException { - - int offset = 0; - int max = 20; - int reqIdx = 0; - List libraryNoticeDTOList = new LinkedList<>(); - while(reqIdx < 2) { - String fullLibraryUrl = UriComponentsBuilder.fromUriString(libraryUrl).queryParam("offset", offset).queryParam("max", max).build().toString(); - ResponseEntity libraryResponse = restTemplate.getForEntity(fullLibraryUrl, LibraryNoticeResponseDTO.class); - LibraryNoticeResponseDTO libraryNoticeResponseDTO = libraryResponse.getBody(); - if(libraryNoticeResponseDTO == null) { -// log.error("도서관 공지 {}번째 요청에 대한 응답의 body가 없습니다.", reqIdx + 1); - throw new InternalLogicException(ErrorCode.LIB_CANNOT_PARSE_JSON); - } - - boolean isLibraryRequestSuccess = libraryNoticeResponseDTO.isSuccess(); - if(!isLibraryRequestSuccess) { -// log.error("도서관 공지 {}번째 요청에 대한 응답이 fail입니다.", reqIdx + 1); - throw new InternalLogicException(ErrorCode.LIB_BAD_RESPONSE); - } - - offset = max; - max = libraryNoticeResponseDTO.getData().getTotalCount() - max; - - libraryNoticeDTOList.addAll(libraryNoticeResponseDTO.getData().getList()); - ++reqIdx; - } - - return convertToCommonFormatDTO(libraryNoticeDTOList); - } - - private List convertToCommonFormatDTO(List libraryNoticeDTOList) { - - List ret = new LinkedList<>(); - for (LibraryNoticeDTO libraryNoticeDTO : libraryNoticeDTOList) { - ret.add((CommonNoticeFormatDTO) dtoConverter.convert(libraryNoticeDTO)); - } - - return ret; - } -} diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeApiClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeApiClient.java new file mode 100644 index 00000000..4b622a0e --- /dev/null +++ b/src/main/java/com/kustacks/kuring/kuapi/api/notice/LibraryNoticeApiClient.java @@ -0,0 +1,91 @@ +package com.kustacks.kuring.kuapi.api.notice; + +import com.kustacks.kuring.common.error.ErrorCode; +import com.kustacks.kuring.common.error.InternalLogicException; +import com.kustacks.kuring.common.utils.converter.DTOConverter; +import com.kustacks.kuring.common.utils.converter.LibraryNoticeDTOToCommonFormatDTOConverter; +import com.kustacks.kuring.kuapi.CategoryName; +import com.kustacks.kuring.kuapi.notice.dto.response.CommonNoticeFormatDTO; +import com.kustacks.kuring.kuapi.notice.dto.response.LibraryNoticeDTO; +import com.kustacks.kuring.kuapi.notice.dto.response.LibraryNoticeResponseDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Component +public class LibraryNoticeApiClient implements NoticeApiClient { + + private static final int MAX_REQUEST_COUNT = 2; + + private final DTOConverter dtoConverter; + private final RestTemplate restTemplate; + + @Value("${library.request-url}") + private String libraryUrl; + + public LibraryNoticeApiClient(LibraryNoticeDTOToCommonFormatDTOConverter dtoConverter, RestTemplate restTemplate) { + this.dtoConverter = dtoConverter; + this.restTemplate = restTemplate; + } + + @Override + public List getNotices(CategoryName categoryName) throws InternalLogicException { + List libraryNoticeDtoList = scrapLibraryNoticeDtos(); + return convertToCommonFormatDto(libraryNoticeDtoList); + } + + private List scrapLibraryNoticeDtos() { + int offset = 0; + int max = 20; + + List libraryNoticeDTOList = new LinkedList<>(); + for (int requestIndex = 0; requestIndex < MAX_REQUEST_COUNT; requestIndex++) { + String completeLibraryUrl = buildUrl(libraryUrl, offset, max); + LibraryNoticeResponseDTO libraryNoticeResponseDTO = restTemplate + .getForEntity(completeLibraryUrl, LibraryNoticeResponseDTO.class) + .getBody(); + + validateResponse(requestIndex, libraryNoticeResponseDTO); + + offset = max; + max = libraryNoticeResponseDTO.getTotalCount() - max; + + libraryNoticeDTOList.addAll(libraryNoticeResponseDTO.getData().getList()); + } + + return libraryNoticeDTOList; + } + + private String buildUrl(String url, int offset, int max) { + return UriComponentsBuilder.fromUriString(url) + .queryParam("offset", offset) + .queryParam("max", max) + .build().toString(); + } + + private List convertToCommonFormatDto(List libraryNoticeDtoList) { + return libraryNoticeDtoList.stream() + .map(dto -> (CommonNoticeFormatDTO) dtoConverter.convert(dto)) + .collect(Collectors.toList()); + } + + private void validateResponse(int requestIndex, LibraryNoticeResponseDTO libraryNoticeResponseDTO) { + if (libraryNoticeResponseDTO == null) { + log.error("도서관 공지 {}번째 요청에 대한 응답의 body가 없습니다.", requestIndex + 1); + throw new InternalLogicException(ErrorCode.LIB_CANNOT_PARSE_JSON); + } + + if (!libraryNoticeResponseDTO.isSuccess()) { + log.error("도서관 공지 {}번째 요청에 대한 응답이 fail입니다.", requestIndex + 1); + throw new InternalLogicException(ErrorCode.LIB_BAD_RESPONSE); + } + } +} + diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeApiClient.java similarity index 79% rename from src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeApiClient.java index 3a36e39f..6f4f0e17 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/notice/NoticeApiClient.java @@ -2,13 +2,13 @@ import com.kustacks.kuring.common.error.InternalLogicException; import com.kustacks.kuring.kuapi.CategoryName; -import com.kustacks.kuring.kuapi.api.APIClient; +import com.kustacks.kuring.kuapi.api.ApiClient; import com.kustacks.kuring.kuapi.notice.dto.response.CommonNoticeFormatDTO; import java.util.List; // TODO: support(CategoryName) 필요 -public interface NoticeAPIClient extends APIClient { +public interface NoticeApiClient extends ApiClient { List getNotices(CategoryName categoryName) throws InternalLogicException; } diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffApiClient.java similarity index 95% rename from src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffApiClient.java index cedff782..a840f508 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/staff/EachDeptStaffApiClient.java @@ -19,14 +19,14 @@ import java.util.Map; @Component -public class EachDeptStaffAPIClient implements StaffAPIClient { +public class EachDeptStaffApiClient implements StaffApiClient { @Value("${staff.each-dept-url}") private String baseUrl; private final JsoupClient jsoupClient; - public EachDeptStaffAPIClient(JsoupClient normalJsoupClient) { + public EachDeptStaffApiClient(JsoupClient normalJsoupClient) { this.jsoupClient = normalJsoupClient; } diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffApiClient.java similarity index 96% rename from src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffApiClient.java index c28bf620..0b097d13 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/staff/KuStaffApiClient.java @@ -17,12 +17,12 @@ import java.util.Map; @Component -public class KuStaffAPIClient implements StaffAPIClient { +public class KuStaffApiClient implements StaffApiClient { private final Map urlMap; private final JsoupClient jsoupClient; - public KuStaffAPIClient( + public KuStaffApiClient( @Value("${staff.living-design-url}") String livingDesignUrl, @Value("${staff.communication-design-url}") String communicationDesignUrl, DeptInfo communicationDesignDept, diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffApiClient.java similarity index 91% rename from src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffApiClient.java index 2c94d43d..654ddbb6 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/staff/RealEstateStaffApiClient.java @@ -14,14 +14,14 @@ import java.util.List; @Component -public class RealEstateStaffAPIClient implements StaffAPIClient { +public class RealEstateStaffApiClient implements StaffApiClient { @Value("${staff.real-estate-url}") private String baseUrl; private final JsoupClient jsoupClient; - public RealEstateStaffAPIClient(JsoupClient proxyJsoupClient) { + public RealEstateStaffApiClient(JsoupClient proxyJsoupClient) { this.jsoupClient = proxyJsoupClient; } diff --git a/src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffAPIClient.java b/src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffApiClient.java similarity index 79% rename from src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffAPIClient.java rename to src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffApiClient.java index c434c14e..c7ec6006 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffAPIClient.java +++ b/src/main/java/com/kustacks/kuring/kuapi/api/staff/StaffApiClient.java @@ -1,13 +1,13 @@ package com.kustacks.kuring.kuapi.api.staff; import com.kustacks.kuring.common.error.InternalLogicException; -import com.kustacks.kuring.kuapi.api.APIClient; +import com.kustacks.kuring.kuapi.api.ApiClient; import com.kustacks.kuring.kuapi.staff.deptinfo.DeptInfo; import org.jsoup.nodes.Document; import java.util.List; -public interface StaffAPIClient extends APIClient { +public interface StaffApiClient extends ApiClient { int SCRAP_TIMEOUT = 10000; diff --git a/src/main/java/com/kustacks/kuring/kuapi/notice/NoticeUpdater.java b/src/main/java/com/kustacks/kuring/kuapi/notice/NoticeUpdater.java index fe351a38..c2b9a0e2 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/notice/NoticeUpdater.java +++ b/src/main/java/com/kustacks/kuring/kuapi/notice/NoticeUpdater.java @@ -11,7 +11,7 @@ import com.kustacks.kuring.common.utils.converter.DateConverter; import com.kustacks.kuring.kuapi.CategoryName; import com.kustacks.kuring.kuapi.Updater; -import com.kustacks.kuring.kuapi.api.notice.NoticeAPIClient; +import com.kustacks.kuring.kuapi.api.notice.NoticeApiClient; import com.kustacks.kuring.kuapi.notice.dto.response.CommonNoticeFormatDTO; import com.kustacks.kuring.notice.domain.Notice; import com.kustacks.kuring.notice.domain.NoticeRepository; @@ -33,7 +33,7 @@ @Component public class NoticeUpdater implements Updater { - private final Map noticeAPIClientMap; + private final Map noticeAPIClientMap; private final DTOConverter dtoConverter; private final DateConverter dateConverter; private final FirebaseService firebaseService; @@ -43,20 +43,16 @@ public class NoticeUpdater implements Updater { private Map categoryMap; public NoticeUpdater(FirebaseService firebaseService, - DTOConverter noticeEntityToNoticeMessageDTOConverter, DateConverter ymdhmsToYmdConverter, - Map noticeAPIClientMap, - + Map noticeAPIClientMap, NoticeRepository noticeRepository, - CategoryRepository categoryRepository) { - + CategoryRepository categoryRepository) + { + this.firebaseService = firebaseService; this.dtoConverter = noticeEntityToNoticeMessageDTOConverter; this.dateConverter = ymdhmsToYmdConverter; this.noticeAPIClientMap = noticeAPIClientMap; - - this.firebaseService = firebaseService; - this.noticeRepository = noticeRepository; this.categoryRepository = categoryRepository; } @@ -64,18 +60,28 @@ public NoticeUpdater(FirebaseService firebaseService, @Override @Scheduled(fixedRate = 10, timeUnit = TimeUnit.MINUTES) public void update() { - log.info("========== 공지 업데이트 시작 =========="); - /* - 학사, 장학, 취창업, 국제, 학생, 산학, 일반, 도서관 공지 갱신 - */ - Map> apiNoticesMap = new HashMap<>(); // 수신한 공지 데이터를 저장할 변수 - for (CategoryName categoryName : CategoryName.values()) { - List commonNoticeFormatDTO; + Map> apiNoticesMap = scrapNewNotices(); + List willBeNotificationNotices = compareAndUpdateDB(apiNoticesMap); + + List notificationDtoList = createNotification(willBeNotificationNotices); + + sendNotificationByFcm(notificationDtoList); + + log.info("========== 공지 업데이트 종료 =========="); + } + + /* + 학사, 장학, 취창업, 국제, 학생, 산학, 일반, 도서관 공지 갱신 + */ + private Map> scrapNewNotices() { + Map> apiNoticesMap = new HashMap<>(); + + for (CategoryName categoryName : CategoryName.values()) { try { - commonNoticeFormatDTO = noticeAPIClientMap.get(categoryName).getNotices(categoryName); + List commonNoticeFormatDTO = noticeAPIClientMap.get(categoryName).getNotices(categoryName); apiNoticesMap.put(categoryName, commonNoticeFormatDTO); } catch (InternalLogicException e) { log.info("{}", e.getErrorCode().getMessage()); @@ -85,41 +91,13 @@ public void update() { } } - // DB에 있는 공지 데이터 카테고리별로 꺼내와서 - // kuisNoticeResponseBody에 있는 데이터가 DB에는 없는 경우 -> DB에 공지 추가 - // DB에 있는 데이터가 kuisNoticeResponseBody에는 없는 경우 -> DB에 공지 삭제 - List willBeNotiNotices = compareAndUpdateDB(apiNoticesMap); - List willBeNotiNoticeDTOList = new ArrayList<>(willBeNotiNotices.size()); - for (Notice notice : willBeNotiNotices) { - if(CategoryName.LIBRARY.getName().equals(notice.getCategory().getName())) { - // TODO: notice entity 내용을 변경해서 사용하는게 좋은 방법인지는 생각을 해봐야함 - // 혹시나 compareAndUpdateDB에서 영속성 컨텍스트에 남아있는 notice entity의 내용이 변경되어서 저장될까봐 - // compareAndUpdateDB에서 saveAndFlush 메서드를 사용함. - notice.setPostedDate(dateConverter.convert(notice.getPostedDate())); - } - willBeNotiNoticeDTOList.add((NoticeMessageDto) dtoConverter.convert(notice)); - } - - // FCM으로 새롭게 수신한 공지 데이터 전송 - try { - firebaseService.sendNoticeMessageList(willBeNotiNoticeDTOList); - log.info("FCM에 정상적으로 메세지를 전송했습니다."); - log.info("전송된 공지 목록은 다음과 같습니다."); - for (NoticeMessageDto messageDTO : willBeNotiNoticeDTOList) { - log.info("아이디 = {}, 날짜 = {}, 카테고리 = {}, 제목 = {}", messageDTO.getArticleId(), messageDTO.getPostedDate(), messageDTO.getCategory(), messageDTO.getSubject()); - } - } catch(FirebaseMessageSendException e) { - log.error("새로운 공지의 FCM 전송에 실패했습니다."); - throw new InternalLogicException(ErrorCode.FB_FAIL_SEND, e); - } catch(Exception e) { - log.error("새로운 공지를 FCM에 보내는 중 알 수 없는 오류가 발생했습니다."); - throw new InternalLogicException(ErrorCode.UNKNOWN_ERROR, e); - } - - log.info("========== 공지 업데이트 종료 =========="); + return apiNoticesMap; } private List compareAndUpdateDB(Map> apiNoticesMap) { + // DB에 있는 공지 데이터 카테고리별로 꺼내와서 + // kuisNoticeResponseBody에 있는 데이터가 DB에는 없는 경우 -> DB에 공지 추가 + // DB에 있는 데이터가 kuisNoticeResponseBody에는 없는 경우 -> DB에 공지 삭제 if(categoryMap == null) { categoryMap = categoryRepository.findAllMap(); @@ -134,7 +112,7 @@ private List compareAndUpdateDB(Map commonNoticeFormatDTOList = apiNoticesMap.get(categoryName); // categoryName에 대응하는, DB에 존재하는 공지 데이터 - Map dbNoticeMap = noticeRepository.findByCategoryMap(noticeCategory); + Map dbNoticeMap = noticeRepository.findNoticeMapByCategory(noticeCategory); // commonNoticeFormatDTOList를 순회하면서 // 현재 공지가 dbNoticeList에 있으면 dbNoticeList에서 해당 공지 없애고(실제 DB에는 아무런 작업 안함) @@ -169,4 +147,35 @@ private List compareAndUpdateDB(Map createNotification(List willBeNotiNotices) { + List willBeNotiNoticeDtoList = new ArrayList<>(willBeNotiNotices.size()); + for (Notice notice : willBeNotiNotices) { + if(notice.isSameCategoryName(CategoryName.LIBRARY)) { + // TODO: notice entity 내용을 변경해서 사용하는게 좋은 방법인지는 생각을 해봐야함 + // 혹시나 compareAndUpdateDB에서 영속성 컨텍스트에 남아있는 notice entity의 내용이 변경되어서 저장될까봐 + // compareAndUpdateDB에서 saveAndFlush 메서드를 사용함. + notice.setPostedDate(dateConverter.convert(notice.getPostedDate())); + } + willBeNotiNoticeDtoList.add((NoticeMessageDto) dtoConverter.convert(notice)); + } + return willBeNotiNoticeDtoList; + } + + private void sendNotificationByFcm(List willBeNotiNoticeDtoList) { + try { + firebaseService.sendNoticeMessageList(willBeNotiNoticeDtoList); + log.info("FCM에 정상적으로 메세지를 전송했습니다."); + log.info("전송된 공지 목록은 다음과 같습니다."); + for (NoticeMessageDto messageDTO : willBeNotiNoticeDtoList) { + log.info("아이디 = {}, 날짜 = {}, 카테고리 = {}, 제목 = {}", messageDTO.getArticleId(), messageDTO.getPostedDate(), messageDTO.getCategory(), messageDTO.getSubject()); + } + } catch(FirebaseMessageSendException e) { + log.error("새로운 공지의 FCM 전송에 실패했습니다."); + throw new InternalLogicException(ErrorCode.FB_FAIL_SEND, e); + } catch(Exception e) { + log.error("새로운 공지를 FCM에 보내는 중 알 수 없는 오류가 발생했습니다."); + throw new InternalLogicException(ErrorCode.UNKNOWN_ERROR, e); + } + } } diff --git a/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeDTO.java b/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeDTO.java index 1983fc79..4d3275ff 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeDTO.java +++ b/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeDTO.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; +import lombok.NoArgsConstructor; @Getter +@NoArgsConstructor public class LibraryNoticeDTO { @JsonProperty("id") private String id; @@ -44,12 +46,6 @@ public class LibraryNoticeDTO { @JsonProperty("commentCnt") private String commentCnt; -// @JsonProperty("attachmentCnt") -// private List attachmentCnt; -// -// @JsonProperty("attachments") -// private List attachments; - @JsonProperty("isPersonal") private boolean isPersonal; diff --git a/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeResponseDTO.java b/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeResponseDTO.java index 81b09c20..b6bdd452 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeResponseDTO.java +++ b/src/main/java/com/kustacks/kuring/kuapi/notice/dto/response/LibraryNoticeResponseDTO.java @@ -3,6 +3,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; +import java.util.List; + @Getter public class LibraryNoticeResponseDTO extends NoticeResponseDTO { @JsonProperty("success") @@ -16,4 +18,12 @@ public class LibraryNoticeResponseDTO extends NoticeResponseDTO { @JsonProperty("data") private LibraryDataDTO data; + + public int getTotalCount() { + return this.data.getTotalCount(); + } + + public List getList() { + return this.data.getList(); + } } diff --git a/src/main/java/com/kustacks/kuring/kuapi/scrap/StaffScraper.java b/src/main/java/com/kustacks/kuring/kuapi/scrap/StaffScraper.java index de4d7bde..83302396 100644 --- a/src/main/java/com/kustacks/kuring/kuapi/scrap/StaffScraper.java +++ b/src/main/java/com/kustacks/kuring/kuapi/scrap/StaffScraper.java @@ -3,7 +3,7 @@ import com.kustacks.kuring.common.dto.StaffDto; import com.kustacks.kuring.common.error.ErrorCode; import com.kustacks.kuring.common.error.InternalLogicException; -import com.kustacks.kuring.kuapi.api.staff.StaffAPIClient; +import com.kustacks.kuring.kuapi.api.staff.StaffApiClient; import com.kustacks.kuring.kuapi.scrap.parser.HTMLParser; import com.kustacks.kuring.kuapi.staff.deptinfo.DeptInfo; import lombok.extern.slf4j.Slf4j; @@ -19,10 +19,10 @@ @Component public class StaffScraper implements KuScraper { - private final List staffAPIClients; + private final List staffAPIClients; private final List htmlParsers; - public StaffScraper(List htmlParsers, List staffAPIClients) { + public StaffScraper(List htmlParsers, List staffAPIClients) { this.staffAPIClients = staffAPIClients; this.htmlParsers = htmlParsers; @@ -34,7 +34,7 @@ public List scrap(DeptInfo deptInfo) throws InternalLogicException { List documents = null; List staffDtoList = new LinkedList<>(); - for (StaffAPIClient staffAPIClient : staffAPIClients) { + for (StaffApiClient staffAPIClient : staffAPIClients) { if(staffAPIClient.support(deptInfo)) { log.info("{} HTML 요청", deptInfo.getDeptName()); documents = staffAPIClient.getHTML(deptInfo); diff --git a/src/main/java/com/kustacks/kuring/notice/business/NoticeService.java b/src/main/java/com/kustacks/kuring/notice/business/NoticeService.java index 0e7169bb..d79ece46 100644 --- a/src/main/java/com/kustacks/kuring/notice/business/NoticeService.java +++ b/src/main/java/com/kustacks/kuring/notice/business/NoticeService.java @@ -112,8 +112,8 @@ private String convertShortNameIntoLongName(String typeShortName) { .orElseThrow(CategoryNotFoundException::new); } - private String convertBaseUrl(String type) { - return CategoryName.LIBRARY.isSameShortName(type) ? libraryBaseUrl : normalBaseUrl; + private String convertBaseUrl(String categoryName) { + return CategoryName.LIBRARY.isSameName(categoryName) ? libraryBaseUrl : normalBaseUrl; } private List getNoticesBySubjectOrCategory(String[] keywords) { diff --git a/src/main/java/com/kustacks/kuring/notice/domain/Notice.java b/src/main/java/com/kustacks/kuring/notice/domain/Notice.java index 6386c644..727abeeb 100644 --- a/src/main/java/com/kustacks/kuring/notice/domain/Notice.java +++ b/src/main/java/com/kustacks/kuring/notice/domain/Notice.java @@ -1,10 +1,10 @@ package com.kustacks.kuring.notice.domain; import com.kustacks.kuring.category.domain.Category; +import com.kustacks.kuring.kuapi.CategoryName; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; import javax.persistence.Column; import javax.persistence.Entity; @@ -16,9 +16,9 @@ import javax.persistence.ManyToOne; import java.util.Objects; -@Getter @Setter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter @Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Notice { @Id @@ -50,6 +50,14 @@ public Notice(String articleId, String postedDate, String updatedDate, String su this.category = category; } + public boolean isSameCategoryName(CategoryName categoryName) { + return this.category.isSameName(categoryName); + } + + public void setPostedDate(String postedDate) { + this.postedDate = postedDate; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -63,3 +71,4 @@ public int hashCode() { return Objects.hash(getId()); } } + diff --git a/src/main/java/com/kustacks/kuring/notice/domain/NoticeRepository.java b/src/main/java/com/kustacks/kuring/notice/domain/NoticeRepository.java index 0be01669..9d3e5601 100644 --- a/src/main/java/com/kustacks/kuring/notice/domain/NoticeRepository.java +++ b/src/main/java/com/kustacks/kuring/notice/domain/NoticeRepository.java @@ -13,7 +13,7 @@ public interface NoticeRepository extends JpaRepository, NoticeQue List findBySubjectContainingOrCategoryNameContaining(String subject, String categoryName); - default Map findByCategoryMap(Category category) { + default Map findNoticeMapByCategory(Category category) { return findByCategory(category).stream().collect(Collectors.toMap(Notice::getArticleId, v -> v)); } } diff --git a/src/main/resources/constants.properties b/src/main/resources/constants.properties index c05b8918..49ebd46a 100644 --- a/src/main/resources/constants.properties +++ b/src/main/resources/constants.properties @@ -1,7 +1,7 @@ notice.request-url=https://kuis.konkuk.ac.kr/CmmnOneStop/find.do notice.referer=https://kuis.konkuk.ac.kr/index.do notice.normal-base-url=https://www.konkuk.ac.kr/do/MessageBoard/ArticleRead.do -notice.library-base-url=https://library.konkuk.ac.kr/#/bbs/notice +notice.library-base-url=https://library.konkuk.ac.kr/library-guide/bulletins/notice library.request-url=https://library.konkuk.ac.kr/pyxis-api/1/bulletin-boards/1/bulletins diff --git a/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientRetryTest.java b/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientRetryTest.java similarity index 92% rename from src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientRetryTest.java rename to src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientRetryTest.java index a9e5c2b8..b6d98690 100644 --- a/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientRetryTest.java +++ b/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientRetryTest.java @@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.given; -@SpringJUnitConfig({KuisNoticeAPIClient.class, RestTemplate.class, KuisNoticeDTOToCommonFormatDTOConverter.class, +@SpringJUnitConfig({KuisNoticeApiClient.class, RestTemplate.class, KuisNoticeDTOToCommonFormatDTOConverter.class, BachelorKuisNoticeRequestBody.class, ScholarshipKuisNoticeRequestBody.class, EmploymentKuisNoticeRequestBody.class, @@ -33,9 +33,9 @@ JsonConfig.class, RetryConfig.class}) @TestPropertySource("classpath:test-constants.properties") @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -public class KuisNoticeAPIClientRetryTest { +public class KuisNoticeApiClientRetryTest { - private final NoticeAPIClient kuisNoticeAPIClient; + private final NoticeApiClient kuisNoticeAPIClient; private final RestTemplate restTemplate; @MockBean @@ -43,7 +43,7 @@ public class KuisNoticeAPIClientRetryTest { private MockRestServiceServer server; - public KuisNoticeAPIClientRetryTest(NoticeAPIClient kuisNoticeAPIClient, RestTemplate restTemplate) { + public KuisNoticeApiClientRetryTest(NoticeApiClient kuisNoticeAPIClient, RestTemplate restTemplate) { this.kuisNoticeAPIClient = kuisNoticeAPIClient; this.restTemplate = restTemplate; diff --git a/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientTest.java b/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientTest.java similarity index 96% rename from src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientTest.java rename to src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientTest.java index fa93d2d3..2f5bd730 100644 --- a/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeAPIClientTest.java +++ b/src/test/java/com/kustacks/kuring/kuapi/api/notice/KuisNoticeApiClientTest.java @@ -30,7 +30,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreators.withUnauthorizedRequest; @SpringJUnitConfig({ - KuisNoticeAPIClient.class, RestTemplate.class, KuisNoticeDTOToCommonFormatDTOConverter.class, + KuisNoticeApiClient.class, RestTemplate.class, KuisNoticeDTOToCommonFormatDTOConverter.class, BachelorKuisNoticeRequestBody.class, ScholarshipKuisNoticeRequestBody.class, EmploymentKuisNoticeRequestBody.class, @@ -41,12 +41,12 @@ JsonConfig.class}) @TestPropertySource("classpath:test-constants.properties") @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -public class KuisNoticeAPIClientTest { +public class KuisNoticeApiClientTest { @Value("${notice.request-url}") private String noticeUrl; - private final KuisNoticeAPIClient kuisNoticeAPIClient; + private final KuisNoticeApiClient kuisNoticeAPIClient; private final RestTemplate restTemplate; @MockBean @@ -55,7 +55,7 @@ public class KuisNoticeAPIClientTest { private MockRestServiceServer server; private String testSession; - public KuisNoticeAPIClientTest(KuisNoticeAPIClient kuisNoticeAPIClient, RestTemplate restTemplate) { + public KuisNoticeApiClientTest(KuisNoticeApiClient kuisNoticeAPIClient, RestTemplate restTemplate) { this.kuisNoticeAPIClient = kuisNoticeAPIClient; this.restTemplate = restTemplate; diff --git a/src/test/java/com/kustacks/kuring/kuapi/api/staff/StaffScraperTest.java b/src/test/java/com/kustacks/kuring/kuapi/api/staff/StaffScraperTest.java index 9792b70b..6c0ff178 100644 --- a/src/test/java/com/kustacks/kuring/kuapi/api/staff/StaffScraperTest.java +++ b/src/test/java/com/kustacks/kuring/kuapi/api/staff/StaffScraperTest.java @@ -43,7 +43,7 @@ @SpringJUnitConfig({ StaffScraper.class, - EachDeptStaffAPIClient.class, KuStaffAPIClient.class, RealEstateStaffAPIClient.class, + EachDeptStaffApiClient.class, KuStaffApiClient.class, RealEstateStaffApiClient.class, EachDeptHTMLParser.class, KuHTMLParser.class, RealEstateHTMLParser.class, NormalJsoupClient.class, KoreanDept.class, LivingDesignDept.class, CommunicationDesignDept.class, RealEstateDept.class, diff --git a/src/test/java/com/kustacks/kuring/kuapi/notice/ParsingKuisAuthManagerTest.java b/src/test/java/com/kustacks/kuring/kuapi/notice/ParsingKuisAuthManagerTest.java index 868644fe..2177ce6d 100644 --- a/src/test/java/com/kustacks/kuring/kuapi/notice/ParsingKuisAuthManagerTest.java +++ b/src/test/java/com/kustacks/kuring/kuapi/notice/ParsingKuisAuthManagerTest.java @@ -1,7 +1,7 @@ package com.kustacks.kuring.kuapi.notice; import com.kustacks.kuring.config.JsonConfig; -import com.kustacks.kuring.config.RestConfig; +import com.kustacks.kuring.config.RestTemplateConfig; import com.kustacks.kuring.common.error.ErrorCode; import com.kustacks.kuring.common.error.InternalLogicException; import com.kustacks.kuring.kuapi.api.notice.KuisAuthManager; @@ -32,7 +32,7 @@ @SpringJUnitConfig({ ParsingKuisAuthManager.class, KuisLoginRequestBody.class, RequestBodyEncoder.class, - RestConfig.class, JsonConfig.class + RestTemplateConfig.class, JsonConfig.class }) @TestPropertySource(locations = "classpath:test-constants.properties") @TestMethodOrder(MethodOrderer.OrderAnnotation.class)