StockHistoryService.java 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package com.danielbohry.stocks.service.stock;
  2. import com.danielbohry.stocks.domain.StockHistory;
  3. import com.danielbohry.stocks.exception.BadRequestException;
  4. import com.danielbohry.stocks.repository.stock.StockHistoryRepository;
  5. import lombok.AllArgsConstructor;
  6. import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
  7. import org.springframework.cache.annotation.Cacheable;
  8. import org.springframework.scheduling.annotation.Scheduled;
  9. import org.springframework.stereotype.Service;
  10. import java.time.Instant;
  11. import java.util.List;
  12. import static java.time.Instant.now;
  13. import static java.time.temporal.ChronoUnit.DAYS;
  14. @Service
  15. @AllArgsConstructor
  16. public class StockHistoryService {
  17. private final StockService service;
  18. private final StockHistoryRepository repository;
  19. public static final String ONCE_PER_DAY_AT_11PM = "0 0 23 * * *";
  20. @Scheduled(cron = ONCE_PER_DAY_AT_11PM)
  21. @SchedulerLock(name = "StockQuoteService_saveQuotes", lockAtLeastFor = "PT5M", lockAtMostFor = "PT15M")
  22. public void saveQuotes() {
  23. List<StockHistory> stocks = service.getAll().stream()
  24. .map(stock -> new StockHistory(stock.getCode(), stock.getCurrency(), stock.getPrice(), now()))
  25. .toList();
  26. repository.saveAll(stocks);
  27. }
  28. @Cacheable(value = "stockHistory", key = "#code + '-' + #range")
  29. public List<StockHistory> get(String code, String range) {
  30. Instant end = Instant.now();
  31. Instant start = switch (range) {
  32. case "5d" -> end.minus(5, DAYS);
  33. case "30d" -> end.minus(30, DAYS);
  34. case "6m" -> end.minus(180, DAYS);
  35. case "1y" -> end.minus(365, DAYS);
  36. default -> throw new BadRequestException("Unsupported range: " + range);
  37. };
  38. return repository.findByCodeAndCreatedAtBetween(code, start, end);
  39. }
  40. }