암호화 모듈 설정 관리 화면 추가 (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:
@@ -0,0 +1,143 @@
|
||||
# 작업내역 — feature/crypto-module (eapim-admin)
|
||||
|
||||
> 작업일: 2026-05-06
|
||||
> 브랜치: `feature/crypto-module`
|
||||
> 작업자: curry772
|
||||
> 프로젝트: `eapim-admin`
|
||||
|
||||
---
|
||||
|
||||
## 작업 목적
|
||||
|
||||
`eapim-online`에서 구현된 암호화모듈 프레임워크(`CryptoModuleManager`)의 설정 데이터(`crypto_module_config`)를
|
||||
관리자 화면에서 CRUD할 수 있는 관리 화면 개발.
|
||||
설정 변경 즉시 게이트웨이 엔진에 동적 반영되어야 한다.
|
||||
|
||||
---
|
||||
|
||||
## 변경 파일 목록
|
||||
|
||||
### JPA 데이터 레이어 — `com.eactive.eai.rms.data.entity.onl.security`
|
||||
|
||||
| 파일 | 설명 |
|
||||
|---|---|
|
||||
| `CryptoModuleConfigRepository.java` | `BaseRepository` + `QuerydslPredicateExecutor` 조합 Repository |
|
||||
| `CryptoModuleConfigDataService.java` | 데이터 서비스 인터페이스. `findAll(pageable, searchName, algType, keySourceType, useYn)` |
|
||||
| `CryptoModuleConfigDataServiceImpl.java` | QueryDSL predicate 기반 검색 구현. `QCryptoModuleConfig` 사용 |
|
||||
|
||||
### 관리 화면 레이어 — `com.eactive.eai.rms.onl.manage.crypto`
|
||||
|
||||
| 파일 | 설명 |
|
||||
|---|---|
|
||||
| `CryptoModuleConfigUI.java` | UI VO (`@Data`, `@JsonProperty` 대문자+언더스코어 규칙). `@NotNull` 검증 포함 |
|
||||
| `CryptoModuleConfigUiMapper.java` | MapStruct Entity↔UI 매퍼. `updateToEntity` (null 무시) 포함 |
|
||||
| `CryptoModuleConfigManService.java` | CRUD 비즈니스 서비스. insert/update 시 `modifiedBy`·`modifiedAt` 자동 설정 |
|
||||
| `CryptoModuleConfigManController.java` | Spring MVC Controller. INSERT/UPDATE/DELETE 후 엔진 재로드 커맨드 broadcast |
|
||||
|
||||
### JSP 화면 — `WebContent/jsp/onl/admin/security/`
|
||||
|
||||
| 파일 | 설명 |
|
||||
|---|---|
|
||||
| `cryptoModuleMan.jsp` | 목록 화면. jqGrid, 4가지 검색 조건(모듈명·알고리즘·키소스·사용여부) |
|
||||
| `cryptoModuleManDetail.jsp` | 상세/등록/수정 화면. `keySourceType` 선택에 따라 STATIC/DYNAMIC 섹션 토글 |
|
||||
|
||||
---
|
||||
|
||||
## URL 구조
|
||||
|
||||
| 용도 | URL |
|
||||
|---|---|
|
||||
| 목록 View | `GET /onl/admin/security/cryptoModuleMan.view` |
|
||||
| 상세 View | `GET /onl/admin/security/cryptoModuleMan.view?cmd=DETAIL&cryptoId={id}` |
|
||||
| 목록 조회 | `POST /onl/admin/security/cryptoModuleMan.json?cmd=LIST` |
|
||||
| 상세 조회 | `POST /onl/admin/security/cryptoModuleMan.json?cmd=DETAIL` |
|
||||
| 등록 | `POST /onl/admin/security/cryptoModuleMan.json?cmd=INSERT` |
|
||||
| 수정 | `POST /onl/admin/security/cryptoModuleMan.json?cmd=UPDATE` |
|
||||
| 삭제 | `POST /onl/admin/security/cryptoModuleMan.json?cmd=DELETE` |
|
||||
|
||||
---
|
||||
|
||||
## 엔진 동적 반영 구조
|
||||
|
||||
```
|
||||
Controller (INSERT / UPDATE / DELETE)
|
||||
└─ service.insert() / update() / delete() ← DB 반영
|
||||
└─ CommonCommand.builder()
|
||||
.name("com.eactive.eai.agent.security.ReloadCryptoModuleCommand")
|
||||
.args(cryptoId)
|
||||
.build()
|
||||
.broadcast(agentUtilService) ← 게이트웨이 전 인스턴스 broadcast
|
||||
└─ CryptoModuleManager.reload(cryptoId)
|
||||
├─ configMap 에서 cryptoId 항목 제거
|
||||
├─ dynamicKeyCache 에서 관련 항목 제거
|
||||
└─ DB 재조회 → useYn=Y 이면 configMap 재등록
|
||||
(DELETE 후 호출 시: DB에 없으므로 제거만 수행)
|
||||
```
|
||||
|
||||
- `RELOAD_CRYPTO_MODULE_COMMAND` 상수는 `CommonCommand.java`에 추가하지 않고
|
||||
`CryptoModuleConfigManController` 내부에 `private static final String`으로 선언
|
||||
|
||||
---
|
||||
|
||||
## 화면 설계
|
||||
|
||||
### 목록 화면 (`cryptoModuleMan.jsp`)
|
||||
|
||||
**검색 조건**
|
||||
|
||||
| 항목 | 유형 | 비고 |
|
||||
|---|---|---|
|
||||
| 모듈명 | text | 부분 일치 (containsIgnoreCase) |
|
||||
| 알고리즘 | select | 전체 / AES / ARIA |
|
||||
| 키 소스 | select | 전체 / STATIC / DYNAMIC |
|
||||
| 사용 여부 | select | 전체 / Y / N |
|
||||
|
||||
**그리드 컬럼**: 모듈명 · 설명 · 알고리즘 · 운영모드 · 키 소스 · 사용여부
|
||||
(CRYPTO_ID는 hidden 컬럼으로 포함, 더블클릭 시 상세 화면 이동에 사용)
|
||||
|
||||
### 상세 화면 (`cryptoModuleManDetail.jsp`)
|
||||
|
||||
**공통 필드**: 모듈명\* · 설명 · 알고리즘\* · 운영모드\* · 패딩 · IV(Hex) · 키소스유형\* · 동적키캐시\* · 캐시TTL · 사용여부\*
|
||||
|
||||
**STATIC 섹션** (`keySourceType = STATIC` 일 때만 표시):
|
||||
- 암호화 키(Hex) \*
|
||||
- 복호화 키(Hex) (미입력 시 암호화 키와 동일)
|
||||
|
||||
**DYNAMIC 섹션** (`keySourceType = DYNAMIC` 일 때만 표시):
|
||||
- 키 도출 전략 FQCN \*
|
||||
- 키 도출 파라미터 JSON \*
|
||||
|
||||
`keySourceType` select 변경 시 JavaScript `toggleKeySourceFields()`로 즉시 토글.
|
||||
|
||||
---
|
||||
|
||||
## 주요 설계 결정
|
||||
|
||||
### 1. `@InitBinder` — Integer 빈 문자열 처리
|
||||
`cacheTtlSec`(Integer)에 빈 문자열이 전송될 수 있으므로 Controller에 `@InitBinder` 등록:
|
||||
```java
|
||||
binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
|
||||
```
|
||||
|
||||
### 2. 로그인 사용자 — `SessionManager.getUserId(request)`
|
||||
`HttpServletRequest`를 Controller에서 받아 `SessionManager.getUserId(request)`로 추출,
|
||||
Service의 `insert()` / `update()` 에 `loginId`로 전달 → `modifiedBy` 설정.
|
||||
|
||||
### 3. JSON 필드명 규칙
|
||||
`@JsonProperty`는 DB 컬럼명 기반 대문자+언더스코어 (`CRYPTO_ID`, `KEY_SOURCE_TYPE` 등).
|
||||
JSP `detail()` 함수에서 제네릭 루프 대신 명시적 필드 매핑으로 처리
|
||||
(기존 `name.toUpperCase()` 패턴은 언더스코어 있는 컬럼명과 불일치하므로).
|
||||
|
||||
### 4. DELETE 후 엔진 반영
|
||||
`CryptoModuleManager.reload(cryptoId)` — DB에서 삭제된 후 호출하면
|
||||
`loader.findById(cryptoId)` 가 empty를 반환 → `configMap` 에서 제거만 수행.
|
||||
별도 RemoveCommand 없이 동일한 `ReloadCryptoModuleCommand` 재사용.
|
||||
|
||||
---
|
||||
|
||||
## 미완료 / 다음 작업
|
||||
|
||||
- [ ] `kjb-gradle.sh compileJava` 실행 → `QCryptoModuleConfig` Q-class 생성 확인
|
||||
- [ ] 관리자 메뉴 테이블에 경로 등록 (`/onl/admin/security/cryptoModuleMan.view`)
|
||||
- [ ] 화면 접근 권한(ACL) 등록
|
||||
- [ ] 전체 파일 커밋 (eapim-admin)
|
||||
Reference in New Issue
Block a user