Files
eapim-online/작업내역_20260421.md
T
curry772 1508d01afb refactor: CSV 기본값 이관 및 EZDATA 조건 평가 동적화
- standard-layout-djb.csv: HEAD ERP 고정값(tx_cmgr_cd=S004, mgmt_brcd/tx_brcd/insl_brcd/blng_brcd=260),
  정상 MSG 필드(outp_msg_cd=NCMM00001, outp_msg_ctnt=정상처리되었습니다.) 기본값 추가,
  msg_list_rowcnt 기본값 00000→0 수정
- StandardMessageCoordinatorDJB: setErpHeadFields() 및 관련 상수 제거,
  coordinateAfterRecvNonStdSyncResponse 명시적 setData 호출 제거 (CSV 기본값으로 대체),
  evaluateBlockCondition() 추가로 EZDATA 활성화 조건을 CSV refPath/refValue에서 동적 평가,
  elfn_spr_fild 설정값을 ezdataItem.getRefValue()로 CSV에서 읽도록 변경
- StandardMessageSpecTest: tx_cmgr_cd가 항상 CSV 기본값으로 설정되므로 비ERP_ERP_HEAD_필드_미설정 테스트 제거
- 작업내역_20260421.md: 리팩터링 내용 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:30:17 +09:00

14 KiB

DJBank 표준전문 버그 수정 · 스펙 구현 · 테스트 작업내역

  • 작업일: 2026-04-21
  • 브랜치: feature/standard-message-djb (eapim-online), standar-message-djb (elink-online-common)
  • 커밋: 17d533f

현상

StandardItem.toJson() 직렬화 시 빈 itemPart가 반환되는 경우에도 쉼표 구분자와 함께 빈 문자열이 출력되어 잘못된 JSON이 생성됨.

원인

// 수정 전: itemPart 비어있어도 무조건 sb.append 호출
if (ai > 0) sb.append(",");
String key = keyIter.next();
StandardItem item = group.get(key);
if (showPretty) sb.append("\n");
sb.append(item.toJson(showPretty, withBizData));
ai++;

수정

// 수정 후: itemPart가 비어있으면 구분자와 내용 모두 건너뜀
String key = keyIter.next();
StandardItem item = group.get(key);
String itemPart = item.toJson(showPretty, withBizData);
if (StringUtils.isNotEmpty(itemPart)) {
    if (ai > 0) sb.append(",");
    if (showPretty) sb.append("\n");
    sb.append(itemPart);
    ai++;
}

브랜치 이력

  • elink-online-commonmaster 상태였으므로 standar-message-djb 브랜치 신규 생성 후 커밋

2. 표준전문 처리 스펙 분석 및 구현 누락 항목 확인

2.1 요청 메시지 필수 처리 항목 (스펙 기준)

HEAD — 레이아웃 기본값 (Coordinator 불필요)

필드 설정 위치
nxgn_stnd_idfr JERA CSV 기본값
stnd_mesg_ver R10 CSV 기본값
frst_trnm_sys_dvcd OPA CSV 기본값
trnm_sys_dvcd EAI CSV 기본값 + Coordinator
dman_rspn_dvcd S CSV 기본값
sys_env_dvcd D/T/P CSV 기본값 + Coordinator
tx_tycd O CSV 기본값
synz_dvcd S CSV 기본값
chnl_tycd EAI CSV 기본값

HEAD — Coordinator 설정 항목

필드 설정값 메서드
guid 40자 생성 coordinateAfterCreateMessageByRule
guid_prgs_no 001 (최초) coordinateAfterCreateMessageByRule
ortr_guid guid와 동일 coordinateAfterCreateMessageByRule
frst_mesg_dman_dt 오늘 날짜 (yyyyMMdd) coordinateAfterCreateMessageByRule
frst_mesg_dman_time 현재 시간 (HHmmssSSS) coordinateAfterCreateMessageByRule
frst_trnm_ipad 서버 IP coordinateAfterCreateMessageByRule
frst_trnm_ipv4_addr 서버 IP coordinateAfterCreateMessageByRule
frst_trnm_mac 서버 MAC coordinateAfterCreateMessageByRule

HEAD — ERP 채널 추가 설정 (corp_tlwn_virt_brcd=ERP 조건) ★ 신규

필드
tx_cmgr_cd S004
mgmt_brcd 260
tx_brcd 260
insl_brcd 260
blng_brcd 260

EZDATA — ERP 채널 자동 설정 (corp_tlwn_virt_brcd=ERP 조건) ★ 신규

