Browse Source

bump springboot 3.5 (#10)

Daniel Bohry 2 months ago
parent
commit
116eec2c62

+ 2 - 2
.github/workflows/build.yml

@@ -13,10 +13,10 @@ jobs:
 
     steps:
       - uses: actions/checkout@v3
-      - name: Set up JDK (Java 21)
+      - name: Set up JDK (Java 25)
         uses: actions/setup-java@v3
         with:
-          java-version: '21'
+          java-version: '25'
           distribution: 'temurin'
       - name: Build with Gradle
         run: chmod +x ./gradlew && ./gradlew clean build test

+ 2 - 2
.github/workflows/buildAndRelease.yml

@@ -16,7 +16,7 @@ jobs:
       - name: Set up JDK
         uses: actions/setup-java@v3
         with:
-          java-version: '21'
+          java-version: '25'
           distribution: 'temurin'
       - name: Build with Gradle
         run: chmod +x ./gradlew && ./gradlew clean build test
@@ -30,7 +30,7 @@ jobs:
       - name: Set up JDK
         uses: actions/setup-java@v3
         with:
-          java-version: '21'
+          java-version: '25'
           distribution: 'temurin'
       - name: Build
         run: ./gradlew build

+ 2 - 2
Dockerfile

@@ -1,4 +1,4 @@
-FROM openjdk:21-slim as BuildJava
-ARG JAR_FILE=build/libs/stocks-be-0.1.jar
+FROM eclipse-temurin:25-jre-noble
+ARG JAR_FILE=build/libs/stocks-be.jar
 COPY ${JAR_FILE} app.jar
 ENTRYPOINT ["java","-jar","/app.jar"]

+ 11 - 12
build.gradle

@@ -1,15 +1,14 @@
 plugins {
     id 'java'
-    id 'org.springframework.boot' version '3.4.3'
-    id 'io.spring.dependency-management' version '1.1.4'
-    id 'com.gorylenko.gradle-git-properties' version '2.5.0'
+    id 'org.springframework.boot' version '3.5.+'
+    id 'io.spring.dependency-management' version '1.1.+'
+    id 'com.gorylenko.gradle-git-properties' version '2.5.3'
 }
 
 group = 'com.danielbohry'
-version = '0.1'
 
 java {
-    sourceCompatibility = '21'
+    sourceCompatibility = '25'
 }
 
 repositories {
@@ -22,21 +21,21 @@ dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-cache'
     implementation 'org.springframework.boot:spring-boot-starter-actuator'
 
-    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.0.2'
-    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
+    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.+'
+    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.+'
     implementation 'com.github.ben-manes.caffeine:caffeine'
-    implementation 'net.javacrumbs.shedlock:shedlock-spring:6.4.0'
-    implementation 'net.javacrumbs.shedlock:shedlock-provider-mongo:6.4.0'
+    implementation 'net.javacrumbs.shedlock:shedlock-spring:6.+'
+    implementation 'net.javacrumbs.shedlock:shedlock-provider-mongo:6.+'
 
-    compileOnly 'org.projectlombok:lombok:1.18.30'
-    annotationProcessor 'org.projectlombok:lombok:1.18.30'
+    compileOnly 'org.projectlombok:lombok'
+    annotationProcessor 'org.projectlombok:lombok'
 
     testImplementation 'org.springframework.boot:spring-boot-starter-test'
 }
 
 dependencyManagement {
     imports {
-        mavenBom "org.springframework.boot:spring-boot-dependencies:3.0.5"
+        mavenBom "org.springframework.boot:spring-boot-dependencies:3.5.+"
     }
 }
 

BIN
gradle/wrapper/gradle-wrapper.jar


+ 4 - 3
gradle/wrapper/gradle-wrapper.properties

@@ -1,6 +1,7 @@
-#Sun Jun 02 18:52:32 CEST 2024
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+zipStorePath=wrapper/dists

+ 14 - 14
gradlew

@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright © 2015-2021 the original authors.
+# Copyright © 2015 the original authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+# SPDX-License-Identifier: Apache-2.0
+#
 
 ##############################################################################
 #
@@ -55,7 +57,7 @@
 #       Darwin, MinGW, and NonStop.
 #
 #   (3) This script is generated from the Groovy template
-#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 #       within the Gradle project.
 #
 #       You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,7 +85,8 @@ done
 # This is normally unused
 # shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
@@ -111,7 +114,6 @@ case "$( uname )" in                #(
   NONSTOP* )        nonstop=true ;;
 esac
 
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
 
 # Determine the Java command to use to start the JVM.
