| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package com.danielbohry.stocks.repository;
- import com.danielbohry.stocks.client.StockClient;
- import com.danielbohry.stocks.domain.Quote;
- import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
- import com.fasterxml.jackson.annotation.JsonProperty;
- import feign.FeignException;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Repository;
- import java.math.BigDecimal;
- import java.time.Instant;
- import java.util.*;
- import java.util.function.Function;
- import java.util.stream.Collectors;
- import static java.time.LocalDateTime.now;
- import static java.util.stream.Collectors.toList;
- @Slf4j
- @Repository
- public class StockRepository {
- private final QuoteRepository repository;
- private final StockClient client;
- private final String key;
- public StockRepository(QuoteRepository repository, StockClient client, @Value("${clients.stock.key}") String key) {
- this.repository = repository;
- this.client = client;
- this.key = key;
- }
- public List<Quote> findAll() {
- return repository.findAll();
- }
- public List<Quote> findLike(String query) {
- return repository.findByNameOrCode(query);
- }
- public Quote findByCode(String code) {
- Optional<Quote> quote = repository.findByCode(code);
- return quote.orElseGet(() -> repository.save(getStockQuote(code)));
- }
- public List<Quote> update(List<Quote> quotes) {
- log.info("Updating [{}] quotes [{}]", quotes.size(), Instant.now());
- List<String> codes = quotes.stream()
- .map(Quote::getCode)
- .collect(toList());
- Map<String, Quote> existingQuotesMap = repository.findByCodeIn(codes)
- .stream()
- .collect(Collectors.toMap(Quote::getCode, Function.identity()));
- log.info("Found [{}] quotes by codes [{}]", existingQuotesMap.size(), Instant.now());
- List<Quote> updatedQuotes = quotes.stream()
- .map(quote -> {
- Quote existingQuote = existingQuotesMap.get(quote.getCode());
- if (existingQuote != null) {
- quote.setId(existingQuote.getId());
- }
- return quote;
- })
- .collect(toList());
- log.info("Updating [{}] quotes [{}]", updatedQuotes.size(), Instant.now());
- List<Quote> result = repository.saveAll(updatedQuotes);
- log.info("Update complete for [{}] quotes [{}]", quotes.size(), Instant.now());
- return result;
- }
- public boolean isValid(String code) {
- Quote quote = repository.findByCode(code).stream().findFirst().orElse(null);
- if (quote != null && "BRL".equals(quote.getCurrency())) return true;
- try {
- log.info("Current stock's name is null. Requesting latest information...");
- client.getStockInfo(code, key);
- return true;
- } catch (FeignException.NotFound e) {
- return false;
- }
- }
- public Quote getStockQuote(String code) {
- Quote quote = repository.findByCode(code).stream().findFirst().orElse(new Quote(code, null, null, null, now()));
- quote.setPrice(getLastPrice(quote));
- if (quote.getName() == null || quote.getPrice() == null) {
- StockInfoResponse info = updateStockInformation(quote.getCode());
- quote.setName(info.getName());
- repository.save(quote);
- }
- return quote;
- }
- private StockInfoResponse updateStockInformation(String code) {
- log.info("Current stock's name is null. Requesting latest information...");
- return client.getStockInfo(code, key);
- }
- private BigDecimal getLastPrice(Quote quote) {
- if (quote.getPrice() == null && "USD".equals(quote.getCurrency())) {
- log.info("Current quote for [{}] is null. Requesting latest quote...", quote);
- return new BigDecimal(client.getStockQuote(quote.getCode(), key).get(0).getLastPrice());
- } else if (quote.getUpdatedAt().isBefore(now().minusDays(5))) {
- log.info("Current quote for [{}] is older than 1 day. Requesting latest quote...", quote);
- return new BigDecimal(client.getStockQuote(quote.getCode(), key).get(0).getLastPrice());
- } else {
- return quote.getPrice();
- }
- }
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @JsonIgnoreProperties(ignoreUnknown = true)
- public static class StockQuoteResponse {
- @JsonProperty("adjClose")
- private String lastPrice;
- @JsonProperty("adjOpen")
- private String openPrice;
- }
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @JsonIgnoreProperties(ignoreUnknown = true)
- public static class StockInfoResponse {
- @JsonProperty("ticker")
- private String code;
- @JsonProperty("name")
- private String name;
- @JsonProperty("exchangeCode")
- private String exchange;
- }
- }
|