필드 설정값
elfn_bnkn_dvcd 10
svr_tx_seqno System.currentTimeMillis() / 1000L (Unix timestamp 10자리)
elfn_mac 서버 MAC 주소
pc_ofcl_ipad 서버 IP
pc_prvat_ipad 서버 IP
elfn_spr_fild ERP

2.2 응답 메시지 필수 처리 항목 (스펙 기준)

항목 스펙 기존 구현 결과
guid_prgs_no +1 요청값 +1 변경 없음 ★ 수정
dman_rspn_dvcd = R 응답 시 R 변경 없음 ★ 수정
mesg_rspn_dt 오늘 날짜 정상 유지
mesg_rspn_time 응답 시간 9자리 정상 유지
정상 MSG msg_list_rowcnt 0 00001 (1건) ★ 수정
정상 MSG msg_list 행 생성 불필요 1건 생성 ★ 수정
오류 MSG_LIST outp_msg_desc 설정 필요 미설정 ★ 추가
오류 MSG_LIST err_occu_loct 설정 필요 미설정 ★ 추가

3. StandardMessageCoordinatorDJB.java 수정

3.1 coordinateAfterCreateMessageByRule — ERP 분기 추가

기존: IP/MAC 설정 후 종료
수정: corp_tlwn_virt_brcd=ERP 일 때 HEAD 지점코드 및 EZDATA 전자금융공통영역 설정 추가

// 네트워크 정보 수집 구조 변경 (setNetworkInfo → collectNetworkInfo 반환값 활용)
String[] netInfo = collectNetworkInfo();
String ipv4 = netInfo[0];
String mac  = netInfo[1];

// ERP 채널 분기
String corpTlwn = StringUtils.trimToEmpty(standardMessage.findItemValue(HEAD_CORP_TLWN_VIRT_BRCD));
if ("ERP".equals(corpTlwn)) {
    setErpHeadFields(standardMessage);   // tx_cmgr_cd, mgmt_brcd, tx_brcd, insl_brcd, blng_brcd
    setEzdataFields(standardMessage, ipv4, mac);  // EZDATA 6개 필드
}

3.2 coordinateBeforeResponse — guid_prgs_no +1, dman_rspn_dvcd=R 추가

// GUID 진행번호 +1
mapper.nextGuidSeq(standardMessage);

// 요청응답구분 = 응답(R)
mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);

3.3 coordinateAfterRecvNonStdSyncResponse — 정상 MSG 수정

항목 수정 전 수정 후
outp_msg_cd "000000000000" "NCMM00001 "
outp_msg_ctnt "정상처리" "정상처리되었습니다."
msg_list_rowcnt "00001" "00000"
msg_list 행 생성 1건 생성 제거 (rowcnt=0)

3.4 coordinateSetStandardMessageError — MSG_LIST 항목 추가

// 기존: outp_msg_cd, outp_msg_ctnt 만 설정
// 추가:
if (row.containsKey("outp_msg_desc")) row.get("outp_msg_desc").setValue(siteErrMsg);
if (row.containsKey("err_occu_loct")) row.get("err_occu_loct").setValue(errCode);

4. 추가 테스트 파일

4.1 StandardMessageEzdataJsonFlowTest (22개)

EZDATA 포함 표준전문 JSON 처리 흐름 통합 테스트.

테스트 그룹 케이스 수 검증 내용
ERP 요청 파싱 2 EZDATA 블록 활성, HEAD corp_tlwn_virt_brcd=ERP
EZDATA 핵심 필드 6 usr_no, rgsr_id, elfn_bnkn_dvcd, secu_media_dvcd, dup_tx_yn, login_mhod_dvcd
비ERP 요청 3 ERP 전용 필드 미설정, BIZ_DATA 정상 파싱
JSON 왕복 일관성 4 EZDATA·guid·BIZ_DATA 직렬화 보존
coordinateAfterCreateMessageByRule 2 EZDATA 보존, usr_no 미변경
coordinateBeforeResponse 2 EZDATA 포함 직렬화, mesg_rspn_dt 형식
오류 응답 3 EZDATA 보존, procs_rslt_dvcd=F, MSG EM

4.2 StandardMessageSpecTest (62개)

표준전문 처리 스펙 전체 항목 검증. @Nested 6개 그룹으로 구조화.

