Skip to content

Commit

Permalink
Merge pull request #155 from AppLinkers/develop
Browse files Browse the repository at this point in the history
Deploy for 7th sprint 최종 거래 완료
  • Loading branch information
yuseogi0218 authored Jan 8, 2024
2 parents de79bd7 + ecd1ca5 commit f9448c9
Show file tree
Hide file tree
Showing 87 changed files with 1,181 additions and 962 deletions.
41 changes: 24 additions & 17 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,25 @@ repositories {
}

dependencies {
runtimeOnly 'com.mysql:mysql-connector-j'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

// h2
testImplementation 'com.h2database:h2'

// test-containers
testImplementation group: 'org.testcontainers', name: 'testcontainers', version: '1.17.2'

// validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// mail
implementation 'org.springframework.boot:spring-boot-starter-mail:3.1.5'

// quartz scheduler
implementation 'org.springframework.boot:spring-boot-starter-quartz'

// lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

// JWT
compileOnly 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2', 'io.jsonwebtoken:jjwt-jackson:0.11.2'
Expand All @@ -61,14 +59,23 @@ dependencies {
// p6spy
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'

// mail
implementation 'org.springframework.boot:spring-boot-starter-mail:3.1.5'

// AWS - S3
implementation 'software.amazon.awssdk:s3:2.21.23'

// aspose-cad
implementation 'com.aspose:aspose-cad:23.7'

// test
testImplementation 'org.springframework.boot:spring-boot-starter-test'

// h2, security, lombok for test
testImplementation 'com.h2database:h2'
testImplementation 'org.springframework.security:spring-security-test'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'

// test-containers
testImplementation group: 'org.testcontainers', name: 'testcontainers', version: '1.17.2'
}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion laser-ordermanage-server-submodule-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.laser.ordermanage.common.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}

