암호화 모듈 설정 관리 화면 추가 (feature/crypto-module)
- CryptoModuleConfig CRUD 관리 화면 신규 개발 - JPA DataService/Repository, MapStruct UiMapper, ManService, Controller - 목록(jqGrid, 4가지 검색조건), 상세/등록/수정/삭제 화면 - INSERT/UPDATE/DELETE 후 게이트웨이 전 인스턴스에 ReloadCryptoModuleCommand broadcast - 버그 수정 - getById(getReferenceById) → findById 교체: Persistable.isNew=true 유지로 인한 persist 에러 - insert 시 entity.setCryptoId(null): 빈 문자열 cryptoId 전송 시 UUID 생성기 오동작 방지 - 검색 버튼 클릭 시 algType/keySourceType/useYn getSearchForJqgrid 누락 수정 - UX 개선 - 암호화키/복호화키/IV 필드에 텍스트→HEX 변환 보조 입력 및 키 길이 실시간 표시 - 상세 화면에 수정자/수정일시 정보성 표시 - DB: EMSADM.CRYPTO_MODULE_CONFIG 테이블 (MODIFIED_BY/MODIFIED_AT 포함 전체 DDL) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
package com.eactive.eai.rms.data.entity.onl.security;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import com.eactive.eai.data.DataService;
|
||||
import com.eactive.eai.data.entity.onl.security.CryptoModuleConfig;
|
||||
|
||||
public interface CryptoModuleConfigDataService extends DataService<CryptoModuleConfig, String> {
|
||||
|
||||
Page<CryptoModuleConfig> findAll(Pageable pageable, String searchName, String algType, String keySourceType, String useYn);
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.eactive.eai.rms.data.entity.onl.security;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.eactive.eai.data.entity.onl.security.CryptoModuleConfig;
|
||||
import com.eactive.eai.data.entity.onl.security.QCryptoModuleConfig;
|
||||
import com.eactive.eai.data.jpa.AbstractDataService;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class CryptoModuleConfigDataServiceImpl
|
||||
extends AbstractDataService<CryptoModuleConfig, String, CryptoModuleConfigRepository>
|
||||
implements CryptoModuleConfigDataService {
|
||||
|
||||
@Override
|
||||
public Page<CryptoModuleConfig> findAll(Pageable pageable, String searchName, String algType,
|
||||
String keySourceType, String useYn) {
|
||||
QCryptoModuleConfig q = QCryptoModuleConfig.cryptoModuleConfig;
|
||||
|
||||
BooleanExpression predicate = q.cryptoName.containsIgnoreCase(searchName != null ? searchName : "");
|
||||
|
||||
if (algType != null && !algType.isEmpty()) {
|
||||
predicate = predicate.and(q.algType.eq(algType));
|
||||
}
|
||||
if (keySourceType != null && !keySourceType.isEmpty()) {
|
||||
predicate = predicate.and(q.keySourceType.eq(keySourceType));
|
||||
}
|
||||
if (useYn != null && !useYn.isEmpty()) {
|
||||
predicate = predicate.and(q.useYn.eq(useYn));
|
||||
}
|
||||
|
||||
return repository.findAll(predicate, pageable);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.eactive.eai.rms.data.entity.onl.security;
|
||||
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
|
||||
import com.eactive.eai.data.entity.onl.security.CryptoModuleConfig;
|
||||
import com.eactive.eai.data.jpa.BaseRepository;
|
||||
|
||||
interface CryptoModuleConfigRepository
|
||||
extends BaseRepository<CryptoModuleConfig, String>, QuerydslPredicateExecutor<CryptoModuleConfig> {
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package com.eactive.eai.rms.onl.manage.crypto;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import com.eactive.eai.agent.command.CommonCommand;
|
||||
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
|
||||
import com.eactive.eai.rms.common.login.SessionManager;
|
||||
import com.eactive.eai.rms.common.vo.GridResponse;
|
||||
|
||||
@Controller
|
||||
public class CryptoModuleConfigManController extends OnlBaseAnnotationController {
|
||||
|
||||
private static final String RELOAD_CRYPTO_MODULE_COMMAND = "com.eactive.eai.agent.security.ReloadCryptoModuleCommand";
|
||||
|
||||
private final CryptoModuleConfigManService service;
|
||||
|
||||
@Autowired
|
||||
public CryptoModuleConfigManController(CryptoModuleConfigManService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(WebDataBinder binder) {
|
||||
binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/onl/admin/security/cryptoModuleMan.view")
|
||||
public String viewList() {
|
||||
return "/onl/admin/security/cryptoModuleMan";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/onl/admin/security/cryptoModuleMan.view", params = "cmd=DETAIL")
|
||||
public String detailView() {
|
||||
return "/onl/admin/security/cryptoModuleManDetail";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/admin/security/cryptoModuleMan.json", params = "cmd=LIST")
|
||||
public ResponseEntity<GridResponse<CryptoModuleConfigUI>> selectList(
|
||||
@SortDefault("cryptoName") Pageable pageable,
|
||||
String searchName, String algType, String keySourceType, String useYn) {
|
||||
Page<CryptoModuleConfigUI> page = service.selectList(pageable, searchName, algType, keySourceType, useYn);
|
||||
return ResponseEntity.ok(new GridResponse<>(page));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/admin/security/cryptoModuleMan.json", params = "cmd=DETAIL")
|
||||
public ResponseEntity<CryptoModuleConfigUI> selectDetail(String cryptoId) {
|
||||
return ResponseEntity.ok(service.selectDetail(cryptoId));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/admin/security/cryptoModuleMan.json", params = "cmd=INSERT")
|
||||
public ResponseEntity<Map<String, String>> insert(@Valid CryptoModuleConfigUI ui, BindingResult bindingResult,
|
||||
HttpServletRequest request) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
Map<String, String> errors = new HashMap<>();
|
||||
for (FieldError error : bindingResult.getFieldErrors()) {
|
||||
errors.put(error.getField(), error.getDefaultMessage());
|
||||
}
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
|
||||
}
|
||||
String cryptoId = service.insert(ui, SessionManager.getUserId(request));
|
||||
CommonCommand.builder()
|
||||
.name(RELOAD_CRYPTO_MODULE_COMMAND)
|
||||
.args(cryptoId)
|
||||
.build()
|
||||
.broadcast(agentUtilService);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/admin/security/cryptoModuleMan.json", params = "cmd=UPDATE")
|
||||
public ResponseEntity<Map<String, String>> update(@Valid CryptoModuleConfigUI ui, BindingResult bindingResult,
|
||||
HttpServletRequest request) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
Map<String, String> errors = new HashMap<>();
|
||||
for (FieldError error : bindingResult.getFieldErrors()) {
|
||||
errors.put(error.getField(), error.getDefaultMessage());
|
||||
}
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
|
||||
}
|
||||
service.update(ui, SessionManager.getUserId(request));
|
||||
CommonCommand.builder()
|
||||
.name(RELOAD_CRYPTO_MODULE_COMMAND)
|
||||
.args(ui.getCryptoId())
|
||||
.build()
|
||||
.broadcast(agentUtilService);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/admin/security/cryptoModuleMan.json", params = "cmd=DELETE")
|
||||
public ResponseEntity<Void> delete(String cryptoId) {
|
||||
service.delete(cryptoId);
|
||||
CommonCommand.builder()
|
||||
.name(RELOAD_CRYPTO_MODULE_COMMAND)
|
||||
.args(cryptoId)
|
||||
.build()
|
||||
.broadcast(agentUtilService);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.eactive.eai.rms.onl.manage.crypto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.eactive.eai.data.entity.onl.security.CryptoModuleConfig;
|
||||
import com.eactive.eai.rms.common.base.BaseService;
|
||||
import com.eactive.eai.rms.data.entity.onl.security.CryptoModuleConfigDataService;
|
||||
import com.eactive.eai.rms.onl.common.exception.BizException;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class CryptoModuleConfigManService extends BaseService {
|
||||
|
||||
private final CryptoModuleConfigDataService dataService;
|
||||
private final CryptoModuleConfigUiMapper mapper;
|
||||
|
||||
@Autowired
|
||||
public CryptoModuleConfigManService(CryptoModuleConfigDataService dataService,
|
||||
CryptoModuleConfigUiMapper mapper) {
|
||||
this.dataService = dataService;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public Page<CryptoModuleConfigUI> selectList(Pageable pageable, String searchName,
|
||||
String algType, String keySourceType, String useYn) {
|
||||
Page<CryptoModuleConfig> page = dataService.findAll(pageable, searchName, algType, keySourceType, useYn);
|
||||
return page.map(mapper::toVo);
|
||||
}
|
||||
|
||||
public CryptoModuleConfigUI selectDetail(String cryptoId) {
|
||||
CryptoModuleConfig entity = dataService.findById(cryptoId)
|
||||
.orElseThrow(() -> new BizException("암호화 모듈을 찾을 수 없습니다: " + cryptoId));
|
||||
return mapper.toVo(entity);
|
||||
}
|
||||
|
||||
public String insert(CryptoModuleConfigUI ui, String loginId) {
|
||||
CryptoModuleConfig entity = mapper.toEntity(ui);
|
||||
entity.setCryptoId(null);
|
||||
entity.setModifiedBy(loginId);
|
||||
entity.setModifiedAt(LocalDateTime.now());
|
||||
dataService.save(entity);
|
||||
return entity.getCryptoId();
|
||||
}
|
||||
|
||||
public void update(CryptoModuleConfigUI ui, String loginId) {
|
||||
CryptoModuleConfig entity = dataService.findById(ui.getCryptoId())
|
||||
.orElseThrow(() -> new BizException("암호화 모듈을 찾을 수 없습니다: " + ui.getCryptoId()));
|
||||
mapper.updateToEntity(ui, entity);
|
||||
entity.setModifiedBy(loginId);
|
||||
entity.setModifiedAt(LocalDateTime.now());
|
||||
dataService.save(entity);
|
||||
}
|
||||
|
||||
public void delete(String cryptoId) {
|
||||
dataService.deleteById(cryptoId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.eactive.eai.rms.onl.manage.crypto;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CryptoModuleConfigUI {
|
||||
|
||||
@JsonProperty("CRYPTO_ID")
|
||||
private String cryptoId;
|
||||
|
||||
@JsonProperty("CRYPTO_NAME")
|
||||
@NotNull
|
||||
@Size(max = 100)
|
||||
private String cryptoName;
|
||||
|
||||
@JsonProperty("CRYPTO_DESC")
|
||||
private String cryptoDesc;
|
||||
|
||||
@JsonProperty("ALG_TYPE")
|
||||
@NotNull
|
||||
private String algType;
|
||||
|
||||
@JsonProperty("CIPHER_MODE")
|
||||
@NotNull
|
||||
private String cipherMode;
|
||||
|
||||
@JsonProperty("PADDING")
|
||||
private String padding;
|
||||
|
||||
@JsonProperty("IV_HEX")
|
||||
private String ivHex;
|
||||
|
||||
@JsonProperty("KEY_SOURCE_TYPE")
|
||||
@NotNull
|
||||
private String keySourceType;
|
||||
|
||||
@JsonProperty("ENC_KEY_HEX")
|
||||
private String encKeyHex;
|
||||
|
||||
@JsonProperty("DEC_KEY_HEX")
|
||||
private String decKeyHex;
|
||||
|
||||
@JsonProperty("KEY_DERIV_STRATEGY")
|
||||
private String keyDerivStrategy;
|
||||
|
||||
@JsonProperty("KEY_DERIV_PARAMS")
|
||||
private String keyDerivParams;
|
||||
|
||||
@JsonProperty("CACHE_YN")
|
||||
@NotNull
|
||||
private String cacheYn;
|
||||
|
||||
@JsonProperty("CACHE_TTL_SEC")
|
||||
private Integer cacheTtlSec;
|
||||
|
||||
@JsonProperty("USE_YN")
|
||||
@NotNull
|
||||
private String useYn;
|
||||
|
||||
@JsonProperty("MODIFIED_BY")
|
||||
private String modifiedBy;
|
||||
|
||||
@JsonProperty("MODIFIED_AT")
|
||||
private String modifiedAt;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.eactive.eai.rms.onl.manage.crypto;
|
||||
|
||||
import org.mapstruct.BeanMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
import com.eactive.eai.data.entity.onl.security.CryptoModuleConfig;
|
||||
import com.eactive.eai.data.mapper.GenericMapper;
|
||||
|
||||
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface CryptoModuleConfigUiMapper extends GenericMapper<CryptoModuleConfigUI, CryptoModuleConfig> {
|
||||
|
||||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
void updateToEntity(CryptoModuleConfigUI ui, @MappingTarget CryptoModuleConfig entity);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user