From a35a8bc14ebce935a47b44f9b65d42e93c4d00a4 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Mon, 8 May 2023 18:53:07 +0900 Subject: [PATCH 1/9] updated merged version --- .../poolc/springproject/poolcreborn/api/ApiSearchRequest.java | 2 +- .../poolc/springproject/poolcreborn/api/NaverApiInvoker.java | 2 +- .../poolc/springproject/poolcreborn/service/BookService.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/poolc/springproject/poolcreborn/api/ApiSearchRequest.java b/src/main/java/com/poolc/springproject/poolcreborn/api/ApiSearchRequest.java index a5612bd..b706318 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/api/ApiSearchRequest.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/api/ApiSearchRequest.java @@ -23,4 +23,4 @@ public ApiSearchRequest(String query, NaverApiInvokerCommand command) { this.query = query; this.command = command; } -} +} \ No newline at end of file diff --git a/src/main/java/com/poolc/springproject/poolcreborn/api/NaverApiInvoker.java b/src/main/java/com/poolc/springproject/poolcreborn/api/NaverApiInvoker.java index 64ca3c2..98ed122 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/api/NaverApiInvoker.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/api/NaverApiInvoker.java @@ -61,4 +61,4 @@ private RequestEntity.HeadersBuilder buildRequest(HttpMethod method, URI uri) } } -} +} \ No newline at end of file diff --git a/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java b/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java index 9fec4b6..c9b639d 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java @@ -35,7 +35,7 @@ public class BookService { private final UserRepository userRepository; public void saveBook(BookRequest bookRequest, String username) throws InvalidRequestException { User user = userRepository.findByUsername(username) - .orElseThrow(() -> new InvalidRequestException(Message.USER_DOES_NOT_EXIST)); + .orElseThrow(() -> new InvalidRequestException(Message.USER_DOES_NOT_EXIST)); if (user != null && user.isAdmin() && !bookRepository.existsByIsbn(bookRequest.getIsbn())) { Book book = new Book(); @@ -113,4 +113,4 @@ public List bookSearch(ApiSearchRequest searchRequest) throws InvalidRe ResponseEntity result = invoker.naverBookSearchApi(); return fromJSONtoBookDtoList(result.getBody()); } -} +} \ No newline at end of file From 5fedd31d8cdf7d14e4b7a4ccd51a9f826a920c6a Mon Sep 17 00:00:00 2001 From: becooq81 <77732679+becooq81@users.noreply.github.com> Date: Mon, 8 May 2023 19:47:13 +0900 Subject: [PATCH 2/9] feat: create deploy.yml --- .github/workflows/deploy.yml | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..9677239 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,67 @@ +name: Deploy to Amazon EC2 + +on: + push: + branches: + - main + +# 본인이 설정한 값을 여기서 채워넣습니다. +# 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름 +env: + AWS_REGION: us-east-2 + S3_BUCKET_NAME: mypoolcbucket + CODE_DEPLOY_APPLICATION_NAME: poolc-reborn + CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: poolc-codedeploy-deployment-group + +permissions: + contents: read + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + environment: production + + steps: + # (1) 기본 체크아웃 + - name: Checkout + uses: actions/checkout@v3 + + # (2) JDK 11 세팅 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '11' + + # (3) Gradle build (Test 제외) + - name: Build with Gradle + uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + with: + arguments: clean build -x test + + # (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용) + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + + # (5) 빌드 결과물을 S3 버킷에 업로드 + - name: Upload to AWS S3 + run: | + aws deploy push \ + --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \ + --ignore-hidden-files \ + --s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \ + --source . + + # (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행 + - name: Deploy to AWS EC2 from S3 + run: | + aws deploy create-deployment \ + --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \ + --deployment-config-name CodeDeployDefault.AllAtOnce \ + --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \ + --s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip From 8704620d458eb6821c39c8cd5101fbf13a4a0ff4 Mon Sep 17 00:00:00 2001 From: becooq81 <77732679+becooq81@users.noreply.github.com> Date: Tue, 9 May 2023 01:22:04 +0900 Subject: [PATCH 3/9] feat: update deploy.yml --- .github/workflows/deploy.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9677239..40338a8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,9 +4,6 @@ on: push: branches: - main - -# 본인이 설정한 값을 여기서 채워넣습니다. -# 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름 env: AWS_REGION: us-east-2 S3_BUCKET_NAME: mypoolcbucket @@ -23,24 +20,24 @@ jobs: environment: production steps: - # (1) 기본 체크아웃 + - name: Checkout uses: actions/checkout@v3 - # (2) JDK 11 세팅 + - name: Set up JDK 11 uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '11' - # (3) Gradle build (Test 제외) + - name: Build with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: arguments: clean build -x test - # (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용) + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: @@ -48,7 +45,7 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - # (5) 빌드 결과물을 S3 버킷에 업로드 + - name: Upload to AWS S3 run: | aws deploy push \ @@ -57,7 +54,7 @@ jobs: --s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \ --source . - # (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행 + - name: Deploy to AWS EC2 from S3 run: | aws deploy create-deployment \ From ba8c6abddf99374ba9bdcada53379481c250ba17 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Tue, 9 May 2023 01:40:29 +0900 Subject: [PATCH 4/9] feat: setup for deployment --- appspec.yml | 23 +++++++++++++++++++++++ build.gradle | 3 +++ scripts/start.sh | 21 +++++++++++++++++++++ scripts/stop.sh | 19 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 appspec.yml create mode 100644 scripts/start.sh create mode 100644 scripts/stop.sh diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 0000000..9882a4f --- /dev/null +++ b/appspec.yml @@ -0,0 +1,23 @@ +version: 0.0 +os: linux + +files: + - source: / + destination: /home/ubuntu/app + overwrite: yes + +permissions: + - object: / + pattern: "**" + owner: ubuntu + group: ubuntu + +hooks: + AfterInstall: + - location: scripts/stop.sh + timeout: 60 + runas: ubuntu + ApplicationStart: + - location: scripts/start.sh + timeout: 60 + runas: ubuntu \ No newline at end of file diff --git a/build.gradle b/build.gradle index e1b2f02..1f311a5 100644 --- a/build.gradle +++ b/build.gradle @@ -50,3 +50,6 @@ dependencies { tasks.named('test') { useJUnitPlatform() } +jar { + enabled = false +} diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100644 index 0000000..126c2a2 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +PROJECT_ROOT="/home/ubuntu/app" +JAR_FILE="$PROJECT_ROOT/spring-webapp.jar" + +APP_LOG="$PROJECT_ROOT/application.log" +ERROR_LOG="$PROJECT_ROOT/error.log" +DEPLOY_LOG="$PROJECT_ROOT/deploy.log" + +TIME_NOW=$(date +%c) + +# build 파일 복사 +echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG +cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE + +# jar 파일 실행 +echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG +nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG & + +CURRENT_PID=$(pgrep -f $JAR_FILE) +echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG \ No newline at end of file diff --git a/scripts/stop.sh b/scripts/stop.sh new file mode 100644 index 0000000..755d347 --- /dev/null +++ b/scripts/stop.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +PROJECT_ROOT="/home/ubuntu/app" +JAR_FILE="$PROJECT_ROOT/spring-webapp.jar" + +DEPLOY_LOG="$PROJECT_ROOT/deploy.log" + +TIME_NOW=$(date +%c) + +# 현재 구동 중인 애플리케이션 pid 확인 +CURRENT_PID=$(pgrep -f $JAR_FILE) + +# 프로세스가 켜져 있으면 종료 +if [ -z $CURRENT_PID ]; then + echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG +else + echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG + kill -15 $CURRENT_PID +fi \ No newline at end of file From dcf6e9a6415a4343755de06db798a8d770a87ff6 Mon Sep 17 00:00:00 2001 From: becooq81 <77732679+becooq81@users.noreply.github.com> Date: Tue, 9 May 2023 01:46:38 +0900 Subject: [PATCH 5/9] feat: update deploy.yml --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 40338a8..118f2a9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,7 +3,7 @@ name: Deploy to Amazon EC2 on: push: branches: - - main + - master env: AWS_REGION: us-east-2 S3_BUCKET_NAME: mypoolcbucket From 35a243d957f691de5a921353ff403a2fb7d7a239 Mon Sep 17 00:00:00 2001 From: becooq81 Date: Tue, 9 May 2023 02:04:21 +0900 Subject: [PATCH 6/9] style: removed unnecessary lines/spaces --- .../poolc/springproject/poolcreborn/service/BookService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java b/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java index c9b639d..c0fe6ab 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/service/BookService.java @@ -1,7 +1,6 @@ package com.poolc.springproject.poolcreborn.service; import com.poolc.springproject.poolcreborn.api.NaverApiInvoker; -import com.poolc.springproject.poolcreborn.api.NaverApiInvokerCommand; import com.poolc.springproject.poolcreborn.exception.InvalidRequestException; import com.poolc.springproject.poolcreborn.exception.InvalidStateException; import com.poolc.springproject.poolcreborn.model.book.Book; @@ -89,7 +88,7 @@ public void returnBook(Long currentBookId, String username) throws Exception { } } - public void registerNaverBook(ApiSearchRequest searchRequest, Long bookId) throws Exception{ + public void registerNaverBook(ApiSearchRequest searchRequest, Long bookId) throws Exception { List bookDtoList = bookSearch(searchRequest); BookDto bookDto = bookDtoList.get(bookId.intValue()); Book book = bookMapper.buildBookFromBookDto(bookDto); From 08f0fc04f23094c88c4e7a58b3c173bfda0ef109 Mon Sep 17 00:00:00 2001 From: becooq81 <77732679+becooq81@users.noreply.github.com> Date: Mon, 15 May 2023 17:08:55 +0900 Subject: [PATCH 7/9] Update README.md --- README.md | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 64046db..cd697fa 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,13 @@ # PoolC-Spring-Practice -풀씨 백엔드와 유사하지만, 일부 기능들을 개선한 서버를 만들어봅시다. 물론 풀씨 페이지는 규모가 상당히 크기에, 모든 컴포넌트를 만들 수 없으니 기본적인 것들만 구현해 봅시다. +풀씨 (동아리) 서버와 유사하지만 주요기능에 집중하여 개선한 서버 사이드 프로젝트입니다. -진행 방식 ---- -- Spring 프로그래밍 연습 스터디는, 하나의 큰 과제를 수행해야 합니다. - - Java 스터디에 비해 자유도가 조금 높으며, 요구 사항이 다소 추상적입니다. -- 직접적인 main 브랜치로의 커밋은 금지 되며, 반드시 Step 수행 이후 Pull Request 요청을 통해 확인이 진행됩니다. - - 본인의 닉네임/이름에 해당하는 브랜치를 만들고, 각 Step 에 대한 브랜치를 만들어서 PR을 진행해 주세요. - - ex) KBC 브랜치를 만들고, Step 1에 대한 결과물은 KBC-step1 로 만들어 주세요. - - 그 이후, PR은 KBC-step1 -> KBC 꼴로 요청해 주세요. -- 각 커밋의 단위는 최소화 해야하며, 다음과 같은 커밋 메시지 양식을 준수해 주세요. - - https://vsfe.notion.site/Git-Convention-84e1df4868974a58a1609b052e815095 +### 주요 기능 목록 +- 회원가입, 로그인 및 회원수정 +- 유저 등급 분리 및 관리 +- 동아리 회원 확인 기능 +- 세미나 등록, 신청, 수정 기능 +- Naver API를 사용하거나 직접 입력으로 책 등록, 책 대출 및 반납 기능 +- AWS를 이용한 CI/CD 프로세스 구축 +- Github Action을 이용한 Pre-hook, Post-hook -요구 사항 (공통) ---- -- 해당 과제는 여러 Step으로 구성되어 있으며, 앞 Step에 대한 PR 및 리뷰가 완료 되어야 뒤 Step을 진행할 수 있습니다. -- 포함된 라이브러리는 기본적인 라이브러리만 포함되어 있으며, 필요에 따라 추가 라이브러리를 사용해도 됩니다. -- 모든 Java 코드는 반드시 Java 코드 컨벤션 가이드를 준수해야 합니다. -- 작성한 메서드에 대한 테스트 코드 작성이 진행되어야 합니다. - - Jacoco 기준, Test Coverage 및 Branch Coverage가 80% 이상이어야 합니다. - - 통합 테스트/단위 테스트 여부는 자유롭게 설정하셔도 됩니다. - - 하지만, 통합 테스트 수행 시, 실제 DB에 전혀 영향이 가지 않아야 합니다. -- 사용하는 DB는 제한이 없습니다. - -요구 사항 (단계) ---- -- 특정 Step 을 마치지 못했다면, 그 다음 Step의 요구 사항을 보지 않는 것을 권장합니다. https://vsfe.notion.site/Spring-PoolC-Backend-Reborn-281c69c2eaf543459fedace987868ea4 From a507cec71553dd47ecbbe030f09e32da8e2b84ef Mon Sep 17 00:00:00 2001 From: becooq81 <77732679+becooq81@users.noreply.github.com> Date: Mon, 15 May 2023 17:12:10 +0900 Subject: [PATCH 8/9] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index cd697fa..58aebc3 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,8 @@ - AWS를 이용한 CI/CD 프로세스 구축 - Github Action을 이용한 Pre-hook, Post-hook +### 사용 기술 + +- Spring Boot +- MySQL +- AWS 배포 From 917ab5b6597c49ebe5e0f2593450e4923f11773f Mon Sep 17 00:00:00 2001 From: becooq81 Date: Fri, 22 Sep 2023 15:01:05 +0900 Subject: [PATCH 9/9] fix: right use of validation annotation --- .../springproject/poolcreborn/model/user/User.java | 10 +++++----- .../poolcreborn/security/SecurityConfig.java | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/poolc/springproject/poolcreborn/model/user/User.java b/src/main/java/com/poolc/springproject/poolcreborn/model/user/User.java index 8606de5..c7c4235 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/model/user/User.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/model/user/User.java @@ -31,7 +31,7 @@ public class User { @IncludeCharInt private String username; - @NotEmpty(message = "암호는 필수 입력 항목입니다.") + @NotBlank(message = "암호는 필수 입력 항목입니다.") @Size(min = 8) private String password; @@ -39,20 +39,20 @@ public class User { private String name; @Email - @NotEmpty(message = "이메일은 필수 입력 항목입니다.") + @NotBlank(message = "이메일은 필수 입력 항목입니다.") private String email; - @NotEmpty(message = "전화번호 필수 입력 항목입니다.") + @NotBlank(message = "전화번호 필수 입력 항목입니다.") @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$") private String mobileNumber; - @NotEmpty(message = "전공은 필수 입력 항목입니다.") + @NotBlank(message = "전공은 필수 입력 항목입니다.") private String major; @NotNull(message = "학번은 필수 입력 항목입니다.") private int studentId; - @NotEmpty(message = "자기소개는 필수 입력 항목입니다.") + @NotBlank(message = "자기소개는 필수 입력 항목입니다.") private String description; @Enumerated(EnumType.STRING) diff --git a/src/main/java/com/poolc/springproject/poolcreborn/security/SecurityConfig.java b/src/main/java/com/poolc/springproject/poolcreborn/security/SecurityConfig.java index 1b41c7b..7a9d99b 100644 --- a/src/main/java/com/poolc/springproject/poolcreborn/security/SecurityConfig.java +++ b/src/main/java/com/poolc/springproject/poolcreborn/security/SecurityConfig.java @@ -102,6 +102,4 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } - - }