Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BSVR-249] 환경변수 관리를 위한 AWS Secret Manger 도입 #178

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a26ce78
build: 중복된 KAKAO_CLIENT_ID 시크릿 변수 통일
pminsung12 Aug 28, 2024
2e7fe9d
build: secret manager 세팅을 위한 aws cloud 의존성 추가 및 spring boot 버전 업
pminsung12 Aug 28, 2024
c533a98
build: secret manager 세팅을 위한 aws cloud 의존성 추가 및 spring boot 버전 업
pminsung12 Aug 28, 2024
2d32678
build: secret manager 세팅을 위한 bootstrap.yml 생성
pminsung12 Aug 28, 2024
ea3a2e8
build: application-aws에 secret manager 적용
pminsung12 Aug 28, 2024
e14dfa0
build: application-datasource에 secret manager 적용
pminsung12 Aug 28, 2024
82ac818
build: application-jpa에서 datasource부분 분리
pminsung12 Aug 28, 2024
f0f28dd
build: application-jwt secret manager로 환경변수 주입
pminsung12 Aug 28, 2024
f06730a
build: application-monitoring.yml secret manager로 환경변수 주입
pminsung12 Aug 28, 2024
10161ec
build: application-oauth.yml secret manager로 환경변수 주입
pminsung12 Aug 28, 2024
f7b0aa1
build: application-sentry.yml secret manager로 환경변수 주입
pminsung12 Aug 28, 2024
3b4f847
build: gitignore 업데이트
pminsung12 Aug 28, 2024
0c729df
build: github action 스크립트에서 불필요한 환경변수 부분 제거
pminsung12 Aug 28, 2024
60e4ebc
feat: AwsSecretsManagerConfig.java 구현
pminsung12 Aug 28, 2024
ff5a43a
chore: application-aws-credentials.yml gitignore에 추가
pminsung12 Aug 28, 2024
e53a56e
build: 시크릿 매니저 config 테스트
pminsung12 Aug 28, 2024
1ec671f
feat: 시크릿 매니저 config 로깅 추가
pminsung12 Aug 28, 2024
aef637f
feat: secret manager java sdk 사용 실패
pminsung12 Aug 29, 2024
371eeab
build: actions에 aws cli 설정 추가
pminsung12 Aug 29, 2024
6a1b158
build: actions에 aws secret manager 접근 부분 삭제
pminsung12 Aug 29, 2024
b19eef8
bug: AwsSecretsManagerConfig 주석처리
pminsung12 Aug 29, 2024
7e89b8e
Merge branch 'main' into feat/BSVR-249
pminsung12 Aug 29, 2024
b23f874
feat: AwsSecretsManagerConfig.java 구현
pminsung12 Sep 3, 2024
a270d94
feat: aws credentials 경로 수정
pminsung12 Sep 3, 2024
e6a6150
feat: application.yaml에 secret manager 설정 추가
pminsung12 Sep 3, 2024
43e8058
feat: redis config에 secret manager 적용
pminsung12 Sep 3, 2024
df0d904
chore: aborting merge
pminsung12 Sep 3, 2024
6d8ea55
feat: - 형태로 저장된 변수들 camelCase로 변환해 등록하는 메서드 추가
pminsung12 Sep 3, 2024
4c85033
feat: object storage properties에 redis 적용
pminsung12 Sep 3, 2024
92d83b9
feat: object storage properties에 redis 적용
pminsung12 Sep 3, 2024
f45ba24
feat: oauth properties에 redis 적용
pminsung12 Sep 3, 2024
35d2de8
feat: jwt properties에 secret manager 적용
pminsung12 Sep 3, 2024
c6d803c
fix: JwtTokenUtil 오류 수정
pminsung12 Sep 3, 2024
4aefb7e
refactor: loki.url로 환경변수 네이밍 변경
pminsung12 Sep 3, 2024
572436c
refactor: 더이상 사용하지 않을 yml 파일 삭제
pminsung12 Sep 5, 2024
dee170f
refactor: profile 업데이트
pminsung12 Sep 5, 2024
d7c7389
refactor: jpa, sentry, test yml 업데이트
pminsung12 Sep 5, 2024
3fa7a9a
fix: AwsSecretsManagerConfig.java와 properties간의 의존관계 설정
pminsung12 Sep 5, 2024
2f6c29c
fix: ReviewLikeServiceTest MockBean 추가
pminsung12 Sep 5, 2024
0bf9742
build: action 스크립트에 credentials 환경변수 설정 추가
pminsung12 Sep 5, 2024
fd979f4
bug: jar 파일에서 binary 파일 가지고 오지 못하는 버그 픽스
pminsung12 Sep 5, 2024
5b26d90
Merge branch 'main' into feat/BSVR-249
pminsung12 Sep 5, 2024
777c246
fix: JwtTokenUtil 오류 수정
pminsung12 Sep 5, 2024
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
37 changes: 9 additions & 28 deletions .github/workflows/dev-build-and-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ jobs:
java-version: "17"
distribution: "corretto"

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_KEY }}
aws-region: ap-northeast-2