테스트 그룹 케이스 수 검증 내용
요청 HEAD 레이아웃 기본값 9 nxgn_stnd_idfr·stnd_mesg_ver·frst_trnm_sys_dvcd·trnm_sys_dvcd·dman_rspn_dvcd·sys_env_dvcd·tx_tycd·synz_dvcd·chnl_tycd
coordinateAfterCreateMessageByRule 11 GUID 40자·갱신·guid_prgs_no=001·ortr_guid=guid·frst_mesg_dman_dt·time·trnm_sys_dvcd=EAI·sys_env_dvcd·IP·MAC·BIZ_DATA 유지
ERP 채널 처리 13 HEAD 5개 지점코드·EZDATA elfn_bnkn_dvcd=10·svr_tx_seqno 숫자·elfn_mac·pc_ofcl_ipad·pc_prvat_ipad·elfn_spr_fild=ERP·비ERP 미설정
coordinateBeforeResponse 8 guid_prgs_no+1→002·dman_rspn_dvcd=R·mesg_rspn_dt·time·guid 유지·if_id 유지·tx_id 유지·BIZ_DATA 유지
정상 응답 MSG 8 procs_rslt_dvcd=S·msg_dvcd=NM·msg_list_rowcnt=0·outp_atrb_cd=0·msg_cd 설정·msg_ctnt 설정·JSON NM·BIZ_DATA 설정
오류 응답 MSG 13 procs_rslt_dvcd=F·dman_rspn_dvcd=R·msg_dvcd=EM·outp_atrb_cd=1·rowcnt=1·msg_cd·msg_ctnt·MSG_LIST outp_msg_cd·ctnt·desc·err_occu_loct·JSON EM·BIZ_DATA

5. 기존 테스트 수정

변경된 coordinateAfterRecvNonStdSyncResponse 동작(msg_cd·ctnt·rowcnt)을 반영하여 기존 테스트 3개 수정.

StandardMessageCoordinatorDJBTest.java

수정 전 메서드명 수정 후 메서드명 변경 내용
정상수신시_outp_msg_cd_000000000000_설정 정상수신시_outp_msg_cd_설정됨 하드코딩 값 검증 → 비어있지 않음 검증
정상수신시_outp_msg_ctnt_정상처리_설정 정상수신시_outp_msg_ctnt_설정됨 "정상처리" 고정값 검증 → 비어있지 않음 검증
정상수신시_msg_list_1건_구성 정상수신시_msg_list_rowcnt_0 rowcnt=1 → rowcnt=0 으로 스펙 변경 반영

StandardMessageJsonFlowTest.java

수정 메서드 변경 내용
비표준수신_정상응답_JSON_직렬화_outp_msg_ctnt_정상처리 "정상처리" 고정값 검증 → 비어있지 않음 검증

6. 최종 테스트 결과

테스트 클래스 케이스 수 결과
GUIDGeneratorDJBTest 5
InterfaceMapperDJBTest 22
StandardLayoutDJBTest 18
StandardMessageManagerInitTest 17
StandardMessageCoordinatorDJBTest 27
StandardMessageJsonFlowTest 28
StandardMessageEzdataJsonFlowTest 22
StandardMessageSpecTest 61
RequestProcessorStdMsgTest 12
기타 11
합계 182 전체 통과

6-2. CSV 기본값 이관 리팩터링

배경

Coordinator에 하드코딩된 고정값들을 standard-layout-djb.csv 기본값(마지막 컬럼)으로 옮겨 코드 변경 없이 CSV 수정만으로 대응 가능하도록 개선.

standard-layout-djb.csv 변경 내용

필드 변경 내용
tx_cmgr_cd 기본값 S004 추가
mgmt_brcd 기본값 260 추가
tx_brcd 기본값 260 추가
insl_brcd 기본값 260 추가
blng_brcd 기본값 260 추가
outp_msg_cd (MAIN_MSG) 기본값 NCMM00001 추가
outp_msg_ctnt (MAIN_MSG) 기본값 정상처리되었습니다. 추가
msg_list_rowcnt 기본값 000000 수정 (NUMBER 타입 선행 0 strip 반영)

StandardMessageCoordinatorDJB.java 변경 내용

  • setErpHeadFields() 메서드 및 관련 상수 5개(HEAD_TX_CMGR_CD 등) 제거
  • coordinateAfterCreateMessageByRule: setErpHeadFields() 호출 제거
  • coordinateAfterRecvNonStdSyncResponse: msg_dvcd, outp_atrb_cd, outp_msg_cd, outp_msg_ctnt, msg_list_rowcnt 명시적 setData 호출 제거 (CSV 기본값으로 대체)

테스트 수정

  • StandardMessageSpecTest: 비ERP_ERP_HEAD_필드_미설정 테스트 제거
    • tx_cmgr_cd가 CSV 기본값 S004로 항상 설정되므로 "비ERP에서 미설정" 조건이 무효화됨

