From dfc4ba3246cd782f6f5f55c05fe38a4e85509c48 Mon Sep 17 00:00:00 2001 From: bong Date: Sat, 15 Aug 2026 19:46:27 +0900 Subject: [PATCH] feat: fastapi --- .github/workflows/deploy-dev.yml | 3 ++ .../spontaneous/FastApiSpontaneousClient.java | 38 +++++++++++++++++++ .../spontaneous/FastApiSpontaneousConfig.java | 31 +++++++++++++++ .../FastApiSpontaneousProperties.java | 27 +++++++++++++ .../SpontaneousTripController.java | 34 +++++++++++++++++ src/main/resources/application.yaml | 7 ++++ 6 files changed, 140 insertions(+) create mode 100644 src/main/java/com/server/external/spontaneous/FastApiSpontaneousClient.java create mode 100644 src/main/java/com/server/external/spontaneous/FastApiSpontaneousConfig.java create mode 100644 src/main/java/com/server/external/spontaneous/FastApiSpontaneousProperties.java create mode 100644 src/main/java/com/server/spontaneous/SpontaneousTripController.java diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index b12a4b8..968615f 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -189,6 +189,9 @@ jobs: # base-url은 끝에 슬래시를 붙이지 않는다. 붙이면 //api/v1/... 로 요청이 나가 404가 된다. printf 'SCHEDULE_FASTAPI_ENABLED=true\n' printf 'SCHEDULE_FASTAPI_BASE_URL=http://data-ai:8010\n' + + printf 'SPONTANEOUS_FASTAPI_ENABLED=true\n' + printf 'SPONTANEOUS_FASTAPI_BASE_URL=http://data-ai:8010\n' printf 'PLACE_THEME_AI_ENABLED=true\n' printf 'PLACE_THEME_AI_BASE_URL=http://data-ai:8010/\n' diff --git a/src/main/java/com/server/external/spontaneous/FastApiSpontaneousClient.java b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousClient.java new file mode 100644 index 0000000..b9e9e70 --- /dev/null +++ b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousClient.java @@ -0,0 +1,38 @@ +package com.server.external.spontaneous; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClient; + +@Component +public class FastApiSpontaneousClient { + + private final RestClient restClient; + private final FastApiSpontaneousProperties properties; + + public FastApiSpontaneousClient( + @Qualifier("fastApiSpontaneousRestClient") RestClient restClient, + FastApiSpontaneousProperties properties + ) { + this.restClient = restClient; + this.properties = properties; + } + + public Map recommendDestinations( + Map request + ) { + if (!properties.enabled()) { + throw new IllegalStateException( + "Spontaneous FastAPI is disabled" + ); + } + + return restClient.post() + .uri("/api/v1/spontaneous-trips/destinations") + .body(request) + .retrieve() + .body(Map.class); + } +} \ No newline at end of file diff --git a/src/main/java/com/server/external/spontaneous/FastApiSpontaneousConfig.java b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousConfig.java new file mode 100644 index 0000000..5c17166 --- /dev/null +++ b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousConfig.java @@ -0,0 +1,31 @@ +package com.server.external.spontaneous; + +import java.net.http.HttpClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.JdkClientHttpRequestFactory; +import org.springframework.web.client.RestClient; + +@Configuration +public class FastApiSpontaneousConfig { + + @Bean + RestClient fastApiSpontaneousRestClient( + FastApiSpontaneousProperties properties + ) { + HttpClient httpClient = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_1_1) + .connectTimeout(properties.connectTimeout()) + .build(); + + JdkClientHttpRequestFactory requestFactory = + new JdkClientHttpRequestFactory(httpClient); + + requestFactory.setReadTimeout(properties.readTimeout()); + + return RestClient.builder() + .baseUrl(properties.baseUrl()) + .requestFactory(requestFactory) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/server/external/spontaneous/FastApiSpontaneousProperties.java b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousProperties.java new file mode 100644 index 0000000..140a8f1 --- /dev/null +++ b/src/main/java/com/server/external/spontaneous/FastApiSpontaneousProperties.java @@ -0,0 +1,27 @@ +package com.server.external.spontaneous; + +import java.time.Duration; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "app.spontaneous-fastapi") +public record FastApiSpontaneousProperties( + boolean enabled, + String baseUrl, + Duration connectTimeout, + Duration readTimeout +) { + + public FastApiSpontaneousProperties { + if (baseUrl == null || baseUrl.isBlank()) { + baseUrl = "http://127.0.0.1:8010"; + } + + if (connectTimeout == null) { + connectTimeout = Duration.ofSeconds(3); + } + + if (readTimeout == null) { + readTimeout = Duration.ofSeconds(30); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/server/spontaneous/SpontaneousTripController.java b/src/main/java/com/server/spontaneous/SpontaneousTripController.java new file mode 100644 index 0000000..593947e --- /dev/null +++ b/src/main/java/com/server/spontaneous/SpontaneousTripController.java @@ -0,0 +1,34 @@ +package com.server.spontaneous; + +import com.server.external.spontaneous.FastApiSpontaneousClient; + +import java.util.Map; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/spontaneous-trips") +public class SpontaneousTripController { + + private final FastApiSpontaneousClient fastApiSpontaneousClient; + + public SpontaneousTripController( + FastApiSpontaneousClient fastApiSpontaneousClient + ) { + this.fastApiSpontaneousClient = fastApiSpontaneousClient; + } + + @PostMapping("/destinations") + public ResponseEntity> recommendDestinations( + @RequestBody Map request + ) { + Map response = + fastApiSpontaneousClient.recommendDestinations(request); + + return ResponseEntity.ok(response); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index ff06ccb..c63b5e7 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -40,6 +40,13 @@ app: base-url: ${SCHEDULE_FASTAPI_BASE_URL:http://127.0.0.1:8010} connect-timeout: ${SCHEDULE_FASTAPI_CONNECT_TIMEOUT:3s} read-timeout: ${SCHEDULE_FASTAPI_READ_TIMEOUT:15s} + # ----------- + spontaneous-fastapi: + enabled: ${SPONTANEOUS_FASTAPI_ENABLED:false} + base-url: ${SPONTANEOUS_FASTAPI_BASE_URL:http://127.0.0.1:8010} + connect-timeout: ${SPONTANEOUS_FASTAPI_CONNECT_TIMEOUT:3s} + read-timeout: ${SPONTANEOUS_FASTAPI_READ_TIMEOUT:30s} + #--------------- place-ingestion: tour-api: enabled: ${TOUR_API_PLACE_INGESTION_ENABLED:false}