From 55d15a261ebadd480f20522dbc30e2e0833b4cd3 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Tue, 27 Jan 2026 13:29:57 +0900 Subject: [PATCH 01/25] =?UTF-8?q?feat:=20google=20cloud=20storage=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../call/service/RecordingServiceImpl.java | 1 + .../unity/domain/call/util/GcsUploader.java | 48 ++++++++++ .../domain/stt/service/SttServiceImpl.java | 91 +++++++++++++------ 4 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/ureca/unity/domain/call/util/GcsUploader.java diff --git a/build.gradle b/build.gradle index abfbee5..2d15d17 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' + implementation 'com.google.cloud:google-cloud-storage:2.30.0' implementation 'com.google.cloud:google-cloud-speech:4.46.0' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' diff --git a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java index e95cf73..dd97bed 100644 --- a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java @@ -1,6 +1,7 @@ package com.ureca.unity.domain.call.service; import com.ureca.unity.domain.call.util.Converter; +import com.ureca.unity.domain.call.util.GcsUploader; import com.ureca.unity.domain.stt.service.SttService; import com.ureca.unity.global.exception.CustomException; import com.ureca.unity.global.exception.ErrorCode; diff --git a/src/main/java/com/ureca/unity/domain/call/util/GcsUploader.java b/src/main/java/com/ureca/unity/domain/call/util/GcsUploader.java new file mode 100644 index 0000000..6407749 --- /dev/null +++ b/src/main/java/com/ureca/unity/domain/call/util/GcsUploader.java @@ -0,0 +1,48 @@ +package com.ureca.unity.domain.call.util; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.cloud.storage.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +import java.nio.file.Files; +import java.nio.file.Path; + +@Slf4j +@Component +public class GcsUploader { + + @Value("${google.cloud.project-id}") private String projectId; + @Value("${google.cloud.bucket-name}") private String bucketName; + @Value("${google.cloud.credentials.location}") private String keyPath; + + public String uploadWav( + String objectName, + Path wavPath + ) throws Exception { + Resource resource = new DefaultResourceLoader().getResource(keyPath); + GoogleCredentials credentials = + GoogleCredentials.fromStream(resource.getInputStream()); + + Storage storage = StorageOptions.newBuilder() + .setProjectId(projectId) + .setCredentials(credentials) + .build() + .getService(); + + log.error("DEBUG GCS PARAMS >>> bucketName=[{}], objectName=[{}], wavPath=[{}]", + bucketName, objectName, wavPath); + + BlobId blobId = BlobId.of(bucketName, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId) + .setContentType("audio/wav") + .build(); + + storage.create(blobInfo, Files.readAllBytes(wavPath)); + + return "gs://" + bucketName + "/" + objectName; + } +} diff --git a/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java b/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java index 12d81ca..65f6a9a 100644 --- a/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java @@ -5,6 +5,7 @@ import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.speech.v1.*; import com.google.protobuf.ByteString; +import com.ureca.unity.domain.call.util.GcsUploader; import com.ureca.unity.domain.stt.mapper.CounselingResultMapper; import com.ureca.unity.domain.stt.model.CounselingResult; import com.ureca.unity.domain.summary.service.SummaryService; @@ -18,6 +19,7 @@ import java.io.File; import java.io.InputStream; import java.nio.file.Files; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service @@ -27,13 +29,14 @@ public class SttServiceImpl implements SttService { private final CounselingResultMapper sttMapper; private final SummaryService summaryService; + private final GcsUploader gcpUploader; @Value("${google.cloud.credentials.location}") private String keyPath; @Override public CounselingResult startStt(File file, long userId) { - // 초기 작업 저장 + CounselingResult job = CounselingResult.builder() .userId(userId) .counselorId(1L) @@ -42,56 +45,78 @@ public CounselingResult startStt(File file, long userId) { .build(); sttMapper.insert(job); + String gcsUri = null; + try { - // 1. 오디오 파일 유효성 검사 및 읽기 - byte[] data = Files.readAllBytes(file.toPath()); - if (data.length == 0) throw new RuntimeException("파일이 비어있습니다."); + if (!file.exists() || file.length() == 0) { + throw new RuntimeException("오디오 파일이 존재하지 않거나 비어있습니다."); + } + + log.info("STT 시작 (Long Audio) - file: {}, size: {} bytes", + file.getAbsolutePath(), file.length()); + + // 1️⃣ GCS 업로드 + String objectName = "recordings/" + + userId + "/" + + job.getCounselingResultId() + ".wav"; + + gcsUri = gcpUploader.uploadWav( + objectName, + file.toPath() + ); - log.info("STT 시작 - 파일 크기: {} bytes", data.length); - ByteString audioBytes = ByteString.copyFrom(data); + log.info("GCS 업로드 완료: {}", gcsUri); + // 2️⃣ RecognitionAudio (URI 기반) RecognitionAudio audio = RecognitionAudio.newBuilder() - .setContent(audioBytes) + .setUri(gcsUri) .build(); - // 2. 설정 최적화 (가장 범용적인 설정) + // 3️⃣ Long Audio 최적화 설정 RecognitionConfig config = RecognitionConfig.newBuilder() - // 브라우저 녹음 파일(WebM/Wav) 헤더를 자동 감지하도록 설정 - .setEncoding(RecognitionConfig.AudioEncoding.ENCODING_UNSPECIFIED) .setLanguageCode("ko-KR") - .setSampleRateHertz(16000) // 특정 포맷이 아니면 생략하는 것이 안전 - .setAudioChannelCount(1) // 아고라 녹음은 보통 단일 채널 + .setEncoding(RecognitionConfig.AudioEncoding.ENCODING_UNSPECIFIED) +// .setSampleRateHertz(16000) // wav 실제 값과 반드시 일치 + .setAudioChannelCount(1) + .setEnableAutomaticPunctuation(true) + .setUseEnhanced(true) + .setModel("latest_long") .build(); - // 3. Google 인증 로드 + // 4️⃣ Google 인증 Resource resource = new DefaultResourceLoader().getResource(keyPath); try (InputStream is = resource.getInputStream()) { + GoogleCredentials credentials = GoogleCredentials.fromStream(is); SpeechSettings settings = SpeechSettings.newBuilder() - .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) + .setCredentialsProvider( + FixedCredentialsProvider.create(credentials)) .build(); try (SpeechClient speechClient = SpeechClient.create(settings)) { - log.info("Google STT 비동기 요청 전송 중..."); - // 4. 비동기 요청 실행 (긴 파일 대응) - OperationFuture responseFuture = + log.info("Google STT longRunningRecognize 요청 전송"); + + OperationFuture< + LongRunningRecognizeResponse, + LongRunningRecognizeMetadata + > future = speechClient.longRunningRecognizeAsync(config, audio); - // 5. 완료될 때까지 기다림 (여기서 블로킹되어야 로그가 남고 파일 삭제가 안전함) - LongRunningRecognizeResponse response = responseFuture.get(); + // ⏳ 긴 파일 대기 (최대 30분) + LongRunningRecognizeResponse response = + future.get(30, TimeUnit.MINUTES); - // 결과 추출 및 로그 String text = response.getResultsList().stream() .map(r -> r.getAlternatives(0).getTranscript()) .collect(Collectors.joining(" ")); - if (text.trim().isEmpty()) { - log.warn("STT 결과가 비어있습니다. 오디오 데이터 확인 필요."); + if (text.isBlank()) { + log.warn("STT 결과가 비어있음"); job.setStatus("FAIL"); job.setTexts("No speech detected."); } else { - log.info("STT 변환 완료: {}", text); + log.info("STT 완료 (length={} chars)", text.length()); job.setStatus("SUCCESS"); job.setTexts(text); } @@ -99,28 +124,34 @@ public CounselingResult startStt(File file, long userId) { } } catch (Exception e) { - log.error("STT 처리 중 치명적 오류: ", e); + log.error("STT 처리 중 오류 발생", e); job.setStatus("FAIL"); job.setTexts("Error: " + e.getMessage()); + } finally { - // 모든 작업이 끝난 후 파일 삭제 + // 5️⃣ 로컬 파일 삭제 if (file.exists()) { - boolean isDeleted = file.delete(); - log.info("임시 파일 삭제 여부: {}", isDeleted); + boolean deleted = file.delete(); + log.info("로컬 wav 파일 삭제: {}", deleted); } } - // 6. DB 업데이트 및 후속 작업 + // 6️⃣ DB 업데이트 sttMapper.updateResult(job); - // 성공 시에만 요약 서비스 호출 + // 7️⃣ 성공 시 요약 호출 if ("SUCCESS".equals(job.getStatus())) { - summaryService.createSummary(job.getCounselingResultId(),job.getUserId(),job.getTexts()); + summaryService.createSummary( + job.getCounselingResultId(), + job.getUserId(), + job.getTexts() + ); } return job; } + @Override public CounselingResult getStt(Long counselingResultId) { return sttMapper.findByCounselingId(counselingResultId); From 298003ca380c1b0160c519a3b9f1ac1c47e372d6 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Tue, 27 Jan 2026 23:06:49 +0900 Subject: [PATCH 02/25] =?UTF-8?q?fix:=20=EB=85=B9=EC=9D=8C=20=EB=B6=88?= =?UTF-8?q?=EA=B0=80=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B8=B4=20STT=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../call/service/RecordingServiceImpl.java | 18 ++++++++++++++++-- .../unity/domain/stt/service/SttService.java | 2 +- .../domain/stt/service/SttServiceImpl.java | 15 ++------------- .../summary/controller/SummaryController.java | 9 +++++++++ .../domain/summary/mapper/SummaryMapper.java | 2 +- .../domain/summary/service/SummaryService.java | 7 +++---- .../resources/mapper/summary/SummaryMapper.xml | 2 +- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java index dd97bed..4cc8af4 100644 --- a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java @@ -1,8 +1,10 @@ package com.ureca.unity.domain.call.service; import com.ureca.unity.domain.call.util.Converter; -import com.ureca.unity.domain.call.util.GcsUploader; +import com.ureca.unity.domain.stt.mapper.CounselingResultMapper; +import com.ureca.unity.domain.stt.model.CounselingResult; import com.ureca.unity.domain.stt.service.SttService; +import com.ureca.unity.domain.summary.mapper.SummaryMapper; import com.ureca.unity.global.exception.CustomException; import com.ureca.unity.global.exception.ErrorCode; import lombok.RequiredArgsConstructor; @@ -35,6 +37,8 @@ public class RecordingServiceImpl implements RecordingService { private final WebClient.Builder webClientBuilder; private final SttService sttService; + private final CounselingResultMapper sttMapper; + private final SummaryMapper summaryMapper; //@Value 주입이 완료된 후, 호출 시점에 WebClient 빌드 private WebClient getWebClient() { @@ -127,6 +131,16 @@ public String start(String resourceId, String channelName, String uid, String to public void stop(String resourceId, String sid, String channelName, String uid, String userId) { log.info("[Agora] Stop 요청 - sid: {}", sid); + Long longUserId=Long.parseLong(userId); + CounselingResult job = CounselingResult.builder() + .userId(longUserId) + .counselorId(1L) + .counselingType("CALL") + .status("LOADING") + .build(); + sttMapper.insert(job); + summaryMapper.insertSummary(job.getCounselingResultId(), longUserId); + Map body = Map.of( "cname", channelName, "uid", uid, @@ -153,7 +167,7 @@ public void stop(String resourceId, String sid, String channelName, String uid, if (wavFile != null && wavFile.exists()) { log.info("최종 WAV 생성 성공: {}", wavFile.getAbsolutePath()); - sttService.startStt(wavFile, Long.parseLong(userId)); + sttService.startStt(wavFile, longUserId, job); } } catch (Exception e) { log.error("비동기 변환 작업 중 오류: {}", e); diff --git a/src/main/java/com/ureca/unity/domain/stt/service/SttService.java b/src/main/java/com/ureca/unity/domain/stt/service/SttService.java index c820850..9c52418 100644 --- a/src/main/java/com/ureca/unity/domain/stt/service/SttService.java +++ b/src/main/java/com/ureca/unity/domain/stt/service/SttService.java @@ -6,7 +6,7 @@ public interface SttService { - CounselingResult startStt(File filePath, long userId); + CounselingResult startStt(File filePath, long userId, CounselingResult job); CounselingResult getStt(Long counselingId); } diff --git a/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java b/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java index 65f6a9a..f64731f 100644 --- a/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/stt/service/SttServiceImpl.java @@ -4,11 +4,10 @@ import com.google.api.gax.longrunning.OperationFuture; import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.speech.v1.*; -import com.google.protobuf.ByteString; -import com.ureca.unity.domain.call.util.GcsUploader; import com.ureca.unity.domain.stt.mapper.CounselingResultMapper; import com.ureca.unity.domain.stt.model.CounselingResult; import com.ureca.unity.domain.summary.service.SummaryService; +import com.ureca.unity.domain.call.util.GcsUploader; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -18,7 +17,6 @@ import java.io.File; import java.io.InputStream; -import java.nio.file.Files; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -35,16 +33,7 @@ public class SttServiceImpl implements SttService { private String keyPath; @Override - public CounselingResult startStt(File file, long userId) { - - CounselingResult job = CounselingResult.builder() - .userId(userId) - .counselorId(1L) - .counselingType("CALL") - .status("LOADING") - .build(); - sttMapper.insert(job); - + public CounselingResult startStt(File file, long userId, CounselingResult job) { String gcsUri = null; try { diff --git a/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java b/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java index 0e11d13..7b5e195 100644 --- a/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java +++ b/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java @@ -4,6 +4,7 @@ import com.ureca.unity.domain.summary.dto.response.SummaryListResponse; import com.ureca.unity.domain.summary.service.SummaryService; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -32,4 +33,12 @@ public List getBookmarkedSummaries(@RequestParam Long userI public SummaryDetailResponse getSummaryDetail(@PathVariable Long summaryId) { return summaryService.getSummaryDetail(summaryId); } + + @GetMapping("/{summaryId}/bookmark") + public ResponseEntity toggleBookmark( + @PathVariable Long summaryId + ){ + boolean done=summaryService.toggleBookmark(summaryId); + return ResponseEntity.ok(done); + } } diff --git a/src/main/java/com/ureca/unity/domain/summary/mapper/SummaryMapper.java b/src/main/java/com/ureca/unity/domain/summary/mapper/SummaryMapper.java index d86ba59..c274524 100644 --- a/src/main/java/com/ureca/unity/domain/summary/mapper/SummaryMapper.java +++ b/src/main/java/com/ureca/unity/domain/summary/mapper/SummaryMapper.java @@ -34,7 +34,7 @@ void updateStatus( Boolean findBookmarkStatus(@Param("summaryId") Long summaryId); - void updateBookmark( + int updateBookmark( @Param("summaryId") Long summaryId, @Param("isBookmarked") boolean isBookmarked ); diff --git a/src/main/java/com/ureca/unity/domain/summary/service/SummaryService.java b/src/main/java/com/ureca/unity/domain/summary/service/SummaryService.java index f88362a..eed8226 100644 --- a/src/main/java/com/ureca/unity/domain/summary/service/SummaryService.java +++ b/src/main/java/com/ureca/unity/domain/summary/service/SummaryService.java @@ -35,8 +35,6 @@ public void createSummary( throw new CustomException(ErrorCode.INVALID_INPUT_VALUE); } - summaryMapper.insertSummary(counselingResultId, userId); - Long summaryId = summaryMapper.findLatestSummaryId(userId, counselingResultId); try { @@ -163,13 +161,14 @@ public SummaryDetailResponse getSummaryDetail(Long summaryId) { } @Transactional - public void toggleBookmark(Long summaryId) { + public boolean toggleBookmark(Long summaryId) { Boolean isBookmarked = summaryMapper.findBookmarkStatus(summaryId); if (isBookmarked == null) { throw new IllegalArgumentException("summary not found"); } - summaryMapper.updateBookmark(summaryId, !isBookmarked); + int done=summaryMapper.updateBookmark(summaryId, !isBookmarked); + return done>0; } } diff --git a/src/main/resources/mapper/summary/SummaryMapper.xml b/src/main/resources/mapper/summary/SummaryMapper.xml index 5588552..5a317b8 100644 --- a/src/main/resources/mapper/summary/SummaryMapper.xml +++ b/src/main/resources/mapper/summary/SummaryMapper.xml @@ -6,7 +6,7 @@ - + INSERT INTO summary ( counseling_result_id, user_id, From af338424e2578ca53f54fb26a4a66dd491540046 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 09:59:01 +0900 Subject: [PATCH 03/25] =?UTF-8?q?fix:=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ureca/unity/domain/call/service/RecordingServiceImpl.java | 4 ++++ .../unity/domain/summary/controller/SummaryController.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java index 4cc8af4..11331ae 100644 --- a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java @@ -176,6 +176,10 @@ public void stop(String resourceId, String sid, String channelName, String uid, } catch (Exception e) { log.error("[Agora] Stop 실패: {}", e.getMessage()); + job.setStatus("FAIL"); + sttMapper.updateResult(job); + Long summaryId = summaryMapper.findLatestSummaryId(longUserId, job.getCounselingResultId()); + summaryMapper.updateStatus(summaryId, "FAIL"); throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR); } } diff --git a/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java b/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java index 7b5e195..810a61a 100644 --- a/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java +++ b/src/main/java/com/ureca/unity/domain/summary/controller/SummaryController.java @@ -34,7 +34,7 @@ public SummaryDetailResponse getSummaryDetail(@PathVariable Long summaryId) { return summaryService.getSummaryDetail(summaryId); } - @GetMapping("/{summaryId}/bookmark") + @PostMapping("/{summaryId}/bookmark") public ResponseEntity toggleBookmark( @PathVariable Long summaryId ){ From cdc36404628db1c917341936f6e93fd8ec1c8c06 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 12:39:02 +0900 Subject: [PATCH 04/25] =?UTF-8?q?feat:=20=EB=B0=B0=ED=8F=AC=20=EC=A4=80?= =?UTF-8?q?=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 10 ++++ build.gradle | 2 +- .../call/service/RecordingServiceImpl.java | 13 ++++- src/main/resources/application-test.yml | 47 ++++++++++++++++ src/main/resources/application.yml | 54 ++++++++++++++++++- .../ureca/unity/UnityApplicationTests.java | 4 ++ 6 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 Dockerfile create mode 100644 src/main/resources/application-test.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d5c7a69 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +# Dockerfile +FROM openjdk:17-alpine + +WORKDIR /app +COPY . /app + +RUN chmod +x ./mvnw +RUN ./mvnw clean package -DskipTests + +CMD ["java", "-jar", "unity-0.0.1-SNAPSHOT.jar"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2d15d17..bd1083f 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' - testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:4.0.1' + testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'io.jsonwebtoken:jjwt-api:0.13.0' diff --git a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java index 11331ae..559c3db 100644 --- a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java @@ -138,8 +138,14 @@ public void stop(String resourceId, String sid, String channelName, String uid, .counselingType("CALL") .status("LOADING") .build(); - sttMapper.insert(job); - summaryMapper.insertSummary(job.getCounselingResultId(), longUserId); + boolean jobPersisted=false; + try{ + sttMapper.insert(job); + summaryMapper.insertSummary(job.getCounselingResultId(), longUserId); + jobPersisted=true; + }catch (Exception e){ + log.error("결과 저장할 DB 연결 실패, 녹음 종료 진행.",e); + } Map body = Map.of( "cname", channelName, @@ -155,6 +161,9 @@ public void stop(String resourceId, String sid, String channelName, String uid, .bodyToMono(Void.class) .block(Duration.ofSeconds(10)); log.info("[Agora] Stop 성공"); + if (!jobPersisted) { + throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR); + } //s3의 파일->wav로 변경->stt CompletableFuture.runAsync(() -> { diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..b56c2b9 --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,47 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + driver-class-name: com + username: sa + password: + +oauth: + naver: + client-id: test + client-secret: test + redirect-uri: test + google: + client-id: test + client-secret: test + redirect-uri: test + kakao: + client-id: test + redirect-uri: test + admin-key: test + +aws: + s3: + bucket: test + access-key: test + secret-key: test + region: ap-northeast-2 + +google: + cloud: + credentials: + location: test + project-id: test + bucket-name: test + +gemini: + api-key: test + +agora: + appId: test + appCert: test + customerId: test + customerSecret: test + +security: + oauth-token: + secret: test diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1609991..6221331 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,6 +9,7 @@ spring: password: ${DB_PASSWORD} hikari: + pool-name: hikari-pool maximum-pool-size: 10 minimum-idle: 5 connection-timeout: 5000 @@ -22,7 +23,7 @@ mybatis: type-aliases-package: com.ureca.unity.domain server: - port: 8080 + port: ${PORT:8080} logging: level: @@ -44,6 +45,57 @@ cors: cookie: secure: ${COOKIE_SECURE:true} +oauth: + naver: + client-id: ${NAVER_CLIENT_ID} + client-secret: ${NAVER_CLIENT_SECRET} + token-uri: https://nid.naver.com/oauth2.0/token + user-info-uri: https://openapi.naver.com/v1/nid/me + redirect-uri: ${NAVER_REDIRECT_URI} + + google: + client-id: ${GOOGLE_CLIENT_ID} + client-secret: ${GOOGLE_CLIENT_SECRET} + token-uri: https://oauth2.googleapis.com/token + user-info-uri: https://www.googleapis.com/oauth2/v2/userinfo + redirect-uri: ${GOOGLE_REDIRECT_URI} + + kakao: + client-id: ${KAKAO_CLIENT_ID} + # client-secret: "" + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + redirect-uri: ${KAKAO_REDIRECT_URI} + admin-key: ${KAKAO_ADMIN_KEY} + +jwt: + issuer: unity + secret: "CHANGE_ME_TO_A_LONG_RANDOM_SECRET_>=_32bytes" + access-expiration-seconds: 3600 # 1시간 + refresh-expiration-seconds: 604800 # 7일 + +agora: + appId: ${AGORA_APP_ID} + appCert: ${AGORA_APP_CERT} + customerId: ${AGORA_CUSTOMER_ID} + customerSecret: ${AGORA_CUSTOMER_SECRET} + +aws: + s3: + bucket: ${S3_BUCKET} + access-key: ${S3_ACCESS_KEY} + secret-key: ${S3_SECRET_KEY} + region: ${S3_REGION} + +google: + cloud: + credentials: + location: ${GOOGLE_CLOUD_LOCATION} + project-id: ${GOOGLE_CLOUD_PROJECT_ID} + bucket-name: ${GOOGLE_CLOUD_BUCKET_NAME} + +gemini: + api-key: ${GEMINI_API_KEY} security: oauth-token: diff --git a/src/test/java/com/ureca/unity/UnityApplicationTests.java b/src/test/java/com/ureca/unity/UnityApplicationTests.java index 2f891c8..9740db3 100644 --- a/src/test/java/com/ureca/unity/UnityApplicationTests.java +++ b/src/test/java/com/ureca/unity/UnityApplicationTests.java @@ -1,9 +1,13 @@ package com.ureca.unity; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; @SpringBootTest +@ActiveProfiles("test") +@Disabled class UnityApplicationTests { @Test From 719caf2d13f86bec1b99da6df922503940b6ed3d Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 13:16:54 +0900 Subject: [PATCH 05/25] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 24 +++++++--- build.gradle | 3 -- .../call/service/RecordingServiceImpl.java | 10 ++-- src/main/resources/application-test.yml | 47 ------------------- src/main/resources/application.yml | 2 +- .../ureca/unity/UnityApplicationTests.java | 17 ------- 6 files changed, 25 insertions(+), 78 deletions(-) delete mode 100644 src/main/resources/application-test.yml delete mode 100644 src/test/java/com/ureca/unity/UnityApplicationTests.java diff --git a/Dockerfile b/Dockerfile index d5c7a69..b10c26e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,22 @@ -# Dockerfile -FROM openjdk:17-alpine +# 1️⃣ Build stage +FROM gradle:8.4-jdk17 AS builder +WORKDIR /app + +# 캐시 최적화 +COPY gradle gradle +COPY build.gradle settings.gradle ./ +COPY gradlew ./ +RUN chmod +x gradlew +RUN ./gradlew dependencies + +# 소스 복사 & 빌드 +COPY src src +RUN ./gradlew clean bootJar -x test +# 2️⃣ Runtime stage +FROM eclipse-temurin:17-jre WORKDIR /app -COPY . /app -RUN chmod +x ./mvnw -RUN ./mvnw clean package -DskipTests +COPY --from=builder /app/build/libs/*.jar app.jar -CMD ["java", "-jar", "unity-0.0.1-SNAPSHOT.jar"] \ No newline at end of file +CMD ["java", "-jar", "app.jar"] diff --git a/build.gradle b/build.gradle index bd1083f..60e3d62 100644 --- a/build.gradle +++ b/build.gradle @@ -37,9 +37,6 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' - testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - implementation 'io.jsonwebtoken:jjwt-api:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0' diff --git a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java index 559c3db..fa2cdc0 100644 --- a/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java +++ b/src/main/java/com/ureca/unity/domain/call/service/RecordingServiceImpl.java @@ -185,10 +185,12 @@ public void stop(String resourceId, String sid, String channelName, String uid, } catch (Exception e) { log.error("[Agora] Stop 실패: {}", e.getMessage()); - job.setStatus("FAIL"); - sttMapper.updateResult(job); - Long summaryId = summaryMapper.findLatestSummaryId(longUserId, job.getCounselingResultId()); - summaryMapper.updateStatus(summaryId, "FAIL"); + if(jobPersisted){ + job.setStatus("FAIL"); + sttMapper.updateResult(job); + Long summaryId = summaryMapper.findLatestSummaryId(longUserId, job.getCounselingResultId()); + if(summaryId!=null)summaryMapper.updateStatus(summaryId, "FAIL"); + } throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR); } } diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml deleted file mode 100644 index b56c2b9..0000000 --- a/src/main/resources/application-test.yml +++ /dev/null @@ -1,47 +0,0 @@ -spring: - datasource: - url: jdbc:h2:mem:testdb - driver-class-name: com - username: sa - password: - -oauth: - naver: - client-id: test - client-secret: test - redirect-uri: test - google: - client-id: test - client-secret: test - redirect-uri: test - kakao: - client-id: test - redirect-uri: test - admin-key: test - -aws: - s3: - bucket: test - access-key: test - secret-key: test - region: ap-northeast-2 - -google: - cloud: - credentials: - location: test - project-id: test - bucket-name: test - -gemini: - api-key: test - -agora: - appId: test - appCert: test - customerId: test - customerSecret: test - -security: - oauth-token: - secret: test diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6221331..a229daf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -70,7 +70,7 @@ oauth: jwt: issuer: unity - secret: "CHANGE_ME_TO_A_LONG_RANDOM_SECRET_>=_32bytes" + secret: ${JWT_SECRET} access-expiration-seconds: 3600 # 1시간 refresh-expiration-seconds: 604800 # 7일 diff --git a/src/test/java/com/ureca/unity/UnityApplicationTests.java b/src/test/java/com/ureca/unity/UnityApplicationTests.java deleted file mode 100644 index 9740db3..0000000 --- a/src/test/java/com/ureca/unity/UnityApplicationTests.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ureca.unity; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; - -@SpringBootTest -@ActiveProfiles("test") -@Disabled -class UnityApplicationTests { - - @Test - void contextLoads() { - } - -} From 953949aa30c31ae15d60db625230abc664e70fe1 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 14:00:34 +0900 Subject: [PATCH 06/25] =?UTF-8?q?fix:=20mainClass=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 60e3d62..539e2f4 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,10 @@ group = 'com.ureca' version = '0.0.1-SNAPSHOT' description = 'unity' +bootJar { + mainClass = 'com.ureca.unity.UnityApplication' +} + java { toolchain { languageVersion = JavaLanguageVersion.of(17) From 4389db6d339bc98c79ee42b60c066e22fa7061fe Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 14:21:43 +0900 Subject: [PATCH 07/25] =?UTF-8?q?fix:=20=EB=B0=B0=ED=8F=AC=20jar=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- build.gradle | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b10c26e..065f490 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,4 +19,4 @@ WORKDIR /app COPY --from=builder /app/build/libs/*.jar app.jar -CMD ["java", "-jar", "app.jar"] +CMD ["java", "-jar", "build/libs/app.jar"] diff --git a/build.gradle b/build.gradle index 539e2f4..2e2d600 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ version = '0.0.1-SNAPSHOT' description = 'unity' bootJar { + archiveFileName="app.jar" mainClass = 'com.ureca.unity.UnityApplication' } From ce98dd0598bc566962d6f84e1f04131e113b3ba7 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 14:35:28 +0900 Subject: [PATCH 08/25] =?UTF-8?q?fix:=20jar=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 065f490..b10c26e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,4 +19,4 @@ WORKDIR /app COPY --from=builder /app/build/libs/*.jar app.jar -CMD ["java", "-jar", "build/libs/app.jar"] +CMD ["java", "-jar", "app.jar"] From 88bb24fceda250c40f5ef452a32625ce98101f32 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 14:47:29 +0900 Subject: [PATCH 09/25] =?UTF-8?q?fix:=20jar=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=9E=AC=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b10c26e..942559f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,6 @@ RUN ./gradlew clean bootJar -x test FROM eclipse-temurin:17-jre WORKDIR /app -COPY --from=builder /app/build/libs/*.jar app.jar +COPY --from=builder /app/build/libs/*-boot.jar app.jar CMD ["java", "-jar", "app.jar"] From 7415665161a5312d5e7ed76025b8f4d55553c741 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 15:01:55 +0900 Subject: [PATCH 10/25] =?UTF-8?q?fix:=20Docker=20file=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index 942559f..7a67eef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,9 @@ -# 1️⃣ Build stage -FROM gradle:8.4-jdk17 AS builder +FROM openjdk:17-jdk-slim as build WORKDIR /app +COPY . . +RUN ./gradlew clean build -x test -# 캐시 최적화 -COPY gradle gradle -COPY build.gradle settings.gradle ./ -COPY gradlew ./ -RUN chmod +x gradlew -RUN ./gradlew dependencies - -# 소스 복사 & 빌드 -COPY src src -RUN ./gradlew clean bootJar -x test - -# 2️⃣ Runtime stage -FROM eclipse-temurin:17-jre +FROM openjdk:17-jdk-slim WORKDIR /app - -COPY --from=builder /app/build/libs/*-boot.jar app.jar - -CMD ["java", "-jar", "app.jar"] +COPY --from=build /app/build/libs/*.jar app.jar +ENTRYPOINT ["java","-jar","app.jar"] \ No newline at end of file From 7ef8d3a012a978f11951ee9650d223b1dcf997dc Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 15:07:56 +0900 Subject: [PATCH 11/25] =?UTF-8?q?Revert=20"fix:=20Docker=20file=20?= =?UTF-8?q?=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7415665161a5312d5e7ed76025b8f4d55553c741. --- Dockerfile | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7a67eef..942559f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,22 @@ -FROM openjdk:17-jdk-slim as build +# 1️⃣ Build stage +FROM gradle:8.4-jdk17 AS builder WORKDIR /app -COPY . . -RUN ./gradlew clean build -x test -FROM openjdk:17-jdk-slim +# 캐시 최적화 +COPY gradle gradle +COPY build.gradle settings.gradle ./ +COPY gradlew ./ +RUN chmod +x gradlew +RUN ./gradlew dependencies + +# 소스 복사 & 빌드 +COPY src src +RUN ./gradlew clean bootJar -x test + +# 2️⃣ Runtime stage +FROM eclipse-temurin:17-jre WORKDIR /app -COPY --from=build /app/build/libs/*.jar app.jar -ENTRYPOINT ["java","-jar","app.jar"] \ No newline at end of file + +COPY --from=builder /app/build/libs/*-boot.jar app.jar + +CMD ["java", "-jar", "app.jar"] From 95d2de0df87dc9071922e832f51e8ef67462209f Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 15:12:58 +0900 Subject: [PATCH 12/25] =?UTF-8?q?fix:=20=EB=8F=84=EC=BB=A4=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=88=98=EC=A0=95...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 942559f..3f4d9c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,22 @@ -# 1️⃣ Build stage FROM gradle:8.4-jdk17 AS builder WORKDIR /app -# 캐시 최적화 +# 1. Gradle 캐시 최적화 COPY gradle gradle COPY build.gradle settings.gradle ./ COPY gradlew ./ RUN chmod +x gradlew RUN ./gradlew dependencies -# 소스 복사 & 빌드 +# 2. 소스 코드 복사 & 빌드 COPY src src RUN ./gradlew clean bootJar -x test -# 2️⃣ Runtime stage FROM eclipse-temurin:17-jre WORKDIR /app +# bootJar만 app.jar로 복사 COPY --from=builder /app/build/libs/*-boot.jar app.jar +# Spring Boot 실행 CMD ["java", "-jar", "app.jar"] From f05868907e4f28e46158d8d581a8fa20c11e0156 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 16:55:32 +0900 Subject: [PATCH 13/25] =?UTF-8?q?fix:=20dockerfile=20=EC=A0=9C=EB=B0=9C=20?= =?UTF-8?q?=EB=A7=88=EC=A7=80=EB=A7=89=20=EC=88=98=EC=A0=95=EC=9D=B4?= =?UTF-8?q?=EA=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 26 ++++++-------------------- build.gradle | 1 - 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3f4d9c2..4c2c41c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,8 @@ -FROM gradle:8.4-jdk17 AS builder +FROM gradle:jdk17-jammy AS build +COPY --chown=gradle:gradle . /app WORKDIR /app +RUN gradle build --no-daemon -# 1. Gradle 캐시 최적화 -COPY gradle gradle -COPY build.gradle settings.gradle ./ -COPY gradlew ./ -RUN chmod +x gradlew -RUN ./gradlew dependencies - -# 2. 소스 코드 복사 & 빌드 -COPY src src -RUN ./gradlew clean bootJar -x test - -FROM eclipse-temurin:17-jre -WORKDIR /app - -# bootJar만 app.jar로 복사 -COPY --from=builder /app/build/libs/*-boot.jar app.jar - -# Spring Boot 실행 -CMD ["java", "-jar", "app.jar"] +FROM eclipse-temurin:17-jdk-jammy +COPY --from=build /app/build/libs/*-0.0.1-SNAPSHOT.jar app.jar +ENTRYPOINT ["java", "-jar", "/app.jar"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2e2d600..539e2f4 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,6 @@ version = '0.0.1-SNAPSHOT' description = 'unity' bootJar { - archiveFileName="app.jar" mainClass = 'com.ureca.unity.UnityApplication' } From 6182572d591b8f086df0a7743f7632f629be1699 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 17:00:34 +0900 Subject: [PATCH 14/25] =?UTF-8?q?fix:=20=EC=A7=84=EC=A7=9C=20=EC=B0=90?= =?UTF-8?q?=EB=A7=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4c2c41c..9b4fd9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM gradle:jdk17-jammy AS build COPY --chown=gradle:gradle . /app WORKDIR /app -RUN gradle build --no-daemon +RUN ./gradlew build --no-daemon FROM eclipse-temurin:17-jdk-jammy COPY --from=build /app/build/libs/*-0.0.1-SNAPSHOT.jar app.jar From 1ec5008a8a154c57ad11228af2bb8700cabbf41b Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 17:09:08 +0900 Subject: [PATCH 15/25] =?UTF-8?q?fix:=20gradlew=20=EC=8B=A4=ED=96=89?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EB=B6=80=EC=97=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 9b4fd9d..e6fbc18 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM gradle:jdk17-jammy AS build COPY --chown=gradle:gradle . /app WORKDIR /app + +RUN chmod +x gradlew RUN ./gradlew build --no-daemon FROM eclipse-temurin:17-jdk-jammy From f4e305e27b572b4ab42420f1398fd634e492b898 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 17:36:24 +0900 Subject: [PATCH 16/25] =?UTF-8?q?fix:=20render=EB=A5=BC=20google=20sql?= =?UTF-8?q?=EC=97=90=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e6fbc18..d6cf34e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,7 @@ RUN ./gradlew build --no-daemon FROM eclipse-temurin:17-jdk-jammy COPY --from=build /app/build/libs/*-0.0.1-SNAPSHOT.jar app.jar -ENTRYPOINT ["java", "-jar", "/app.jar"] \ No newline at end of file +# 컨테이너 시작 시 Cloud SQL Proxy와 Spring Boot 앱 동시 실행 +ENTRYPOINT ["/bin/sh", "-c", "\ + /cloud_sql_proxy -dir=/cloudsql -credential_file=/secrets/service-account.json & \ + java -Dspring.datasource.url=jdbc:mysql://127.0.0.1:3306/ureca_compre_project -Dspring.datasource.username=$DB_USERNAME -Dspring.datasource.password=$DB_PASSWORD -jar /app.jar"] \ No newline at end of file From 449b2d993854f509e7e4295c5fea1453699616ec Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 18:41:46 +0900 Subject: [PATCH 17/25] =?UTF-8?q?fix:=20render=EB=A5=BC=20google=20sql?= =?UTF-8?q?=EC=97=90=20=EC=97=B0=EA=B2=B02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index d6cf34e..b9ed60d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,15 @@ FROM gradle:jdk17-jammy AS build COPY --chown=gradle:gradle . /app WORKDIR /app - RUN chmod +x gradlew RUN ./gradlew build --no-daemon FROM eclipse-temurin:17-jdk-jammy +WORKDIR /app +RUN wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy \ + && chmod +x cloud_sql_proxy + COPY --from=build /app/build/libs/*-0.0.1-SNAPSHOT.jar app.jar -# 컨테이너 시작 시 Cloud SQL Proxy와 Spring Boot 앱 동시 실행 -ENTRYPOINT ["/bin/sh", "-c", "\ - /cloud_sql_proxy -dir=/cloudsql -credential_file=/secrets/service-account.json & \ - java -Dspring.datasource.url=jdbc:mysql://127.0.0.1:3306/ureca_compre_project -Dspring.datasource.username=$DB_USERNAME -Dspring.datasource.password=$DB_PASSWORD -jar /app.jar"] \ No newline at end of file +COPY ./render-access.json /secrets/render-access.json +RUN chmod 400 /secrets/render-access.json +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy -instances=folkloric-clock-391008:asia-northeast3:ureca-3-unity=tcp:3306 --credentials-file=/secrets/render-access.json & java -jar app.jar & wait"] \ No newline at end of file From 02e4ac73cfa5543ca4ca9bc2aab050cb0904411f Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 19:28:06 +0900 Subject: [PATCH 18/25] =?UTF-8?q?fix:=20render=EB=A5=BC=20google=20sql?= =?UTF-8?q?=EC=97=90=20=EC=97=B0=EA=B2=B03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index b9ed60d..f2c4b10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,14 +2,20 @@ FROM gradle:jdk17-jammy AS build COPY --chown=gradle:gradle . /app WORKDIR /app RUN chmod +x gradlew -RUN ./gradlew build --no-daemon +RUN ./gradlew build --no-daemon -x test # 테스트 제외로 빌드 속도 향상 + +# ... (빌드 단계 생략: gradle:jdk17-jammy AS build 등 기존 코드 유지) FROM eclipse-temurin:17-jdk-jammy WORKDIR /app -RUN wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy \ - && chmod +x cloud_sql_proxy -COPY --from=build /app/build/libs/*-0.0.1-SNAPSHOT.jar app.jar +# Cloud SQL Auth Proxy 설치 및 권한 설정 +RUN apt-get update && apt-get install -y wget && \ + wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && \ + chmod +x cloud_sql_proxy + +COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy -instances=folkloric-clock-391008:asia-northeast3:ureca-3-unity=tcp:3306 --credentials-file=/secrets/render-access.json & java -jar app.jar & wait"] \ No newline at end of file + +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy -instances=folkloric-clock-391008:asia-northeast3:ureca-3-unity=tcp:0.0.0.0:3306 -credential_file=/secrets/render-access.json & sleep 5; java -jar app.jar"] \ No newline at end of file From eba588e429005d758019803910bf73c7a4c61de8 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 19:42:38 +0900 Subject: [PATCH 19/25] =?UTF-8?q?fix:=20render=EB=A5=BC=20google=20sql?= =?UTF-8?q?=EC=97=90=20=EC=97=B0=EA=B2=B04?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index f2c4b10..ce0c514 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,12 +10,11 @@ FROM eclipse-temurin:17-jdk-jammy WORKDIR /app # Cloud SQL Auth Proxy 설치 및 권한 설정 -RUN apt-get update && apt-get install -y wget && \ - wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && \ +RUN wget https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.8.1/cloud-sql-proxy.linux.amd64 -O cloud_sql_proxy && \ chmod +x cloud_sql_proxy COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy -instances=folkloric-clock-391008:asia-northeast3:ureca-3-unity=tcp:0.0.0.0:3306 -credential_file=/secrets/render-access.json & sleep 5; java -jar app.jar"] \ No newline at end of file +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 0.0.0.0 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file From b6581e2bd071d52bd699b48e7d36a47dd5f1e767 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 20:10:37 +0900 Subject: [PATCH 20/25] =?UTF-8?q?fix:=20address=20=EC=A2=81=ED=9E=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ce0c514..6ba4570 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 0.0.0.0 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file From 836bc3efca954ae2d46de09c7d882e36b93ae372 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 20:32:26 +0900 Subject: [PATCH 21/25] =?UTF-8?q?fix:=20proxy=EA=B0=80=20=EC=9E=90?= =?UTF-8?q?=EB=A6=AC=EC=9E=A1=EC=9D=84=20=EC=8B=9C=EA=B0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6ba4570..1daac5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 15; java -jar app.jar"] \ No newline at end of file From 6c2020158161870effc4c15e7b7b04c0b0fa5b19 Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 20:53:14 +0900 Subject: [PATCH 22/25] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B9=85=20=EB=A0=88?= =?UTF-8?q?=EB=B2=A8=20=EB=86=92=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- src/main/resources/application.yml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1daac5e..6ba4570 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 15; java -jar app.jar"] \ No newline at end of file +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a229daf..8db5bed 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -28,8 +28,10 @@ server: logging: level: root: info - com.ureca.unity: debug - com.zaxxer.hikari.pool: info + com: + zaxxer: + hikari: DEBUG + org.springframework.jdbc: DEBUG springdoc: swagger-ui: From 32cbcc0694fd3bd7653867fbb81b81c8b8751f0d Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 21:10:25 +0900 Subject: [PATCH 23/25] =?UTF-8?q?fix:=20render=EB=A5=BC=20google=20sql?= =?UTF-8?q?=EC=97=90=20=EC=97=B0=EA=B2=B05?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- src/main/resources/application.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6ba4570..ddf5c00 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json RUN chmod 400 /secrets/render-access.json -ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 5; java -jar app.jar"] \ No newline at end of file +ENTRYPOINT ["sh", "-c", "./cloud_sql_proxy --address 127.0.0.1 --port 3306 --credentials-file /secrets/render-access.json folkloric-clock-391008:asia-northeast3:ureca-3-unity & sleep 30; java -jar app.jar"] \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8db5bed..8057f70 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -14,8 +14,8 @@ spring: minimum-idle: 5 connection-timeout: 5000 connection-init-sql: SELECT 1 - idle-timeout: 600000 - max-lifetime: 1800000 + idle-timeout: 300000 + max-lifetime: 600000 auto-commit: true mybatis: From b8b8893269206ff7da617c2a18755d4e88421ade Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 21:55:57 +0900 Subject: [PATCH 24/25] =?UTF-8?q?fix:=20=EC=8B=9C=EA=B0=84=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=20=EB=8A=98=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8057f70..a229daf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -14,8 +14,8 @@ spring: minimum-idle: 5 connection-timeout: 5000 connection-init-sql: SELECT 1 - idle-timeout: 300000 - max-lifetime: 600000 + idle-timeout: 600000 + max-lifetime: 1800000 auto-commit: true mybatis: @@ -28,10 +28,8 @@ server: logging: level: root: info - com: - zaxxer: - hikari: DEBUG - org.springframework.jdbc: DEBUG + com.ureca.unity: debug + com.zaxxer.hikari.pool: info springdoc: swagger-ui: From 31ad6005a8b0ac3708bc1b123021fc7b5c68b90a Mon Sep 17 00:00:00 2001 From: 40food <40food@naver.com> Date: Wed, 28 Jan 2026 22:05:44 +0900 Subject: [PATCH 25/25] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ddf5c00..c6396a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,8 +10,10 @@ FROM eclipse-temurin:17-jdk-jammy WORKDIR /app # Cloud SQL Auth Proxy 설치 및 권한 설정 -RUN wget https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.8.1/cloud-sql-proxy.linux.amd64 -O cloud_sql_proxy && \ - chmod +x cloud_sql_proxy +ARG CLOUD_SQL_PROXY_SHA256="8c6d76380f4b7005473eb2e13991d6239f90da021cf58d91d062739479e577cf" +RUN wget -q https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.8.1/cloud-sql-proxy.linux.amd64 -O /usr/local/bin/cloud_sql_proxy && \ + echo "${CLOUD_SQL_PROXY_SHA256} /usr/local/bin/cloud_sql_proxy" | sha256sum -c - && \ + chmod +x /usr/local/bin/cloud_sql_proxy COPY --from=build /app/build/libs/*.jar app.jar COPY ./render-access.json /secrets/render-access.json