[Java] download 서버 추가 설계

이건영·2023년 9월 21일
0
post-custom-banner
  • api 서버 다운로드 요청 -> DB에 request data 저장 -> requestId 발급 -> SQS에 requestId값 전송
  • download 서버 SQS message pull -> DB에서 request data select -> download 실행

SQS Listener

public class SqsDownloadListener {

	private final UserDownloadRequestRepository userDownloadRequestRepository;
	private final DownloadRouteService downloadRouteService;
	private final DownloadQueueItemReceptionCheckService downloadQueueItemReceptionCheckService;

	@Transactional(propagation = Propagation.REQUIRED)
	@SqsListener(value = "${aws.sqs.download.name:dev-download}", deletionPolicy = SqsMessageDeletionPolicy.ALWAYS)
	public void getSQSMessage(
		@Payload Long requestId
	) {
		UserDownloadRequest downloadRequest = getDownloadRequestInfo(requestId);
		downloadRequest.receiveSuccess();

		log.info("download item listen success - [{}]", downloadRequest.getDownloadType());
		downloadRouteService.route(downloadRequest);
	}

	public UserDownloadRequest getDownloadRequestInfo(Long requestId) {
		return UserDownloadRequestRepository.findById(requestId).orElseThrow(...);
	}

}

DownloadRouteService class 생성

  • @PostConstruct를 사용하여 의존성 주입 후 downloadRequestMappingHandlers 변수 초기화
  • DownloadRequestMappingHandler interface에 선언되어 있는 route() 함수 호출
public class DownloadRouteService {

	private final ApplicationContext applicationContext;
	private List<DownloadRequestMappingHandler> downloadRequestMappingHandlers;

	@PostConstruct
	public void init() {
		this.downloadRequestMappingHandlers = newArrayList(applicationContext.getBeansOfType(DownloadRequestMappingHandler.class).values());
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void route(UserDownloadRequest downloadRequest) {

		for (DownloadRequestMappingHandler requestMappingHandler : this.downloadRequestMappingHandlers) {
			if (requestMappingHandler.route(downloadHistory.getDownloadId(), downloadRequest)) {
				return;
			}
		}
        log.error("DOWNLOAD FAIL");
	}
}

DownloadRequestMappingHandler를 상속하는 class 생성

  • ExcelDownloadRequestMappingHandler, PptDownloadRequestMappingHandler, ZipDownloadRequestMappingHandler
  • @PostConstruct를 사용하여 의존성 주입 후 excelDownloadableBeans 변수 초기화
public interface DownloadRequestMappingHandler {
	boolean route(String downloadId, UserDownloadRequest downloadRequest);
}

///////////////////////////////////////////////////////////

class ExcelDownloadRequestMappingHandler implements DownloadRequestMappingHandler {
	private final ApplicationContext applicationContext;
	private Map<String, ExcelDownloadable> excelDownloadableBeans;

	@PostConstruct
	public void init() {
		excelDownloadableBeans = applicationContext.getBeansOfType(ExcelDownloadable.class);
	}

	@Override
	public boolean route(String downloadId, UserDownloadRequest downloadRequest) {
		
		for (ExcelDownloadable excelDownloadable : excelDownloadableBeans.values()) {
			if (!excelDownloadable.equalsType(downloadRequest.getDownloadType())) {
				continue;
			}
			...
            
			return true;
		}
		return false;
	}

}

DownloadHandler class 생성

  • 각 download type에 맞는 handler() 함수 생성
public class DownloadHandler {
	//Excel
	public void handleDownload(
		String downloadId,
		ExcelWorkbookConsumer excelWorkbookConsumer,
		ExcelDownloadHistoryManager excelDownloadHistoryManager,
		Object requestData
	) {
    	...
    }
    
    //PPT
    public void handleDownload(
		String downloadId,
		PptWorkbookConsumer pptWorkbookConsumer,
		PptDownloadHistoryManager pptDownloadHistoryManager,
		Object requestData
	) {
    	...
    }
    
    //ZIP
    public void handleDownload(
		String downloadId,
		ZipDownloadRunnable zipDownloadRunnable,
		ZipDownloadHistoryManager zipDownloadHistoryManager,
		Object requestData
	) {
    	...
    }
}

download기능들 download type에 맞게 interface 상속

public interface Downloadable {
	boolean equalsType(DownloadType requestDownloadType);
}

///////////////////////////////////////////////////////////

public interface ExcelDownloadable extends Downloadable {
	void handle(ExcelDownloadRequest request) throws Exception;
}

public interface PPTDownloadable extends Downloadable{
	void handle(PPTDownloadRequest request) throws Exception;
}

public interface ZipDownloadable extends Downloadable{
	void handle(ZipDownloadRequest request) throws Exception;
	String resolveCopyRootDir(Environment environment, String id);
}

///////////////////////////////////////////////////////////

public class UserInfoExcelDownload implements ExcelDownloadable{

	private void startDownload() {
    	...
    }
	...
    
    @Override
    public void handle() throws Exception {
    	...
        startDownload();
    }
    
    @Override
    public boolean equalsType(DownloadType requestDownloadType) {
    	return DownloadType.USER_INFO_EXCEL == requestDownloadType;
    }
}
profile
일단 해보자
post-custom-banner

0개의 댓글