Skip to content

Commit

Permalink
[refactor] currentPriceRepository 개선 (#435)
Browse files Browse the repository at this point in the history
* rename: 메서드명을 fetchCurrentPrice로 변경

* refactor: 현재가 조회 모듈 리팩토링

* refactor: redis key, value 메서드 추가

* rename: currentPriceRepository 클래스명 변경

* rename: CurrentPriceRedisRepository의 메소드를 인터페이스에 맞게 변경
  • Loading branch information
yonghwankim-dev authored Aug 12, 2024
1 parent 236fffb commit 8959077
Show file tree
Hide file tree
Showing 38 changed files with 219 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import codesquad.fineants.domain.gainhistory.domain.dto.response.PortfolioGainHistoryCreateResponse;
import codesquad.fineants.domain.gainhistory.domain.entity.PortfolioGainHistory;
import codesquad.fineants.domain.gainhistory.repository.PortfolioGainHistoryRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import codesquad.fineants.domain.portfolio.repository.PortfolioRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,7 +24,7 @@
public class PortfolioGainHistoryService {
private final PortfolioGainHistoryRepository repository;
private final PortfolioRepository portfolioRepository;
private final CurrentPriceRepository currentPriceRepository;
private final CurrentPriceRedisRepository currentPriceRedisRepository;

@Transactional
@Scheduled(cron = "0 0 16 * * ?") // 매일 16시에 실행
Expand All @@ -39,7 +39,7 @@ public PortfolioGainHistoryCreateResponse addPortfolioGainHistory() {
List<PortfolioGainHistory> portfolioGainHistories = new ArrayList<>();

for (Portfolio portfolio : portfolios) {
portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRepository);
portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository);
PortfolioGainHistory latestHistory =
repository.findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
portfolio.getId(), LocalDateTime.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
import org.springframework.stereotype.Component;

import codesquad.fineants.domain.holding.domain.dto.response.PortfolioDividendChartItem;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class DividendChart {

private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;

public List<PortfolioDividendChartItem> createBy(Portfolio portfolio, LocalDate currentLocalDate) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import org.springframework.stereotype.Component;

import codesquad.fineants.domain.holding.domain.dto.response.PortfolioPieChartItem;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class PieChart {

private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;

public List<PortfolioPieChartItem> createBy(Portfolio portfolio) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import org.springframework.stereotype.Component;

import codesquad.fineants.domain.holding.domain.dto.response.PortfolioSectorChartItem;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class SectorChart {
private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;

public List<PortfolioSectorChartItem> createBy(Portfolio portfolio) {
portfolio.applyCurrentPriceAllHoldingsBy(manager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import codesquad.fineants.domain.dividend.domain.entity.StockDividend;
import codesquad.fineants.domain.holding.domain.dto.response.PortfolioPieChartItem;
import codesquad.fineants.domain.kis.repository.ClosingPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import codesquad.fineants.domain.purchasehistory.domain.entity.PurchaseHistory;
import codesquad.fineants.domain.stock.domain.entity.Stock;
Expand Down Expand Up @@ -208,7 +208,7 @@ public Map<Integer, Expression> createMonthlyDividendMap(LocalDate currentLocalD
return monthlyDividends;
}

public void applyCurrentPrice(CurrentPriceRepository manager) {
public void applyCurrentPrice(CurrentPriceRedisRepository manager) {
Bank bank = Bank.getInstance();
Currency to = Currency.KRW;
this.currentPrice = stock.getCurrentPrice(manager).reduce(bank, to);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import codesquad.fineants.domain.gainhistory.repository.PortfolioGainHistoryRepository;
import codesquad.fineants.domain.holding.domain.dto.response.PortfolioDetailRealTimeItem;
import codesquad.fineants.domain.holding.domain.dto.response.PortfolioDetailResponse;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class PortfolioDetailFactory {

private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;
private final PortfolioGainHistoryRepository portfolioGainHistoryRepository;

public PortfolioDetailResponse createPortfolioDetailItem(Portfolio portfolio) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import codesquad.fineants.domain.holding.domain.dto.response.PortfolioHoldingItem;
import codesquad.fineants.domain.holding.domain.dto.response.PortfolioHoldingRealTimeItem;
import codesquad.fineants.domain.kis.repository.ClosingPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.portfolio.domain.entity.Portfolio;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class PortfolioHoldingDetailFactory {

private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;
private final ClosingPriceRepository closingPriceRepository;

public List<PortfolioHoldingItem> createPortfolioHoldingItems(Portfolio portfolio) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public static KisCurrentPrice create(String tickerSymbol, Long price) {
return new KisCurrentPrice(tickerSymbol, price);
}

public String toRedisKey(String format) {
return String.format(format, tickerSymbol);
}

public String toRedisValue() {
return String.valueOf(price);
}

static class KisCurrentPriceDeserializer extends JsonDeserializer<KisCurrentPrice> {
@Override
public KisCurrentPrice deserialize(JsonParser parser, DeserializationContext context) throws
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package codesquad.fineants.domain.kis.repository;

import static codesquad.fineants.domain.kis.service.KisService.*;

import java.util.Arrays;
import java.util.Optional;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import codesquad.fineants.domain.common.money.Money;
import codesquad.fineants.domain.kis.client.KisClient;
import codesquad.fineants.domain.kis.client.KisCurrentPrice;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Repository
public class CurrentPriceRedisRepository implements PriceRepository {
private static final String CURRENT_PRICE_FORMAT = "cp:%s";
private final RedisTemplate<String, String> redisTemplate;
private final KisClient kisClient;

@Override
public void savePrice(KisCurrentPrice... currentPrices) {
Arrays.stream(currentPrices).forEach(this::savePrice);
}

private KisCurrentPrice savePrice(KisCurrentPrice currentPrice) {
redisTemplate.opsForValue().set(currentPrice.toRedisKey(CURRENT_PRICE_FORMAT), currentPrice.toRedisValue());
return currentPrice;
}

@Override
public Optional<Money> fetchPriceBy(String tickerSymbol) {
Optional<String> currentPrice = getCachedPrice(tickerSymbol);
if (currentPrice.isEmpty()) {
Optional<KisCurrentPrice> kisCurrentPrice = fetchAndCachePriceFromKis(tickerSymbol);
return kisCurrentPrice
.map(KisCurrentPrice::getPrice)
.map(Money::won);
}
return currentPrice.map(Money::won);
}

private Optional<String> getCachedPrice(String tickerSymbol) {
return Optional.ofNullable(redisTemplate.opsForValue().get(String.format(CURRENT_PRICE_FORMAT, tickerSymbol)));
}

private Optional<KisCurrentPrice> fetchAndCachePriceFromKis(String tickerSymbol) {
return kisClient.fetchCurrentPrice(tickerSymbol)
.blockOptional(TIMEOUT)
.map(this::savePrice);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package codesquad.fineants.domain.kis.repository;

import java.util.Optional;

import codesquad.fineants.domain.common.money.Money;
import codesquad.fineants.domain.kis.client.KisCurrentPrice;

public interface PriceRepository {
void savePrice(KisCurrentPrice... currentPrices);

Optional<Money> fetchPriceBy(String tickerSymbol);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import codesquad.fineants.domain.kis.domain.dto.response.KisIpo;
import codesquad.fineants.domain.kis.domain.dto.response.KisSearchStockInfo;
import codesquad.fineants.domain.kis.repository.ClosingPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.kis.repository.HolidayRepository;
import codesquad.fineants.domain.kis.repository.KisAccessTokenRepository;
import codesquad.fineants.domain.notification.event.publisher.PortfolioPublisher;
Expand All @@ -56,7 +56,7 @@ public class KisService {
private final KisClient kisClient;
private final PortfolioHoldingRepository portFolioHoldingRepository;
private final KisAccessTokenRepository manager;
private final CurrentPriceRepository currentPriceRepository;
private final CurrentPriceRedisRepository currentPriceRedisRepository;
private final ClosingPriceRepository closingPriceRepository;
private final HolidayRepository holidayRepository;
private final StockTargetPricePublisher stockTargetPricePublisher;
Expand Down Expand Up @@ -111,7 +111,7 @@ public List<KisCurrentPrice> refreshStockCurrentPrice(List<String> tickerSymbols
.filter(Objects::nonNull)
.toList();

prices.forEach(currentPriceRepository::addCurrentPrice);
prices.forEach(currentPriceRedisRepository::savePrice);

log.info("종목 현재가 {}개중 {}개 갱신", tickerSymbols.size(), prices.size());
return prices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.notification.domain.entity.policy.ConditionEvaluator;
import codesquad.fineants.domain.notification.domain.entity.policy.TargetGainNotificationEvaluator;
import codesquad.fineants.domain.notification.domain.entity.policy.maxloss.MaxLossAccountPreferenceCondition;
Expand Down Expand Up @@ -36,7 +36,7 @@
public class NotificationConfig {

private final NotificationSentRepository sentManager;
private final CurrentPriceRepository currentPriceRepository;
private final CurrentPriceRedisRepository currentPriceRedisRepository;
private final FirebaseNotificationProvider firebaseNotificationProvider;

@Bean
Expand Down Expand Up @@ -82,7 +82,7 @@ public MaxLossNotificationPolicy maxLossNotificationPolicy() {
public TargetPriceNotificationPolicy targetPriceNotificationPolicy() {
return new TargetPriceNotificationPolicy(
List.of(
new TargetPriceCondition(currentPriceRepository),
new TargetPriceCondition(currentPriceRedisRepository),
new TargetPriceActiveCondition(),
new TargetPriceSentHistoryCondition(sentManager)
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import codesquad.fineants.domain.notification.domain.entity.policy.NotificationCondition;
import codesquad.fineants.domain.stock_target_price.domain.entity.TargetPriceNotification;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class TargetPriceCondition implements NotificationCondition<TargetPriceNotification> {

private final CurrentPriceRepository manager;
private final CurrentPriceRedisRepository manager;

@Override
public boolean isSatisfiedBy(TargetPriceNotification targetPriceNotification) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.springframework.transaction.annotation.Transactional;

import codesquad.fineants.domain.common.notification.Notifiable;
import codesquad.fineants.domain.kis.repository.CurrentPriceRepository;
import codesquad.fineants.domain.kis.repository.CurrentPriceRedisRepository;
import codesquad.fineants.domain.member.domain.entity.Member;
import codesquad.fineants.domain.member.repository.MemberRepository;
import codesquad.fineants.domain.notification.domain.dto.request.NotificationSaveRequest;
Expand Down Expand Up @@ -50,7 +50,7 @@ public class NotificationService {
private final PortfolioRepository portfolioRepository;
private final NotificationRepository notificationRepository;
private final MemberRepository memberRepository;
private final CurrentPriceRepository currentPriceRepository;
private final CurrentPriceRedisRepository currentPriceRedisRepository;
private final NotificationSentRepository sentManager;
private final StockTargetPriceRepository stockTargetPriceRepository;
private final TargetGainNotificationPolicy targetGainNotificationPolicy;
Expand Down Expand Up @@ -95,7 +95,7 @@ private Member findMember(Long memberId) {
public NotifyMessageResponse notifyTargetGainAll() {
// 모든 회원의 포트폴리오 중에서 입력으로 받은 종목들을 가진 포트폴리오들을 조회
List<Notifiable> portfolios = portfolioRepository.findAllWithAll().stream()
.peek(portfolio -> portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRepository))
.peek(portfolio -> portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository))
.collect(Collectors.toList());
Consumer<Long> sentFunction = sentManager::addTargetGainSendHistory;
return PortfolioNotifyMessagesResponse.create(
Expand All @@ -111,7 +111,7 @@ public NotifyMessageResponse notifyTargetGainAll() {
@Transactional
public NotifyMessageResponse notifyTargetGain(Long portfolioId) {
Portfolio portfolio = portfolioRepository.findByPortfolioIdWithAll(portfolioId).stream()
.peek(p -> p.applyCurrentPriceAllHoldingsBy(currentPriceRepository))
.peek(p -> p.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository))
.findFirst()
.orElseThrow(() -> new FineAntsException(PortfolioErrorCode.NOT_FOUND_PORTFOLIO));
Consumer<Long> sentFunction = sentManager::addTargetGainSendHistory;
Expand Down Expand Up @@ -171,7 +171,7 @@ private Map<String, String> getMessageIdMap(List<SentNotifyMessage> sentNotifyMe
@Transactional
public NotifyMessageResponse notifyMaxLossAll() {
List<Notifiable> portfolios = portfolioRepository.findAllWithAll().stream()
.peek(portfolio -> portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRepository))
.peek(portfolio -> portfolio.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository))
.collect(Collectors.toList());
Consumer<Long> sentFunction = sentManager::addMaxLossSendHistory;
return PortfolioNotifyMessagesResponse.create(
Expand All @@ -187,7 +187,7 @@ public NotifyMessageResponse notifyMaxLossAll() {
@Transactional
public NotifyMessageResponse notifyMaxLoss(Long portfolioId) {
Portfolio portfolio = portfolioRepository.findByPortfolioIdWithAll(portfolioId)
.stream().peek(p -> p.applyCurrentPriceAllHoldingsBy(currentPriceRepository))
.stream().peek(p -> p.applyCurrentPriceAllHoldingsBy(currentPriceRedisRepository))
.findAny()
.orElseThrow(() -> new FineAntsException(PortfolioErrorCode.NOT_FOUND_PORTFOLIO));
Consumer<Long> sentFunction = sentManager::addMaxLossSendHistory;
Expand Down
Loading

0 comments on commit 8959077

Please sign in to comment.