@@ -144,7 +146,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
     case $MAX_FD in #(
       max*)
         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045
+        # shellcheck disable=SC2039,SC3045
         MAX_FD=$( ulimit -H -n ) ||
             warn "Could not query maximum file descriptor limit"
     esac
@@ -152,7 +154,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
       '' | soft) :;; #(
       *)
         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045
+        # shellcheck disable=SC2039,SC3045
         ulimit -n "$MAX_FD" ||
             warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
@@ -169,7 +171,6 @@ fi
 # For Cygwin or MSYS, switch paths to Windows format before running java
 if "$cygwin" || "$msys" ; then
     APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
-    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
 
     JAVACMD=$( cygpath --unix "$JAVACMD" )
 
@@ -201,16 +202,15 @@ fi
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
-# Collect all arguments for the java command;
-#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-#     shell script including quotes and variable substitutions, so put them in
-#     double quotes to make sure that they get re-expanded; and
-#   * put everything else in single quotes, so that it's not re-expanded.
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
-        -classpath "$CLASSPATH" \
-        org.gradle.wrapper.GradleWrapperMain \
+        -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
         "$@"
 
 # Stop when "xargs" is not available.

+ 13 - 12
gradlew.bat

@@ -13,6 +13,8 @@
 @rem See the License for the specific language governing permissions and
 @rem limitations under the License.
 @rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
 
 @if "%DEBUG%"=="" @echo off
 @rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
 if %ERRORLEVEL% equ 0 goto execute
 
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
@@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
 if exist "%JAVA_EXE%" goto execute
 
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
 
 goto fail
 
 :execute
 @rem Setup the command line
 
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
 
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
 
 :end
 @rem End local scope for the variables with windows NT shell

+ 0 - 11
src/main/java/com/danielbohry/stocks/api/stock/StockController.java

@@ -1,6 +1,5 @@
 package com.danielbohry.stocks.api.stock;
 
-import com.danielbohry.stocks.context.UserContextHolder;
 import com.danielbohry.stocks.domain.Stock;
 import com.danielbohry.stocks.domain.StockInfo;
 import com.danielbohry.stocks.service.stock.StockInfoService;
@@ -74,16 +73,6 @@ public class StockController {
         }
     }
 