@Primary
@Bean
public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public enum ErrorCode {
MISSING_QUOTATION("-014", HttpStatus.BAD_REQUEST, "거래의 견적서가 존재하지 않습니다."),
MISSING_PURCHASE_ORDER("-015", HttpStatus.BAD_REQUEST, "거래의 발주서가 존재하지 않습니다."),
DEFAULT_DELIVERY_ADDRESS_DELETE("-016", HttpStatus.BAD_REQUEST, "기본 배송지는 삭제할 수 없습니다."),
MISSING_PURCHASE_ORDER_FILE("-017", HttpStatus.BAD_REQUEST, "발주서 최초 작성 시, 발주서 파일은 필수 사항입니다."),

// 401 UNAUTHORIZED 인증 자격 정보가 유효하지 않음
UNAUTHORIZED("-100", HttpStatus.UNAUTHORIZED, "인증 자격 정보가 유효하지 않습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package com.laser.ordermanage.common.exception.dto.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Builder
@Getter
@AllArgsConstructor
public class ErrorResponse {

private HttpStatus httpStatus;
private String errorCode;
private String message;

}
public record ErrorResponse (
HttpStatus httpStatus,
String errorCode,
String message
) { }
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse

private void createJwtErrorResponse(HttpServletRequest request, HttpServletResponse response, CustomCommonException e) throws IOException {

response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setStatus(e.getHttpStatus().value());

ObjectMapper objectMapper = new ObjectMapper();
String responseBody = objectMapper.writeValueAsString(e.toErrorResponse());

try (PrintWriter writer = response.getWriter()) {
String responseBody = objectMapper.writeValueAsString(e.toErrorResponse());

response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setStatus(e.getHttpStatus().value());

writer.write(responseBody);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.laser.ordermanage.common.paging;

import lombok.Getter;

import java.util.List;

@Getter
public class ListResponse<T> {

private final List<T> contents;

private final Long totalElements;

public record ListResponse<T>(
List<T> contents,
Long totalElements
) {
public ListResponse(List<T> contents) {
this.contents = contents;
this.totalElements = (long) contents.size();
this(
contents,
(long) contents.size()
);
}
}
45 changes: 18 additions & 27 deletions src/main/java/com/laser/ordermanage/common/paging/PageResponse.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,27 @@
package com.laser.ordermanage.common.paging;

import lombok.Getter;
import org.springframework.data.domain.Page;

import java.util.List;

@Getter
public class PageResponse<T> {

private final List<T> contents;

private final Integer page;

private final Integer size;

private final Long totalElements;

private final Integer totalPages;

private final Boolean first;

private final Boolean last;

public record PageResponse<T>(
List<T> contents,
Integer page,
Integer size,
Long totalElements,
Integer totalPages,
Boolean first,
Boolean last
) {
public PageResponse(Page<T> contentPage) {
this.contents = contentPage.getContent();

this.page = contentPage.getNumber() + 1;
this.size = contentPage.getNumberOfElements();
this.totalElements = contentPage.getTotalElements();
this.totalPages = contentPage.getTotalPages();
this.first = (contentPage.getNumber() == 0) ? Boolean.TRUE : Boolean.FALSE;
this.last = ((contentPage.getNumber() + 1) == contentPage.getTotalPages()) ? Boolean.TRUE : Boolean.FALSE;

this(
contentPage.getContent(),
contentPage.getNumber() + 1,
contentPage.getNumberOfElements(),
contentPage.getTotalElements(),
contentPage.getTotalPages(),
contentPage.getNumber() == 0,
(contentPage.getNumber() + 1) == contentPage.getTotalPages()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.laser.ordermanage.common.scheduler.config;

import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class SchedulerConfig {

@QuartzDataSource
@Bean
@ConfigurationProperties(prefix = "spring.quartz.datasource")
public DataSource quartzDataSource() {
return DataSourceBuilder.create().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.laser.ordermanage.common.scheduler.dto.request;

import lombok.Builder;

import java.util.Date;

@Builder
public record JobRequest (
String name,
String group,
Date startAt
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.laser.ordermanage.common.scheduler.job;

import com.laser.ordermanage.factory.service.FactoryOrderService;
import com.laser.ordermanage.order.domain.Order;
import com.laser.ordermanage.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
public class ChangeStageToCompletedJob implements Job {

private final OrderService orderService;
private final FactoryOrderService factoryOrderService;

@Override
public void execute(JobExecutionContext context) {
Long orderId = Long.valueOf(context.getJobDetail().getKey().getName());

Order order = orderService.getOrderById(orderId);

if (!order.enableChangeStageToCompleted()) {
return;
}

factoryOrderService.changeStageToCompleted(order);

factoryOrderService.sendEmailForChangeStageToCompleted(order);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.laser.ordermanage.common.scheduler.service;

import com.laser.ordermanage.common.exception.CustomCommonException;
import com.laser.ordermanage.common.exception.ErrorCode;
import com.laser.ordermanage.common.scheduler.dto.request.JobRequest;
import com.laser.ordermanage.common.scheduler.util.JobUtil;
import com.laser.ordermanage.common.scheduler.job.ChangeStageToCompletedJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

@Slf4j
@RequiredArgsConstructor
@Service
public class ScheduleService {

private final SchedulerFactoryBean schedulerFactoryBean;

public void createJobForChangeStageToCompleted(Long orderId) {
JobRequest jobRequest = JobRequest.builder()
.name(orderId.toString())
.group(ChangeStageToCompletedJob.class.getName()) // orderId 에 해당하는 거래의 상태를 COMPLETED 로 변경하는 작업
.startAt(DateBuilder.futureDate(7, DateBuilder.IntervalUnit.DAY)) // 7일 후
.build();
this.addJob(jobRequest, ChangeStageToCompletedJob.class);
}

private void addJob(JobRequest jobRequest, Class<? extends Job> jobClass) {
Trigger trigger = JobUtil.createTrigger(jobRequest);
JobDetail jobDetail = JobUtil.createJob(jobRequest, jobClass);

try {
schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
throw new CustomCommonException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}

public void removeJobForChangeStageToCompleted(Long orderId) {
this.removeJob(String.valueOf(orderId), ChangeStageToCompletedJob.class.getName());
}

private void removeJob(String jobName, String groupName) {
JobKey jobKey = JobKey.jobKey(jobName, groupName);

try {
schedulerFactoryBean.getScheduler().deleteJob(jobKey);
} catch (SchedulerException e) {
// Trigger 해제를 실패하는 경우
throw new CustomCommonException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.laser.ordermanage.common.scheduler.util;

import com.laser.ordermanage.common.scheduler.dto.request.JobRequest;
import org.quartz.*;

public class JobUtil {

private JobUtil() {
}

public static Trigger createTrigger(JobRequest jobRequest) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobRequest.name(), jobRequest.group());

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.startAt(jobRequest.startAt())
.build();

return trigger;
}

public static JobDetail createJob(JobRequest jobRequest, Class<? extends Job> jobClass) {
JobKey jobKey = JobKey.jobKey(jobRequest.name(), jobRequest.group());

JobDetail job = JobBuilder.newJob(jobClass)
.withIdentity(jobKey)
.build();

return job;
}

}
Loading

0 comments on commit f9448c9

Please sign in to comment.