Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEV-289] 파일서버 분리 #109

Merged
merged 8 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions nginx.dev.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ http {
keepalive 10;
}

upstream file {
zone upstreams 64K;
server host.docker.internal:4010 fail_timeout=5s;
keepalive 10;
}

upstream client {
zone upstream 64K;
server host.docker.internal:3000 fail_timeout=5s;
Expand All @@ -31,6 +37,12 @@ http {
proxy_set_header Connection "";
}

location /api/file {
proxy_pass http://file/file;
proxy_http_version 1.1;
proxy_set_header Connection "";
}

location /api/waiting {
proxy_pass http://waiting/waiting;
proxy_http_version 1.1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public class RequestMatcherHolder {
new RequestInfo(POST, "/stress-test/**", null),

// files
new RequestInfo(POST, "/files/**", RoleEnum.SELLER),
new RequestInfo(GET, "/files/**", null)
new RequestInfo(GET, "/meta-file/**", RoleEnum.SELLER)
);
private final ConcurrentHashMap<String, RequestMatcher> reqMatcherCacheMap = new ConcurrentHashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.tiketeer.Tiketeer.auth.SecurityContextHelper;
import com.tiketeer.Tiketeer.domain.ticketing.controller.dto.GetAllTicketingsResponseDto;
Expand Down Expand Up @@ -74,24 +72,22 @@ public ResponseEntity<ApiResponse<GetTicketingResponseDto>> getTicketing(@PathVa
return ResponseEntity.status(HttpStatus.OK).body(responseBody);
}

@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PostMapping
public ResponseEntity<ApiResponse<PostTicketingResponseDto>> postTicketing(
@Valid @RequestPart(value = "request") PostTicketingRequestDto request,
@RequestPart(value = "thumbnail", required = false) MultipartFile thumbnail
@Valid @RequestBody PostTicketingRequestDto request
) {
var memberEmail = securityContextHelper.getEmailInToken();
var result = createTicketingUseCase.createTicketing(request.convertToDto(memberEmail, thumbnail));
var result = createTicketingUseCase.createTicketing(request.convertToDto(memberEmail));
var responseBody = ApiResponse.wrap(PostTicketingResponseDto.convertFromDto(result));
return ResponseEntity.status(HttpStatus.CREATED).body(responseBody);
}

@PatchMapping(path = "/{ticketingId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PatchMapping(path = "/{ticketingId}")
public ResponseEntity<?> patchTicketing(@PathVariable String ticketingId,
@Valid @RequestPart(value = "request") PatchTicketingRequestDto request,
@RequestPart(value = "thumbnail", required = false) MultipartFile thumbnail
@Valid @RequestBody PatchTicketingRequestDto request
) {
var memberEmail = securityContextHelper.getEmailInToken();
updateTicketingUseCase.updateTicketing(request.convertToDto(ticketingId, memberEmail, thumbnail));
updateTicketingUseCase.updateTicketing(request.convertToDto(ticketingId, memberEmail));
return ResponseEntity.ok().build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import java.time.LocalDateTime;
import java.util.UUID;

import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.tiketeer.Tiketeer.domain.ticketing.usecase.dto.UpdateTicketingCommandDto;

Expand Down Expand Up @@ -37,6 +35,8 @@ public class PatchTicketingRequestDto {
@NotNull
private final Long price;

private final String thumbnailPath;

@NotNull
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
private final LocalDateTime eventTime;
Expand All @@ -53,6 +53,7 @@ public class PatchTicketingRequestDto {
public PatchTicketingRequestDto(
@NotBlank String title,
String description,
String thumbnailPath,
@NotBlank String location,
@NotBlank String category,
@NotNull Integer runningMinutes,
Expand All @@ -71,13 +72,13 @@ public PatchTicketingRequestDto(
this.eventTime = eventTime;
this.saleStart = saleStart;
this.saleEnd = saleEnd;
this.thumbnailPath = thumbnailPath;
}

public UpdateTicketingCommandDto convertToDto(String ticketingId, String memberEmail, MultipartFile thumbnail) {
public UpdateTicketingCommandDto convertToDto(String ticketingId, String memberEmail) {
return UpdateTicketingCommandDto.builder()
.ticketingId(UUID.fromString(ticketingId))
.email(memberEmail)
.thumbnail(thumbnail)
.title(title)
.description(description)
.location(location)
Expand All @@ -88,6 +89,7 @@ public UpdateTicketingCommandDto convertToDto(String ticketingId, String memberE
.eventTime(eventTime)
.saleStart(saleStart)
.saleEnd(saleEnd)
.thumbnailPath(thumbnailPath)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.time.LocalDateTime;

import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.tiketeer.Tiketeer.domain.ticketing.usecase.dto.CreateTicketingCommandDto;

Expand Down Expand Up @@ -40,6 +38,8 @@ public class PostTicketingRequestDto {
@Positive
private final Long price;

private final String thumbnailPath;

@NotNull
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
private final LocalDateTime eventTime;
Expand All @@ -60,7 +60,7 @@ public PostTicketingRequestDto(
@NotBlank String category,
@NotNull Integer runningMinutes,
@NotNull Integer stock,
@NotNull Long price,
@NotNull Long price, String thumbnailPath,
@NotNull LocalDateTime eventTime,
@NotNull LocalDateTime saleStart,
@NotNull LocalDateTime saleEnd) {
Expand All @@ -71,15 +71,16 @@ public PostTicketingRequestDto(
this.runningMinutes = runningMinutes;
this.stock = stock;
this.price = price;
this.thumbnailPath = thumbnailPath;
this.eventTime = eventTime;
this.saleStart = saleStart;
this.saleEnd = saleEnd;
}

public CreateTicketingCommandDto convertToDto(String memberEmail, MultipartFile thumbnail) {
public CreateTicketingCommandDto convertToDto(String memberEmail) {
return CreateTicketingCommandDto.builder()
.memberEmail(memberEmail)
.thumbnail(thumbnail)
.thumbnailPath(thumbnailPath)
.title(title)
.description(description)
.location(location)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.tiketeer.Tiketeer.domain.ticketing.usecase;

import java.io.IOException;
import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.tiketeer.Tiketeer.constant.StorageEnum;
import com.tiketeer.Tiketeer.domain.member.exception.MemberNotFoundException;
Expand All @@ -19,10 +17,6 @@
import com.tiketeer.Tiketeer.domain.ticketing.service.TicketingStockService;
import com.tiketeer.Tiketeer.domain.ticketing.usecase.dto.CreateTicketingCommandDto;
import com.tiketeer.Tiketeer.domain.ticketing.usecase.dto.CreateTicketingResultDto;
import com.tiketeer.Tiketeer.infra.storage.FileValidator;
import com.tiketeer.Tiketeer.infra.storage.StorageFile;
import com.tiketeer.Tiketeer.infra.storage.exception.UploadFileRuntimeException;
import com.tiketeer.Tiketeer.infra.storage.strategy.FileStorageStrategy;

import lombok.extern.slf4j.Slf4j;

Expand All @@ -32,18 +26,16 @@ public class CreateTicketingUseCase {
private final TicketingService ticketingService;
private final TicketingStockService ticketingStockService;
private final MemberRepository memberRepository;
private final FileStorageStrategy fileStorageStrategy;

@Value("${custom.policy.storage}")
private StorageEnum storageEnum;

@Autowired
public CreateTicketingUseCase(TicketingService ticketingService, TicketingStockService ticketingStockService,
MemberRepository memberRepository, FileStorageStrategy fileStorageStrategy) {
MemberRepository memberRepository) {
this.ticketingService = ticketingService;
this.ticketingStockService = ticketingStockService;
this.memberRepository = memberRepository;
this.fileStorageStrategy = fileStorageStrategy;
}

@Transactional
Expand All @@ -64,8 +56,6 @@ public CreateTicketingResultDto createTicketing(CreateTicketingCommandDto comman
var member = memberRepository.findByEmail(command.getMemberEmail())
.orElseThrow(MemberNotFoundException::new);

var fileId = uploadFile(command.getThumbnail());

var ticketing = ticketingService.saveTicketing(
Ticketing.builder()
.member(member)
Expand All @@ -79,7 +69,7 @@ public CreateTicketingResultDto createTicketing(CreateTicketingCommandDto comman
.eventTime(command.getEventTime())
.saleStart(command.getSaleStart())
.saleEnd(command.getSaleEnd())
.thumbnailPath(fileId)
.thumbnailPath(command.getThumbnailPath())
.storageEnum(storageEnum)
.build());

Expand All @@ -103,29 +93,4 @@ private boolean isSaleDurationValid(LocalDateTime baseTime,
&& saleEnd.isAfter(saleStart);
}

private void checkFileIsImage(MultipartFile multipartFile) {
if (!FileValidator.isImage(multipartFile)) {
log.error("file should be of image type {}", multipartFile.getName());
throw new UploadFileRuntimeException();
}
}

private String uploadFile(MultipartFile thumbnail) {
if (thumbnail == null) {
return null;
}
String fileId = null;
try {
checkFileIsImage(thumbnail);
StorageFile file = StorageFile.builder()
.fileName(thumbnail.getOriginalFilename())
.byteArray(thumbnail.getBytes())
.build();
fileId = fileStorageStrategy.uploadFile(file);
} catch (IOException e) {
throw new UploadFileRuntimeException();
}
return fileId;
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.tiketeer.Tiketeer.domain.ticketing.usecase;

import java.io.IOException;
import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.tiketeer.Tiketeer.constant.StorageEnum;
import com.tiketeer.Tiketeer.domain.ticketing.exception.EventTimeNotValidException;
Expand All @@ -17,10 +15,6 @@
import com.tiketeer.Tiketeer.domain.ticketing.service.TicketingService;
import com.tiketeer.Tiketeer.domain.ticketing.service.TicketingStockService;
import com.tiketeer.Tiketeer.domain.ticketing.usecase.dto.UpdateTicketingCommandDto;
import com.tiketeer.Tiketeer.infra.storage.FileValidator;
import com.tiketeer.Tiketeer.infra.storage.StorageFile;
import com.tiketeer.Tiketeer.infra.storage.exception.UploadFileRuntimeException;
import com.tiketeer.Tiketeer.infra.storage.strategy.FileStorageStrategy;

import lombok.extern.slf4j.Slf4j;

Expand All @@ -29,17 +23,14 @@
public class UpdateTicketingUseCase {
private final TicketingService ticketingService;
private final TicketingStockService ticketingStockService;
private final FileStorageStrategy fileStorageStrategy;

@Value("${custom.policy.storage}")
private StorageEnum storageEnum;

@Autowired
public UpdateTicketingUseCase(TicketingService ticketingService, TicketingStockService ticketingStockService,
FileStorageStrategy fileStorageStrategy) {
public UpdateTicketingUseCase(TicketingService ticketingService, TicketingStockService ticketingStockService) {
this.ticketingService = ticketingService;
this.ticketingStockService = ticketingStockService;
this.fileStorageStrategy = fileStorageStrategy;
}

@Transactional
Expand All @@ -65,9 +56,7 @@ public void updateTicketing(UpdateTicketingCommandDto command) {
ticketingService.validateTicketingOwnership(ticketing, command.getEmail());
ticketingService.validateTicketingMetadata(eventTime, saleStart, saleEnd);

var fileId = uploadFile(command.getThumbnail());

ticketing.setThumbnailPath(fileId);
ticketing.setThumbnailPath(command.getThumbnailPath());
ticketing.setStorageEnum(storageEnum);

ticketing.setTitle(command.getTitle());
Expand All @@ -94,28 +83,4 @@ private boolean isSaleDurationValid(LocalDateTime baseTime,
&& saleEnd.isAfter(saleStart);
}

private void checkFileIsImage(MultipartFile multipartFile) {
if (!FileValidator.isImage(multipartFile)) {
log.error("file should be of image type {}", multipartFile.getName());
throw new UploadFileRuntimeException();
}
}

private String uploadFile(MultipartFile thumbnail) {
if (thumbnail == null) {
return null;
}
String fileId = null;
try {
checkFileIsImage(thumbnail);
StorageFile file = StorageFile.builder()
.fileName(thumbnail.getOriginalFilename())
.byteArray(thumbnail.getBytes())
.build();
fileId = fileStorageStrategy.uploadFile(file);
} catch (IOException e) {
throw new UploadFileRuntimeException();
}
return fileId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.time.LocalDateTime;

import org.springframework.web.multipart.MultipartFile;

import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
Expand All @@ -22,7 +20,7 @@ public class CreateTicketingCommandDto {
private final LocalDateTime eventTime;
private final LocalDateTime saleStart;
private final LocalDateTime saleEnd;
private final MultipartFile thumbnail;
private final String thumbnailPath;
private LocalDateTime commandCreatedAt = LocalDateTime.now();

@Builder
Expand All @@ -35,7 +33,7 @@ public CreateTicketingCommandDto(
Integer runningMinutes,
Integer stock,
Long price,
MultipartFile thumbnail,
String thumbnailPath,
LocalDateTime eventTime,
LocalDateTime saleStart,
LocalDateTime saleEnd, LocalDateTime commandCreatedAt) {
Expand All @@ -50,7 +48,7 @@ public CreateTicketingCommandDto(
this.eventTime = eventTime;
this.saleStart = saleStart;
this.saleEnd = saleEnd;
this.thumbnail = thumbnail;
this.thumbnailPath = thumbnailPath;
if (commandCreatedAt != null) {
this.commandCreatedAt = commandCreatedAt;
}
Expand Down
Loading
Loading