diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4df12e4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +# 빌드 산출물 +build/ +out/ +**/build/ +**/out/ + +# Gradle +.gradle/ + +# IDE +.idea/ +*.iml + +# Git +.git +.gitignore + +# OS +.DS_Store + +# 환경변수 파일 제외 +framey-env/ + +# Spring Boot 로컬 설정 제외 +**/application-local.yml +**/application-local.yaml + +# 빌드에 불필요한 파일 +*.pem +*.md diff --git a/.github/workflows/dev-deploy.yaml b/.github/workflows/dev-deploy.yaml new file mode 100644 index 0000000..d5c7f54 --- /dev/null +++ b/.github/workflows/dev-deploy.yaml @@ -0,0 +1,135 @@ +name: Dev Deploy + +on: + push: + branches: [dev] + +jobs: + detect-changes: + runs-on: ubuntu-latest + outputs: + member: ${{ steps.filter.outputs.member }} + collage: ${{ steps.filter.outputs.collage }} + archive: ${{ steps.filter.outputs.archive }} + swagger: ${{ steps.filter.outputs.swagger }} + nginx: ${{ steps.filter.outputs.nginx }} + steps: + - uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + shared: &shared + - 'framey-common/**' + - 'framey-web/**' + - 'framey-monitoring/**' + - 'build.gradle' + - 'settings.gradle' + - 'gradle/**' + member: + - *shared + - 'framey-application/member-service/**' + collage: + - *shared + - 'framey-application/collage-service/**' + archive: + - *shared + - 'framey-application/archive-service/**' + swagger: + - 'framey-infrastructure/swagger-dev/**' + nginx: + - 'framey-infrastructure/nginx/**' + + deploy: + needs: detect-changes + runs-on: ubuntu-latest + if: | + needs.detect-changes.outputs.member == 'true' || + needs.detect-changes.outputs.collage == 'true' || + needs.detect-changes.outputs.archive == 'true' || + needs.detect-changes.outputs.swagger == 'true' || + needs.detect-changes.outputs.nginx == 'true' + + steps: + - name: Build target services list + id: targets + run: | + SERVICES="" + if [ "${{ needs.detect-changes.outputs.member }}" == "true" ]; then + SERVICES="$SERVICES member-dev" + fi + if [ "${{ needs.detect-changes.outputs.collage }}" == "true" ]; then + SERVICES="$SERVICES collage-dev" + fi + if [ "${{ needs.detect-changes.outputs.archive }}" == "true" ]; then + SERVICES="$SERVICES archive-dev" + fi + if [ "${{ needs.detect-changes.outputs.swagger }}" == "true" ]; then + SERVICES="$SERVICES swagger-dev" + fi + if [ "${{ needs.detect-changes.outputs.nginx }}" == "true" ]; then + SERVICES="$SERVICES nginx" + fi + echo "services=$SERVICES" >> $GITHUB_OUTPUT + + - name: Deploy to DEV EC2 + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.DEV_EC2_HOST }} + username: ${{ secrets.DEV_EC2_USER }} + key: ${{ secrets.DEV_EC2_SSH_KEY }} + script: | + cd /home/ec2-user/Framey-Server + + git pull origin dev + + export DEV_DB_URL="${{ secrets.DEV_DB_URL }}" + export DEV_DB_USER="${{ secrets.DEV_DB_USER }}" + export DEV_DB_PASSWORD="${{ secrets.DEV_DB_PASSWORD }}" + + docker compose \ + -f framey-infrastructure/docker/dev/docker-compose.dev.yaml \ + up -d --build --no-deps ${{ steps.targets.outputs.services }} + + - name: Health Check + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.DEV_EC2_HOST }} + username: ${{ secrets.DEV_EC2_USER }} + key: ${{ secrets.DEV_EC2_SSH_KEY }} + script: | + sleep 30 + + SERVICES="${{ steps.targets.outputs.services }}" + + check_health() { + local name=$1 + local port=$2 + for i in $(seq 1 20); do + if docker exec framey-dev-${name} \ + wget -qO- http://localhost:${port}/actuator/health 2>/dev/null \ + | grep -q '"status":"UP"'; then + echo "✅ ${name} is healthy" + return 0 + fi + sleep 5 + done + echo "❌ ${name} health check failed" + docker logs --tail=50 framey-dev-${name} + return 1 + } + + FAILED=0 + + if echo "$SERVICES" | grep -q "member-dev"; then + check_health "member" 8081 || FAILED=1 + fi + if echo "$SERVICES" | grep -q "collage-dev"; then + check_health "collage" 8082 || FAILED=1 + fi + if echo "$SERVICES" | grep -q "archive-dev"; then + check_health "archive" 8083 || FAILED=1 + fi + + exit $FAILED diff --git a/.github/workflows/pr-ci.yaml b/.github/workflows/pr-ci.yaml new file mode 100644 index 0000000..de314f8 --- /dev/null +++ b/.github/workflows/pr-ci.yaml @@ -0,0 +1,43 @@ +# pr 올렸을때 작동 workflow +name: PR CI + +on: + #dev 브렌치 + pull_request: + branches: [dev] + +jobs: + test: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_DB: framey_test + POSTGRES_USER: test + POSTGRES_PASSWORD: test + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U test" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + cache: gradle + + - run: chmod +x gradlew + + - run: ./gradlew clean test check --no-daemon + env: + TEST_DB_URL: jdbc:postgresql://localhost:5432/framey_test + TEST_DB_USER: test + TEST_DB_PASSWORD: test diff --git a/.gitignore b/.gitignore index 60bb4a3..76cfe8b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,8 @@ bin/ .env .env.* !.env.example +### env 폴더 추적 제외 ### +framey-env/ ### OS ### .DS_Store @@ -46,4 +48,4 @@ Thumbs.db logs/ ### Local Docker Data ### -**/docker/**/data/ \ No newline at end of file +**/docker/**/data/ diff --git a/build.gradle b/build.gradle index 0ad417c..e5f006b 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ subprojects { toolVersion = '10.26.1' configFile = rootProject.file( - 'common/checkstyle/naver-checkstyle-rules.xml' + 'framey-common/checkstyle/naver-checkstyle-rules.xml' ) maxWarnings = 0 @@ -55,7 +55,7 @@ subprojects { configProperties = [ 'suppressionFile': rootProject - .file('common/checkstyle/naver-checkstyle-suppressions.xml') + .file('framey-common/checkstyle/naver-checkstyle-suppressions.xml') .absolutePath ] } @@ -70,4 +70,4 @@ subprojects { tasks.withType(Test).configureEach { useJUnitPlatform() } -} \ No newline at end of file +} diff --git a/common/common-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/common/common-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 2fefcf9..0000000 --- a/common/common-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -framey.common.config.MonitoringAutoConfiguration \ No newline at end of file diff --git a/common/common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/common/common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index a72b15c..0000000 --- a/common/common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -framey.common.config.SwaggerConfig diff --git "a/docs/common/Swagger\354\240\201\354\232\251\352\264\200\353\240\250\353\254\270\354\204\234.md" "b/docs/common/Swagger\354\240\201\354\232\251\352\264\200\353\240\250\353\254\270\354\204\234.md" index 5ef75e7..61b139b 100644 --- "a/docs/common/Swagger\354\240\201\354\232\251\352\264\200\353\240\250\353\254\270\354\204\234.md" +++ "b/docs/common/Swagger\354\240\201\354\232\251\352\264\200\353\240\250\353\254\270\354\204\234.md" @@ -2,15 +2,15 @@ ### 서비스 모듈 의존성 추가 -Swagger를 사용할 각 서비스 모듈의 `build.gradle`에 `common-web` 의존성을 추가합니다. +Swagger를 사용할 각 서비스 모듈의 `build.gradle`에 `framey-web` 의존성을 추가합니다. ```gradle dependencies { - implementation project(':common:common-web') + implementation project(':framey-web') } ``` -`common-web`에는 다음 의존성이 포함되어 있습니다. +`framey-web`에는 다음 의존성이 포함되어 있습니다. ```gradle api 'org.springframework.boot:spring-boot-starter-web' @@ -91,7 +91,7 @@ http://localhost:{서비스 포트}/swagger http://localhost:{서비스 포트}/v3/api-docs ``` -`common-web`과 같이 독립적으로 실행되지 않는 공통 라이브러리 모듈에는 별도의 Swagger 주소가 생성되지 않습니다. +`framey-web`과 같이 독립적으로 실행되지 않는 공통 라이브러리 모듈에는 별도의 Swagger 주소가 생성되지 않습니다. #### 개발 환경 diff --git "a/docs/common/\353\241\234\352\271\205\354\213\234\354\212\244\355\205\234\352\265\254\354\266\225\352\264\200\353\240\250\353\254\270\354\204\234.md" "b/docs/common/\353\241\234\352\271\205\354\213\234\354\212\244\355\205\234\352\265\254\354\266\225\352\264\200\353\240\250\353\254\270\354\204\234.md" index f790ba3..7361bcd 100644 --- "a/docs/common/\353\241\234\352\271\205\354\213\234\354\212\244\355\205\234\352\265\254\354\266\225\352\264\200\353\240\250\353\254\270\354\204\234.md" +++ "b/docs/common/\353\241\234\352\271\205\354\213\234\354\212\244\355\205\234\352\265\254\354\266\225\352\264\200\353\240\250\353\254\270\354\204\234.md" @@ -5,7 +5,7 @@ ### 기능 -`common-monitoring` 기능 +`framey-monitoring` 기능 - **TraceId 생성** - HTTP 요청마다 고유 랜덤 TraceId를 생성. @@ -29,16 +29,16 @@ ```gradle rootProject.name = 'server' -include ':common:common-monitoring' +include ':framey-monitoring' //ex) include 'identity-service' : identity-service 모듈 추가 ``` #### 2. `build.gradle`에 의존성을 추가합니다 -새로운 서비스 모듈의 `build.gradle`에 `common-monitoring`을 의존성으로 추가해야 +새로운 서비스 모듈의 `build.gradle`에 `framey-monitoring`을 의존성으로 추가해야 ```gradle dependencies { - implementation project(':common:common-monitoring') + implementation project(':framey-monitoring') } ``` @@ -67,16 +67,16 @@ spring: #### 4. Logback 설정 -`common-monitoring`에 기본 `logback-spring.xml`이 포함되어 있으므로, 별도의 Logback 파일이 없어도 공통 설정이 자동으로 각모듈에 적용됩니다. +`framey-monitoring`에 기본 `logback-spring.xml`이 포함되어 있으므로, 별도의 Logback 파일이 없어도 공통 설정이 자동으로 각모듈에 적용됩니다. 서비스에서 별도의 `logback-spring.xml`을 추가하면, -`common-monitoring`의 기본 설정 대신 해당 설정이 적용됩니다. +`framey-monitoring`의 기본 설정 대신 해당 설정이 적용됩니다. ##### (참고) 공통 Logback 설정 관련 -공통 Logback 설정파일은 `common-monitoring`내에 있습니다. +공통 Logback 설정파일은 `framey-monitoring`내에 있습니다. ```text -common/common-monitoring/ +framey-monitoring/ └── src/main/resources/ └── logback-spring.xml ``` diff --git a/framey-application/archive-service/Dockerfile b/framey-application/archive-service/Dockerfile new file mode 100644 index 0000000..615c8c7 --- /dev/null +++ b/framey-application/archive-service/Dockerfile @@ -0,0 +1,15 @@ +FROM eclipse-temurin:21-jdk-alpine AS build +WORKDIR /app +COPY . . +RUN chmod +x ./gradlew +RUN --mount=type=cache,target=/root/.gradle,sharing=locked \ + ./gradlew :framey-application:archive-service:bootJar --no-daemon + +# Runtime Stage +FROM eclipse-temurin:21-jre-alpine +WORKDIR /app +COPY --from=build \ + /app/framey-application/archive-service/build/libs/*.jar \ + app.jar +EXPOSE 8083 +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/framey-application/archive-service/build.gradle b/framey-application/archive-service/build.gradle new file mode 100644 index 0000000..65d89fd --- /dev/null +++ b/framey-application/archive-service/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.springframework.boot' + id 'java-library' +} + +dependencies { + api project(':framey-common') + api project(':framey-web') + implementation project(":framey-monitoring") + + //postgreSQL + runtimeOnly 'org.postgresql:postgresql' + + testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test' + testImplementation 'com.fasterxml.jackson.core:jackson-databind' +} diff --git a/framey-application/archive-service/src/main/java/framey/archive/ArchiveServiceApplication.java b/framey-application/archive-service/src/main/java/framey/archive/ArchiveServiceApplication.java new file mode 100644 index 0000000..750b5a0 --- /dev/null +++ b/framey-application/archive-service/src/main/java/framey/archive/ArchiveServiceApplication.java @@ -0,0 +1,14 @@ +package framey.archive; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; + +@ConfigurationPropertiesScan +@SpringBootApplication +public class ArchiveServiceApplication { + public static void main(String[] args) { + SpringApplication.run(ArchiveServiceApplication.class, args); + } + +} diff --git a/framey-application/archive-service/src/main/resources/application-dev.yaml b/framey-application/archive-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..e6eaa41 --- /dev/null +++ b/framey-application/archive-service/src/main/resources/application-dev.yaml @@ -0,0 +1,33 @@ +spring: + datasource: + url: ${DEV_DB_URL} + username: ${DEV_DB_USER} + password: ${DEV_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: validate + open-in-view: false + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 + +springdoc: + api-docs: + enabled: true + swagger-ui: + enabled: false + +management: + endpoints: + web: + exposure: + include: health,info + endpoint: + health: + probes: + enabled: true diff --git a/framey-application/archive-service/src/main/resources/application-local.yaml b/framey-application/archive-service/src/main/resources/application-local.yaml new file mode 100644 index 0000000..369a11a --- /dev/null +++ b/framey-application/archive-service/src/main/resources/application-local.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${LOCAL_DB_URL} + username: ${LOCAL_DB_USER} + password: ${LOCAL_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 diff --git a/framey-application/archive-service/src/main/resources/application.yaml b/framey-application/archive-service/src/main/resources/application.yaml new file mode 100644 index 0000000..a1cfa9e --- /dev/null +++ b/framey-application/archive-service/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: archive-service + profiles: + active: local +server: + port: 8083 +#swagger +springdoc: + api-docs: + enabled: true diff --git a/framey-application/archive-service/src/test/java/framey/archive/ArchiveServiceApplicationTests.java b/framey-application/archive-service/src/test/java/framey/archive/ArchiveServiceApplicationTests.java new file mode 100644 index 0000000..33f4781 --- /dev/null +++ b/framey-application/archive-service/src/test/java/framey/archive/ArchiveServiceApplicationTests.java @@ -0,0 +1,13 @@ +package framey.archive; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles("test") +public class ArchiveServiceApplicationTests { + @Test + void contextLoads() { + } +} diff --git a/framey-application/archive-service/src/test/resources/application-test.yaml b/framey-application/archive-service/src/test/resources/application-test.yaml new file mode 100644 index 0000000..f57546e --- /dev/null +++ b/framey-application/archive-service/src/test/resources/application-test.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${TEST_DB_URL} + username: ${TEST_DB_USER} + password: ${TEST_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: create-drop + open-in-view: false + properties: + hibernate: + format_sql: true + show_sql: true diff --git a/framey-application/collage-service/Dockerfile b/framey-application/collage-service/Dockerfile new file mode 100644 index 0000000..1a4915c --- /dev/null +++ b/framey-application/collage-service/Dockerfile @@ -0,0 +1,14 @@ +FROM eclipse-temurin:21-jdk-alpine AS build +WORKDIR /app +COPY . . +RUN chmod +x ./gradlew +RUN --mount=type=cache,target=/root/.gradle,sharing=locked \ + ./gradlew :framey-application:collage-service:bootJar --no-daemon +# Runtime Stage +FROM eclipse-temurin:21-jre-alpine +WORKDIR /app +COPY --from=build \ + /app/framey-application/collage-service/build/libs/*.jar \ + app.jar +EXPOSE 8082 +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/framey-application/collage-service/build.gradle b/framey-application/collage-service/build.gradle new file mode 100644 index 0000000..023fe70 --- /dev/null +++ b/framey-application/collage-service/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.springframework.boot' + id 'java-library' +} + +dependencies { + api project(':framey-common') + api project(':framey-web') + implementation project(":framey-monitoring") + + //postgreSQLa + runtimeOnly 'org.postgresql:postgresql' + + testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test' + testImplementation 'com.fasterxml.jackson.core:jackson-databind' +} diff --git a/framey-application/collage-service/src/main/java/framey/collage/CollageServiceApplication.java b/framey-application/collage-service/src/main/java/framey/collage/CollageServiceApplication.java new file mode 100644 index 0000000..7a0e680 --- /dev/null +++ b/framey-application/collage-service/src/main/java/framey/collage/CollageServiceApplication.java @@ -0,0 +1,13 @@ +package framey.collage; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; + +@ConfigurationPropertiesScan +@SpringBootApplication +public class CollageServiceApplication { + public static void main(String[] args) { + SpringApplication.run(CollageServiceApplication.class, args); + } +} diff --git a/framey-application/collage-service/src/main/resources/application-dev.yaml b/framey-application/collage-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..e6eaa41 --- /dev/null +++ b/framey-application/collage-service/src/main/resources/application-dev.yaml @@ -0,0 +1,33 @@ +spring: + datasource: + url: ${DEV_DB_URL} + username: ${DEV_DB_USER} + password: ${DEV_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: validate + open-in-view: false + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 + +springdoc: + api-docs: + enabled: true + swagger-ui: + enabled: false + +management: + endpoints: + web: + exposure: + include: health,info + endpoint: + health: + probes: + enabled: true diff --git a/framey-application/collage-service/src/main/resources/application-local.yaml b/framey-application/collage-service/src/main/resources/application-local.yaml new file mode 100644 index 0000000..38df6cb --- /dev/null +++ b/framey-application/collage-service/src/main/resources/application-local.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${LOCAL_DB_URl} + username: ${LOCAL_DB_USER} + password: ${LOCAL_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 diff --git a/framey-application/collage-service/src/main/resources/application.yaml b/framey-application/collage-service/src/main/resources/application.yaml new file mode 100644 index 0000000..e38196c --- /dev/null +++ b/framey-application/collage-service/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: collage-service + profiles: + active: local +server: + port: 8082 +#swagger +springdoc: + api-docs: + enabled: true diff --git a/framey-application/collage-service/src/test/java/framey/collage/CollageServiceApplicationTests.java b/framey-application/collage-service/src/test/java/framey/collage/CollageServiceApplicationTests.java new file mode 100644 index 0000000..0f5188b --- /dev/null +++ b/framey-application/collage-service/src/test/java/framey/collage/CollageServiceApplicationTests.java @@ -0,0 +1,13 @@ +package framey.collage; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles("test") +class CollageServiceApplicationTests { + @Test + void contextLoads() { + } +} diff --git a/framey-application/collage-service/src/test/resources/application-test.yaml b/framey-application/collage-service/src/test/resources/application-test.yaml new file mode 100644 index 0000000..73b48ad --- /dev/null +++ b/framey-application/collage-service/src/test/resources/application-test.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${TEST_DB_URL} + username: ${TEST_DB_USER} + password: ${TEST_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: update + open-in-view: false + properties: + hibernate: + format_sql: true + show_sql: true diff --git a/framey-application/member-service/Dockerfile b/framey-application/member-service/Dockerfile new file mode 100644 index 0000000..2956be4 --- /dev/null +++ b/framey-application/member-service/Dockerfile @@ -0,0 +1,15 @@ +FROM eclipse-temurin:21-jdk-alpine AS build +WORKDIR /app +COPY . . +RUN chmod +x ./gradlew +RUN --mount=type=cache,target=/root/.gradle,sharing=locked \ + ./gradlew :framey-application:member-service:bootJar --no-daemon +# Runtime Stage +FROM eclipse-temurin:21-jre-alpine +WORKDIR /app +COPY --from=build \ + /app/framey-application/member-service/build/libs/*.jar \ + app.jar + +EXPOSE 8081 +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/framey-application/member-service/build.gradle b/framey-application/member-service/build.gradle new file mode 100644 index 0000000..65d89fd --- /dev/null +++ b/framey-application/member-service/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.springframework.boot' + id 'java-library' +} + +dependencies { + api project(':framey-common') + api project(':framey-web') + implementation project(":framey-monitoring") + + //postgreSQL + runtimeOnly 'org.postgresql:postgresql' + + testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test' + testImplementation 'com.fasterxml.jackson.core:jackson-databind' +} diff --git a/framey-application/member-service/src/main/java/framey/member/MemberServiceApplication.java b/framey-application/member-service/src/main/java/framey/member/MemberServiceApplication.java new file mode 100644 index 0000000..fa35db5 --- /dev/null +++ b/framey-application/member-service/src/main/java/framey/member/MemberServiceApplication.java @@ -0,0 +1,13 @@ +package framey.member; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; + +@ConfigurationPropertiesScan +@SpringBootApplication +public class MemberServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MemberServiceApplication.class, args); + } +} diff --git a/framey-application/member-service/src/main/resources/application-dev.yaml b/framey-application/member-service/src/main/resources/application-dev.yaml new file mode 100644 index 0000000..e6eaa41 --- /dev/null +++ b/framey-application/member-service/src/main/resources/application-dev.yaml @@ -0,0 +1,33 @@ +spring: + datasource: + url: ${DEV_DB_URL} + username: ${DEV_DB_USER} + password: ${DEV_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: validate + open-in-view: false + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 + +springdoc: + api-docs: + enabled: true + swagger-ui: + enabled: false + +management: + endpoints: + web: + exposure: + include: health,info + endpoint: + health: + probes: + enabled: true diff --git a/framey-application/member-service/src/main/resources/application-local.yaml b/framey-application/member-service/src/main/resources/application-local.yaml new file mode 100644 index 0000000..369a11a --- /dev/null +++ b/framey-application/member-service/src/main/resources/application-local.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${LOCAL_DB_URL} + username: ${LOCAL_DB_USER} + password: ${LOCAL_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + highlight_sql: true + default_batch_fetch_size: 100 diff --git a/framey-application/member-service/src/main/resources/application.yaml b/framey-application/member-service/src/main/resources/application.yaml new file mode 100644 index 0000000..383a600 --- /dev/null +++ b/framey-application/member-service/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: member-service + profiles: + active: local +server: + port: 8081 +#swagger +springdoc: + api-docs: + enabled: true diff --git a/framey-application/member-service/src/test/java/framey/member/MemberServiceApplicationTests.java b/framey-application/member-service/src/test/java/framey/member/MemberServiceApplicationTests.java new file mode 100644 index 0000000..c8d8962 --- /dev/null +++ b/framey-application/member-service/src/test/java/framey/member/MemberServiceApplicationTests.java @@ -0,0 +1,13 @@ +package framey.member; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles("test") +class MemberServiceApplicationTests { + @Test + void contextLoads() { + } +} diff --git a/framey-application/member-service/src/test/resources/application-test.yaml b/framey-application/member-service/src/test/resources/application-test.yaml new file mode 100644 index 0000000..f57546e --- /dev/null +++ b/framey-application/member-service/src/test/resources/application-test.yaml @@ -0,0 +1,15 @@ +spring: + datasource: + url: ${TEST_DB_URL} + username: ${TEST_DB_USER} + password: ${TEST_DB_PASSWORD} + driver-class-name: org.postgresql.Driver + + jpa: + hibernate: + ddl-auto: create-drop + open-in-view: false + properties: + hibernate: + format_sql: true + show_sql: true diff --git a/common/common-jpa/build.gradle b/framey-common/build.gradle similarity index 62% rename from common/common-jpa/build.gradle rename to framey-common/build.gradle index a0189fc..cdfbe13 100644 --- a/common/common-jpa/build.gradle +++ b/framey-common/build.gradle @@ -4,4 +4,5 @@ plugins { dependencies { api 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' } diff --git a/common/checkstyle/naver-checkstyle-rules.xml b/framey-common/checkstyle/naver-checkstyle-rules.xml similarity index 100% rename from common/checkstyle/naver-checkstyle-rules.xml rename to framey-common/checkstyle/naver-checkstyle-rules.xml diff --git a/common/checkstyle/naver-checkstyle-suppressions.xml b/framey-common/checkstyle/naver-checkstyle-suppressions.xml similarity index 100% rename from common/checkstyle/naver-checkstyle-suppressions.xml rename to framey-common/checkstyle/naver-checkstyle-suppressions.xml diff --git a/common/checkstyle/naver-eclipse-formatter.xml b/framey-common/checkstyle/naver-eclipse-formatter.xml similarity index 100% rename from common/checkstyle/naver-eclipse-formatter.xml rename to framey-common/checkstyle/naver-eclipse-formatter.xml diff --git a/common/checkstyle/naver-intellij-formatter.xml b/framey-common/checkstyle/naver-intellij-formatter.xml similarity index 100% rename from common/checkstyle/naver-intellij-formatter.xml rename to framey-common/checkstyle/naver-intellij-formatter.xml diff --git a/common/checkstyle/naver.importorder b/framey-common/checkstyle/naver.importorder similarity index 100% rename from common/checkstyle/naver.importorder rename to framey-common/checkstyle/naver.importorder diff --git a/common/common-web/src/main/java/framey/common/exception/BusinessException.java b/framey-common/src/main/java/framey/common/exception/BusinessException.java similarity index 100% rename from common/common-web/src/main/java/framey/common/exception/BusinessException.java rename to framey-common/src/main/java/framey/common/exception/BusinessException.java diff --git a/common/common-web/src/main/java/framey/common/exception/CommonErrorCode.java b/framey-common/src/main/java/framey/common/exception/CommonErrorCode.java similarity index 100% rename from common/common-web/src/main/java/framey/common/exception/CommonErrorCode.java rename to framey-common/src/main/java/framey/common/exception/CommonErrorCode.java diff --git a/common/common-web/src/main/java/framey/common/exception/ServiceUnavailableException.java b/framey-common/src/main/java/framey/common/exception/ServiceUnavailableException.java similarity index 100% rename from common/common-web/src/main/java/framey/common/exception/ServiceUnavailableException.java rename to framey-common/src/main/java/framey/common/exception/ServiceUnavailableException.java diff --git a/common/common-jpa/src/main/java/framey/db/entity/BaseEntity.java b/framey-common/src/main/java/framey/common/jpa/BaseEntity.java similarity index 96% rename from common/common-jpa/src/main/java/framey/db/entity/BaseEntity.java rename to framey-common/src/main/java/framey/common/jpa/BaseEntity.java index e66be4c..a68b2d5 100644 --- a/common/common-jpa/src/main/java/framey/db/entity/BaseEntity.java +++ b/framey-common/src/main/java/framey/common/jpa/BaseEntity.java @@ -1,4 +1,4 @@ -package framey.db.entity; +package framey.common.jpa; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; diff --git a/common/common-web/src/main/java/framey/common/response/ApiResponse.java b/framey-common/src/main/java/framey/common/response/ApiResponse.java similarity index 100% rename from common/common-web/src/main/java/framey/common/response/ApiResponse.java rename to framey-common/src/main/java/framey/common/response/ApiResponse.java diff --git a/common/common-web/src/main/java/framey/common/response/ErrorCode.java b/framey-common/src/main/java/framey/common/response/ErrorCode.java similarity index 100% rename from common/common-web/src/main/java/framey/common/response/ErrorCode.java rename to framey-common/src/main/java/framey/common/response/ErrorCode.java diff --git a/common/common-web/src/main/java/framey/common/response/SuccessCode.java b/framey-common/src/main/java/framey/common/response/SuccessCode.java similarity index 100% rename from common/common-web/src/main/java/framey/common/response/SuccessCode.java rename to framey-common/src/main/java/framey/common/response/SuccessCode.java diff --git a/framey-infrastructure/docker/dev/docker-compose.dev.yaml b/framey-infrastructure/docker/dev/docker-compose.dev.yaml new file mode 100644 index 0000000..5290652 --- /dev/null +++ b/framey-infrastructure/docker/dev/docker-compose.dev.yaml @@ -0,0 +1,115 @@ +name: framey-dev + +services: + member-dev: + build: + context: ../../.. + dockerfile: framey-application/member-service/Dockerfile + image: framey-member:dev + container_name: framey-dev-member + restart: unless-stopped + environment: + SPRING_PROFILES_ACTIVE: dev + SERVER_PORT: 8081 + DEV_DB_URL: ${DEV_DB_URL} + DEV_DB_USER: ${DEV_DB_USER} + DEV_DB_PASSWORD: ${DEV_DB_PASSWORD} + networks: + - framey-dev + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://localhost:8081/actuator/health || exit 1" + ] + interval: 15s + timeout: 5s + retries: 10 + start_period: 40s + + collage-dev: + build: + context: ../../.. + dockerfile: framey-application/collage-service/Dockerfile + image: framey-collage:dev + container_name: framey-dev-collage + restart: unless-stopped + environment: + SPRING_PROFILES_ACTIVE: dev + SERVER_PORT: 8082 + DEV_DB_URL: ${DEV_DB_URL} + DEV_DB_USER: ${DEV_DB_USER} + DEV_DB_PASSWORD: ${DEV_DB_PASSWORD} + networks: + - framey-dev + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://localhost:8082/actuator/health || exit 1" + ] + interval: 15s + timeout: 5s + retries: 10 + start_period: 40s + + archive-dev: + build: + context: ../../.. + dockerfile: framey-application/archive-service/Dockerfile + image: framey-archive:dev + container_name: framey-dev-archive + restart: unless-stopped + environment: + SPRING_PROFILES_ACTIVE: dev + SERVER_PORT: 8083 + DEV_DB_URL: ${DEV_DB_URL} + DEV_DB_USER: ${DEV_DB_USER} + DEV_DB_PASSWORD: ${DEV_DB_PASSWORD} + networks: + - framey-dev + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://localhost:8083/actuator/health || exit 1" + ] + interval: 15s + timeout: 5s + retries: 10 + start_period: 40s + + swagger-dev: + build: + context: ../../swagger-dev + dockerfile: Dockerfile + container_name: framey-dev-swagger + restart: unless-stopped + networks: + - framey-dev + nginx: + image: nginx:1.27-alpine + container_name: framey-dev-nginx + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ../../nginx/dev/default.conf:/etc/nginx/conf.d/default.conf:ro + - /etc/letsencrypt:/etc/letsencrypt:ro + - /var/www/certbot:/var/www/certbot:ro + depends_on: + member-dev: + condition: service_healthy + collage-dev: + condition: service_healthy + archive-dev: + condition: service_healthy + swagger-dev: + condition: service_started + networks: + - framey-dev + +networks: + framey-dev: + name: framey-dev diff --git a/common/docker/local/docker-compose.local.yaml b/framey-infrastructure/docker/local/docker-compose.local.yaml similarity index 53% rename from common/docker/local/docker-compose.local.yaml rename to framey-infrastructure/docker/local/docker-compose.local.yaml index f4aa977..4db6229 100644 --- a/common/docker/local/docker-compose.local.yaml +++ b/framey-infrastructure/docker/local/docker-compose.local.yaml @@ -1,21 +1,27 @@ +name: framey-local + services: postgres: image: postgres:16-alpine container_name: framey-local-postgres ports: - - "5432:5432" + - "5433:5432" environment: - POSTGRES_DB: framey_local - POSTGRES_USER: root - POSTGRES_PASSWORD: root + POSTGRES_DB: ${LOCAL_DB_NAME} + POSTGRES_USER: ${LOCAL_DB_USER} + POSTGRES_PASSWORD: ${LOCAL_DB_PASSWORD} volumes: - framey-postgres-data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U root -d framey_local"] + test: + [ + "CMD-SHELL", + "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" + ] interval: 10s timeout: 5s retries: 5 diff --git a/framey-infrastructure/docker/local/docker-compose.test.yaml b/framey-infrastructure/docker/local/docker-compose.test.yaml new file mode 100644 index 0000000..dc42506 --- /dev/null +++ b/framey-infrastructure/docker/local/docker-compose.test.yaml @@ -0,0 +1,31 @@ +name: framey-test + +services: + postgres: + image: postgres:16-alpine + container_name: framey-test-postgres + + ports: + - "5434:5432" + + environment: + POSTGRES_DB: ${TEST_DB_NAME} + POSTGRES_USER: ${TEST_DB_USER} + POSTGRES_PASSWORD: ${TEST_DB_PASSWORD} + + volumes: + - framey-test-postgres-data:/var/lib/postgresql/data + + healthcheck: + test: + [ + "CMD-SHELL", + "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" + ] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + +volumes: + framey-test-postgres-data: diff --git a/framey-infrastructure/nginx/dev/bootstrap.conf b/framey-infrastructure/nginx/dev/bootstrap.conf new file mode 100644 index 0000000..3009806 --- /dev/null +++ b/framey-infrastructure/nginx/dev/bootstrap.conf @@ -0,0 +1,14 @@ +server { + listen 80; + server_name dev-swagger.framey.kr; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + try_files $uri =404; + } + + location / { + default_type text/plain; + return 200 "FRAMEY DEV HTTP OK\n"; + } +} diff --git a/framey-infrastructure/nginx/dev/default.conf b/framey-infrastructure/nginx/dev/default.conf new file mode 100644 index 0000000..534e17b --- /dev/null +++ b/framey-infrastructure/nginx/dev/default.conf @@ -0,0 +1,122 @@ +# HTTP → HTTPS +server { + listen 80; + server_name dev-swagger.framey.kr; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + location / { + return 301 https://$host$request_uri; + } +} + +# HTTPS +server { + listen 443 ssl; + http2 on; + + server_name dev-swagger.framey.kr; + + ssl_certificate /etc/letsencrypt/live/dev-swagger.framey.kr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/dev-swagger.framey.kr/privkey.pem; + + # ========================= + # OpenAPI + # ========================= + location = /api-docs/member { + proxy_pass http://member-dev:8081/v3/api-docs; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /api-docs/collage { + proxy_pass http://collage-dev:8082/v3/api-docs; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /api-docs/archive { + proxy_pass http://archive-dev:8083/v3/api-docs; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # ========================= + # Member Service + # ========================= + location = /api/v1/members { + proxy_pass http://member-dev:8081; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ^~ /api/v1/members/ { + proxy_pass http://member-dev:8081; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # ========================= + # Collage Service + # ========================= + location = /api/v1/collages { + proxy_pass http://collage-dev:8082; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ^~ /api/v1/collages/ { + proxy_pass http://collage-dev:8082; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # ========================= + # Archive Service + # ========================= + location = /api/v1/archives { + proxy_pass http://archive-dev:8083; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location ^~ /api/v1/archives/ { + proxy_pass http://archive-dev:8083; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # ========================= + # Swagger UI + # ========================= + + location / { + proxy_pass http://swagger-dev:8080; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/framey-infrastructure/swagger-dev/Dockerfile b/framey-infrastructure/swagger-dev/Dockerfile new file mode 100644 index 0000000..9f6b6e0 --- /dev/null +++ b/framey-infrastructure/swagger-dev/Dockerfile @@ -0,0 +1,4 @@ +# swagger 전용 도커 이미지 +FROM swaggerapi/swagger-ui:v5.31.0 +COPY swagger-config.json /usr/share/nginx/html/swagger-config.json +ENV CONFIG_URL=/swagger-config.json diff --git a/framey-infrastructure/swagger-dev/swagger-config.json b/framey-infrastructure/swagger-dev/swagger-config.json new file mode 100644 index 0000000..035a33b --- /dev/null +++ b/framey-infrastructure/swagger-dev/swagger-config.json @@ -0,0 +1,23 @@ +{ + "_comment": "서비스가 추가되거나 변경될 경우 항목 추가 및 수정 필요", + "urls": [ + { + "name": "Member Service", + "url": "/api-docs/member" + }, + { + "name": "Collage Service", + "url": "/api-docs/collage" + }, + { + "name": "Archive Service", + "url": "/api-docs/archive" + } + ], + "urls.primaryName": "Member Service", + "deepLinking": true, + "displayRequestDuration": true, + "operationsSorter": "method", + "tagsSorter": "alpha", + "persistAuthorization": true +} diff --git a/common/common-monitoring/build.gradle b/framey-monitoring/build.gradle similarity index 100% rename from common/common-monitoring/build.gradle rename to framey-monitoring/build.gradle diff --git a/common/common-monitoring/src/main/java/framey/common/annotation/LogActivity.java b/framey-monitoring/src/main/java/framey/monitoring/annotation/LogActivity.java similarity index 88% rename from common/common-monitoring/src/main/java/framey/common/annotation/LogActivity.java rename to framey-monitoring/src/main/java/framey/monitoring/annotation/LogActivity.java index f6606c4..2852e87 100644 --- a/common/common-monitoring/src/main/java/framey/common/annotation/LogActivity.java +++ b/framey-monitoring/src/main/java/framey/monitoring/annotation/LogActivity.java @@ -1,4 +1,4 @@ -package framey.common.annotation; +package framey.monitoring.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/common/common-monitoring/src/main/java/framey/common/aspect/LogActivityAspect.java b/framey-monitoring/src/main/java/framey/monitoring/aspect/LogActivityAspect.java similarity index 90% rename from common/common-monitoring/src/main/java/framey/common/aspect/LogActivityAspect.java rename to framey-monitoring/src/main/java/framey/monitoring/aspect/LogActivityAspect.java index 333f446..9884f8b 100644 --- a/common/common-monitoring/src/main/java/framey/common/aspect/LogActivityAspect.java +++ b/framey-monitoring/src/main/java/framey/monitoring/aspect/LogActivityAspect.java @@ -1,10 +1,10 @@ -package framey.common.aspect; +package framey.monitoring.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import framey.common.annotation.LogActivity; +import framey.monitoring.annotation.LogActivity; import lombok.extern.slf4j.Slf4j; @@ -33,4 +33,4 @@ public Object logActivity(ProceedingJoinPoint joinPoint, LogActivity logActivity throw e; } } -} \ No newline at end of file +} diff --git a/common/common-monitoring/src/main/java/framey/common/config/MonitoringAutoConfiguration.java b/framey-monitoring/src/main/java/framey/monitoring/config/MonitoringAutoConfiguration.java similarity index 74% rename from common/common-monitoring/src/main/java/framey/common/config/MonitoringAutoConfiguration.java rename to framey-monitoring/src/main/java/framey/monitoring/config/MonitoringAutoConfiguration.java index 558d5d3..32ee1e0 100644 --- a/common/common-monitoring/src/main/java/framey/common/config/MonitoringAutoConfiguration.java +++ b/framey-monitoring/src/main/java/framey/monitoring/config/MonitoringAutoConfiguration.java @@ -1,7 +1,7 @@ -package framey.common.config; +package framey.monitoring.config; -import framey.common.aspect.LogActivityAspect; -import framey.common.filter.TraceIdFilter; +import framey.monitoring.aspect.LogActivityAspect; +import framey.monitoring.filter.TraceIdFilter; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Bean; diff --git a/common/common-monitoring/src/main/java/framey/common/filter/TraceIdFilter.java b/framey-monitoring/src/main/java/framey/monitoring/filter/TraceIdFilter.java similarity index 96% rename from common/common-monitoring/src/main/java/framey/common/filter/TraceIdFilter.java rename to framey-monitoring/src/main/java/framey/monitoring/filter/TraceIdFilter.java index 3b4b1ee..ce6cc4e 100644 --- a/common/common-monitoring/src/main/java/framey/common/filter/TraceIdFilter.java +++ b/framey-monitoring/src/main/java/framey/monitoring/filter/TraceIdFilter.java @@ -1,4 +1,4 @@ -package framey.common.filter; +package framey.monitoring.filter; import java.io.IOException; import java.util.UUID; @@ -37,4 +37,4 @@ protected void doFilterInternal( MDC.remove(TRACE_ID); } } -} \ No newline at end of file +} diff --git a/framey-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/framey-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..223a12d --- /dev/null +++ b/framey-monitoring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +framey.monitoring.config.MonitoringAutoConfiguration diff --git a/common/common-monitoring/src/main/resources/logback-spring.xml b/framey-monitoring/src/main/resources/logback-spring.xml similarity index 98% rename from common/common-monitoring/src/main/resources/logback-spring.xml rename to framey-monitoring/src/main/resources/logback-spring.xml index 27f7ff3..b3a7b04 100644 --- a/common/common-monitoring/src/main/resources/logback-spring.xml +++ b/framey-monitoring/src/main/resources/logback-spring.xml @@ -61,4 +61,4 @@ - \ No newline at end of file + diff --git a/common/common-web/build.gradle b/framey-web/build.gradle similarity index 87% rename from common/common-web/build.gradle rename to framey-web/build.gradle index 2157f49..7eb7dce 100644 --- a/common/common-web/build.gradle +++ b/framey-web/build.gradle @@ -3,6 +3,8 @@ plugins { } dependencies { + api project(':framey-common') + api 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' api 'org.springdoc:springdoc-openapi-starter-webmvc-ui:3.1.1' diff --git a/common/common-web/src/main/java/framey/common/advice/CommonExceptionHandler.java b/framey-web/src/main/java/framey/web/advice/CommonExceptionHandler.java similarity index 94% rename from common/common-web/src/main/java/framey/common/advice/CommonExceptionHandler.java rename to framey-web/src/main/java/framey/web/advice/CommonExceptionHandler.java index a4d8b7c..c6597c0 100644 --- a/common/common-web/src/main/java/framey/common/advice/CommonExceptionHandler.java +++ b/framey-web/src/main/java/framey/web/advice/CommonExceptionHandler.java @@ -1,4 +1,4 @@ -package framey.common.advice; +package framey.web.advice; import framey.common.exception.BusinessException; import framey.common.exception.CommonErrorCode; @@ -49,10 +49,7 @@ public ResponseEntity> handleBusinessException( final BusinessException e ) { log.warn( - "{} 발생! errorCode={}", - e.getClass().getSimpleName(), - e.getErrorCode().getValue(), - e + "{} 발생! errorCode={}", e.getClass().getSimpleName(), e.getErrorCode().getValue(), e ); return ResponseEntity.status(e.getErrorCode().getHttpStatus()) .body(fail(e.getErrorCode())); diff --git a/common/common-web/src/main/java/framey/common/config/CommonWebAutoConfiguration.java b/framey-web/src/main/java/framey/web/config/CommonWebAutoConfiguration.java similarity index 73% rename from common/common-web/src/main/java/framey/common/config/CommonWebAutoConfiguration.java rename to framey-web/src/main/java/framey/web/config/CommonWebAutoConfiguration.java index 354c7ac..1943962 100644 --- a/common/common-web/src/main/java/framey/common/config/CommonWebAutoConfiguration.java +++ b/framey-web/src/main/java/framey/web/config/CommonWebAutoConfiguration.java @@ -1,6 +1,6 @@ -package framey.common.config; +package framey.web.config; -import framey.common.advice.CommonExceptionHandler; +import framey.web.advice.CommonExceptionHandler; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Import; diff --git a/common/common-web/src/main/java/framey/common/config/SwaggerConfig.java b/framey-web/src/main/java/framey/web/config/SwaggerConfig.java similarity index 95% rename from common/common-web/src/main/java/framey/common/config/SwaggerConfig.java rename to framey-web/src/main/java/framey/web/config/SwaggerConfig.java index 9a2c4d8..255f635 100644 --- a/common/common-web/src/main/java/framey/common/config/SwaggerConfig.java +++ b/framey-web/src/main/java/framey/web/config/SwaggerConfig.java @@ -1,6 +1,6 @@ -package framey.common.config; +package framey.web.config; -import framey.common.swagger.ErrorCodeExampleCustomizer; +import framey.web.swagger.ErrorCodeExampleCustomizer; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; diff --git a/common/common-web/src/main/java/framey/common/swagger/ErrorCodeExampleCustomizer.java b/framey-web/src/main/java/framey/web/swagger/ErrorCodeExampleCustomizer.java similarity index 85% rename from common/common-web/src/main/java/framey/common/swagger/ErrorCodeExampleCustomizer.java rename to framey-web/src/main/java/framey/web/swagger/ErrorCodeExampleCustomizer.java index 3419c82..1ae852d 100644 --- a/common/common-web/src/main/java/framey/common/swagger/ErrorCodeExampleCustomizer.java +++ b/framey-web/src/main/java/framey/web/swagger/ErrorCodeExampleCustomizer.java @@ -1,13 +1,14 @@ -package framey.common.swagger; +package framey.web.swagger; -import framey.common.response.ApiResponse; import framey.common.response.ErrorCode; -import framey.common.swagger.annotation.ApiErrorCodeExample; -import framey.common.swagger.annotation.PublicApi; +import framey.web.swagger.annotation.ApiErrorCodeExample; +import framey.web.swagger.annotation.PublicApi; + import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.examples.Example; import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; import org.springdoc.core.customizers.OperationCustomizer; import org.springframework.web.method.HandlerMethod; @@ -16,11 +17,13 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; public class ErrorCodeExampleCustomizer implements OperationCustomizer { private static final String APPLICATION_JSON = "application/json"; + private static final String ENUM_TYPE_REQUIRED_MESSAGE = "ErrorCode 구현체는 enum 타입이어야 합니다."; @Override public Operation customize( @@ -59,7 +62,7 @@ private void handleErrorCodeExamples( return; } - List includes = Arrays.asList(annotation.include()); + Set includes = Set.of(annotation.include()); List exampleHolders = Arrays.stream(annotation.value()) @@ -86,10 +89,7 @@ private void handleErrorCodeExamples( operation.setResponses(responses); } - addExamplesToResponses( - responses, - examplesByStatus - ); + addExamplesToResponses(responses, examplesByStatus); } private List getErrorCodes( @@ -99,7 +99,8 @@ private List getErrorCodes( if (constants == null) { throw new IllegalArgumentException( - "ErrorCode 구현체는 enum이어야 합니다: " + ENUM_TYPE_REQUIRED_MESSAGE + + " type=" + type.getName() ); } @@ -112,7 +113,7 @@ private List getErrorCodes( private String getEnumName(ErrorCode errorCode) { if (!(errorCode instanceof Enum enumValue)) { throw new IllegalArgumentException( - "ErrorCode 구현체는 enum이어야 합니다." + ENUM_TYPE_REQUIRED_MESSAGE ); } @@ -133,7 +134,7 @@ private Example createExample(ErrorCode errorCode) { Example example = new Example(); example.setValue( - ApiResponse.fail(errorCode) + framey.common.response.ApiResponse.fail(errorCode) ); return example; @@ -146,10 +147,10 @@ private void addExamplesToResponses( examplesByStatus.forEach((status, exampleHolders) -> { String statusCode = String.valueOf(status); - io.swagger.v3.oas.models.responses.ApiResponse response = + ApiResponse response = responses.computeIfAbsent( statusCode, - key -> new io.swagger.v3.oas.models.responses.ApiResponse() + key -> new ApiResponse() .description("Error Response") ); @@ -161,7 +162,8 @@ private void addExamplesToResponses( if (mediaType == null) { mediaType = new MediaType(); - response.getContent().addMediaType(APPLICATION_JSON, mediaType); + response.getContent() + .addMediaType(APPLICATION_JSON, mediaType); } for (ExampleHolder exampleHolder : exampleHolders) { diff --git a/common/common-web/src/main/java/framey/common/swagger/ExampleHolder.java b/framey-web/src/main/java/framey/web/swagger/ExampleHolder.java similarity index 87% rename from common/common-web/src/main/java/framey/common/swagger/ExampleHolder.java rename to framey-web/src/main/java/framey/web/swagger/ExampleHolder.java index ee7a4a3..32702a1 100644 --- a/common/common-web/src/main/java/framey/common/swagger/ExampleHolder.java +++ b/framey-web/src/main/java/framey/web/swagger/ExampleHolder.java @@ -1,4 +1,4 @@ -package framey.common.swagger; +package framey.web.swagger; import io.swagger.v3.oas.models.examples.Example; import lombok.Builder; diff --git a/common/common-web/src/main/java/framey/common/swagger/annotation/ApiErrorCodeExample.java b/framey-web/src/main/java/framey/web/swagger/annotation/ApiErrorCodeExample.java similarity index 90% rename from common/common-web/src/main/java/framey/common/swagger/annotation/ApiErrorCodeExample.java rename to framey-web/src/main/java/framey/web/swagger/annotation/ApiErrorCodeExample.java index ab38250..7262f0f 100644 --- a/common/common-web/src/main/java/framey/common/swagger/annotation/ApiErrorCodeExample.java +++ b/framey-web/src/main/java/framey/web/swagger/annotation/ApiErrorCodeExample.java @@ -1,4 +1,4 @@ -package framey.common.swagger.annotation; +package framey.web.swagger.annotation; import framey.common.response.ErrorCode; import java.lang.annotation.ElementType; diff --git a/common/common-web/src/main/java/framey/common/swagger/annotation/PublicApi.java b/framey-web/src/main/java/framey/web/swagger/annotation/PublicApi.java similarity index 87% rename from common/common-web/src/main/java/framey/common/swagger/annotation/PublicApi.java rename to framey-web/src/main/java/framey/web/swagger/annotation/PublicApi.java index cc34eb4..e1083e4 100644 --- a/common/common-web/src/main/java/framey/common/swagger/annotation/PublicApi.java +++ b/framey-web/src/main/java/framey/web/swagger/annotation/PublicApi.java @@ -1,4 +1,4 @@ -package framey.common.swagger.annotation; +package framey.web.swagger.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/framey-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/framey-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..b9b57ca --- /dev/null +++ b/framey-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +framey.web.config.SwaggerConfig +framey.web.config.CommonWebAutoConfiguration diff --git a/settings.gradle b/settings.gradle index 970e481..d8e1b3d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,8 @@ rootProject.name = 'server' -include ':common:common-monitoring' -include ':common:common-jpa' -include ':common:common-web' +include ':framey-common' +include ':framey-web' +include ':framey-monitoring' +include ':framey-application:member-service' +include ':framey-application:collage-service' +include ':framey-application:archive-service'