- name: Cache Gradle
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -111,36 +118,10 @@ jobs:
-p 9292:9292 \
-p 3100:3100 \
-e SPRING_PROFILES_ACTIVE=dev \
-e SPRING_SERVLET_MULTIPART_MAX-FILE-SIZE=30MB \
-e SPRING_SERVLET_MULTIPART_MAX-REQUEST-SIZE=30MB \
-e AWS_REDIS_HOST=${{ secrets.DEV_REDIS_HOST }} \
-e AWS_REDIS_PORT=${{ secrets.DEV_REDIS_PORT }} \
-e SPRING_DATASOURCE_URL=${{ secrets.DEV_DB_URL }} \
-e SPRING_DATASOURCE_USERNAME=${{ secrets.DEV_DB_USERNAME }} \
-e SPRING_DATASOURCE_PASSWORD=${{ secrets.DEV_DB_PASSWORD }} \
-e SPRING_JWT_SECRET=${{ secrets.JWT_SECRET }} \
-e OAUTH_CLIENTID=${{ secrets.KAKAO_CLIENT_ID }} \
-e OAUTH_KAUTHTOKENURLHOST=${{ secrets.KAUTH_TOKEN_URL_HOST }} \
-e OAUTH_KAUTHUSERURLHOST=${{ secrets.KAUTH_USER_URL_HOST }} \
-e OAUTH_KAKAOCLIENTID=${{ secrets.OAUTH_KAKAOCLIENTID }} \
-e OAUTH_KAKAOAUTHTOKENURLHOST=${{ secrets.KAKAOAUTHTOKENURLHOST }} \
-e OAUTH_KAKAOAUTHUSERURLHOST=${{ secrets.KAKAOAUTHUSERURLHOST }} \
-e OAUTH_KAKAOREDIRECTURL=${{ secrets.KAKAOREDIRECTURL }} \
-e OAUTH_GOOGLECLIENTID=${{ secrets.GOOGLECLIENTID }} \
-e OAUTH_GOOGLECLIENTSECRET=${{ secrets.GOOGLECLIENTSECRET }} \
-e OAUTH_GOOGLEREDIRECTURL=${{ secrets.GOOGLEREDIRECTURL }} \
-e OAUTH_GOOGLEAUTHTOKENURLHOST=${{ secrets.GOOGLEAUTHTOKENURLHOST }} \
-e OAUTH_GOOGLEUSERURLHOST=${{ secrets.GOOGLEUSERURLHOST }} \
-e SPRING_JPA_HIBERNATE_DDL_AUTO=validate \
-e AWS_S3_ACCESS_KEY=${{ secrets.AWS_S3_ACCESS_KEY }} \
-e AWS_S3_SECRET_KEY=${{ secrets.AWS_S3_SECRET_KEY }} \
-e AWS_S3_BUCKET_NAME=${{ secrets.DEV_AWS_S3_BUCKET_NAME }} \
-e AWS_S3_BASICPROFILEIMAGEURL=${{ secrets.BASICPROFILEIMAGEURL }} \
-e SPRING_CREDENTIALS_ACCESS_KEY=${{secrets.AWS_S3_ACCESS_KEY}} \
-e SPRING_CREDENTIALS_SECRET_KEY=${{secrets.AWS_S3_SECRET_KEY}} \
-e TZ=Asia/Seoul \
-e SENTRY_DSN=${{ secrets.SENTRY_DSN }} \
-e SENTRY_ENABLE_TRACING=true \
-e SENTRY_ENVIRONMENT=prod \
-e LOKI_URL=${{ secrets.LOKI_SERVER_URL }} \
${{ secrets.DOCKERHUB_USERNAME }}/spot-server:dev-${{ github.sha }}
docker system prune -af

