Skip to content

Commit f4c1884

Browse files
authored
Merge pull request #43 from Block-Guard/refactor/#42/gpt-api-client
[Refactor] AI 서버 통신 로직 리펙토링
2 parents 0eb8228 + 84e3394 commit f4c1884

File tree

2 files changed

+66
-40
lines changed

2 files changed

+66
-40
lines changed

src/main/java/com/blockguard/server/domain/analysis/application/FraudAnalysisService.java

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,12 @@
55
import com.blockguard.server.domain.analysis.dto.request.GptRequest;
66
import com.blockguard.server.domain.analysis.dto.response.FraudAnalysisResponse;
77
import com.blockguard.server.domain.analysis.dto.response.GptResponse;
8-
import com.blockguard.server.global.common.codes.ErrorCode;
9-
import com.blockguard.server.global.exception.BusinessExceptionHandler;
8+
import com.blockguard.server.infra.gpt.GptApiClient;
109
import com.blockguard.server.infra.ocr.NaverOcrClient;
11-
import lombok.AllArgsConstructor;
1210
import lombok.RequiredArgsConstructor;
1311
import lombok.extern.slf4j.Slf4j;
14-
import org.springframework.beans.factory.annotation.Value;
15-
import org.springframework.http.*;
1612
import org.springframework.stereotype.Service;
1713
import org.springframework.util.StringUtils;
18-
import org.springframework.web.client.RestClientException;
19-
import org.springframework.web.client.RestTemplate;
2014
import org.springframework.web.multipart.MultipartFile;
2115

2216
import java.io.IOException;
@@ -29,10 +23,7 @@
2923
public class FraudAnalysisService {
3024

3125
private final NaverOcrClient naverOcrClient;
32-
private final RestTemplate restTemplate;
33-
34-
@Value("${ai.server.url}")
35-
private String aiBaseUrl;
26+
private final GptApiClient gptApiClient;
3627

3728
public FraudAnalysisResponse fraudAnalysis(FraudAnalysisRequest fraudAnalysisRequest, List<MultipartFile> imageFiles) {
3829
List<String> keywords = new ArrayList<>();
@@ -44,36 +35,17 @@ public FraudAnalysisResponse fraudAnalysis(FraudAnalysisRequest fraudAnalysisReq
4435

4536
GptRequest gptRequest = buildGptRequest(fraudAnalysisRequest, keywords, additionalDescription, imageContent);
4637

47-
try {
48-
HttpHeaders headers = new HttpHeaders();
49-
headers.setContentType(MediaType.APPLICATION_JSON);
50-
51-
HttpEntity<GptRequest> entity = new HttpEntity<>(gptRequest, headers);
52-
ResponseEntity<GptResponse> response = restTemplate.postForEntity(
53-
aiBaseUrl,
54-
entity,
55-
GptResponse.class
56-
);
57-
58-
if (response.getBody() == null || !response.getStatusCode().is2xxSuccessful()) {
59-
log.error("AI 서버 응답 오류: status={}, body={}", response.getStatusCode(), response.getBody());
60-
throw new BusinessExceptionHandler(ErrorCode.AI_SERVER_ERROR);
61-
}
38+
// ai 서버 호출
39+
GptResponse gptResponse = gptApiClient.analyze(gptRequest);
6240

63-
double score = response.getBody().getScore();
64-
return FraudAnalysisResponse
65-
.builder()
66-
.keywords(response.getBody().getKeywords())
67-
.score(response.getBody().getScore())
68-
.estimatedFraudType(response.getBody().getEstimatedFraudType())
69-
.explanation(response.getBody().getExplanation())
70-
.riskLevel(RiskLevel.fromScore(score).getValue())
71-
.build();
72-
73-
} catch (RestClientException e){
74-
log.error("AI 서버 통신 실패: {}", e.getMessage());
75-
throw new BusinessExceptionHandler(ErrorCode.AI_SERVER_ERROR);
76-
}
41+
double score = gptResponse.getScore();
42+
return FraudAnalysisResponse.builder()
43+
.keywords(gptResponse.getKeywords())
44+
.score(gptResponse.getScore())
45+
.estimatedFraudType(gptResponse.getEstimatedFraudType())
46+
.explanation(gptResponse.getExplanation())
47+
.riskLevel(RiskLevel.fromScore(score).getValue())
48+
.build();
7749
}
7850

7951
private String extractOcrText(List<MultipartFile> imageFiles) {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.blockguard.server.infra.gpt;
2+
3+
import com.blockguard.server.domain.analysis.dto.request.GptRequest;
4+
import com.blockguard.server.domain.analysis.dto.response.GptResponse;
5+
import com.blockguard.server.global.common.codes.ErrorCode;
6+
import com.blockguard.server.global.exception.BusinessExceptionHandler;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.http.HttpEntity;
11+
import org.springframework.http.HttpHeaders;
12+
import org.springframework.http.MediaType;
13+
import org.springframework.http.ResponseEntity;
14+
import org.springframework.stereotype.Component;
15+
import org.springframework.web.client.RestClientException;
16+
import org.springframework.web.client.RestTemplate;
17+
18+
@Slf4j
19+
@Component
20+
@RequiredArgsConstructor
21+
public class GptApiClient {
22+
23+
private final RestTemplate restTemplate;
24+
25+
@Value("${ai.server.url}")
26+
private String aiServerUrl;
27+
28+
public GptResponse analyze(GptRequest gptRequest) {
29+
log.info("gpt server 사기 분석 api 호출");
30+
31+
HttpHeaders headers = new HttpHeaders();
32+
headers.setContentType(MediaType.APPLICATION_JSON);
33+
34+
HttpEntity<GptRequest> entity = new HttpEntity<>(gptRequest, headers);
35+
36+
try {
37+
ResponseEntity<GptResponse> response = restTemplate.postForEntity(
38+
aiServerUrl,
39+
entity,
40+
GptResponse.class
41+
);
42+
43+
if (response.getBody() == null || !response.getStatusCode().is2xxSuccessful()) {
44+
log.error("GPT API error: status={}, body={}", response.getStatusCode(), response.getBody());
45+
throw new BusinessExceptionHandler(ErrorCode.AI_SERVER_ERROR);
46+
}
47+
return response.getBody();
48+
49+
} catch (RestClientException e){
50+
log.error("GPT API communication failed: {}", e.getMessage());
51+
throw new BusinessExceptionHandler(ErrorCode.AI_SERVER_ERROR);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)