diff --git a/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java index 7989ce31..a09e897b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java @@ -13,7 +13,12 @@ import jakarta.transaction.Transactional; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; @Tag(name = "모델 관리", description = "모델 관리 API") @RequiredArgsConstructor @@ -27,42 +32,42 @@ public class ModelMngApiController { @Operation(summary = "모델관리 목록") @GetMapping public ApiResponseDto> findModelMgmtList( - @RequestParam(required = false) LocalDate startDate, - @RequestParam(required = false) LocalDate endDate, - @RequestParam(required = false, defaultValue = "createCompleteDttm") String sortColumn, - @RequestParam(required = false) String modelType, - @RequestParam(required = false) String searchVal, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "20") int size) { + @RequestParam(required = false) LocalDate startDate, + @RequestParam(required = false) LocalDate endDate, + @RequestParam(required = false, defaultValue = "createCompleteDttm") String sortColumn, + @RequestParam(required = false) String modelType, + @RequestParam(required = false) String searchVal, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "20") int size) { ModelMngDto.searchReq searchReq = new ModelMngDto.searchReq(page, size, sortColumn + ",desc"); Page result = - modelMngService.findModelMgmtList(searchReq, startDate, endDate, modelType, searchVal); + modelMngService.findModelMgmtList(searchReq, startDate, endDate, modelType, searchVal); return ApiResponseDto.ok(result); } @Operation(summary = "삭제", description = "모델을 삭제 합니다.") @ApiResponses( - value = { - @ApiResponse( - responseCode = "204", - description = "모델 삭제 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = Long.class))), - @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), - @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) + value = { + @ApiResponse( + responseCode = "204", + description = "모델 삭제 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Long.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) @DeleteMapping("/{modelVer}") public ApiResponseDto removeModel( - @io.swagger.v3.oas.annotations.parameters.RequestBody( - description = "모델 삭제 요청 정보", - required = true) - @PathVariable - String modelVer) { + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "모델 삭제 요청 정보", + required = true) + @PathVariable + String modelVer) { return ApiResponseDto.okObject(modelMngService.removeModel(modelVer)); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java index 588e0018..5fb01c3b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java @@ -16,41 +16,70 @@ import org.springframework.data.domain.Sort; public class ModelMngDto { + @CodeExpose + @Getter + @AllArgsConstructor + public enum ModelType implements EnumType { + M1("모델 M1"), + M2("모델 M2"), + M3("모델 M3"); + + private final String desc; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return desc; + } + } + @Schema(name = "ModelMgmtDto Basic", description = "모델관리 엔티티 기본 정보") @Getter @NoArgsConstructor public static class Basic { + private Long modelUid; private String modelVer; - private String hyperVer; - private String epochVer; - private String dockerFileNm; - @JsonFormatDttm private ZonedDateTime createCompleteDttm; - @JsonFormatDttm private ZonedDateTime recentUseDttm; + @JsonFormatDttm + private ZonedDateTime createCompleteDttm; + @JsonFormatDttm + private ZonedDateTime recentUseDttm; private Boolean deleted; - @JsonFormatDttm private ZonedDateTime createdDttm; + @JsonFormatDttm + private ZonedDateTime createdDttm; private Long createdUid; - @JsonFormatDttm private ZonedDateTime updatedDttm; + @JsonFormatDttm + private ZonedDateTime updatedDttm; private Long updatedUid; + private String modelType; + private String filePath; + private String fileName; + private String memo; + public Basic( - String modelVer, - String hyperVer, - String epochVer, - String dockerFileNm, - ZonedDateTime createCompleteDttm, - ZonedDateTime recentUseDttm, - Boolean deleted, - ZonedDateTime createdDttm, - Long createdUid, - ZonedDateTime updatedDttm, - Long updatedUid) { + Long modelUid, + String modelVer, + ZonedDateTime createCompleteDttm, + ZonedDateTime recentUseDttm, + Boolean deleted, + ZonedDateTime createdDttm, + Long createdUid, + ZonedDateTime updatedDttm, + Long updatedUid, + String modelType, + String filePath, + String fileName, + String memo + ) { + this.modelUid = modelUid; this.modelVer = modelVer; - this.hyperVer = hyperVer; - this.epochVer = epochVer; - this.dockerFileNm = dockerFileNm; this.createCompleteDttm = createCompleteDttm; this.recentUseDttm = recentUseDttm; this.deleted = deleted; @@ -58,6 +87,10 @@ public class ModelMngDto { this.createdUid = createdUid; this.updatedDttm = updatedDttm; this.updatedUid = updatedUid; + this.modelType = modelType; + this.filePath = filePath; + this.fileName = fileName; + this.memo = memo; } } @@ -67,17 +100,18 @@ public class ModelMngDto { @NoArgsConstructor @AllArgsConstructor public static class ModelList { + private Integer rowNum; private String modelVer; private String fileName; private String modelType; private String createCompleteDttm; - private String recentUseDttm; private BigDecimal f1Score; private BigDecimal precision; private BigDecimal recall; private BigDecimal accuracy; private BigDecimal iou; + private String memo; private Boolean deleted; } @@ -112,31 +146,10 @@ public class ModelMngDto { String[] sortParams = sort.split(","); String property = sortParams[0]; Sort.Direction direction = - sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; + sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; return PageRequest.of(page, size, Sort.by(direction, property)); } return PageRequest.of(page, size); } } - - @CodeExpose - @Getter - @AllArgsConstructor - public enum ModelType implements EnumType { - M1("모델 M1"), - M2("모델 M2"), - M3("모델 M3"); - - private final String desc; - - @Override - public String getId() { - return name(); - } - - @Override - public String getText() { - return desc; - } - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java b/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java index 02c7e518..02d8d6ca 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java @@ -15,16 +15,17 @@ public class ModelMngService { private final ModelMngCoreService modelMngCoreService; public Page findModelMgmtList( - ModelMngDto.searchReq searchReq, - LocalDate startDate, - LocalDate endDate, - String modelType, - String searchVal) { + ModelMngDto.searchReq searchReq, + LocalDate startDate, + LocalDate endDate, + String modelType, + String searchVal) { return modelMngCoreService.findModelMgmtList( - searchReq, startDate, endDate, modelType, searchVal); + searchReq, startDate, endDate, modelType, searchVal); } public ApiResponseDto.ResponseObj removeModel(String modelVer) { return modelMngCoreService.removeModel(modelVer); } + } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ModelMngEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ModelMngEntity.java index 9e40a9d9..2e423cee 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ModelMngEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ModelMngEntity.java @@ -1,7 +1,12 @@ package com.kamco.cd.kamcoback.postgres.entity; import com.kamco.cd.kamcoback.postgres.CommonDateEntity; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import java.time.ZonedDateTime; import lombok.Getter; import lombok.Setter; @@ -11,6 +16,7 @@ import lombok.Setter; @Entity @Table(name = "tb_model_mng") public class ModelMngEntity extends CommonDateEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "model_uid") @@ -21,7 +27,7 @@ public class ModelMngEntity extends CommonDateEntity { @Column(name = "create_complete_dttm") private ZonedDateTime createCompleteDttm; - + @Column(name = "recent_use_dttm") private ZonedDateTime recentUseDttm; @@ -43,6 +49,9 @@ public class ModelMngEntity extends CommonDateEntity { @Column(name = "file_name") private String fileName; + @Column(name = "memo") + private String memo; + public void deleted() { this.deleted = true; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryCustom.java index 5d34fdee..4f89d0b8 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryCustom.java @@ -9,11 +9,12 @@ import org.springframework.data.domain.Page; public interface ModelMngRepositoryCustom { Page findModelMgmtList( - ModelMngDto.searchReq searchReq, - LocalDate startDate, - LocalDate endDate, - String modelType, - String searchVal); + ModelMngDto.searchReq searchReq, + LocalDate startDate, + LocalDate endDate, + String modelType, + String searchVal); Optional findByModelUid(String modelVer); + } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java index c9056fe7..0ab11cf3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java @@ -9,7 +9,10 @@ import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Expression; import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.*; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.math.BigDecimal; import java.time.LocalDate; @@ -26,7 +29,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class ModelMngRepositoryImpl extends QuerydslRepositorySupport - implements ModelMngRepositoryCustom { + implements ModelMngRepositoryCustom { private final JPAQueryFactory queryFactory; private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)"); @@ -38,19 +41,19 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport @Override public Page findModelMgmtList( - ModelMngDto.searchReq searchReq, - LocalDate startDate, - LocalDate endDate, - String modelType, - String searchVal) { + ModelMngDto.searchReq searchReq, + LocalDate startDate, + LocalDate endDate, + String modelType, + String searchVal) { Pageable pageable = searchReq.toPageable(); Sort sort = pageable.getSort(); String property = "createCompleteDttm"; // 기본으로 생성완료일 기준 Map> sortColumnMap = - Map.of( - "createCompleteDttm", modelMngEntity.createCompleteDttm, - "recentUseDttm", modelMngEntity.recentUseDttm); + Map.of( + "createCompleteDttm", modelMngEntity.createCompleteDttm, + "recentUseDttm", modelMngEntity.recentUseDttm); if (sort.isSorted()) { Sort.Order order = sort.iterator().next(); @@ -60,47 +63,46 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport Expression sortColumn = sortColumnMap.get(property); List foundContent = - queryFactory - .select( - Projections.constructor( - ModelMngDto.ModelList.class, - Expressions.numberTemplate( - Integer.class, "row_number() over(order by {0} desc)", sortColumn), - modelMngEntity.modelVer, - modelMngEntity.fileName, - modelMngEntity.modelType, - Expressions.stringTemplate( - "to_char({0}, 'YYYY-MM-DD')", modelMngEntity.createCompleteDttm), - Expressions.stringTemplate( - "to_char({0}, 'YYYY-MM-DD')", modelMngEntity.recentUseDttm), - roundNumericToPercent(modelResultMetricEntity.f1Score), - roundNumericToPercent(modelResultMetricEntity.precision), - roundNumericToPercent(modelResultMetricEntity.recall), - roundNumericToPercent(modelResultMetricEntity.loss), - roundNumericToPercent(modelResultMetricEntity.iou), - modelMngEntity.deleted)) - .from(modelMngEntity) - .innerJoin(modelResultMetricEntity) - .on(modelMngEntity.modelUid.eq(modelResultMetricEntity.modelUid)) - .where( - eventEndedAtBetween(startDate, endDate, property), - searchModelVersion(modelType, searchVal), - modelMngEntity.deleted.isFalse().or(modelMngEntity.deleted.isNull())) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .orderBy( - QuerydslOrderUtil.getOrderSpecifiers( - pageable, ModelMngEntity.class, "modelMngEntity")) - .fetch(); + queryFactory + .select( + Projections.constructor( + ModelMngDto.ModelList.class, + Expressions.numberTemplate( + Integer.class, "row_number() over(order by {0} desc)", sortColumn), + modelMngEntity.modelVer, + modelMngEntity.fileName, + modelMngEntity.modelType, + Expressions.stringTemplate( + "to_char({0}, 'YYYY-MM-DD')", modelMngEntity.createCompleteDttm), + roundNumericToPercent(modelResultMetricEntity.f1Score), + roundNumericToPercent(modelResultMetricEntity.precision), + roundNumericToPercent(modelResultMetricEntity.recall), + roundNumericToPercent(modelResultMetricEntity.loss), + roundNumericToPercent(modelResultMetricEntity.iou), + modelMngEntity.memo, + modelMngEntity.deleted)) + .from(modelMngEntity) + .innerJoin(modelResultMetricEntity) + .on(modelMngEntity.modelUid.eq(modelResultMetricEntity.modelUid)) + .where( + eventEndedAtBetween(startDate, endDate, property), + searchModelVersion(modelType, searchVal), + modelMngEntity.deleted.isFalse().or(modelMngEntity.deleted.isNull())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy( + QuerydslOrderUtil.getOrderSpecifiers( + pageable, ModelMngEntity.class, "modelMngEntity")) + .fetch(); Long countQuery = - queryFactory - .select(modelMngEntity.modelUid.count()) - .from(modelMngEntity) - .where( - eventEndedAtBetween(startDate, endDate, property), - searchModelVersion(modelType, searchVal)) - .fetchOne(); + queryFactory + .select(modelMngEntity.modelUid.count()) + .from(modelMngEntity) + .where( + eventEndedAtBetween(startDate, endDate, property), + searchModelVersion(modelType, searchVal)) + .fetchOne(); return new PageImpl<>(foundContent, pageable, countQuery); } @@ -108,14 +110,14 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport @Override public Optional findByModelUid(String modelVer) { return Optional.ofNullable( - queryFactory - .selectFrom(modelMngEntity) - .where(modelMngEntity.modelVer.eq(modelVer)) - .fetchOne()); + queryFactory + .selectFrom(modelMngEntity) + .where(modelMngEntity.modelVer.eq(modelVer)) + .fetchOne()); } private BooleanExpression eventEndedAtBetween( - LocalDate startDate, LocalDate endDate, String sortColumn) { + LocalDate startDate, LocalDate endDate, String sortColumn) { if (Objects.isNull(startDate) || Objects.isNull(endDate)) { return null; } @@ -125,14 +127,14 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport if (sortColumn.equals("createCompleteDttm")) { return modelMngEntity - .createCompleteDttm - .goe(startDateTime.atZone(zone)) - .and(modelMngEntity.createCompleteDttm.lt(endDateTime.atZone(zone))); + .createCompleteDttm + .goe(startDateTime.atZone(zone)) + .and(modelMngEntity.createCompleteDttm.lt(endDateTime.atZone(zone))); } else { return modelMngEntity - .recentUseDttm - .goe(startDateTime.atZone(zone)) - .and(modelMngEntity.recentUseDttm.lt(endDateTime.atZone(zone))); + .recentUseDttm + .goe(startDateTime.atZone(zone)) + .and(modelMngEntity.recentUseDttm.lt(endDateTime.atZone(zone))); } }