Expand Down
30 changes: 2 additions & 28 deletions .github/workflows/manual-prod-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,9 @@ jobs:
-p 9292:9292 \
-p 3100:3100 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_SERVLET_MULTIPART_MAX-FILE-SIZE=30MB \
-e SPRING_SERVLET_MULTIPART_MAX-REQUEST-SIZE=30MB \
-e AWS_REDIS_HOST=${{ secrets.PROD_REDIS_HOST }} \
-e AWS_REDIS_PORT=${{ secrets.PROD_REDIS_PORT }} \
-e SPRING_DATASOURCE_URL=${{ secrets.PROD_DB_URL }} \
-e SPRING_DATASOURCE_USERNAME=${{ secrets.PROD_DB_USERNAME }} \
-e SPRING_DATASOURCE_PASSWORD=${{ secrets.PROD_DB_PASSWORD }} \
-e SPRING_JWT_SECRET=${{ secrets.JWT_SECRET }} \
-e KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }} \
-e OAUTH_KAUTHTOKENURLHOST=${{ secrets.KAUTH_TOKEN_URL_HOST }} \
-e OAUTH_KAUTHUSERURLHOST=${{ secrets.KAUTH_USER_URL_HOST }} \
-e OAUTH_KAKAOCLIENTID=${{ secrets.OAUTH_KAKAOCLIENTID }} \
-e OAUTH_KAKAOAUTHTOKENURLHOST=${{ secrets.KAKAOAUTHTOKENURLHOST }} \
-e OAUTH_KAKAOAUTHUSERURLHOST=${{ secrets.KAKAOAUTHUSERURLHOST }} \
-e OAUTH_KAKAOREDIRECTURL=${{ secrets.KAKAOREDIRECTURL }} \
-e OAUTH_GOOGLECLIENTID=${{ secrets.GOOGLECLIENTID }} \
-e OAUTH_GOOGLECLIENTSECRET=${{ secrets.GOOGLECLIENTSECRET }} \
-e OAUTH_GOOGLEREDIRECTURL=${{ secrets.GOOGLEREDIRECTURL }} \
-e OAUTH_GOOGLEAUTHTOKENURLHOST=${{ secrets.GOOGLEAUTHTOKENURLHOST }} \
-e OAUTH_GOOGLEUSERURLHOST=${{ secrets.GOOGLEUSERURLHOST }} \
-e SPRING_JPA_HIBERNATE_DDL_AUTO=validate \
-e AWS_S3_ACCESS_KEY=${{ secrets.AWS_S3_ACCESS_KEY }} \
-e AWS_S3_SECRET_KEY=${{ secrets.AWS_S3_SECRET_KEY }} \
-e AWS_S3_BUCKET_NAME=${{ secrets.PROD_AWS_S3_BUCKET_NAME }} \
-e AWS_S3_BASICPROFILEIMAGEURL=${{ secrets.BASICPROFILEIMAGEURL }} \
-e SPRING_CREDENTIALS_ACCESS_KEY=${{secrets.AWS_S3_ACCESS_KEY}} \
-e SPRING_CREDENTIALS_SECRET_KEY=${{secrets.AWS_S3_SECRET_KEY}} \
-e TZ=Asia/Seoul \
-e SENTRY_DSN=${{ secrets.SENTRY_DSN }} \
-e SENTRY_ENABLE_TRACING=true \
-e SENTRY_ENVIRONMENT=prod \
-e LOKI_URL=${{ secrets.LOKI_SERVER_URL }} \
${{ secrets.DOCKERHUB_USERNAME }}/spot-server:prod-${{ github.event.inputs.tag }}
docker system prune -af
10 changes: 1 addition & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,5 @@ gradle-app.setting

