Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#120 #122

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions dodam-application/dodam-rest-api/build.gradle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엔터 한개 빼주세요

Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ dependencies {
implementation project(':dodam-in-system-available:dodam-melon-chart-client')
implementation project(':dodam-in-system-available:dodam-ncp-object-storage-client')
implementation project(':dodam-in-system-available:dodam-neis-meal-client')
implementation project(':dodam-in-system-available:dodam-neis-schedule-client')
implementation project(':dodam-in-system-available:dodam-neis-client-core')
implementation project(':dodam-in-system-available:dodam-token-client')
implementation project(':dodam-in-system-available:dodam-youtube-video-client')


implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import b1nd.dodam.domain.rds.schedule.entity.Schedule;
import b1nd.dodam.domain.rds.schedule.enumeration.TargetGrade;
import b1nd.dodam.domain.rds.schedule.service.ScheduleService;
import b1nd.dodam.neis.schedule.client.NeisScheduleClient;
import b1nd.dodam.neis.schedule.client.data.NeisSchedule;
import b1nd.dodam.restapi.schedule.application.data.req.ScheduleReq;
import b1nd.dodam.restapi.schedule.application.data.res.ScheduleRes;
import b1nd.dodam.restapi.support.data.Response;
Expand All @@ -24,6 +26,7 @@
public class ScheduleUseCase {

private final ScheduleService scheduleService;
private final NeisScheduleClient neisScheduleClient;

@Transactional(rollbackFor = Exception.class)
public Response create(ScheduleReq req) {
Expand Down Expand Up @@ -66,4 +69,24 @@ public ResponseData<List<ScheduleRes>> getByDate(int year, int month, int day) {
return ResponseData.ok("해당 날짜의 일정 조회 성공", ScheduleRes.of(scheduleService.getByDate(LocalDate.of(year, month, day))));
}

@Transactional(rollbackFor = Exception.class)
public Response createScheduleByNeis(LocalDate startDate, LocalDate endDate){
List<NeisSchedule> neisSchedule = neisScheduleClient.getSchedules(startDate, endDate);
List<Schedule> schedules = neisSchedule
.parallelStream()
.map(this::scheduleBuilderForNeis)
.toList();
scheduleService.saveAll(schedules);
return ResponseData.ok("neis로 일정 저장 성공");
}

private Schedule scheduleBuilderForNeis(NeisSchedule neisSchedule){
return Schedule.builder()
.name(neisSchedule.eventName())
.startDate(neisSchedule.startDate())
.endDate(neisSchedule.endDate())
.targetGrades(neisSchedule.grades().stream().map(TargetGrade::of).collect(Collectors.toSet()))
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ public ResponseData<List<ScheduleRes>> getAllOrderByIdDesc(@RequestParam int pag
return useCase.getAllOrderByIdDesc(page, size);
}

@PostMapping("/neis")
public Response createByNeis(
@RequestParam LocalDate startDate,
@RequestParam LocalDate endDate
){
return useCase.createScheduleByNeis(startDate, endDate);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ app:
neis:
apiKey: ${NEIS_KEY}
url: ${NEIS_URL}
meal:
meal-endpoint: ${NEIS_MEAL_ENDPOINT}
schedule:
schedule-endpoint: ${NEIS_SCHEDULE_ENDPOINT}
codenary:
url: ${CODENARY_URL}
melon:
Expand Down
7 changes: 7 additions & 0 deletions dodam-in-system-available/dodam-neis-client-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies {
implementation 'org.springframework:spring-context:6.0.6'
implementation 'org.springframework:spring-web:6.0.6'
implementation 'org.springframework:spring-tx:6.0.6'

implementation 'org.springframework.boot:spring-boot:3.0.4'
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package b1nd.dodam.neis.meal.client.properties;
package b1nd.dodam.neis.client.core;

import lombok.Getter;
import lombok.Setter;
Expand All @@ -9,7 +9,7 @@
@Setter
@Configuration
@ConfigurationProperties("app.neis")
public class NeisProperties {
public class NeisCoreProperties {

private String apiKey;
private String url;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package com.b1nd.dodam.neis.client.core;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
implementation project(':dodam-in-system-available:dodam-client-core')
implementation project(':dodam-in-system-available:dodam-neis-client-core')

implementation 'org.springframework:spring-context:6.0.6'
implementation 'org.springframework:spring-web:6.0.6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import b1nd.dodam.neis.meal.client.data.Food;
import b1nd.dodam.neis.meal.client.data.FoodDetail;
import b1nd.dodam.neis.meal.client.data.Meal;
import b1nd.dodam.neis.meal.client.properties.NeisProperties;
import b1nd.dodam.neis.meal.client.properties.NeisMealProperties;
import b1nd.dodam.neis.meal.client.support.MealConverter;
import b1nd.dodam.neis.client.core.NeisCoreProperties;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.json.simple.JSONArray;
Expand All @@ -24,8 +25,9 @@
@RequiredArgsConstructor
public class NeisMealClient {

private final NeisProperties neisProperties;
private final NeisMealProperties neisMealProperties;
private final WebClientSupport webClient;
private final NeisCoreProperties neisCoreProperties;

@Cacheable(value = "meal-day", key = "#year.toString().concat(-#month).concat(-#day)")
public Meal getMeal(int year, int month, int day) {
Expand Down Expand Up @@ -95,8 +97,8 @@ public List<Meal> getMealOfMonth(int year, int month) {

private String getByDate(String date) {
return webClient.get(
UriComponentsBuilder.fromUriString(neisProperties.getUrl())
.build(neisProperties.getApiKey(), date).toString(),
UriComponentsBuilder.fromUriString(neisCoreProperties.getUrl()+neisMealProperties.getMealEndpoint())
.build(neisCoreProperties.getApiKey(), date).toString(),
String.class
).block();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package b1nd.dodam.neis.meal.client.properties;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Getter
@Setter
@Configuration
@ConfigurationProperties("app.neis.meal")
public class NeisMealProperties {

private String mealEndpoint;

}
16 changes: 16 additions & 0 deletions dodam-in-system-available/dodam-neis-schedule-client/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
dependencies {
implementation project(':dodam-in-system-available:dodam-client-core')
implementation project(':dodam-in-system-available:dodam-neis-client-core')

implementation 'org.springframework:spring-context:6.0.6'
implementation 'org.springframework:spring-web:6.0.6'
implementation 'org.springframework:spring-tx:6.0.6'

implementation 'org.springframework.boot:spring-boot:3.0.4'

implementation 'com.fasterxml.jackson.core:jackson-annotations:2.14.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

implementation 'com.googlecode.json-simple:json-simple:1.1.1'
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mealData에서 null처리 해야 nullPointException이 안 뜰것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null이 들어올 일이 없을 듯 합니다

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 메소드는 다 stream형식으로 하였는데 getSchedules메소드만 stream을 적용 안 한 이유가 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로직이 복잡해서 stream을 쓰면 가독성이 안좋아질 것 같아서 사용 안했습니다

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일정 합칠때 distinct 필요할것 같아요

Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package b1nd.dodam.neis.schedule.client;

import b1nd.dodam.client.core.WebClientSupport;
import b1nd.dodam.neis.client.core.NeisCoreProperties;
import b1nd.dodam.neis.schedule.client.data.NeisSchedule;
import b1nd.dodam.neis.schedule.client.properties.NeisScheduleProperties;
import b1nd.dodam.neis.schedule.client.util.NeisScheduleUtil;
import lombok.RequiredArgsConstructor;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class NeisScheduleClient {
private final WebClientSupport webClient;
private final NeisCoreProperties coreProperties;
private final NeisScheduleProperties scheduleProperties;

public List<NeisSchedule> getSchedules(LocalDate startDate, LocalDate endDate) {
String rawResponse = getRawSchedule(startDate, endDate);
JSONArray rawData = NeisScheduleUtil.getRawData(rawResponse);
List<NeisSchedule> scheduleList = new ArrayList<>();

for (Object object : rawData) {
JSONObject mealData = (JSONObject) object;

String eventName = String.valueOf(mealData.get("EVENT_NM"));
List<String> grades = NeisScheduleUtil.determineGrades(mealData);
LocalDate date = NeisScheduleUtil.parseDate(String.valueOf(mealData.get("AA_YMD")));

scheduleList.add(new NeisSchedule(eventName, grades, date, null));
}

return mergeSchedules(scheduleList);
}

private List<NeisSchedule> mergeSchedules(List<NeisSchedule> scheduleList) {
return scheduleList.stream()
.collect(Collectors.groupingBy(NeisSchedule::eventName))
.entrySet().stream()
.map(entry -> createMergedSchedule(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}

private NeisSchedule createMergedSchedule(String eventName, List<NeisSchedule> schedules) {
LocalDate minDate = schedules.stream()
.map(NeisSchedule::startDate)
.min(LocalDate::compareTo)
.orElse(null);

LocalDate maxDate = schedules.stream()
.map(NeisSchedule::startDate)
.max(LocalDate::compareTo)
.orElse(null);

List<String> mergedGrades = schedules.get(0).grades();
return new NeisSchedule(eventName, mergedGrades, minDate, maxDate);
}

private String getRawSchedule(LocalDate startDate, LocalDate endDate) {
return webClient.get(
UriComponentsBuilder.fromUriString(coreProperties.getUrl() + scheduleProperties.getScheduleEndpoint())
.build(coreProperties.getApiKey(), startDate, endDate).toString(),
String.class
).block();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package b1nd.dodam.neis.schedule.client.data;

import java.time.LocalDate;
import java.util.List;

public record NeisSchedule(
String eventName,
List<String> grades,
LocalDate startDate,
LocalDate endDate
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package b1nd.dodam.neis.schedule.client.properties;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Getter
@Setter
@Configuration
@ConfigurationProperties("app.neis.schedule")
public class NeisScheduleProperties {

private String scheduleEndpoint;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package b1nd.dodam.neis.schedule.client.util;

import b1nd.dodam.core.exception.global.InternalServerException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class NeisScheduleUtil {

public static List<String> determineGrades(JSONObject mealData) {
List<String> grades = new ArrayList<>();
if ("Y".equals(mealData.get("ONE_GRADE_EVENT_YN"))) grades.add("1학년");
if ("Y".equals(mealData.get("TW_GRADE_EVENT_YN"))) grades.add("2학년");
if ("Y".equals(mealData.get("THREE_GRADE_EVENT_YN"))) grades.add("3학년");

if (grades.size() == 3) {
grades.clear();
grades.add("전교생");
}
return grades;
}

public static LocalDate parseDate(String dateString) {
return LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyyMMdd"));
}

public static JSONArray getRawData(String response) {
try {
JSONParser jsonParser = new JSONParser();
JSONObject parse = (JSONObject) jsonParser.parse(response);
JSONArray schoolScheduleInfo = (JSONArray) parse.get("SchoolSchedule");
JSONObject scheduleInfo = (JSONObject) schoolScheduleInfo.get(1);
return (JSONArray) scheduleInfo.get("row");
} catch (Exception e) {
throw new InternalServerException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package com.b1nd.dodam.neis.schedule.client;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public void save(Schedule schedule) {
repository.save(schedule);
}

public void saveAll(List<Schedule> schedules) {
repository.saveAll(schedules);
}

public void deleteById(int id) {
repository.deleteById(id);
}
Expand Down
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ include 'dodam-in-system-available:dodam-gabia-client'
include 'dodam-in-system-available:dodam-ncp-object-storage-client'
include 'dodam-in-system-available:dodam-codenary-client'
include 'dodam-in-system-available:dodam-neis-meal-client'
include 'dodam-in-system-available:dodam-neis-schedule-client'
include 'dodam-in-system-available:dodam-neis-client-core'

//dodam-application
include 'dodam-application'
Expand Down