Skip to content

Commit

Permalink
Merge pull request #144 from DSM-PICK/develop
Browse files Browse the repository at this point in the history
add :: bug message api
  • Loading branch information
rudeh2926 authored Apr 25, 2024
2 parents 916b8ed + a6c19bd commit f700150
Show file tree
Hide file tree
Showing 34 changed files with 373 additions and 65 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/git-action-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ jobs:
DSM_LOGIN=${{ secrets.DSM_LOGIN }}
NEIS_KEY=${{ secrets.NEIS_KEY }}
WEBHOOK_PROD=${{ secrets.WEBHOOK_PROD }}
DISCORD=${{ secrets.DISCORD }}
WEBHOOK_MESSAGE=${{ secrets.WEBHOOK_MESSAGE }}
AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}
AWS_BUCKET=${{ secrets.AWS_BUCKET }}
AWS_STATIC=${{ secrets.AWS_STATIC }}
- name: Discord Alert Success
uses: sarisia/actions-status-discord@v1
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/git-action-stag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ jobs:
DSM_LOGIN=${{ secrets.DSM_LOGIN }}
NEIS_KEY=${{ secrets.NEIS_KEY }}
WEBHOOK_STAG=${{ secrets.WEBHOOK_STAG }}
DISCORD=${{ secrets.DISCORD }}
WEBHOOK_MESSAGE=${{ secrets.WEBHOOK_MESSAGE }}
AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}
AWS_BUCKET=${{ secrets.AWS_BUCKET }}
AWS_STATIC=${{ secrets.AWS_STATIC }}
- name: Discord Alert Success
uses: sarisia/actions-status-discord@v1
Expand Down
16 changes: 14 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,20 @@ ENV WEBHOOK_PROD ${WEBHOOK_PROD}
ARG WEBHOOK_STAG
ENV WEBHOOK_STAG ${WEBHOOK_STAG}

ARG DISCORD
ENV DISCORD ${DISCORD}
ARG WEBHOOK_MESSAGE
ENV WEBHOOK_MESSAGE ${WEBHOOK_MESSAGE}

ARG AWS_ACCESS_KEY
ENV AWS_ACCESS_KEY ${AWS_ACCESS_KEY}

ARG AWS_SECRET_KEY
ENV AWS_SECRET_KEY ${AWS_SECRET_KEY}

ARG AWS_BUCKET
ENV AWS_BUCKET ${AWS_BUCKET}

ARG AWS_STATIC
ENV AWS_STATIC ${AWS_STATIC}

