Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package site.icebang.common.health.service;

import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -14,7 +14,7 @@
@RequiredArgsConstructor
public class HealthCheckService {

private final RestClient restClient;
private final RestTemplate restTemplate;

private final FastApiProperties fastApiProperties;

Expand All @@ -24,7 +24,7 @@ public String ping() {
log.info("Attempting to connect to FastAPI server at: {}", url);

try {
return restClient.get().uri(url).retrieve().body(String.class);
return restTemplate.getForObject(url, String.class);
} catch (RestClientException e) {
log.error("Failed to connect to FastAPI server at {}. Error: {}", url, e.getMessage());
return "ERROR: Cannot connect to FastAPI";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import org.slf4j.MDC;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -14,8 +14,8 @@
/**
* 외부 FastAPI 서버와의 모든 HTTP 통신을 전담하는 어댑터 클래스입니다.
*
* <p>이 클래스는 내부 시스템의 다른 부분들이 외부 시스템의 상세한 통신 방법을 알 필요가 없도록 HTTP 요청/응답 로직을 캡슐화합니다. {@code RestClient}을
* 사용하여 실제 통신을 수행하며, 모든 FastAPI 요청은 이 클래스의 {@code call} 메소드를 통해 이루어져야 합니다.
* <p>이 클래스는 내부 시스템의 다른 부분들이 외부 시스템의 상세한 통신 방법을 알 필요가 없도록 HTTP 요청/응답 로직을 캡슐화합니다. {@code
* RestTemplate}을 사용하여 실제 통신을 수행하며, 모든 FastAPI 요청은 이 클래스의 {@code call} 메소드를 통해 이루어져야 합니다.
*
* <h2>사용 예제:</h2>
*
Expand All @@ -34,7 +34,7 @@
@RequiredArgsConstructor
public class FastApiAdapter {

private final RestClient restClient;
private final RestTemplate restTemplate;
private final FastApiProperties properties;

/**
Expand All @@ -47,32 +47,26 @@ public class FastApiAdapter {
* @param method 사용할 HTTP 메소드 (예: HttpMethod.POST)
* @param requestBody 요청에 담을 JSON 문자열
* @return 성공 시 API 응답 Body 문자열, 실패 시 null
* @see RestClient
* @see RestTemplate
* @since v0.1.0
*/
public String call(String endpoint, HttpMethod method, String requestBody) {
String fullUrl = properties.getUrl() + endpoint;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

String traceId = MDC.get("traceId");
if (traceId != null) {
headers.set("X-Request-ID", traceId);
log.debug("TraceID 헤더 추가: {}", traceId);
}

HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);

try {
log.debug("FastAPI 요청: URL={}, Method={}, Body={}", fullUrl, method, requestBody);

ResponseEntity<String> responseEntity =
restClient
.method(method)
.uri(fullUrl)
.contentType(MediaType.APPLICATION_JSON)
.headers(
headers -> {
String traceId = MDC.get("traceId");
if (traceId != null) {
headers.set("X-Request-ID", traceId);
log.debug("TraceID 헤더 추가: {}", traceId);
}
})
.body(requestBody)
.retrieve()
.toEntity(String.class);

restTemplate.exchange(fullUrl, method, requestEntity, String.class);
String responseBody = responseEntity.getBody();
log.debug("FastAPI 응답: Status={}, Body={}", responseEntity.getStatusCode(), responseBody);
return responseBody;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import java.time.Duration;
import java.util.TimeZone;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand All @@ -16,13 +17,13 @@
/**
* 애플리케이션의 웹 관련 설정을 담당하는 Java 기반 설정 클래스입니다.
*
* <p>이 클래스는 애플리케이션 전역에서 사용될 웹 관련 빈(Bean)들을 생성하고 구성합니다. 현재는 외부 API 통신을 위한 {@code RestClient} 빈을 중앙에서
* 관리하는 역할을 합니다.
* <p>이 클래스는 애플리케이션 전역에서 사용될 웹 관련 빈(Bean)들을 생성하고 구성합니다. 현재는 외부 API 통신을 위한 {@code RestTemplate} 빈을
* 중앙에서 관리하는 역할을 합니다.
*
* <h2>주요 기능:</h2>
*
* <ul>
* <li>커넥션 및 읽기 타임아웃이 설정된 RestClient 빈 생성
* <li>커넥션 및 읽기 타임아웃이 설정된 RestTemplate 빈 생성
* </ul>
*
* @author jihu0210@naver.com
Expand All @@ -32,21 +33,29 @@
public class WebConfig {

/**
* 외부 API 통신을 위한 RestClient 빈을 생성하여 스프링 컨테이너에 등록합니다.
* 외부 API 통신을 위한 RestTemplate 빈을 생성하여 스프링 컨테이너에 등록합니다.
*
* <p>커넥션 및 읽기 타임아웃을 각각 30초로 설정한 {@code SimpleClientHttpRequestFactory}를 사용하여 RestClient를 구성합니다.
* 이렇게 생성된 RestClient 빈은 애플리케이션의 다른 컴포넌트에서 주입받아 외부 시스템과의 HTTP 통신에 사용됩니다.
* <p>기본 {@code RestTemplateBuilder}를 사용하되, 커넥션 및 읽기 타임아웃을 각각 30초로 명시적으로 설정하기 위해 {@code
* SimpleClientHttpRequestFactory}를 구성하여 주입합니다. 이렇게 생성된 RestTemplate 빈은 애플리케이션의 다른 컴포넌트에서 주입받아 외부
* 시스템과의 HTTP 통신에 사용됩니다.
*
* @return 타임아웃이 설정된 RestClient 인스턴스
* @param builder Spring Boot가 자동으로 구성해주는 RestTemplateBuilder 객체
* @return 타임아웃이 설정된 RestTemplate 인스턴스
* @see RestTemplate
* @see RestTemplateBuilder
* @since v0.1.0
*/
@Bean
public RestClient restClient() {
public RestTemplate restTemplate(RestTemplateBuilder builder) {
// 1. SimpleClientHttpRequestFactory 객체를 직접 생성
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(Duration.ofSeconds(30));
requestFactory.setReadTimeout(Duration.ofSeconds(30));

return RestClient.builder().requestFactory(requestFactory).build();
// 2. 타임아웃 설정 (이 메서드들은 deprecated 아님)
requestFactory.setConnectTimeout(Duration.ofSeconds(30000));
requestFactory.setReadTimeout(Duration.ofSeconds(30000));

// 3. 빌더에 직접 생성한 requestFactory를 설정
return builder.requestFactory(() -> requestFactory).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import org.junit.jupiter.api.Test;

import site.icebang.e2e.setup.annotation.E2eTest;
import site.icebang.e2e.setup.support.E2eTestSupport;

@E2eTest
class ContextLoadE2eTests extends E2eTestSupport {

@Test
Expand Down
Loading
Loading