Skip to content

Commit

Permalink
Merge pull request #11 from DDD-Community/feature/POLABO-108
Browse files Browse the repository at this point in the history
chore(POLABO-107): 개발 서버 배포 테스트
  • Loading branch information
dldmsql authored Aug 6, 2024
2 parents 5f053da + 4c72785 commit f370540
Show file tree
Hide file tree
Showing 39 changed files with 1,200 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/cd-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ jobs:
- name: Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
host: ${{ secrets.EC2_HOST_DEV }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_KEY }}
script: |
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPOSITORY }}
docker stop polabo-dev
docker rm polabo-dev
docker pull ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
docker run -d -v /etc/localtime:/etc/localtime:ro -v /usr/share/zoneinfo/Asia/Seoul:/etc/timezone:ro -e ENVIRONMENT_VALUE=-Dspring.profiles.active=dev --name polabo-dev -p 8080:8080 --restart=always --network host ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
docker run -d -v /etc/localtime:/etc/localtime:ro -v /usr/share/zoneinfo/Asia/Seoul:/etc/timezone:ro -e ENVIRONMENT_VALUE=-Dspring.profiles.active=local --name polabo-dev -p 8080:8080 --restart=always --network host ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
84 changes: 84 additions & 0 deletions .github/workflows/cd-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Java CI with Gradle

on:
push:
branches: [ "main" ]

jobs:
build:
## checkout후 자바 21 버전으로 설정을 합니다
runs-on: ubuntu-latest
env:
DB_URL: ${{ secrets.DB_URL }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
JASYPT_ENCRYPTOR_PASSWORD: ${{ secrets.JASYPT_ENCRYPTOR_PASSWORD }}

steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/gradle-build-action@v2

- name: Increase Gradle memory settings
run: |
echo "org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8" >> ~/.gradle/gradle.properties
echo "kotlin.daemon.jvmargs=-Xmx4g" >> ~/.gradle/gradle.properties
## gradlew 의 권한을 줍니다.
- name: Grant execute permission for gradlew
run: chmod +x gradlew

## gradle build
- name: Build with Gradle
run: ./gradlew clean build -x test

## 이미지 태그에 시간 설정을 하기위해서 현재 시간을 가져옵니다.
- name: Get current time
uses: 1466587594/get-current-time@v2
id: current-time
with:
format: YYYY-MM-DDTHH-mm-ss
utcOffset: "+09:00"

- name: Show Current Time
run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}"
## AWS에 로그인. aws-region은 서울로 설정(ap-northeast-2)
- 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: ap-northeast-2
## ECR에 로그인
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
## sample라는 ECR 리파지터리에 현재 시간 태그를 생성하고, 푸쉬
## 앞의 스탭에서 ${{steps.current-time.outputs.formattedTime}}로 현재 시간을 가져옵니다.
- name: Build, tag, and push image to Amazon ECR
run: |
docker build --build-arg PASSWORD=$PASSWORD -t polabo:${{steps.current-time.outputs.formattedTime}} .
docker tag polabo:${{steps.current-time.outputs.formattedTime}} ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
docker push ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
env:
PASSWORD: ${{ secrets.JASYPT_ENCRYPTOR_PASSWORD }}

- name: Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_KEY }}
script: |
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPOSITORY }}
docker stop polabo-dev
docker rm polabo-dev
docker pull ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
docker run -d -v /etc/localtime:/etc/localtime:ro -v /usr/share/zoneinfo/Asia/Seoul:/etc/timezone:ro -e ENVIRONMENT_VALUE=-Dspring.profiles.active=dev --name polabo-dev -p 8080:8080 --restart=always --network host ${{ secrets.ECR_REGISTRY }}/polabo:${{steps.current-time.outputs.formattedTime}}
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ dependencies {
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("io.netty:netty-resolver-dns-native-macos:4.1.68.Final:osx-aarch_64")

implementation("io.jsonwebtoken:jjwt-api:0.11.2")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.2")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.2")
}