-    @Hidden
-    @PostMapping("/generate")
-    public ResponseEntity<Void> generateStockInfo() {
-        if (UserContextHolder.isAdmin()) {
-            infoService.generate();
-        }
-
-        return ResponseEntity.ok().build();
-    }
-
     private Stock convert(String input, String currency) {
         String[] value = input.split(",");
         log.info("Importing [{}]", (Object) value);

+ 0 - 53
src/main/java/com/danielbohry/stocks/client/FinanceClient.java

@@ -1,53 +0,0 @@
-package com.danielbohry.stocks.client;
-
-import com.danielbohry.stocks.domain.Stock;
-import com.danielbohry.stocks.domain.StockInfo;
-import com.danielbohry.stocks.repository.stock.StockRepository.StockMetadataResponse;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static java.time.Instant.now;
-
-@Slf4j
-@Component
-@RequiredArgsConstructor
-public class FinanceClient {
-
-    private final StockClient client;
-
-    @Value("${clients.stock.key}")
-    private String key;
-
-    public List<StockInfo> fetchStockInfo(List<Stock> quotes) {
-        List<StockInfo> response = new ArrayList<>();
-        try {
-            String[] tickers = quotes.stream()
-                .map(Stock::getCode)
-                .filter(ObjectUtils::isNotEmpty)
-                .toArray(String[]::new);
-
-            List<StockMetadataResponse> metadata = client.getMetadata(key, String.join(",", tickers));
-
-            metadata.forEach(meta -> response.add(StockInfo.builder()
-                .code(meta.getTicker().toUpperCase())
-                .name(meta.getName())
-                .headquarters(meta.getLocation())
-                .industry(meta.getSector() + " - " + meta.getIndustry())
-                .companyWebsite(meta.getCompanyWebsite())
-                .secWebsite(meta.getSecWebsite())
-                .updatedAt(now())
-                .build()));
-            return response;
-        } catch (Exception e) {
-            log.error(e.getMessage());
-            return null;
-        }
-    }
-
-}

+ 0 - 126
src/main/java/com/danielbohry/stocks/client/InferenceClient.java

@@ -1,126 +0,0 @@
-package com.danielbohry.stocks.client;
-
-import com.danielbohry.stocks.domain.Stock;
-import com.danielbohry.stocks.domain.StockInfo;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static java.time.Instant.now;
-
-@Slf4j
-@Component
-@RequiredArgsConstructor
-public class InferenceClient {
-
-    private final RestTemplate rest;
-
-    @Value("${clients.inference.url}")
-    private String baseUrl;
-
-    @Value("${clients.inference.model}")
-    private String model;
-
-    private static final String PROMPT = """
-        Ignore all previous instructions. You are an API. Respond only with a **valid JSON object** using the exact format and keys below.
-        Do not include any explanation, markdown, or extra text.
-        
-        Respond with JSON in the following format:
-        {
-          "founded": "<4-digit year or 'unknown'>",
-          "ipo": "<4-digit year or 'unknown'>",
-          "headquarters": "<city and state/country or 'unknown'>",
-          "industry": "<industry sector or 'unknown'>",
-          "description": "<description or 'unknown'>"
-        }
-        
-        Make sure the output is a valid JSON string with no extra text or markdown.
-        
-        Company stock code:
-        """;
-
-    private static final ObjectMapper mapper = new ObjectMapper();
-
-    public StockInfo infer(Stock quote) {
-        String inference = infer(PROMPT + quote.getCode());
-
-        return buildStockInfo(quote, inference);
-    }
-
-    private String infer(String prompt) {
-        try {
-            Map<String, Object> requestBody = new HashMap<>();
-            requestBody.put("model", model);
-            requestBody.put("prompt", prompt);
-            requestBody.put("stream", false);
-
-            HttpHeaders headers = new HttpHeaders();
-            headers.setContentType(MediaType.APPLICATION_JSON);
-
-            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
-            ResponseEntity<InferenceResponse> response = rest.postForEntity(baseUrl + "/api/generate", request, InferenceResponse.class);
-
-            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
-                return response.getBody().getResponse();
-            } else {
-                return null;
-            }
-
-        } catch (Exception e) {
-            log.error("Error during inference", e);
-            return null;
-        }
-    }
-
-    private StockInfo buildStockInfo(Stock stock, String inference) {
-        try {
-            String cleanInference = inference.replaceAll("(?i)^[^{]*\\{", "{").replaceAll("[^}]*$", "}").trim();
-            Inference parsed = mapper.readValue(cleanInference, Inference.class);
-
-            return StockInfo.builder()
-                .code(stock.getCode())
-                .name(stock.getName())
-                .description(parsed.getDescription())
-                .foundation(parsed.getFounded())
-                .ipo(parsed.getIpo())
-                .headquarters(parsed.getHeadquarters())
-                .industry(parsed.getIndustry())
-                .build();
-        } catch (Exception e) {
-            log.error("Failed to parse inference response [{}]", inference, e);
-            return null;
-        }
-    }
-
-    @NoArgsConstructor
-    @AllArgsConstructor
-    @Data
-    public static class Inference {
-        private String founded;
-        private String ipo;
-        private String exchange;
-        private String headquarters;
-        private String industry;
-        private String description;
-    }
-
-    @NoArgsConstructor
-    @AllArgsConstructor
-    @Data
-    public static class InferenceResponse {
-        private String response;
-    }
-}

+ 0 - 29
src/main/java/com/danielbohry/stocks/client/StockClient.java

@@ -1,29 +0,0 @@
-package com.danielbohry.stocks.client;
-
-import com.danielbohry.stocks.config.FeignConfig;
-import com.danielbohry.stocks.repository.stock.StockRepository.StockInfoResponse;
-import com.danielbohry.stocks.repository.stock.StockRepository.StockMetadataResponse;
-import com.danielbohry.stocks.repository.stock.StockRepository.StockQuoteResponse;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import java.util.List;
-
-@FeignClient(name = "stockClient", url = "${clients.stock.url}", configuration = FeignConfig.class)
-public interface StockClient {
-
-    @GetMapping("daily/{symbol}/prices")
-    List<StockQuoteResponse> getStockQuote(@PathVariable("symbol") String symbol,
-                                           @RequestParam("token") String apiKey);
-
-    @GetMapping("daily/{symbol}")
-    StockInfoResponse getStockInfo(@PathVariable("symbol") String symbol,
-                                   @RequestParam("token") String apiKey);
-
-    @GetMapping("fundamentals/meta")
-    List<StockMetadataResponse> getMetadata(@RequestParam("token") String apiKey,
-                                            @RequestParam("tickers") String tickers);
-
-}

+ 4 - 95
src/main/java/com/danielbohry/stocks/repository/stock/StockRepository.java

