Skip to content

Commit af56704

Browse files
committed
fix: AI 서버 요청에 Presigned URL 전달 방식 수정
1 parent cf15a52 commit af56704

1 file changed

Lines changed: 71 additions & 14 deletions

File tree

  • src/main/java/com/quadcore/voiceandtext/infrastructure/analysis

src/main/java/com/quadcore/voiceandtext/infrastructure/analysis/AiService.java

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import org.springframework.boot.web.client.RestTemplateBuilder;
99
import org.springframework.http.*;
1010
import org.springframework.stereotype.Service;
11+
import org.springframework.web.client.HttpStatusCodeException;
1112
import org.springframework.web.client.RestTemplate;
1213

14+
import java.net.URI;
1315
import java.time.Duration;
1416
import java.util.Map;
1517

@@ -37,31 +39,86 @@ private void init() {
3739
}
3840

3941
public void requestAnalysis(AnalysisRequest analysisRequest) {
40-
String presignedUrl = s3Service.generatePresignedUrl(analysisRequest.getAudioFile().getStorageLocation(), Duration.ofMinutes(10));
42+
String key = null;
43+
if (analysisRequest.getAudioFile() != null) {
44+
key = analysisRequest.getAudioFile().getStorageLocation();
45+
if (key == null || key.isBlank()) {
46+
key = extractKeyFromFileUrl(analysisRequest.getAudioFile().getFileUrl());
47+
}
48+
}
49+
50+
if (key == null || key.isBlank()) {
51+
throw new RuntimeException("AudioFile storage location or S3 key is missing for analysisRequest=" + analysisRequest.getId());
52+
}
53+
54+
String presignedUrl = s3Service.generatePresignedUrl(key, Duration.ofMinutes(10));
55+
boolean hasSignature = presignedUrl.contains("X-Amz-Signature");
56+
57+
log.info("AI 서버 요청 URL 생성: analysisRequestId={}, presignedUrl.length={}, hasSignature={}",
58+
analysisRequest.getId(), presignedUrl.length(), hasSignature);
4159

4260
Map<String, Object> requestBody = Map.of(
43-
"analysisRequestId", analysisRequest.getId(),
44-
"audioUrl", presignedUrl,
45-
"durationSeconds", analysisRequest.getAudioFile().getDurationSeconds()
46-
// callbackUrl은 나중에 추가
61+
"file_url", presignedUrl
4762
);
4863

4964
HttpHeaders headers = new HttpHeaders();
5065
headers.setContentType(MediaType.APPLICATION_JSON);
5166

5267
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
5368

54-
ResponseEntity<String> response = restTemplate.exchange(
55-
aiServerUrl + "/api/analyze",
56-
HttpMethod.POST,
57-
entity,
58-
String.class
59-
);
69+
try {
70+
ResponseEntity<String> response = restTemplate.exchange(
71+
URI.create(aiServerUrl),
72+
HttpMethod.POST,
73+
entity,
74+
String.class
75+
);
76+
77+
if (!response.getStatusCode().equals(HttpStatus.OK)) {
78+
log.error("AI 서버 요청 실패: analysisRequestId={}, status={}, body={}",
79+
analysisRequest.getId(), response.getStatusCodeValue(), response.getBody());
80+
throw new RuntimeException("AI 서버 요청 실패: " + response.getStatusCodeValue());
81+
}
6082

61-
if (response.getStatusCode() != HttpStatus.OK) {
62-
throw new RuntimeException("AI 서버 요청 실패: " + response.getStatusCode());
83+
log.info("AI 서버 요청 성공: {}", analysisRequest.getId());
84+
} catch (HttpStatusCodeException e) {
85+
log.error("AI 서버 요청 실패: analysisRequestId={}, status={}, responseBody={}",
86+
analysisRequest.getId(), e.getRawStatusCode(), e.getResponseBodyAsString(), e);
87+
throw new RuntimeException("AI 서버 요청 실패: " + e.getRawStatusCode(), e);
88+
} catch (Exception e) {
89+
log.error("AI 서버 요청 중 예외 발생: analysisRequestId={}, message={}",
90+
analysisRequest.getId(), e.getMessage(), e);
91+
throw new RuntimeException("AI 서버 요청 실패", e);
92+
}
93+
}
94+
95+
private String extractKeyFromFileUrl(String fileUrl) {
96+
if (fileUrl == null || fileUrl.isBlank()) {
97+
return null;
6398
}
6499

65-
log.info("AI 서버 요청 성공: {}", analysisRequest.getId());
100+
try {
101+
URI uri = URI.create(fileUrl);
102+
String path = uri.getPath();
103+
if (path == null || path.isBlank()) {
104+
return null;
105+
}
106+
if (path.startsWith("/")) {
107+
path = path.substring(1);
108+
}
109+
110+
String host = uri.getHost();
111+
if (host != null && host.contains("s3")) {
112+
if (path.contains("/")) {
113+
return path.startsWith("/") ? path.substring(1) : path;
114+
}
115+
return path;
116+
}
117+
118+
return path;
119+
} catch (Exception e) {
120+
log.warn("fileUrl에서 S3 키 추출 실패: {}", fileUrl);
121+
return null;
122+
}
66123
}
67124
}

0 commit comments

Comments
 (0)