tasks.withType<KotlinCompile> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package com.ddd.sonnypolabobe.domain.board.controller
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardGetResponse
import com.ddd.sonnypolabobe.domain.board.service.BoardService
import com.ddd.sonnypolabobe.domain.user.dto.UserDto
import com.ddd.sonnypolabobe.global.response.ApplicationResponse
import com.ddd.sonnypolabobe.logger
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
Expand All @@ -22,10 +25,16 @@ class BoardController(
@Operation(summary = "보드 생성", description = """
보드를 생성합니다.
userId는 추후 회원가입 기능이 추가될 것을 대비한 것입니다. 지금은 null로 주세요.
userId 타입을 UUID -> Long으로 변경하였습니다. - 2024.08.03
""")
@PostMapping
fun create(@RequestBody request : BoardCreateRequest)
= ApplicationResponse.ok(this.boardService.create(request))
= run {
val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res
request.userId = user.id
ApplicationResponse.ok(this.boardService.create(request))
}

@Operation(summary = "보드 조회", description = """
보드를 조회합니다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ data class BoardCreateRequest(
@field:Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*()_+=-])(?=.*[ㄱ-ㅎㅏ-ㅣ가-힣]).{1,20}$", message = "제목은 국문, 영문, 숫자, 특수문자, 띄어쓰기를 포함한 20자 이내여야 합니다.")
val title: String,
@Schema(description = "작성자 아이디", example = "null", required = false)
val userId: UUID? = null
var userId: Long? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.ddd.sonnypolabobe.domain.board.my.controller

import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
import com.ddd.sonnypolabobe.domain.board.my.service.MyBoardService
import com.ddd.sonnypolabobe.domain.user.dto.UserDto
import com.ddd.sonnypolabobe.global.entity.PageDto
import com.ddd.sonnypolabobe.global.response.ApplicationResponse
import com.ddd.sonnypolabobe.global.util.DateConverter.convertToKst
import io.swagger.v3.oas.annotations.Operation
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.annotation.*
import java.time.LocalDateTime

@RestController
@RequestMapping("/api/v1/my/boards")
class MyBoardController(private val myBoardService : MyBoardService) {

@Operation(summary = "내 보드 목록 조회", description = """
내 보드 목록을 조회합니다.
""")
@GetMapping
fun getMyBoards(
@RequestParam page : Int,
@RequestParam size : Int
) = ApplicationResponse.ok(
PageDto(
content = listOf(
MyBoardDto.Companion.PageListRes(
id = 1L,
title = "보드 제목",
createdAt = convertToKst(LocalDateTime.now()),
totalCount = 1L
)
),
page = page,
size = size,
total = 10
)
)

@Operation(
summary = "내 보드 이름 수정",
description = """
내 보드 이름을 수정합니다.
"""
)
@PutMapping("/{id}")
fun updateMyBoard(
@PathVariable id : String,
@RequestBody request : MyBoardDto.Companion.MBUpdateReq
) = run {
val userId = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res
this.myBoardService.updateMyBoard(id, request, userId.id)
ApplicationResponse.ok()
}

@Operation(
summary = "내 보드 삭제",
description = """
내 보드를 삭제합니다.
"""
)
@DeleteMapping("/{id}")
fun deleteMyBoard(
@PathVariable id : String
) = run {
val userId = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res
this.myBoardService.deleteMyBoard(id, userId.id)
ApplicationResponse.ok()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ddd.sonnypolabobe.domain.board.my.dto

import com.fasterxml.jackson.annotation.JsonProperty
import org.springframework.format.annotation.DateTimeFormat
import java.time.LocalDateTime
import java.util.UUID

class MyBoardDto {
companion object {
data class MBUpdateReq(
@JsonProperty("title")
val title: String
)

data class PageListRes(
val id: Long,
val title: String,
@DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE)
val createdAt: LocalDateTime,
val totalCount: Long
)

data class GetOneRes(
val id: UUID,
val title: String,
@DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE)
val createdAt: LocalDateTime,
val userId : Long?
)

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ddd.sonnypolabobe.domain.board.my.service

import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
import com.ddd.sonnypolabobe.domain.board.repository.BoardJooqRepository
import com.ddd.sonnypolabobe.global.util.UuidConverter
import org.springframework.stereotype.Service

@Service
class MyBoardService(private val boardJooqRepository: BoardJooqRepository) {
fun updateMyBoard(id: String, request: MyBoardDto.Companion.MBUpdateReq, userId: Long) {
val board = this.boardJooqRepository.findById(UuidConverter.stringToUUID(id))
?: throw IllegalArgumentException("해당 보드가 존재하지 않습니다.")
if (board.userId != userId) {
throw IllegalArgumentException("해당 보드에 대한 권한이 없습니다.")
}
this.boardJooqRepository.updateTitle(UuidConverter.stringToUUID(id), request.title)
}

fun deleteMyBoard(id: String, userId: Long) {
val board = this.boardJooqRepository.findById(UuidConverter.stringToUUID(id))
?: throw IllegalArgumentException("해당 보드가 존재하지 않습니다.")
if (board.userId != userId) {
throw IllegalArgumentException("해당 보드에 대한 권한이 없습니다.")
}
this.boardJooqRepository.delete(UuidConverter.stringToUUID(id))
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.ddd.sonnypolabobe.domain.board.repository

import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
import com.ddd.sonnypolabobe.jooq.polabo.tables.Board
import org.jooq.Record6
import java.time.LocalDateTime
import java.util.*

interface BoardJooqRepository {
fun insertOne(request: BoardCreateRequest): ByteArray?
fun selectOneById(id: UUID) : Array<out Record6<String?, Long?, String?, String?, LocalDateTime?, ByteArray?>>
fun selectOneById(id: UUID) : Array<out Record6<String?, Long?, String?, String?, LocalDateTime?, Long?>>
fun selectTotalCount(): Long
fun selectTodayTotalCount(): Long
fun findById(id: UUID): MyBoardDto.Companion.GetOneRes?
fun updateTitle(id: UUID, title: String)
fun delete(id: UUID)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.ddd.sonnypolabobe.domain.board.repository

import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardGetResponse
import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
import com.ddd.sonnypolabobe.global.util.DateConverter
import com.ddd.sonnypolabobe.global.util.UuidConverter
import com.ddd.sonnypolabobe.global.util.UuidGenerator
Expand Down Expand Up @@ -34,7 +35,7 @@ class BoardJooqRepositoryImpl(
return if (result == 1) id else null
}

override fun selectOneById(id: UUID): Array<out Record6<String?, Long?, String?, String?, LocalDateTime?, ByteArray?>> {
override fun selectOneById(id: UUID): Array<out Record6<String?, Long?, String?, String?, LocalDateTime?, Long?>> {
val jBoard = Board.BOARD
val jPolaroid = Polaroid.POLAROID
return this.dslContext
Expand Down Expand Up @@ -82,4 +83,34 @@ class BoardJooqRepositoryImpl(
))
.fetchOne(0, Long::class.java) ?: 0L
}

override fun findById(id: UUID): MyBoardDto.Companion.GetOneRes? {
val jBoard = Board.BOARD
return this.dslContext.selectFrom(jBoard)
.where(jBoard.ID.eq(UuidConverter.uuidToByteArray(id)))
.fetchOne()?.map {
MyBoardDto.Companion.GetOneRes(
id = UuidConverter.byteArrayToUUID(it.get("id", ByteArray::class.java)!!),
title = it.get("title", String::class.java)!!,
createdAt = it.get("created_at", LocalDateTime::class.java)!!,
userId = it.get("user_id", Long::class.java),
)
}
}

override fun updateTitle(id: UUID, title: String) {
val jBoard = Board.BOARD
this.dslContext.update(jBoard)
.set(jBoard.TITLE, title)
.where(jBoard.ID.eq(UuidConverter.uuidToByteArray(id)))
.execute()
}

override fun delete(id: UUID) {
val jBoard = Board.BOARD
this.dslContext.update(jBoard)
.set(jBoard.YN, 0)
.where(jBoard.ID.eq(UuidConverter.uuidToByteArray(id)))
.execute()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class BoardService(
id = it.value2() ?: 0L,
imageUrl = it.value3()?.let { it1 -> s3Util.getImgUrl(it1) } ?: "",
oneLineMessage = it.value4() ?: "폴라보와의 추억 한 줄",
userId = it.value6()?.let { it1 -> UuidConverter.byteArrayToUUID(it1) }
userId = it.value6() ?: 0L
)
}.filter { it.id != 0L }
BoardGetResponse(title = title ?: "", items = polaroids)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ddd.sonnypolabobe.domain.oauth.controller

import com.ddd.sonnypolabobe.domain.oauth.service.OauthService
import com.ddd.sonnypolabobe.global.response.ApplicationResponse
import io.swagger.v3.oas.annotations.Operation
import org.springframework.http.HttpHeaders
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/api/v1/oauth")
class OauthController(private val oauthService: OauthService) {

@Operation(summary = "카카오 소셜 로그인", description = """
카카오 소셜 로그인을 진행합니다.
인가 코드를 파라미터로 넘겨주세요.
""")
@GetMapping("/sign-in")
fun login(@RequestParam(name = "code") code : String) = ApplicationResponse.ok(this.oauthService.signIn(code))

@PutMapping("/re-issue")
fun reIssue(
@RequestHeader(name = "Authorization", required = true) header: String
) = run {
ApplicationResponse.ok(this.oauthService.reIssue(header))
}
}
Loading

0 comments on commit f370540

Please sign in to comment.