@@ -1,18 +1,10 @@
 package com.danielbohry.stocks.repository.stock;
 
-import com.danielbohry.stocks.client.StockClient;
 import com.danielbohry.stocks.domain.Stock;
-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.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -20,22 +12,14 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static java.time.Instant.now;
-import static java.time.temporal.ChronoUnit.DAYS;
 import static java.util.stream.Collectors.toList;
 
 @Slf4j
 @Repository
+@AllArgsConstructor
 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<Stock> findAll() {
         return repository.findAll();
@@ -80,87 +64,12 @@ public class StockRepository {
 
     public boolean isValid(String code) {
         Stock quote = repository.findByCode(code).stream().findFirst().orElse(null);
-
-        if (quote != null) 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;
-        }
+        return quote != null;
     }
 
     public Stock getStockQuote(String code) {
-        Stock quote = repository.findByCode(code).stream().findFirst().orElse(new Stock(code, null, 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) {
-        return client.getStockInfo(code, key);
-    }
-
-    private BigDecimal getLastPrice(Stock 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().minus(5, DAYS))) {
-            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;
-    }
-
-    @Data
-    @AllArgsConstructor
-    @NoArgsConstructor
-    @JsonIgnoreProperties(ignoreUnknown = true)
-    public static class StockMetadataResponse {
-        private String ticker;
-        private String name;
-        private String sector;
-        private String industry;
-        private String location;
-        private String companyWebsite;
-        @JsonProperty("reportingCurrency")
-        private String currency;
-        @JsonProperty("secFilingWebsite")
-        private String secWebsite;
+        return repository.findByCode(code).stream().findFirst()
+            .orElse(new Stock(code, null, null, null, null, now()));
     }
 
 }

+ 0 - 37
src/main/java/com/danielbohry/stocks/service/stock/StockInfoService.java

@@ -1,29 +1,18 @@
 package com.danielbohry.stocks.service.stock;
 
-import com.danielbohry.stocks.client.FinanceClient;
-import com.danielbohry.stocks.domain.Stock;
 import com.danielbohry.stocks.domain.StockInfo;
 import com.danielbohry.stocks.exception.NotFoundException;
 import com.danielbohry.stocks.repository.stock.StockInfoRepository;
-import com.danielbohry.stocks.repository.stock.StockRepository;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.cache.annotation.Cacheable;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Set;
-
-import static java.util.stream.Collectors.toSet;
-
 @Slf4j
 @Service
 @AllArgsConstructor
 public class StockInfoService {
 
-    private FinanceClient client;
-    private StockRepository stockRepository;
     private StockInfoRepository infoRepository;
 
     @Cacheable(value = "stockInfo", key = "#code")
@@ -32,30 +21,4 @@ public class StockInfoService {
             .orElseThrow(() -> new NotFoundException("No stock found with id: " + code));
     }
 
-    @Async("stockInfoExecutor")
-    public void generate() {
-        List<Stock> stocks = stockRepository.findAll();
-
-        Set<String> existingIds = infoRepository.findAllById(
-                stocks.stream()
-                    .map(Stock::getCode)
-                    .collect(toSet())
-            ).stream()
-            .map(StockInfo::getCode)
-            .collect(toSet());
-
-        List<Stock> request = stocks.stream()
-            .filter(stock -> !existingIds.contains(stock.getCode()))
-            .filter(stock -> !stock.getCode().contains(":"))
-            .toList();
-
-        int batchSize = 20;
-        for (int i = 0; i < request.size(); i += batchSize) {
-            int end = Math.min(i + batchSize, request.size());
-            List<Stock> batch = request.subList(i, end);
-            List<StockInfo> stockInfos = client.fetchStockInfo(batch);
-            infoRepository.saveAll(stockInfos);
-        }
-    }
-
 }

+ 0 - 6
src/main/resources/application.yml

@@ -2,15 +2,9 @@ server:
   port: ${port:8080}
 
 clients:
-  stock:
-    url: ${stock_provider:https://api.tiingo.com/tiingo}
-    key: ${stock_key:}
   exchange:
     url: ${exchange_provider:https://v6.exchangerate-api.com/v6}
     key: ${exchange_key:}
-  inference:
-    url: ${inference_client:}
-    model: ${inference_model:}
 
 encryption:
   key: ${encryption_key:}

+ 1 - 1
src/test/resources/application.yml

@@ -3,7 +3,7 @@ server:
 
 clients:
   stock:
-    url: ${provider:http://mock.com}
+
     key: ${key:fake-key}
   exchange:
     url: ${exchange_provider:http://mock.com}