.env

*.application-jwt.yml
*.application-monitoring.yml
application-jwt.yml
application-oauth.yml
application-sentry.yml
application-aws.yaml
application-mixpanel.yaml

# 민성 레디스 바이너리 파일
redis-server-7.2.3-mac-arm64
redis-server-7.2.3-mac-arm64
4 changes: 0 additions & 4 deletions application/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,3 @@ bin/
### Mac OS ###
.DS_Store

*.application-jwt.yml

### loki ###
**/application-monitoring.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package org.depromeet.spot.application.common.jwt;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "spring.jwt")
public record JwtProperties(String secret) {}
@DependsOn("awsSecretsManagerConfig")
public class JwtProperties {
String secret;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,21 @@ public String generateToken(Long memberId, MemberRole memberRole) {
.setClaims(createClaims(memberId, memberRole))
.setIssuedAt(current)
.setExpiration(expiredAt)
.signWith(SignatureAlgorithm.HS256, properties.secret().getBytes())
.signWith(SignatureAlgorithm.HS256, properties.getSecret().getBytes())
.compact();
}

public Long getIdFromJWT(String token) {
return Jwts.parser()
.setSigningKey(properties.secret().getBytes())
.setSigningKey(properties.getSecret().getBytes())
.parseClaimsJws(token)
.getBody()
.get("memberId", Long.class);
}

public String getRoleFromJWT(String token) {
return Jwts.parser()
.setSigningKey(properties.secret().getBytes())
.setSigningKey(properties.getSecret().getBytes())
.parseClaimsJws(token)
.getBody()
.get("role", String.class);
Expand Down Expand Up @@ -122,7 +122,7 @@ private Map<String, Object> createClaims(Long memberId, MemberRole role) {
}

private Key createSignature() {
byte[] apiKeySecretBytes = properties.secret().getBytes();
byte[] apiKeySecretBytes = properties.getSecret().getBytes();
return new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<appender name="LOKI_APPENDER" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://${LOKI_URL}:3100/loki/api/v1/push</url>
<url>http://${loki.url}:3100/loki/api/v1/push</url>
</http>
<format>
<label>
Expand Down
32 changes: 21 additions & 11 deletions application/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,14 @@ spring:
group:
local:
- jpa
- aws
- jwt
- oauth
- aws-credentials
- mixpanel
dev:
- jpa
- aws
- jwt
- oauth
- monitoring
- mixpanel
prod:
- jpa
- aws
- jwt
- oauth
- sentry
- monitoring
- mixpanel
servlet:
multipart:
Expand Down Expand Up @@ -56,21 +46,41 @@ management:
web:
exposure:
include: "*"

# secret manager
aws:
secretsmanager:
name: spot-local-secrets
cloud:
aws:
region:
static: ap-northeast-2
stack:
auto: false
---
spring:
config:
activate:
on-profile: local
aws:
secretsmanager:
name: spot-local-secrets
---
spring:
config:
activate:
on-profile: dev
aws:
secretsmanager:
name: spot-dev-secrets
---
spring:
config:
activate:
on-profile: prod
aws:
secretsmanager:
name: spot-prod-secrets

decorator:
datasource:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.depromeet.spot.application;

Check failure on line 1 in application/src/test/java/org/depromeet/spot/application/ReviewLikeServiceTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

ReviewLikeServiceTest.멀티_스레드_환경에서_리뷰_공감_수를_정상적으로_증가시킬_수_있다()

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@58647985 testClass = org.depromeet.spot.application.ReviewLikeServiceTest, locations = [], classes = [org.depromeet.spot.application.SpotApplication], contextInitializerClasses = [], activeProfiles = ["test"], propertySourceDescriptors = [PropertySourceDescriptor[locations=[classpath:application-test.yml], ignoreResourceNotFound=false, name=null, propertySourceFactory=null, encoding=null]], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f165b9ed, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@7fe7c640, [ImportsContextCustomizer@4536a09a key = [org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, com.github.gavlyukovskiy.boot.jdbc.decorator.DataSourceDecoratorAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@6da00fb9, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@13cf7d52, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@d03d2483, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@60a2630a, org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizer@6eeade6c, org.springframework.boot.test.context.SpringBootTestAnnotation@e75bbc6e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@58647985 testClass = org.depromeet.spot.application.ReviewLikeServiceTest, locations = [], classes = [org.depromeet.spot.application.SpotApplication], contextInitializerClasses = [], activeProfiles = ["test"], propertySourceDescriptors = [PropertySourceDescriptor[locations=[classpath:application-test.yml], ignoreResourceNotFound=false, name=null, propertySourceFactory=null, encoding=null]], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f165b9ed, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@7fe7c640, [ImportsContextCustomizer@4536a09a key = [org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, com.github.gavlyukovskiy.boot.jdbc.decorator.DataSourceDecoratorAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@6da00fb9, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@13cf7d52, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@d03d2483, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@60a2630a, org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizer@6eeade6c, org.springframework.boot.test.context.SpringBootTestAnnotation@e75bbc6e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:378)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:383)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:378)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:377)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:290)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:289)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:279)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:278)
	at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'redissonClient' defined in class path resource [org/depromeet/spot/infrastructure/redis/RedissonConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=redissonConfig; factoryMethodName=redissonClient; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/depromeet/spot/infrastructure/redis/RedissonConfig.class]] for bean 'redissonClient' since there is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=embeddedRedisConfig; factoryMethodName=redissonClient; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/depromeet/spot/infrastructure/redis/EmbeddedRedisConfig.class]] bound.
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:1017)
	at app//org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:277)
	at app//org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
	at app//org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
	at app//org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:428)
	at app//org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:289)
	at app//org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
	at app//org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
	at app//org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788)
	at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606)
	at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
	at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
	at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
	at app//org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
	at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
	at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
	at app//org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
	at app//org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
	at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
	at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
	at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
	at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
	... 86 more

