Skip to content

Commit

Permalink
Merge pull request #139 from Genti2024/fix/create-pgreq
Browse files Browse the repository at this point in the history
Fix/create pgreq
  • Loading branch information
BYEONGRYEOL authored Sep 2, 2024
2 parents 52d6bac + ebaa929 commit 0fc9be1
Show file tree
Hide file tree
Showing 13 changed files with 339 additions and 154 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.gt.genti.picturegeneraterequest.service;

import static com.gt.genti.constants.RedisConstants.LOCK_TTL_SECONDS;
import static com.gt.genti.picturegeneraterequest.service.mapper.PictureGenerateRequestStatusForUser.*;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -60,6 +63,7 @@ public class PictureGenerateRequestService implements PictureGenerateRequestUseC
private final PictureGenerateFailedEventPublisher pictureGenerateFailedEventPublisher;
private final PGRESStatusToPGRESStatusForAdminMapper pgresStatusToPGRESStatusForAdminMapper = new PGRESStatusToPGRESStatusForAdminMapper();
private final PGREQStatusToPGREQStatusForUserMapper pgreqStatusToPGREQStatusForUserMapper = new PGREQStatusToPGREQStatusForUserMapper();
private final RedisTemplate<String, String> redisTemplate;

@Override
public Page<PGREQAdminMatchedDetailFindByAdminResponseDto> getAllAdminMatched(Pageable pageable) {
Expand Down Expand Up @@ -179,43 +183,69 @@ public PGREQStatusResponseDto getPendingPGREQStatusIfExists(Long userId) {
@Override
public PictureGenerateRequest createPGREQ(Long userId, PGREQSaveCommand pgreqSaveCommand) {
User foundUser = findUserById(userId);
String posePictureKey = "";
PicturePose foundPicturePose = null;
if (!Objects.isNull(pgreqSaveCommand.getPosePictureKey())) {
posePictureKey = pgreqSaveCommand.getPosePictureKey();
String finalPosePictureKey = posePictureKey;
foundPicturePose = pictureService.findByKeyPicturePose(posePictureKey).orElseGet(() -> {
log.info("""
%s 유저가 요청에 포함한 포즈참고사진 key [%s] 기존 사진을 찾을 수 없어 신규 저장""".formatted(foundUser.getEmail(),
finalPosePictureKey));
return pictureService.updatePicture(
CreatePicturePoseCommand.builder().key(finalPosePictureKey).uploader(foundUser).build());
});
}

List<String> facePictureUrl = pgreqSaveCommand.getFacePictureKeyList();
List<PictureUserFace> uploadedFacePictureList = pictureService.updateIfNotExistsPictureUserFace(facePictureUrl,
foundUser);

String promptAdvanced = openAIService.getAdvancedPrompt(
new PromptAdvancementRequestCommand(pgreqSaveCommand.getPrompt()));
log.info(promptAdvanced);

PictureGenerateRequest createdPGREQ = PictureGenerateRequest.builder()
.requester(foundUser)
.promptAdvanced(promptAdvanced)
.prompt(pgreqSaveCommand.getPrompt())
.shotCoverage(pgreqSaveCommand.getShotCoverage())
.cameraAngle(pgreqSaveCommand.getCameraAngle())
.pictureRatio(pgreqSaveCommand.getPictureRatio())
.picturePose(foundPicturePose)
.userFacePictureList(uploadedFacePictureList)
.build();
throwIfNewPictureGenerateRequestNotAvailable(foundUser);

PictureGenerateRequest savedPGREQ = pictureGenerateRequestPort.save(createdPGREQ);
requestMatchService.matchNewRequest(savedPGREQ);
String lockKey = "LOCK:" + userId + ":" + "createPGREQ";
Boolean lockGranted = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", LOCK_TTL_SECONDS, TimeUnit.SECONDS);
if (Boolean.FALSE.equals(lockGranted)) {
throw ExpectedException.withLogging(ResponseCode.PictureGenerateRequestAlreadyProcessed);
}
try {
String posePictureKey = "";
PicturePose foundPicturePose = null;
if (!Objects.isNull(pgreqSaveCommand.getPosePictureKey())) {
posePictureKey = pgreqSaveCommand.getPosePictureKey();
String finalPosePictureKey = posePictureKey;
foundPicturePose = pictureService.findByKeyPicturePose(posePictureKey).orElseGet(() -> {
log.info("""
%s 유저가 요청에 포함한 포즈참고사진 key [%s] 기존 사진을 찾을 수 없어 신규 저장""".formatted(foundUser.getEmail(),
finalPosePictureKey));
return pictureService.updatePicture(
CreatePicturePoseCommand.builder().key(finalPosePictureKey).uploader(foundUser).build());
});
}

List<String> facePictureUrl = pgreqSaveCommand.getFacePictureKeyList();
List<PictureUserFace> uploadedFacePictureList = pictureService.updateIfNotExistsPictureUserFace(
facePictureUrl, foundUser);

String promptAdvanced = openAIService.getAdvancedPrompt(
new PromptAdvancementRequestCommand(pgreqSaveCommand.getPrompt()));
log.info(promptAdvanced);

PictureGenerateRequest createdPGREQ = PictureGenerateRequest.builder()
.requester(foundUser)
.promptAdvanced(promptAdvanced)
.prompt(pgreqSaveCommand.getPrompt())
.shotCoverage(pgreqSaveCommand.getShotCoverage())
.cameraAngle(pgreqSaveCommand.getCameraAngle())
.pictureRatio(pgreqSaveCommand.getPictureRatio())
.picturePose(foundPicturePose)
.userFacePictureList(uploadedFacePictureList)
.build();

PictureGenerateRequest savedPGREQ = pictureGenerateRequestPort.save(createdPGREQ);
requestMatchService.matchNewRequest(savedPGREQ);

return savedPGREQ;
} finally {
Boolean keyDeleted = redisTemplate.delete(lockKey);
if (Boolean.FALSE.equals(keyDeleted)) {
log.error("Redis에 key {} 값이 존재하지 않습니다.", lockKey);
}
}
}

return savedPGREQ;
private void throwIfNewPictureGenerateRequestNotAvailable(User foundUser) {
pictureGenerateRequestPort.findTopByRequesterOrderByCreatedAtDesc(foundUser)
.ifPresent(recentPictureGenerateRequest -> {
boolean isRequestProcessed = !NEW_REQUEST_AVAILABLE.equals(
pgreqStatusToPGREQStatusForUserMapper.dbToClient(
recentPictureGenerateRequest.getPictureGenerateRequestStatus()));
if (isRequestProcessed) {
throw ExpectedException.withLogging(ResponseCode.PictureGenerateRequestAlreadyProcessed);
}
});
}

private User findUserById(Long userId) {
Expand Down
5 changes: 2 additions & 3 deletions genti-api/src/main/resources/file-appender.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>./logs/app.log</file>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/genti-%d{yyyy-MM-dd}.log</fileNamePattern>
<fileNamePattern>/logs/genti-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
Expand Down
18 changes: 18 additions & 0 deletions genti-api/src/test/java/com/gt/genti/BaseTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.gt.genti;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.test.context.ActiveProfiles;

import com.gt.genti.config.ScheduleConfig;
import com.gt.genti.discord.DiscordAppender;

@SpringBootTest
@ActiveProfiles({"secret", "common", "test"})
@ComponentScan(basePackages = "com.gt.genti", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ScheduleConfig.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {DiscordAppender.class})})
public abstract class BaseTest {

}
50 changes: 21 additions & 29 deletions genti-api/src/test/java/com/gt/genti/CancelledPGREQTest.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.gt.genti;

import static com.gt.genti.TestUtils.*;
import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import com.gt.genti.TestUtils.Domain;
import com.gt.genti.TestUtils.Dto;
import com.gt.genti.config.TestConfig;
import com.gt.genti.matchingstrategy.model.RequestMatchStrategy;
import com.gt.genti.picturegeneraterequest.controller.CreatorPGREQController;
import com.gt.genti.picturegeneraterequest.controller.UserPGREQController;
import com.gt.genti.picturegeneraterequest.dto.request.PGREQSaveRequestDto;
import com.gt.genti.picturegeneraterequest.dto.response.PGREQStatusResponseDto;
Expand All @@ -19,9 +19,6 @@
import com.gt.genti.picturegeneraterequest.repository.PictureGenerateRequestRepository;
import com.gt.genti.picturegeneraterequest.service.RequestMatchService;
import com.gt.genti.picturegeneraterequest.service.mapper.PictureGenerateRequestStatusForUser;
import com.gt.genti.picturegenerateresponse.repository.PictureGenerateResponseRepository;
import com.gt.genti.picturegenerateresponse.service.PictureGenerateWorkService;
import com.gt.genti.report.service.ReportService;
import com.gt.genti.usecase.PictureGenerateRequestUseCase;
import com.gt.genti.user.model.User;
import com.gt.genti.user.model.UserRole;
Expand All @@ -37,47 +34,38 @@ public class CancelledPGREQTest {
@Autowired
UserPGREQController userPGREQController;

@Autowired
PictureGenerateWorkService pictureGenerateWorkService;

@Autowired
UserService userService;

@Autowired
ReportService reportService;

@Autowired
UserRepository userRepository;
@Autowired
PictureGenerateResponseRepository pictureGenerateResponseRepository;

@Autowired
PictureGenerateRequestRepository pictureGenerateRequestRepository;
@Autowired
private CreatorPGREQController creatorPGREQController;
@Autowired
RequestMatchService requestMatchService;


@Test
void canceledPGREQTest(){
// given
User creatorUser = getTestCreatorUser();
void canceledPGREQTest() {
// given
User creatorUser = Domain.createUser(UserRole.CREATOR);
User savedCreatorUser = userRepository.save(creatorUser);
userService.updateUserRole(savedCreatorUser.getId(), getUserRoleUpdateRequestDto(UserRole.CREATOR));
userService.updateUserRole(savedCreatorUser.getId(),
Dto.getUserRoleUpdateRequestDto(UserRole.CREATOR));

// 요청을 수행할 유저 생성
User newUser = getTestUser();
User newUser = Domain.createUser(UserRole.USER);
User savedUser = userRepository.save(newUser);

// 사진생성요청 생성 dto
PGREQSaveRequestDto pgreqSaveRequestDto = getPGREQSaveRequestDto();
PGREQSaveRequestDto pgreqSaveRequestDto = Dto.getPGREQSaveRequestDto();

// 공급자에게 매칭되기위해 매칭전략 변경
requestMatchService.changeMatchingStrategy(RequestMatchStrategy.CREATOR_ADMIN);

// 사진생성요청 생성
PictureGenerateRequest pgreq = pictureGenerateRequestUseCase.createPGREQ(savedUser.getId(), pgreqSaveRequestDto.toCommand());
PictureGenerateRequest pgreq = pictureGenerateRequestUseCase.createPGREQ(savedUser.getId(),
pgreqSaveRequestDto.toCommand());

// 강제 취소처리
pgreq.canceled();
Expand All @@ -87,7 +75,9 @@ void canceledPGREQTest(){

// when
// 현재 사진생성요청의 상태를 조회
PGREQStatusResponseDto responseDto = userPGREQController.getPendingPGRESStatus(savedUser.getId()).getBody().getResponse();
PGREQStatusResponseDto responseDto = userPGREQController.getPendingPGRESStatus(savedUser.getId())
.getBody()
.getResponse();

// then
// 취소상태여야한다.
Expand All @@ -97,16 +87,18 @@ void canceledPGREQTest(){

// when
// 사진생성요청이 취소되었음을 유저가 인지했다고 알리는 api 호출
Boolean isSuccess = userPGREQController.confirmCanceledPGREQ(savedUser.getId(), responseDto.getPictureGenerateRequestId())
.getBody().getResponse();
Boolean isSuccess = userPGREQController.confirmCanceledPGREQ(savedUser.getId(),
responseDto.getPictureGenerateRequestId()).getBody().getResponse();
assertThat(isSuccess).isTrue();
// 현재 사진생성요청의 상태를 다시 조회
PGREQStatusResponseDto responseDtoAfterConfirmCanceled = userPGREQController.getPendingPGRESStatus(savedUser.getId()).getBody().getResponse();
PGREQStatusResponseDto responseDtoAfterConfirmCanceled = userPGREQController.getPendingPGRESStatus(
savedUser.getId()).getBody().getResponse();

// then
// 새로운 요청이 가능해야한다.
assertThat(responseDtoAfterConfirmCanceled.getPictureGenerateRequestId()).isNull();
assertThat(responseDtoAfterConfirmCanceled.getStatus()).isEqualTo(PictureGenerateRequestStatusForUser.NEW_REQUEST_AVAILABLE);
assertThat(responseDtoAfterConfirmCanceled.getStatus()).isEqualTo(
PictureGenerateRequestStatusForUser.NEW_REQUEST_AVAILABLE);
assertThat(responseDtoAfterConfirmCanceled.getPictureGenerateResponse()).isNull();

}
Expand Down
4 changes: 2 additions & 2 deletions genti-api/src/test/java/com/gt/genti/MatchTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ public class MatchTest {
@Test
public void oneRequestWithAdminStrategy() {
// given
User requester = getTestUser();
User requester = Domain.createUser(UserRole.USER);
User savedUser = userRepository.save(requester);

User adminUser = getTestAdminUser();
User adminUser = Domain.createUser(UserRole.ADMIN);
User savedAdmin = userRepository.save(adminUser);
// admin으로 uploaderrole 변경시 admin creator 생성됨
userService.updateUserRole(savedAdmin.getId(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gt.genti;

import static com.gt.genti.TestUtils.*;
import static com.gt.genti.TestUtils.Dto.*;
import static com.gt.genti.picturegeneraterequest.service.mapper.PictureGenerateRequestStatusForUser.*;
import static org.assertj.core.api.Assertions.*;

Expand Down Expand Up @@ -75,16 +76,16 @@ class PictureGeneratePendingApiTest {
void newlyCreatedAndMatchedToAdminPictureGenerateRequestIsInProgresstest() {
// given
// 어드민유저, 어드민 공급자 생성
User adminUser = getTestAdminUser();
User adminUser = Domain.createUser(UserRole.ADMIN);
User savedAdminUser = userRepository.save(adminUser);
userService.updateUserRole(savedAdminUser.getId(), getUserRoleUpdateRequestDto(UserRole.ADMIN));

// 요청을 수행할 유저 생성
User newUser = getTestUser();
User newUser = Domain.createUser(UserRole.USER);
User savedUser = userRepository.save(newUser);

// 사진생성요청 생성 dto
PGREQSaveRequestDto pgreqSaveRequestDto = getPGREQSaveRequestDto();
PGREQSaveRequestDto pgreqSaveRequestDto = Dto.getPGREQSaveRequestDto();

// when
// 사진생성요청 생성
Expand All @@ -108,16 +109,16 @@ void newlyCreatedAndMatchedToAdminPictureGenerateRequestIsInProgresstest() {
void IfUserReportsRecentPictureGenerateRequestThenNew_REQUEST_AVAILABLE_Test() {
// given
// 어드민유저, 어드민 공급자 생성
User adminUser = getTestAdminUser();
User adminUser = Domain.createUser(UserRole.ADMIN);
User savedAdminUser = userRepository.save(adminUser);
userService.updateUserRole(savedAdminUser.getId(), getUserRoleUpdateRequestDto(UserRole.ADMIN));
userService.updateUserRole(savedAdminUser.getId(), Dto.getUserRoleUpdateRequestDto(UserRole.ADMIN));

// 요청을 수행할 유저 생성
User newUser = getTestUser();
User newUser = Domain.createUser(UserRole.USER);
User savedUser = userRepository.save(newUser);

// 사진생성요청 생성 dto
PGREQSaveRequestDto pgreqSaveRequestDto = getPGREQSaveRequestDto();
PGREQSaveRequestDto pgreqSaveRequestDto = Dto.getPGREQSaveRequestDto();

// when
// 사진생성요청 생성
Expand Down Expand Up @@ -165,14 +166,14 @@ void IfUserReportsRecentPictureGenerateRequestThenNew_REQUEST_AVAILABLE_Test() {
void pictureGenerateRequestCancelledByCreatorExitTest() {
// given
// 공급자 유저 생성
User creatorUser = getTestCreatorUser();
User creatorUser = Domain.createUser(UserRole.CREATOR);
User savedCreatorUser = userRepository.save(creatorUser);
userService.updateUserRole(savedCreatorUser.getId(), getUserRoleUpdateRequestDto(UserRole.CREATOR));

User roleUpdatedUser = userRepository.findById(savedCreatorUser.getId()).orElseThrow();

// 요청을 수행할 유저 생성
User newUser = getTestUser();
User newUser = Domain.createUser(UserRole.USER);
User savedUser = userRepository.save(newUser);

// 사진생성요청 생성 dto
Expand Down
Loading

0 comments on commit 0fc9be1

Please sign in to comment.