-
Notifications
You must be signed in to change notification settings - Fork 16
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
[refactor] 일정 조율 기능을 제거한다. #630
[refactor] 일정 조율 기능을 제거한다. #630
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
간단히 메서드에 의도 적어두었습니다. 참고해주시면 감사하겠습니다.
일정 조율의 경우 너무 많은 경우의 수를 가지기 때문에 홀로 테스트하는데 많은 어려움이 있었습니다. 저희끼리 좀 더 다양한 시나리오를 구성한 뒤 함께 테스트 코드를 작성해보는 시간을 가져보는 건 어떨까요?? 의견 남겨 주시면 감사하겠습니다!
public List<PeriodResponse> getAvailablePeriods(final Long categoryId, final DateRangeRequest request) { | ||
AvailablePeriodMaterial material = scheduleService.findInMembersByCategoryIdAndDateRange(categoryId, request); | ||
|
||
String startDateTime = request.getStartDateTime().format(DateTimeFormatter.ofPattern(DATE_FORMAT)); | ||
String endDateTime = request.getEndDateTime().format(DateTimeFormatter.ofPattern(DATE_FORMAT)); | ||
|
||
List<IntegrationSchedule> schedules = material.getInternalSchedules(); | ||
List<IntegrationSchedule> externalSchedules = toExternalSchedules(startDateTime, endDateTime, material); | ||
|
||
schedules.addAll(externalSchedules); | ||
Scheduler scheduler = new Scheduler(schedules, request.getStartDateTime(), request.getEndDateTime()); | ||
|
||
return toPeriodResponses(scheduler); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
가능한 구간을 조회하기 위한 메서드입니다.
AvailablePeriodMaterial material = scheduleService.findInMembersByCategoryIdAndDateRange(categoryId, request);
해당 부분에서 트랜잭션이 마무리 되고, 이후에는 트랜잭션 외부에서 진행됨을 인지해주세요!
private List<IntegrationSchedule> toExternalSchedules(final String startDateTime, final String endDateTime, | ||
final AvailablePeriodMaterial material) { | ||
return material.getTokenByExternalIds() | ||
.entrySet() | ||
.stream() | ||
.map(entry -> toExternalSchedules(entry, startDateTime, endDateTime)) | ||
.flatMap(Collection::stream) | ||
.collect(Collectors.toList()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
외부 access token 조회를 위한 refresh token 별 외부 캘린더 id를 기반으로 외부 캘린더 리스트를 가져온 뒤 합체합니다.
private List<IntegrationSchedule> toExternalSchedules(final Entry<String, List<ExternalRequestMaterial>> entry, | ||
final String startDateTime, final String endDateTime) { | ||
String refreshToken = entry.getKey(); | ||
List<ExternalRequestMaterial> externalRequestMaterials = entry.getValue(); | ||
|
||
String accessToken = oAuthClient.getAccessToken(refreshToken).getAccessToken(); | ||
|
||
return externalRequestMaterials.stream() | ||
.map(externalRequestMaterial -> | ||
toExternalSchedules(accessToken, externalRequestMaterial, startDateTime, endDateTime)) | ||
.flatMap(Collection::stream) | ||
.collect(Collectors.toList()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
토큰을 조회하고 실제 외부 서버에게 조회된 일정 리스트를 합체하여 반환합니다.
private List<IntegrationSchedule> toExternalSchedules(final String accessToken, | ||
final ExternalRequestMaterial externalRequestMaterial, | ||
final String startDateTime, final String endDateTime) { | ||
Long internalCategoryId = externalRequestMaterial.getInternalCategoryId(); | ||
String externalCalendarId = externalRequestMaterial.getExternalCalendarId(); | ||
|
||
return externalCalendarClient.getExternalCalendarSchedules( | ||
accessToken, internalCategoryId, externalCalendarId, startDateTime, endDateTime); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실제 외부 서버에게 일정 리스트를 조회하는 부분입니다.
public AvailablePeriodMaterial findInMembersByCategoryIdAndDateRange(final Long categoryId, | ||
final DateRangeRequest request) { | ||
List<Long> memberIds = toMemberIds(categoryId); | ||
List<Subscription> subscriptions = subscriptionRepository.findByMemberIdIn(memberIds); | ||
|
||
List<IntegrationSchedule> internalSchedules = toInternalSchedules(subscriptions, request); | ||
Map<String, List<ExternalRequestMaterial>> tokenByExternalIds = toTokenByExternalIds(subscriptions); | ||
|
||
return new AvailablePeriodMaterial(internalSchedules, tokenByExternalIds); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
특정 카테고리에 대한 내부 일정 리스트와 외부 캘린더 일정 조회를 위한 정보를 dto로 만들어 반환합니다.
private List<IntegrationSchedule> toInternalSchedules(final List<Subscription> subscriptions, | ||
final DateRangeRequest request) { | ||
List<Category> internalCategories = toInternalCategories(subscriptions); | ||
|
||
LocalDateTime startDate = request.getStartDateTime(); | ||
LocalDateTime endDate = request.getEndDateTime(); | ||
return scheduleRepository.getByCategoriesAndBetween(internalCategories, startDate, endDate); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구독 정보에서 내부 카테고리 리스트 정보를 조회하여 일정 리스트를 반환합니다.
private Map<String, List<ExternalRequestMaterial>> toTokenByExternalIds(final List<Subscription> subscriptions) { | ||
return subscriptions.stream() | ||
.filter(Subscription::hasExternalCategory) | ||
.map(this::toExternalRequestMaterial) | ||
.collect(Collectors.groupingBy(ExternalRequestMaterial::getRefreshToken)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refresh token 별 외부 캘린더 조회를 위한 메타 데이터를 그룹핑합니다.
간단한 예시로 제가 구글 개인 일정 및 우테코 일정을 구글에서 등록한 뒤 구독 했다고 가정합니다. 제 refresh token 하나 당 두 개의 외부 캘린더 id를 기반으로 모두 조회해야 하기 때문에 그룹핑을 활용 했습니다.
public class AvailablePeriodMaterial { | ||
|
||
private final List<IntegrationSchedule> internalSchedules; | ||
private final Map<String, List<ExternalRequestMaterial>> tokenByExternalIds; | ||
|
||
public AvailablePeriodMaterial(final List<IntegrationSchedule> internalSchedules, | ||
final Map<String, List<ExternalRequestMaterial>> tokenByExternalIds) { | ||
this.internalSchedules = new ArrayList<>(internalSchedules); | ||
this.tokenByExternalIds = new HashMap<>(tokenByExternalIds); | ||
} | ||
|
||
public List<IntegrationSchedule> getInternalSchedules() { | ||
return new ArrayList<>(internalSchedules); | ||
} | ||
|
||
public Map<String, List<ExternalRequestMaterial>> getTokenByExternalIds() { | ||
return new HashMap<>(tokenByExternalIds); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앞서 언급한 것 처럼 가능한 일정 구간 조회를 위한 정보를 담은 dto입니다. 이렇게 추가적인 dto를 생성한 이유는 트랜잭션 구간 내에서 최대한 많은 DB 정보를 조회한 뒤 이를 기반으로 외부 리소스에 관련된 처리를 진행하기 위함입니다.
bc6ec30
to
769f4be
Compare
f149bc0
to
1818e09
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕... 조율.. 😭
아직 조율 기능을 덜 보내준 곳이 있어서 코멘트 달았습니다!
public class AvailablePeriodMaterial { | ||
|
||
private final List<IntegrationSchedule> internalSchedules; | ||
private final Map<String, List<ExternalRequestMaterial>> tokenByExternalIds; | ||
|
||
public AvailablePeriodMaterial(final List<IntegrationSchedule> internalSchedules, | ||
final Map<String, List<ExternalRequestMaterial>> tokenByExternalIds) { | ||
this.internalSchedules = new ArrayList<>(internalSchedules); | ||
this.tokenByExternalIds = new HashMap<>(tokenByExternalIds); | ||
} | ||
|
||
public List<IntegrationSchedule> getInternalSchedules() { | ||
return new ArrayList<>(internalSchedules); | ||
} | ||
|
||
public Map<String, List<ExternalRequestMaterial>> getTokenByExternalIds() { | ||
return new HashMap<>(tokenByExternalIds); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일정 조율 기능이 제거되어도 이 클래스는 사용되나요? 현재는 사용하고 있는 곳이 없는 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
유리야... 잘가... 행복했다😥
9bc197f
to
fac6d23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매트 안녕하세요! 작성 해주신 코드 잘보았습니다~
조유리가 사라지면서 많은 코드들이 사라졌군요..!
코드가 많이 사라져서 좋으면서도 조유리와 이별해서 아쉽네요😔
바로 approve하겠습니다!
[feat] PR을 등록한다.
작업 내용
드디어 composition의 모든 서비스를 제거 하였습니다... 다만 워낙에 일정 조율 로직이 복잡하고 많은 쿼리와 네트워크 통신을 유발해서 우리 서비스에서 정상적으로 동작할 수 있을지 조금 걱정이 되네요. 테스트 코드 까지 꼼꼼하게 짜 보려 했는데 외부 리소스 관련 Stub 때문에 테스트가 매우 부실한 상태입니다. 이 점 인지해주시고, 우선적으로 코드 스타일 부터 확인해주시면 감사하겠습니다.
테스트는 추후 이야기 나눠보고 보충할 예정이고, 아직 쿼리 분석은 못했습니다. 시간이 좀 더 소요될 것 같아서 내일 오전 중으로 진행해야 할 것 같네요.
이슈 내용 중 일부
스크린샷
주의사항
Closes #615