import static org.junit.jupiter.api.Assertions.assertEquals;

Expand All @@ -7,6 +7,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

import org.depromeet.spot.application.common.jwt.JwtProperties;
import org.depromeet.spot.domain.member.Level;
import org.depromeet.spot.domain.member.Member;
import org.depromeet.spot.domain.member.enums.MemberRole;
Expand All @@ -21,6 +22,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.jdbc.Sql;
Expand All @@ -35,7 +37,7 @@
@SpringBootTest
@Testcontainers
@ActiveProfiles("test")
@TestPropertySource("classpath:application-test.yml")
@TestPropertySource({"classpath:application-test.yml"})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@SqlGroup({
@Sql(
Expand All @@ -47,6 +49,10 @@
})
class ReviewLikeServiceTest {

// @MockBean private JwtTokenUtil jwtTokenUtil;
//
@MockBean private JwtProperties jwtProperties;

@Autowired private ReviewLikeService reviewLikeService;

@Autowired private ReadReviewUsecase readReviewUsecase;
Expand Down
5 changes: 4 additions & 1 deletion application/src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ aws:
redis:
host: localhost
port: 6379
credentials:
access-key: ${AWS_S3_ACCESS_KEY}
secret-key: ${AWS_S3_SECRET_KEY}

oauth:
kakaoClientId: ${KAKAO_CLIENT_ID}
Expand All @@ -19,7 +22,7 @@ oauth:
googleClientSecret: ${GOOGLE_CLIENT_SECRET}
googleRedirectUrl: ${GOOGLE_REDIRECT_URL}
googleAuthTokenUrlHost: ${GOOGLE_AUTH_TOKEN_URL_HOST}
googleUserUrlHost: ${GOOGLE_USER_URL_HOST}
googleAuthUserUrlHost: ${GOOGLE_USER_URL_HOST}

spring:
datasource:
Expand Down
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ subprojects {
testCompileOnly("org.projectlombok:lombok:_")
testAnnotationProcessor("org.projectlombok:lombok:_")

// aws
implementation("org.springframework.cloud:spring-cloud-starter-bootstrap:_")
implementation("org.springframework.cloud:spring-cloud-starter-aws-secrets-manager-config:_")

// configuration processor
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:_")

Expand Down
3 changes: 3 additions & 0 deletions common/src/main/resources/application-sentry.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sentry:
enable-tracing: true
environment: prod
Loading
Loading