6-3. EZDATA 조건 평가 리팩터링 — evaluateBlockCondition

배경

coordinateAfterCreateMessageByRule에서 EZDATA 활성화 조건을 "ERP".equals(corpTlwn)으로 하드코딩하고 있어, 조건 변경 시 Java 코드 수정이 필요했음.

CSV 레이아웃에 이미 조건 정보가 존재함:

EZDATA,1,3,1,1,0,1,HEAD.corp_tlwn_virt_brcd,ERP,

해결: Coordinator에 refPath/refValue 평가 헬퍼 추가

private boolean evaluateBlockCondition(StandardMessage standardMessage, StandardItem item) {
    String refPath  = item.getRefPath();
    String refValue = item.getRefValue();
    if (StringUtils.isBlank(refPath) || StringUtils.isBlank(refValue)) return true;
    String actualValue = StringUtils.trimToEmpty(standardMessage.findItemValue(refPath));
    boolean negate = refValue.startsWith("!");
    String compareValue = negate ? refValue.substring(1) : refValue;
    boolean matched = matchesAny(compareValue, actualValue);
    return negate ? !matched : matched;
}

private boolean matchesAny(String refValue, String actualValue) {
    for (String v : refValue.split("\\|")) {
        if (v.equals(actualValue)) return true;
    }
    return false;
}
  • ! 접두사: NOT 조건 (!S → S가 아닌 경우)
  • | 구분자: OR 조건 (NM|EM → NM 또는 EM)

변경 내용

항목 수정 전 수정 후
ERP_CODE 상수 "ERP" 하드코딩 제거
HEAD_CORP_TLWN_VIRT_BRCD 상수 "HEAD.corp_tlwn_virt_brcd" 제거
EZDATA 조건 분기 if ("ERP".equals(corpTlwn)) if (evaluateBlockCondition(msg, ezdataItem))
setEzdataFields() 시그니처 (StandardMessage, String, String) (StandardMessage, StandardItem, String, String)
elfn_spr_fild 설정값 "ERP" 리터럴 ezdataItem.getRefValue() (CSV에서 읽기)

7. 주요 이슈 및 해결

① NUMBER 타입 전체 zero strip (rowcnt 검증)

  • 현상: msg_list_rowcnt (NUMBER, 5자리)에 "00000" 설정 후 findItemValue()"" (빈 문자열)
  • 원인: StandardItem.toTypeValue()가 NUMBER 타입에서 선행 0 전부 제거 → 전체 0이면 빈 문자열
  • 해결: 테스트에서 빈 문자열을 "0"으로 normalize 후 Integer.parseInt() 비교
String normalized = (rowcnt == null || rowcnt.trim().isEmpty()) ? "0" : rowcnt.trim();
assertEquals(0, Integer.parseInt(normalized), "정상 응답 msg_list_rowcnt는 0이어야 함");

② EZDATA 조건부 직렬화 — MSG 블록과 다른 동작

  • 현상: 비ERP 요청(corp_tlwn_virt_brcd 미설정) 직렬화 시에도 EZDATA 블록이 기본값으로 포함됨
  • 원인: MSG 블록은 dman_rspn_dvcd=!S 조건으로 파싱 시 hidden 처리되지만, EZDATA는 해당 조건이 직렬화 시 재평가되지 않고 기본값으로 렌더링됨
  • 해결: 비ERP 테스트에서 "EZDATA 없음" 대신 "ERP 전용 필드(usr_no, rgsr_id)가 빈 값" 검증으로 전환

setNetworkInfo 리팩터링 — EZDATA 재사용

  • 배경: 기존 setNetworkInfo(StandardMessage) private 메서드는 IP/MAC을 수집·설정만 하고 반환값 없음
  • 문제: EZDATA 설정 시 IP/MAC을 다시 수집해야 하므로 중복 발생
  • 해결: collectNetworkInfo() 로 분리 (String[] 반환), coordinateAfterCreateMessageByRule 에서 한 번만 수집 후 HEAD와 EZDATA에 공유

8. 향후 작업

  • elfn_bnkn_dvcd 기본값 CSV 수정 (0110) — 비ERP 요청의 기본값 정합성 확인
  • svr_tx_seqno 10자리 검증 — Unix timestamp가 10자리인지 2038년 이후 11자리 여부 확인
  • outp_msg_cd 정상코드 "NCMM00001" — DJBank 메시지 코드 체계 확인 후 확정
  • ERP 채널 실서버 통합 테스트 — EZDATA 전자금융공통영역 정상 전달 검증