ARG JAR_FILE=./build/libs/*.jar
COPY ${JAR_FILE} application.jar
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ dependencies {
implementation(Dependencies.APACHE_POI_OOXML)

implementation(Dependencies.GSON)

implementation(Dependencies.AWS)
}

tasks.withType<KotlinCompile> {
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ object Dependencies {
const val APACHE_POI_OOXML = "org.apache.poi:poi-ooxml:${DependencyVersions.APACHE_POI}"

const val GSON = "com.google.code.gson:gson:${DependencyVersions.GSON}"

const val AWS = "com.amazonaws:aws-java-sdk-s3:${DependencyVersions.AWS}"
}
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/DependencyVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ object DependencyVersions {
const val QUERYDSL = "5.0.0"
const val APACHE_POI = "5.2.5"
const val GSON = "2.8.7"
const val AWS = "1.12.281"
}
42 changes: 42 additions & 0 deletions src/main/kotlin/dsm/pick2024/domain/bug/AddBugService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dsm.pick2024.domain.bug

import dsm.pick2024.domain.bug.presentation.dto.request.BugRequest
import dsm.pick2024.domain.user.facade.UserFacade
import dsm.pick2024.infrastructure.feign.client.dto.request.DiscordMessageRequest
import dsm.pick2024.infrastructure.feign.client.DiscordBugClient
import dsm.pick2024.infrastructure.s3.FileUtil
import dsm.pick2024.infrastructure.s3.PathList
import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Service

@Service
class AddBugService(
private val fileUtil: FileUtil,
private val discordBugClient: DiscordBugClient,
private val userFacade: UserFacade
) {
@Async
fun bugAlarm(request: BugRequest) {
val message = DiscordMessageRequest(
content = "# 🚨 버그 제보",
embeds = listOf(
DiscordMessageRequest.Embed(
title = "ℹ️ 버그 정보",
description = """
### 🕖 버그 제목
${request.title}
### 🔗 버그 내용
${request.content}
### 📄 이미지
```
${request.fileName?.let { fileUtil.generateObjectUrl(request.fileName, PathList.BUG) }}
```
### 🧑🏻‍💻 버그 제보자
${userFacade.currentUser().name}
""".trimIndent()
)
)
)
discordBugClient.sendMessage(message)
}
}
14 changes: 14 additions & 0 deletions src/main/kotlin/dsm/pick2024/domain/bug/UploadBugImageService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dsm.pick2024.domain.bug

import dsm.pick2024.infrastructure.s3.ImageService
import dsm.pick2024.infrastructure.s3.PathList
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile

@Service
class UploadBugImageService(
private val imageService: ImageService
) {
fun uploadBugImage(file: MultipartFile) =
imageService.uploadImage(file, PathList.BUG)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dsm.pick2024.domain.bug.presentation

import dsm.pick2024.domain.bug.AddBugService
import dsm.pick2024.domain.bug.UploadBugImageService
import dsm.pick2024.domain.bug.presentation.dto.request.BugRequest
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestPart
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile

@Tag(name = "버그제보 api")
@RestController
@RequestMapping("/bug")
class BugController(
private val uploadBugImageService: UploadBugImageService,
private val addBugService: AddBugService
) {

@Operation(summary = "버그제보 이미지 업로드 API")
@ResponseStatus(value = HttpStatus.OK)
@PostMapping("/upload")
fun uploadBugImage(
@RequestPart(name = "file") file: MultipartFile
) =
uploadBugImageService.uploadBugImage(file)

@Operation(summary = "버그제부 문자 전송 API")
@ResponseStatus(value = HttpStatus.CREATED)
@PostMapping("/message")
fun sendBugMessage(
@RequestBody bugRequest: BugRequest
) =
addBugService.bugAlarm(bugRequest)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dsm.pick2024.domain.bug.presentation.dto.request

data class BugRequest(
val title: String,
val content: String,
val fileName: String?
)
29 changes: 29 additions & 0 deletions src/main/kotlin/dsm/pick2024/global/config/aws/AwsConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dsm.pick2024.global.config.aws

import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class AwsConfig(
@Value("\${cloud.aws.credentials.accessKey}")
private val accessKey: String,
@Value("\${cloud.aws.credentials.secretKey}")
private val secretKey: String,
@Value("\${cloud.aws.region.static}")
private val region: String
) {
@Bean
fun amazonS3(): AmazonS3 {
val awsCredentials: AWSCredentials = BasicAWSCredentials(accessKey, secretKey)
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(AWSStaticCredentialsProvider(awsCredentials))
.build()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dsm.pick2024.global.error

import dsm.pick2024.global.discord.DiscordController
import dsm.pick2024.infrastructure.discord.DiscordComponet
import dsm.pick2024.global.error.exception.PickException
import org.springframework.context.MessageSource
import org.springframework.core.env.Environment
Expand All @@ -14,7 +14,7 @@ import java.io.Serializable
@RestControllerAdvice
class GlobalExceptionHandler(
private val messageSource: MessageSource,
private val discordController: DiscordController,
private val discordComponet: DiscordComponet,
private val environment: Environment
) {

Expand All @@ -30,7 +30,7 @@ class GlobalExceptionHandler(
@ExceptionHandler(Exception::class)
fun exception(e: PickException, request: WebRequest): ResponseEntity<Any>? {
if (!listOf(environment.activeProfiles).contains<Serializable?>("local")) {
discordController.sendDiscordAlarm(e, request)
discordComponet.sendDiscordAlarm(e, request)
return ResponseEntity(
ErrorResponse(e.errorCode.status, e.message),
HttpStatus.valueOf(e.errorCode.status)
Expand Down
36 changes: 15 additions & 21 deletions src/main/kotlin/dsm/pick2024/global/error/exception/ErrorCode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,38 @@ enum class ErrorCode(
val status: Int,
val message: String
) {
FEIGN_BAD_REQUEST(400, "Feign Bad Request"),
FEIGN_UNAUTHORIZED(401, "Feign UnAuthorized"),
FEIGN_FORBIDDEN(403, "Feign Forbidden"),
FEIGN_SERVER_ERROR(500, "Feign Server Error"),

USER_NOT_FOUND(404, "User Not Found"),
EXISTS_SELF_STUDY_TEACHER(409, "Exists Self Study Teacher"),
ALREADY_APPLYING_EARLY_RETURN(409, "Already applying For Early Return Application"),
ALREADY_APPLYING_PICNIC(409, "Already applying For Picnic Application"),
ALREADY_APPLYING_MOVEMENT(409, "Already applying for movement"),

FEIGN_UNAUTHORIZED(401, "Feign UnAuthorized"),
PASSWORD_MISS_MATCH(401, "Password Miss Match"),
INVALID_TOKEN(401, "Invalid Token"),
EXPIRED_TOKEN(401, "Expired Token"),

USER_NOT_FOUND(404, "User Not Found"),
ADMIN_NOT_FOUND(404, "Admin Not Found"),

SELF_STUDY_NOT_FOUND(404, "Self Study Not Found"),
EXISTS_SELF_STUDY_TEACHER(409, "Exists Self Study Teacher"),

EARLY_RETURN_NOT_FOUND(404, "Early Return Application Not Found"),
ALREADY_APPLYING_EARLY_RETURN(409, "Already applying For Early Return Application"),

APPLICATION_NOT_FOUND(404, "Application Not Found"),
ALREADY_APPLYING_MOVEMENT(409, "Already applying for movement"),
STATUS_NOT_FOUND(404, "Status Not Found"),

CLASSROOM_NOT_FOUND(404, "Classroom Not Found"),

WEEKEND_MEAL_NOT_FOUND(404, "WeekendMeal Not Found"),

ALREADY_APPLYING_PICNIC(409, "Already applying For Picnic Application"),

INVALID_TOKEN(401, "Invalid Token"),
EXPIRED_TOKEN(401, "Expired Token"),

CLUB_NOT_FOUND(404, "Club Not Found"),

NOTICE_NOT_FOUND(404, "Notice Not Found"),

SCHEDULE_NOT_FOUND(404, "Schedule Not Found"),

NOT_ADMIN(403, "Not an Admin"),
NOT_STUDENT(403, "Not an Student"),

FEIGN_BAD_REQUEST(400, "Feign Bad Request"),
FILE_IS_EMPTY(400, "File does not exist"),
BAD_FILE_EXTENSION(400, "File Extension is invalid"),

// Internal Server Error
INTERNAL_SERVER_ERROR(500, "Internal Server Error")
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
FEIGN_SERVER_ERROR(500, "Feign Server Error")
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dsm.pick2024.global.discord
package dsm.pick2024.infrastructure.discord

import dsm.pick2024.global.discord.DiscordMessage.Embed
import dsm.pick2024.infrastructure.feign.client.DiscordClient
import dsm.pick2024.infrastructure.feign.client.dto.request.DiscordMessageRequest.Embed
import dsm.pick2024.infrastructure.feign.client.DiscordProdClient
import dsm.pick2024.infrastructure.feign.client.DiscordStagClient
import dsm.pick2024.infrastructure.feign.client.dto.request.DiscordMessageRequest
import org.springframework.core.env.Environment
import org.springframework.stereotype.Component
import org.springframework.web.context.request.ServletWebRequest
Expand All @@ -11,15 +13,16 @@ import java.io.StringWriter
import java.time.LocalDateTime

@Component
class DiscordController(
private val discordClient: DiscordClient,
class DiscordComponet(
private val discordStagClient: DiscordStagClient,
private val discordProdClient: DiscordProdClient,
private val environment: Environment
) {
fun sendDiscordAlarm(e: Exception, request: WebRequest) {
if (isProductionEnvironment()) {
discordClient.prodSendAlarm(createMessage(e, request))
discordProdClient.prodSendAlarm(createMessage(e, request))
} else {
discordClient.stagSendAlarm(createMessage(e, request))
discordStagClient.stagSendAlarm(createMessage(e, request))
}
}

Expand All @@ -28,8 +31,8 @@ class DiscordController(
return "prod" in activeProfiles
}

private fun createMessage(e: Exception, request: WebRequest): DiscordMessage {
return DiscordMessage(
private fun createMessage(e: Exception, request: WebRequest): DiscordMessageRequest {
return DiscordMessageRequest(
content = "# 🚨 에러 발생",
embeds = listOf(
Embed(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.google.gson.Gson
import dsm.pick2024.domain.meal.entity.MealJpaEntity
import dsm.pick2024.infrastructure.feign.client.NeisFeignClient
import dsm.pick2024.infrastructure.feign.client.property.NeisFeignClientRequestProperty
import dsm.pick2024.infrastructure.feign.client.response.NeisFeignClientMealServiceDietInfoResponse
import dsm.pick2024.infrastructure.feign.client.dto.response.NeisFeignClientMealServiceDietInfoResponse
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import java.time.LocalDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.google.gson.Gson
import dsm.pick2024.domain.schedule.entity.ScheduleJpaEntity
import dsm.pick2024.infrastructure.feign.client.NeisFeignClient
import dsm.pick2024.infrastructure.feign.client.property.NeisFeignClientRequestProperty
import dsm.pick2024.infrastructure.feign.client.response.NeisFeignClientScheduleResponse
import dsm.pick2024.infrastructure.feign.client.dto.response.NeisFeignClientScheduleResponse
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import org.springframework.beans.factory.annotation.Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.google.gson.Gson
import dsm.pick2024.domain.timetable.entity.TimetableJpaEntity
import dsm.pick2024.infrastructure.feign.client.NeisFeignClient
import dsm.pick2024.infrastructure.feign.client.property.NeisFeignClientRequestProperty
import dsm.pick2024.infrastructure.feign.client.response.NeisFeignClientTimetableResponse
import dsm.pick2024.infrastructure.feign.client.dto.response.NeisFeignClientTimetableResponse
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import org.springframework.beans.factory.annotation.Value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dsm.pick2024.infrastructure.feign.client

import dsm.pick2024.infrastructure.feign.client.dto.request.DiscordMessageRequest
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody

@FeignClient(name = "discord-bug-message-client", url = "\${discord.webhook.message}")
interface DiscordBugClient {
@PostMapping
fun sendMessage(
@RequestBody message: DiscordMessageRequest
)
}

This file was deleted.

Loading

0 comments on commit f700150

Please sign in to comment.