Skip to content

Commit

Permalink
Api-v0.0.3-8
Browse files Browse the repository at this point in the history
  • Loading branch information
kdomo authored Jul 10, 2023
2 parents cb0eb71 + ca880bd commit 9a9035e
Show file tree
Hide file tree
Showing 18 changed files with 79 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.depromeet.whatnow.api.image.controller

import com.depromeet.whatnow.api.image.dto.ImageCommentElement
import com.depromeet.whatnow.api.image.dto.ImageDto
import com.depromeet.whatnow.api.image.dto.ImageUrlResponse
import com.depromeet.whatnow.api.image.dto.PromiseImageDetailResponse
import com.depromeet.whatnow.api.image.dto.PromiseImageResponse
Expand Down Expand Up @@ -50,8 +51,8 @@ class ImageController(
@PathVariable imageKey: String,
@RequestParam fileExtension: ImageFileExtension,
@RequestParam promiseImageCommentType: PromiseImageCommentType,
) {
successUseCase.promiseUploadImageSuccess(promiseId, imageKey, fileExtension, promiseImageCommentType)
): ImageDto {
return successUseCase.promiseUploadImageSuccess(promiseId, imageKey, fileExtension, promiseImageCommentType)
}

@Tag(name = "6-1 [약속 이미지]")
Expand Down Expand Up @@ -94,7 +95,7 @@ class ImageController(
@Tag(name = "6-2 [유저 이미지]")
@Operation(summary = "유저 프로필 이미지 업로드 성공 요청")
@PostMapping("/{imageKey}/users/me")
fun userUploadImageSuccess(@PathVariable imageKey: String, @RequestParam fileExtension: ImageFileExtension) {
successUseCase.userUploadImageSuccess(imageKey, fileExtension)
fun userUploadImageSuccess(@PathVariable imageKey: String, @RequestParam fileExtension: ImageFileExtension): ImageDto {
return successUseCase.userUploadImageSuccess(imageKey, fileExtension)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.depromeet.whatnow.api.image.dto

data class ImageDto(
val imageUrl: String,
) {
companion object {
fun from(imageUrl: String): ImageDto {
return ImageDto(imageUrl)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.depromeet.whatnow.api.image.usecase

import com.depromeet.whatnow.annotation.UseCase
import com.depromeet.whatnow.api.image.dto.ImageDto
import com.depromeet.whatnow.config.s3.ImageFileExtension
import com.depromeet.whatnow.config.security.SecurityUtils
import com.depromeet.whatnow.domains.image.domain.PromiseImageCommentType
Expand All @@ -15,13 +16,21 @@ class ImageUploadSuccessUseCase(
imageKey: String,
fileExtension: ImageFileExtension,
promiseImageCommentType: PromiseImageCommentType,
) {
): ImageDto {
val currentUserId: Long = SecurityUtils.currentUserId
imageDomainService.promiseImageUploadSuccess(currentUserId, promiseId, imageKey, fileExtension, promiseImageCommentType)
val imageUrl = imageDomainService.promiseImageUploadSuccess(
currentUserId,
promiseId,
imageKey,
fileExtension,
promiseImageCommentType,
)
return ImageDto.from(imageUrl)
}

fun userUploadImageSuccess(imageKey: String, fileExtension: ImageFileExtension) {
fun userUploadImageSuccess(imageKey: String, fileExtension: ImageFileExtension): ImageDto {
val currentUserId: Long = SecurityUtils.currentUserId
imageDomainService.userImageUploadSuccess(currentUserId, imageKey, fileExtension)
val imageUrl = imageDomainService.userImageUploadSuccess(currentUserId, imageKey, fileExtension)
return ImageDto.from(imageUrl)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.depromeet.whatnow.annotation.Helper
import com.depromeet.whatnow.api.NcpLocalSearchClient
import com.depromeet.whatnow.api.dto.NcpMapInfoResponse
import com.depromeet.whatnow.config.NcpProperties
import com.depromeet.whatnow.consts.NCP_LOCAL_SEARCH_DISPLAY_COUNT

@Helper
class NcpHelper(
Expand All @@ -14,6 +15,6 @@ class NcpHelper(

// 검색 키워드 조회
fun getLocalSearch(keyword: String): NcpMapInfoResponse {
return ncpClient.searchByKeyword(ncpPropertie.accessKey, ncpPropertie.secretKey, keyword)
return ncpClient.searchByKeyword(ncpPropertie.accessKey, ncpPropertie.secretKey, NCP_LOCAL_SEARCH_DISPLAY_COUNT, keyword)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import com.depromeet.whatnow.common.vo.PlaceVo
import com.depromeet.whatnow.domains.promise.adaptor.PromiseAdaptor
import com.depromeet.whatnow.domains.promise.domain.Promise
import com.depromeet.whatnow.domains.promise.service.PromiseDomainService
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime

@UseCase
class PromiseRegisterUseCase(
val promiseAdaptor: PromiseAdaptor,
val promiseDomainService: PromiseDomainService,
) {
@Transactional
fun createPromise(promiseRequest: PromiseRequest): PromiseDto {
val promise = promiseDomainService.save(
Promise(
Expand All @@ -23,6 +25,7 @@ class PromiseRegisterUseCase(
endTime = promiseRequest.endTime,
),
)
promise.createPromiseEvent()
return PromiseDto.from(promise)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.given
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
Expand All @@ -33,8 +34,9 @@ class PromiseImageUploadSuccessUseCaseTest {
@Test
fun `약속 이미지 업로드 성공 요청시 정상적이라면 에러가 발생하지 않는다`() {
// given
given(imageDomainService.promiseImageUploadSuccess(1, 1, "imageKey", ImageFileExtension.JPG, PromiseImageCommentType.SORRY_LATE))
.willReturn("imageUrl")
// when

// then
assertThatCode {
imageUploadSuccessUseCase.promiseUploadImageSuccess(1, "imageKey", ImageFileExtension.JPG, PromiseImageCommentType.SORRY_LATE)
Expand All @@ -44,7 +46,8 @@ class PromiseImageUploadSuccessUseCaseTest {
@Test
fun `유저 프로필 업로드 성공 요청시 정상적이라면 에러가 발생하지 않는다`() {
// given

given(imageDomainService.userImageUploadSuccess(1, "imageKey", ImageFileExtension.JPG))
.willReturn("imageUrl")
// when

// then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const val DEV = "dev"
const val LOCAL = "local"
const val WITHDRAW_PREFIX = "withdraw"
const val RADIUS_WAIT_CONFIRM = 200
const val SLACK_MAX_LENGTH = 1000

const val NCP_LOCAL_SEARCH_DISPLAY_COUNT = 10
const val IMAGE_DOMAIN = "https://image.whatnow.kr"
const val ASSERT_IMAGE_DOMAIN = "https://image.whatnow.kr/assert"
const val USER_DEFAULT_PROFILE_IMAGE = "https://image.whatnow.kr/assert/users/default.svg"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ class ImageDomainService(
imageKey: String,
fileExtension: ImageFileExtension,
promiseImageCommentType: PromiseImageCommentType,
) {
): String {
val promiseUser = promiseUserAdapter.findByPromiseIdAndUserId(promiseId, userId)
validatePromiseUserType(promiseUser.promiseUserType!!, promiseImageCommentType)

val imageUrl = IMAGE_DOMAIN + "/" + springEnvironmentHelper.activeProfile + "/" + "promise/$promiseId/$imageKey"
promiseImageAdapter.save(
PromiseImage.of(promiseId, userId, imageUrl, imageKey, fileExtension, promiseImageCommentType),
)
return imageUrl
}

@Transactional
fun userImageUploadSuccess(userId: Long, imageKey: String, fileExtension: ImageFileExtension) {
fun userImageUploadSuccess(userId: Long, imageKey: String, fileExtension: ImageFileExtension): String {
val imageUrl = IMAGE_DOMAIN + "/" + springEnvironmentHelper.activeProfile + "/" + "user/$userId/$imageKey"
userImageAdapter.save(UserImage.of(userId, imageUrl, imageKey, fileExtension))
return imageUrl
}

private fun validatePromiseUserType(promiseUserType: PromiseUserType, promiseImageCommentType: PromiseImageCommentType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import java.time.LocalDateTime
import javax.persistence.Column
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.PostPersist
import javax.persistence.Table

@Entity
Expand All @@ -33,7 +33,7 @@ class Promise(
@Embedded
var meetPlace: PlaceVo? = null,

@Enumerated
@Enumerated(EnumType.STRING)
var promiseType: PromiseType = PromiseType.BEFORE,

@Id
Expand All @@ -44,7 +44,6 @@ class Promise(
// 차후 이벤트 domain 설계 되면 생성시에 Domain 계층에서 validate 하겠습니다
// var promiseValidator: PromiseValidator,
) : BaseTimeEntity() {
@PostPersist
fun createPromiseEvent() {
Events.raise(PromiseRegisterEvent(this.id!!, this.mainUserId))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import com.depromeet.whatnow.events.domainEvent.PromiseUserRegisterEvent
import javax.persistence.Column
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.PostPersist
import javax.persistence.PostUpdate
import javax.persistence.Table

Expand All @@ -23,10 +24,10 @@ class PromiseUser(
var userId: Long,

@Embedded
var userLocation: CoordinateVo? = null,
var userLocation: CoordinateVo = CoordinateVo(0.0, 0.0),

@Embedded
var promiseUserType: PromiseUserType? = PromiseUserType.READY,
@Enumerated(EnumType.STRING)
var promiseUserType: PromiseUserType = PromiseUserType.READY,

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -41,7 +42,6 @@ class PromiseUser(
Events.raise(PromiseUserCancelEvent(this.promiseId, this.userId, this.id!!))
}

@PostPersist
fun createPromiseUserEvent() {
Events.raise(PromiseUserRegisterEvent(this.promiseId, this.userId, this.id!!))
}
Expand All @@ -56,10 +56,10 @@ class PromiseUser(
}

fun updatePromiseUserType(promiseUserType: PromiseUserType?) {
this.promiseUserType = promiseUserType
this.promiseUserType = promiseUserType!!
}
fun updatePromiseUserLocation(userLocation: CoordinateVo?) {
this.userLocation = userLocation
this.userLocation = userLocation!!
}
fun userLocationInit() {
this.userLocation = CoordinateVo(0.0, 0.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUser
import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType
import com.google.common.geometry.S2LatLng
import org.springframework.stereotype.Service
import javax.transaction.Transactional
import org.springframework.transaction.annotation.Transactional

@Service
class PromiseUserDomainService(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.depromeet.whatnow.events.handler

import com.depromeet.whatnow.annotation.Handler
import com.depromeet.whatnow.common.vo.CoordinateVo
import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUser
import com.depromeet.whatnow.domains.promiseuser.service.PromiseUserDomainService
import com.depromeet.whatnow.events.domainEvent.PromiseRegisterEvent
Expand All @@ -19,6 +20,10 @@ class PromiseRegisterEventHandler(
val promiseUser = PromiseUser(
promiseId = promiseRegisterEvent.promiseId,
userId = promiseRegisterEvent.userId,
userLocation = CoordinateVo(
latitude = 0.0,
longitude = 0.0,
),
)
promiseUserDomainService.createPromiseUser(promiseUser)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface NcpLocalSearchClient {
fun searchByKeyword(
@RequestHeader("X-Naver-Client-Id") accessKey: String,
@RequestHeader("X-Naver-Client-Secret") secretKey: String,
@RequestParam display: Int = 10,
@RequestParam query: String,
): NcpMapInfoResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SlackAsyncErrorSender(
fun execute(cachingRequest: ContentCachingRequestWrapper, userId: Long) {
val url = cachingRequest.requestURL.toString()
val method = cachingRequest.method
val body = objectMapper.readTree(cachingRequest.contentAsByteArray.contentToString())
val body = objectMapper.readTree(cachingRequest.contentAsByteArray.decodeToString())
val errorUserIP = cachingRequest.remoteAddr
val layoutBlocks: MutableList<LayoutBlock> = ArrayList()
layoutBlocks.add(
Expand Down Expand Up @@ -65,8 +65,8 @@ class SlackAsyncErrorSender(

val url = cachingRequest.requestURL.toString()
val method = cachingRequest.method
val body = objectMapper.readTree(cachingRequest.contentAsByteArray.contentToString())

val body = objectMapper.readTree(cachingRequest.contentAsByteArray.decodeToString())
println(body)
val errorMessage = e.message
val errorStack = slackProvider.getErrorStack(e)
val errorUserIP = cachingRequest.remoteAddr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.depromeet.whatnow.api.config.slack
import com.depromeet.whatnow.annotation.Helper
import com.depromeet.whatnow.config.slack.SlackProperties
import com.depromeet.whatnow.config.slack.SlackProperties.SlackSecret
import com.depromeet.whatnow.consts.SLACK_MAX_LENGTH
import com.slack.api.model.block.LayoutBlock
import org.springframework.scheduling.annotation.Async
import java.util.Arrays
Expand All @@ -13,16 +14,15 @@ class SlackErrorNotificationProvider(
val slackProperties: SlackProperties,
) {
var slackWebHook: SlackSecret = slackProperties.webhook
val MAX_LENGTH = 500

fun getErrorStack(throwable: Throwable): String {
val exceptionAsStrings = Arrays.toString(throwable.stackTrace)
val cutLength = Math.min(exceptionAsStrings.length, MAX_LENGTH)
val cutLength = Math.min(exceptionAsStrings.length, SLACK_MAX_LENGTH)
return exceptionAsStrings.substring(0, cutLength)
}

@Async
fun sendNotification(layoutBlocks: List<LayoutBlock>) {
slackHelper.sendNotification(slackWebHook.channelId, layoutBlocks)
slackHelper.sendNotification(slackWebHook.url, slackWebHook.token, slackWebHook.channelId, layoutBlocks)
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
package com.depromeet.whatnow.api.config.slack

import com.depromeet.whatnow.helper.SpringEnvironmentHelper
import com.slack.api.methods.MethodsClient
import com.slack.api.Slack
import com.slack.api.methods.SlackApiException
import com.slack.api.methods.request.chat.ChatPostMessageRequest
import com.slack.api.model.block.LayoutBlock
import com.slack.api.webhook.Payload
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component

@Component
class SlackHelper(
val springEnvironmentHelper: SpringEnvironmentHelper,
val methodsClient: MethodsClient,
) {
val logger: Logger = LoggerFactory.getLogger(SlackHelper::class.java)
fun sendNotification(CHANNEL_ID: String, layoutBlocks: List<LayoutBlock>) {
fun sendNotification(url: String, token: String, channelId: String, layoutBlocks: List<LayoutBlock>) {
if (!springEnvironmentHelper.isProdAndDevProfile) {
// Local 환경일 경우 적용
// if (!springEnvironmentHelper.isLocalProfile) {
return
}
val chatPostMessageRequest = ChatPostMessageRequest.builder()
.channel(CHANNEL_ID)
.text("")
val methodsClient = Slack.getInstance()
val payload = Payload.builder()
.text("Slack Notification")
.username("WhatNow-Bot")
.blocks(layoutBlocks)
.build()
try {
methodsClient.chatPostMessage(chatPostMessageRequest)
methodsClient.send(url, payload)
} catch (slackApiException: SlackApiException) {
logger.error(slackApiException.toString())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class SlackServiceNotificationProvider(
var slackWebHook: SlackSecret = slackProperties.webhook

fun sendNotification(layoutBlocks: MutableList<LayoutBlock>) {
slackHelper.sendNotification(slackWebHook.channelId, layoutBlocks)
slackHelper.sendNotification(slackWebHook.channelId, slackWebHook.token, slackWebHook.channelId, layoutBlocks)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class NcpLocalSearchClientTest() {
.withBody(responseJson),
),
)
val response = client.searchByKeyword(accessKey, secretKey, query)
val response = client.searchByKeyword(accessKey, secretKey, 10, query)
assertEquals(response.items.size, 1)
}
}

0 comments on commit 9a9035e

Please sign in to comment.