84 Commits

Author SHA1 Message Date
curry772 1240b24c90 BIZ_DATA 항목 추가 2026-06-12 09:08:02 +09:00
curry772 7346c3070d eaiSvcCd 추출 로직 변경
- StandarMessage에 이미 eaiSvcCd가 설정되어 있으면 그것을 이용(비표준)
- 표준전문에서 조합하도록 수정(표준)
2026-06-12 09:07:40 +09:00
curry772 9a597a52ac afterFoundEaiMessage 함수에 프러퍼티 이용 헤더매핑 로직 추가
- DJB_IN_HTTHEAD_STDHEAD_MAPPING 프러퍼티 그룹 이용
2026-06-12 09:05:50 +09:00
curry772 5653a183eb GUID 생성 시 시스템코드 OPA 사용으로 변경 2026-06-12 09:01:27 +09:00
curry772 0e3a612bc0 TemplateAdapterErrorMsgHandler 를 이용하여 오류메시지 생성할 수 있도록 변경 2026-06-09 13:49:32 +09:00
curry772 68c29b962e feat: StandardMessageCoordinatorDJB에 callProp refValue 값 주입 기능 추가
- coordinateAfterCreateMessageByRule에서 StandardItem의 refValue가
   \${callProp.키} 패턴이면 Properties에서 값을 꺼내 setValue로 설정한다.
- \${callProp.키:기본값} 구문으로 기본값 지정 가능
- 점(.) 구분으로 Properties/Map 중첩 구조 탐색 지원
- GROUP 타입 재귀 순회, GRID/FARRAY는 건너뜀
2026-06-05 17:20:09 +09:00
curry772 dafe80f8bc fix: SiftingAppender 파일 락 해결 및 거래 로그 on/off 제어 추가
- DJErpApiAdapterController: MDC 제어를 TxSiftContext.begin/end로 교체
- TxSiftContext.end()를 별도 finally로 분리하여 항상 실행 보장
- elink-online-core: Logger SiftingAppender 개선 (submodule)
- elink-online-common: TxSiftContext 추가 (submodule)
2026-06-05 14:06:40 +09:00
curry772 9e78a0e199 ApiRequestBodyFilter 테스트를 위한 url pattern /dj/* 추가 2026-06-02 18:08:11 +09:00
curry772 3ec18b17e8 테스크 코드 이동 2026-06-02 18:06:55 +09:00
curry772 90464ee33f 성능 튜닝 2026-06-02 18:06:29 +09:00
curry772 60e6b30c9b api id, eai svc cd 추출 부분 ApiKeyExtractFilter로 이동 2026-06-02 18:06:19 +09:00
curry772 7d89d6d43e XML 메시지 지원 2026-06-02 08:30:51 +09:00
curry772 7109c56623 DJBank에 필요없는 클래스 정리
- 타 사이트 설정파일 및 표준전문 클래스
2026-06-01 09:57:06 +09:00
curry772 6a53e29710 eai.tableowner AGWADM -> AGWAPP 변경 2026-06-01 09:41:10 +09:00
curry772 eff7b31490 암복호화 함수 이름 변경 및 단위테스트 추가
- 클래스이름 오타 수정
- Parser 단위 테스트 추가
2026-06-01 08:58:08 +09:00
curry772 e2950a339f API 수신 RequestMapping 추가 2026-05-28 13:31:35 +09:00
curry772 01e4e36345 HsmContextSha256KeyDerivationStrategy 추가
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:30:37 +09:00
curry772 698b3ca7b6 JWT 서명 알고리즘 RS256 → PS256 교체 — AuthorizationServerConfig
PssJwtAccessTokenConverter 적용

- jwtAccessTokenConverter()에서 PssJwtAccessTokenConverter 사용으로 변경
- 기존 JwtAccessTokenConverter + setKeyPair() → new
PssJwtAccessTokenConverter(privateKey, publicKey)
- PEM 도출·setVerifierKey() 호출은 생성자 내부로 이전
- elink-online-common 서브모듈 업데이트 (RsaPssSigner, RsaPssVerifier,
PssJwtAccessTokenConverter 추가)
2026-05-28 13:28:41 +09:00
curry772 c74d1777df Dynamic IV 도출 지원 — DerivedKey iv 필드 추가, HsmKeyAndIvDerivationStrategy 구현 2026-05-27 13:48:23 +09:00
curry772 c95307901e DJBErp -> DJB 클래스 이름 첨자 변경 2026-05-27 10:49:22 +09:00
curry772 c12ff0a64a chore: 서브모듈들 master HEAD로 업데이트 2026-05-27 10:34:25 +09:00
curry772 1c82f0121c 설계서 ignore 추가 2026-05-27 10:33:23 +09:00
curry772 82998b475c DJBRequestProcessor Override 메소드 시그니쳐 변경 2026-05-27 10:32:08 +09:00
curry772 7336267b32 Reload/RemoveInflowClientControlCommand 패키지 이동 2026-05-27 10:30:54 +09:00
curry772 8d69c459d9 클라이언트 유량제어 관련 단위테스트 eapim-online 이동 2026-05-26 16:36:16 +09:00
curry772 4f54ee5259 클라이언트 유량제어 eapim-online 이동 2026-05-26 16:33:15 +09:00
curry772 912a282b54 body 전체 암복호화 대상 필터 (설계서 작성 코딩) 2026-05-26 15:16:54 +09:00
curry772 e8c379f3c7 대상 없는 암복호화 필터 제거 2026-05-26 13:43:10 +09:00
curry772 6ab138b63a 전체 body 암호화를 사용하지 않는 기관의 필터 제거
- 카카오페이, 네이버페이
2026-05-26 13:41:29 +09:00
curry772 c2ad7be7e4 전체암호화를 상용하지 않는 기관의 필터 제거
- 카카오페이, 네이버페이
2026-05-26 13:40:52 +09:00
curry772 aea4134437 Erp 응답용 외부 암호화 없음 2026-05-26 13:28:32 +09:00
curry772 bf91d02be7 암복호화 function 개발
- 암호화모듈서비스(CryptoModuleService)를 호출하여 암복호화 수행하는 function
2026-05-26 10:15:22 +09:00
curry772 9fcce55966 coordinateAfterParsing 수정 2026-05-26 09:54:53 +09:00
curry772 1f285c3bfd DJBank 암복호화필터 설계
- 기관별 InCryptoFilter를 상속한 필터 설계
- 기관별 OutCryptoFilter를 상송한 필터 설계
- 대상 기관 : 카카오뱅크, 카카오페이, 네이버Fn, 토스뱅크, 제주은행, DJErp
2026-05-26 09:51:53 +09:00
curry772 13608ebc8e chore: elink-online-common/core 서브모듈을 master HEAD로 업데이트 2026-05-19 11:22:18 +09:00
curry772 202538c50c 거래파일로그(SIFT_LOGGER) 출력기능 개발
- UUID별로 거래파일로그 생성
2026-05-19 11:19:39 +09:00
curry772 ade012a1f7 JSON 메시지 validation 기능 수정
- 기본 동작 변경 : transformer.validation=true
2026-05-18 14:01:42 +09:00
curry772 abe3756f69 chore: elink-online-common 서브모듈을 master HEAD로 업데이트 2026-05-18 10:58:50 +09:00
curry772 65fc0d0df4 context.xml rename 2026-05-18 10:49:49 +09:00
curry772 c34a2c019b 분별 통계 메트릭 로직 변경
- totoalCnt는 400시점으로 변경
- 시간 메트릭 생성 동작 기본값 false로 기본 처리하지 않도록 변경
2026-05-18 10:46:43 +09:00
curry772 6dbe557584 chore: elink-online-common 서브모듈을 master HEAD로 업데이트
feature/cryptofilter 머지 후 생성된 머지 커밋 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:24:54 +09:00
curry772 1185329b78 Merge branch 'feature/cryptofilter' 2026-05-14 15:24:20 +09:00
curry772 a86d1ba30f chore: elink-online-common 서브모듈 업데이트 (JSON 파싱 횟수 최적화)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 14:53:55 +09:00
curry772 17a343c4ac chore: elink-online-common 서브모듈 업데이트 (decryptField mergeAtRoot 수정)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 13:35:10 +09:00
curry772 dd352fef42 chore: elink-online-common 서브모듈 업데이트 (BaseCryptoFilter 잔여 참조 수정)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:28:08 +09:00
curry772 656cd39d30 refactor: CryptoFilter → InCryptoFilter 참조 교체 및 서브모듈 업데이트
- DJBErpCryptoFilter: CryptoFilter → InCryptoFilter 상속 변경
- EncFieldCryptoFilter: BaseCryptoFilter → InCryptoFilter 사용으로 변경
- DJErpApiAdapterService: CryptoFilter.PROP_MODULE_NAME → AbstractCryptoFilter.PROP_MODULE_NAME
- elink-online-common 서브모듈 feature/cryptofilter 브랜치 반영

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:26:50 +09:00
curry772 7be74095c5 refactor: HttpAdapterFilterFactoryKjb 제거 - elink-online-common 서브모듈 업데이트
- DJErpApiAdapterController 임포트를 HttpAdapterFilterFactory로 교체
- elink-online-common 서브모듈 포인터 업데이트 (c4a250d)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:18:22 +09:00
curry772 28b233aeff refactor: HttpClient5 어댑터 필터 패키지를 elink-online-common으로 이동
- custom/kjb/adapter/http/client/filter/ 패키지 삭제 (elink-online-common으로 이동)
- custom/kjb/adapter/http/client/impl/HttpClient5AdapterServiceRestAddFilter.java 삭제
- elink-online-common 서브모듈 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 15:58:32 +09:00
curry772 7a5958481f chore: elink-online-common 서브모듈 업데이트 (테스트 로그 추가)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:54:00 +09:00
curry772 ac15633b21 Merge branch 'feature/crypto-module'
CryptoFilter 암복호화 필터, HSM 연동, EncFieldCryptoFilter 실거래 검증 완료
2026-05-13 13:30:21 +09:00
curry772 158987b367 feat: EncFieldCryptoFilter 추가 및 DJErp 어댑터 암호화 모듈 연동
- EncFieldCryptoFilter 추가: /encryptedData 경로 고정 CryptoFilter 구현체
  (CryptoAdapterFilter 대체, custom 패키지로 분리)
- DJErpApiAdapterService: CRYPTO_MODULE_NAME 프로퍼티 transactionProp에 전달
- elink-online-common 서브모듈 업데이트
  (CryptoFilter UPPER_UNDERSCORE 키, HSM 통합 테스트 포함)
- elink-online-transformer 서브모듈 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:30:09 +09:00
curry772 bf9f865508 feat: elink-online-transformer 서브모듈 업데이트 (ConcatN 함수 추가)
- ConcatN: 파라미터 수 제한 없는 가변 문자열 연결 함수 (numberOfParameters=-1)
- ConcatNFunctionTest, ConcatNParserTest 단위테스트 추가
- .gitignore에 작업내역 문서 패턴 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 20:07:47 +09:00
curry772 9c9ad8c19c Merge branch 'feature/crypto-module'
- HSM 키 파생 전략 elink-online-common으로 이동
- HsmContextSha256KeyDerivationStrategyTest elink-online-common으로 이동
- elink-online-common 서브모듈 업데이트 (CryptoFilter AAD 지원 + 단위테스트)
2026-05-12 20:07:10 +09:00
curry772 8ace28675b feat: elink-online-common 서브모듈 업데이트 (CryptoFilter AAD 지원 + 단위테스트)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 18:15:54 +09:00
curry772 1ab36c077b feat: HsmContextSha256KeyDerivationStrategyTest elink-online-common으로 이동
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:37:30 +09:00
curry772 547232bb26 feat: HSM 키 파생 전략 elink-online-common으로 이동 및 서브모듈 업데이트
- HsmContextSha256KeyDerivationStrategy: custom 패키지에서 elink-online-common으로 이동
- elink-online-common: feature/crypto-module 브랜치 (HSM 전략 클래스 + master 머지)
- elink-online-core-jpa: CryptoModuleConfig JPA Entity 및 Loader 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:34:20 +09:00
curry772 ebd89afa0d Merge branch 'feature/template-adapter-error-msg-handler' 2026-05-12 13:06:21 +09:00
curry772 407eccc827 feat: elink-online-common 서브모듈 업데이트 (기본값 문법 + JSON 파싱)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 13:05:43 +09:00
curry772 cebdfd6a19 fix: elink-online-common 서브모듈 업데이트 (PropManager 목 객체 수정)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 10:47:54 +09:00
curry772 1fd8712de0 Merge branch 'feature/template-adapter-error-msg-handler' into master 2026-05-12 09:44:19 +09:00
curry772 be204abb5e feat: elink-online-common 서브모듈 업데이트 (TemplateAdapterErrorMsgHandler)
서브모듈 elink-online-common 을 feature/template-adapter-error-msg-handler
브랜치의 신규 커밋으로 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:43:00 +09:00
curry772 c2ad6d2423 Merge branch 'feature/inflow-control-improvement' into master 2026-05-08 10:51:48 +09:00
curry772 b6954139fe fix: custom.inflow 컴포넌트 스캔 추가 및 /manage/* FrontFilter 등록
- authserver-servlet.xml: com.eactive.eai.custom.inflow 패키지 component-scan 추가
  (ClientInflowTargetBucketController/MetricController 빈 등록)
- web.xml: FrontFilter url-pattern에 /manage/* 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 10:50:14 +09:00
curry772 d46fa8bd1a refactor: 클라이언트 버킷 상태 모니터링 custom.inflow 패키지로 분리
- InflowTargetBucketService/Controller에서 클라이언트 관련 메서드/엔드포인트 제거
- ClientInflowTargetBucketService/Controller를 custom.inflow 패키지에 신규 생성
  (ClientInflowTargetMetricService/Controller 패턴과 일치)
- 관련 단위 테스트 추가 및 기존 테스트에서 클라이언트 케이스 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 10:22:15 +09:00
curry772 31171d0187 feat: 클라이언트 유량제어/RequestProcessor custom 패키지로 분리
- DJBRequestProcessor: inbound.processor → custom.inbound.processor 이동
- ClientInflowTargetMetricService/Controller: custom.inflow 패키지 신규 생성
  클라이언트 메트릭 API(/manage/inflow/client/**)를 InflowTargetMetric*에서 분리
- InflowTargetMetricService/Controller: 클라이언트 관련 메서드/엔드포인트 제거
- InflowTargetBucketService: getClientDualManager() 분리 반영
- standard-message-config.properties: requestProcessor.class 경로 업데이트
- 단위 테스트: ClientInflowTargetMetric{Service,Controller}Test 추가,
  기존 테스트에서 클라이언트 케이스 분리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:02:51 +09:00
curry772 45ad9d8b6f Merge branch 'feature/crypto-module' into master 2026-05-07 15:39:00 +09:00
curry772 dd02c5902e feat: DJB ERP 연동 암복호화 필터 추가 및 단위테스트 작성
- DJBErpCryptoFilter: CryptoFilter 상속, httpHeaderGroup 헤더 JSON에서
  x-emp-nm(groupSeq|empNo) 파싱 → groupSeq를 runtimeContext로 전달
- DJBErpCryptoFilterTest: 17개 단위테스트 (buildRuntimeContext/doPreFilter/doPostFilter)
- elink-online-common 서브모듈 업데이트 (CryptoFilter 기반 클래스 포함)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 15:04:01 +09:00
curry772 c225104711 feat: 암호화모듈 프레임워크 적용 및 사이트 특화 전략 추가
- 서브모듈 포인터 업데이트 (elink-online-common, elink-online-core-jpa)
- HsmContextSha256KeyDerivationStrategy: SHA-256(masterKey || contextValue) 키 도출 전략
  elink-online-common에서 eapim-online custom 패키지로 분리 (사이트 의존성)
  FQCN: com.eactive.eai.custom.security.keyderiv.strategy.HsmContextSha256KeyDerivationStrategy
- HsmContextSha256KeyDerivationStrategyTest 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 16:50:17 +09:00
curry772 efcc7fe208 Merge branch 'feature/inflow-control-improvement'
- AbstractInflowControlManager 상속 구조 리팩토링
- DualInflowControlManager DAO 이중 호출 제거 및 타겟 메트릭 추가
- 어댑터/인터페이스/클라이언트 유량제어 메트릭 API 추가
- 관련 단위테스트 수정 및 추가
2026-04-30 10:17:15 +09:00
curry772 8bcbee7e52 feat: 어댑터/인터페이스/클라이언트 유량제어 메트릭 API 추가
InflowTargetMetricController / InflowTargetMetricService / TargetMetricDTO 추가.
어댑터·인터페이스·클라이언트별 허용/초당거절/임계거절 카운터 조회 및 초기화 API 제공.
단위테스트: InflowTargetMetricServiceTest(26건), InflowTargetMetricControllerTest(16건).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 10:16:10 +09:00
curry772 04aa0df977 refactor: InflowGroupBucketService / InflowTargetBucketService AbstractInflowControlManager 타입 적용
서브모듈 리팩토링(AbstractInflowControlManager 분리)에 맞춰
InflowControlManager.getInstance() 호출을 InflowControlUtil.getInflowControlManager()로 변경.
반환 타입을 AbstractInflowControlManager로 통일.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 10:15:55 +09:00
curry772 2eeee58d35 test: 버킷 상태 모니터링 Service/Controller 단위 테스트 추가
getDualManager()를 protected로 변경하여 서브클래스 오버라이드 방식으로 mock 주입

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 15:15:18 +09:00
curry772 5f24bacd48 feat: 어댑터/인터페이스/클라이언트 버킷 상태 모니터링 API 추가
- InflowTargetBucketController: 버킷 상태 조회 REST API
  GET /manage/inflow/adapter/bucket-status
  GET /manage/inflow/adapter/{adapterId}/bucket-status
  GET /manage/inflow/interface/bucket-status
  GET /manage/inflow/interface/{interfaceId}/bucket-status
  GET /manage/inflow/client/bucket-status
  GET /manage/inflow/client/{clientId}/bucket-status
- InflowTargetBucketService: DualInflowControlManager 에서 버킷 상태 조회
- TargetBucketStatusDTO: 어댑터/인터페이스/클라이언트 공통 버킷 상태 DTO

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 14:59:26 +09:00
curry772 21c3bcbc6a chore: elink-online-common 서브모듈 포인터 업데이트 (TypedCircuitBreaker 단위테스트)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 14:47:30 +09:00
curry772 aff3ed6658 Merge branch 'feature/hsm-integration-jdk8' into master 2026-04-29 12:59:41 +09:00
curry772 8947fc248f chore: elink-online-common 서브모듈 포인터 업데이트 (HSM 캐시/PropManager 연동)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 12:59:26 +09:00
curry772 58f659a179 chore: elink-online-common 서브모듈 포인터 업데이트 (HSM 연동)
feat: SafeNet HSM 연동 구현 (JDK 8 / SunPKCS11) 커밋 반영
  서브모듈 d08c7ef → acdb580

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 20:52:45 +09:00
curry772 745df6d073 Merge branch 'feature/inflow-control-improvement' into master 2026-04-27 17:25:10 +09:00
curry772 4a41398f03 Merge branch 'feature/jejubank-oauth-bypass' into master 2026-04-27 16:42:03 +09:00
curry772 3a578b3c70 토큰 발급 실패 오류 추가 - 미확인오류추가 2026-04-27 15:58:36 +09:00
curry772 4d479e4fd6 refactor: DualRequestProcessor 패키지 이동 반영
- standard-message-config.properties: requestProcessor.class 경로 수정
  com.eactive.eai.common.inflow.dual → com.eactive.eai.inbound.processor
- elink-online-common 서브모듈 포인터 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 13:50:58 +09:00
curry772 780b9bd934 feat: 그룹 유량제어 메트릭 API 추가
- GroupMetricDTO: allowed/rejectedPerSecond/rejectedThreshold/rejectRatio 등
- InflowGroupMetricService: DualInflowControlManager를 통한 메트릭 조회·초기화
  (getManager() protected 처리 — 단위 테스트 서브클래싱 지원)
- InflowGroupMetricController: 4개 엔드포인트
  GET  /{groupId}/metric, GET  /metric
  POST /{groupId}/metric/reset, POST /metric/reset
- 단위 테스트 2종 (Service 16건, Controller 8건) 전체 통과
- elink-online-common 서브모듈 포인터 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 09:40:46 +09:00
curry772 42f52a4974 refactor: InflowGroupBucketService 리플렉션 제거
Field 리플렉션으로 groupBucketList에 직접 접근하던 getCustomGroupBucket()을
InflowControlManager.getGroupBucket() public 메서드 호출로 교체.
불필요한 java.lang.reflect.Field, Map import 및 @SuppressWarnings 제거.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 15:21:15 +09:00
curry772 1a79c39e76 Merge branch 'feature/standard-message-djb' 2026-04-23 14:14:58 +09:00
133 changed files with 5840 additions and 5174 deletions
+2
View File
@@ -239,3 +239,5 @@ gradle-app.setting
# Claude Code # Claude Code
.claude/ .claude/
/작업내역*.md /작업내역*.md
/설계서*.md
/분석서*.md
@@ -25,6 +25,9 @@
base-package="com.eactive.eai.adapter" /> base-package="com.eactive.eai.adapter" />
<context:component-scan <context:component-scan
base-package="com.eactive.eai.manage" /> base-package="com.eactive.eai.manage" />
<context:component-scan
base-package="com.eactive.eai.custom.inflow" />
<context:annotation-config /> <context:annotation-config />
<mvc:annotation-driven /> <mvc:annotation-driven />
<mvc:default-servlet-handler /> <mvc:default-servlet-handler />
@@ -18,5 +18,5 @@ eai.rmiserviceport=30112
eai.systemmode=D eai.systemmode=D
# EAI FEP MCI GW ... # EAI FEP MCI GW ...
eai.systemtype=API eai.systemtype=API
eai.tableowner=AGWADM eai.tableowner=AGWAPP
eai.server.extractor=[0,2],[0,2],[-2] eai.server.extractor=[0,2],[0,2],[-2]
@@ -1,2 +1,2 @@
#\uae30\uc874 ENV \ud56d\ubaa9 \uc678 \uae30\ud0c0 \uc2dc\uc2a4\ud15c \ud504\ub85c\ud37c\ud2f0\ub85c \uc815\uc758\uac00 \ud544\uc694\ud55c \ud544\ub4dc\ub97c \uc815\uc758 #\uae30\uc874 ENV \ud56d\ubaa9 \uc678 \uae30\ud0c0 \uc2dc\uc2a4\ud15c \ud504\ub85c\ud37c\ud2f0\ub85c \uc815\uc758\uac00 \ud544\uc694\ud55c \ud544\ub4dc\ub97c \uc815\uc758
transformer.validation=false transformer.validation=true
+2 -1
View File
@@ -19,6 +19,7 @@
<url-pattern>/agent/*</url-pattern> <url-pattern>/agent/*</url-pattern>
<url-pattern>/common/*</url-pattern> <url-pattern>/common/*</url-pattern>
<url-pattern>/management/*</url-pattern> <url-pattern>/management/*</url-pattern>
<url-pattern>/manage/*</url-pattern>
<url-pattern>/mgr/*</url-pattern> <url-pattern>/mgr/*</url-pattern>
</filter-mapping> </filter-mapping>
@@ -29,7 +30,7 @@
<filter-mapping> <filter-mapping>
<filter-name>ApiRequestBodyFilter</filter-name> <filter-name>ApiRequestBodyFilter</filter-name>
<url-pattern>/api/*</url-pattern> <!-- 필요한 URL 패턴 --> <url-pattern>/api/*</url-pattern> <!-- 필요한 URL 패턴 -->
<url-pattern>/mapi/*</url-pattern> <!-- 필요한 URL 패턴 --> <url-pattern>/dj/*</url-pattern> <!-- 필요한 URL 패턴 -->
</filter-mapping> </filter-mapping>
-26
View File
@@ -1,26 +0,0 @@
# comment start with #
# level; // 0 : root ~ n
# type; // 0: Message, 1: Field, 2:Group 3, Array, 4 : BIZ DATA
# size // 0 : variable, > 0 fixed
# fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
# length;
# dataType; // 0: String, 1: Number
#name,level,type,size,fieldType,length,dataType,refPath,refValue,value
ElinkHeader ,0,0,1,0, 0,0,,,
Header ,1,2,1,1, 0,0,,,
StndCicsTrncd ,2,1,1,1,10,0,,,
StndIntnlStndTelgmLen,2,1,1,1,10,11,,,0
StndTranBaseYmd ,2,1,1,1,10,0,,,
Common ,1,2,0,0, 0,0,Header.StndCicsTrncd,JI6H,null
TranInfo ,2,2,1,0, 0,0,,,
StndCicsTrncd ,3,1,1,0, 3,0,,,
StndTelgmRecvTranCd ,3,1,1,0,10,0,,,
StndPrcssRtdTranCd ,3,1,1,0,10,0,,,
Array ,1,3,0,0, 3,0,,,
Item1 ,2,1,1,0,10,0,,,JI6H
Group ,2,3,1,0, 1,0,,,
gitem1 ,3,1,1,0,10,1,,,726
gitem2 ,3,1,1,0,10,0,,,20220905
FArray ,1,4,0,0,10,0,,,
bizData ,1,9,1,0, 0,0,,,
zzData ,1,1,1,0, 2,10,,,ZZ
1 # comment start with #
2 # level; // 0 : root ~ n
3 # type; // 0: Message, 1: Field, 2:Group 3, Array, 4 : BIZ DATA
4 # size // 0 : variable, > 0 fixed
5 # fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
6 # length;
7 # dataType; // 0: String, 1: Number
8 #name,level,type,size,fieldType,length,dataType,refPath,refValue,value
9 ElinkHeader ,0,0,1,0, 0,0,,,
10 Header ,1,2,1,1, 0,0,,,
11 StndCicsTrncd ,2,1,1,1,10,0,,,
12 StndIntnlStndTelgmLen,2,1,1,1,10,11,,,0
13 StndTranBaseYmd ,2,1,1,1,10,0,,,
14 Common ,1,2,0,0, 0,0,Header.StndCicsTrncd,JI6H,null
15 TranInfo ,2,2,1,0, 0,0,,,
16 StndCicsTrncd ,3,1,1,0, 3,0,,,
17 StndTelgmRecvTranCd ,3,1,1,0,10,0,,,
18 StndPrcssRtdTranCd ,3,1,1,0,10,0,,,
19 Array ,1,3,0,0, 3,0,,,
20 Item1 ,2,1,1,0,10,0,,,JI6H
21 Group ,2,3,1,0, 1,0,,,
22 gitem1 ,3,1,1,0,10,1,,,726
23 gitem2 ,3,1,1,0,10,0,,,20220905
24 FArray ,1,4,0,0,10,0,,,
25 bizData ,1,9,1,0, 0,0,,,
26 zzData ,1,1,1,0, 2,10,,,ZZ
-41
View File
@@ -1,41 +0,0 @@
#-----------------------------------------------------------------------------
# comment start with #
# level; // 0 : root ~ n
# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
# size // 0 : variable, > 0 fixed
# fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
# length;
# dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
STD_HNCPHEADER_REQ ,0 ,0 ,1 ,0 ,0 ,0 , , ,
msg_len ,1 ,1 ,1 ,0 ,6 ,1 , , ,199
global_id ,1 ,1 ,1 ,0 ,29 ,0 , , ,GIDNO00000000001111
service_id ,1 ,1 ,1 ,0 ,10 ,0 , , ,ELINKSVC01
service_cmt ,1 ,1 ,1 ,0 ,100 ,0 , , ,ELINK TEST Service
service_tn ,1 ,1 ,1 ,0 ,1 ,0 , , ,0
Session_id ,1 ,1 ,1 ,0 ,100 ,0 , , ,SESSIONID001
encrypt_yn ,1 ,1 ,1 ,0 ,2 ,0 , , ,NO
http_url ,1 ,1 ,1 ,0 ,100 ,0 , , ,
screen_id ,1 ,1 ,1 ,0 ,13 ,0 , , ,SCREEN0000001
scr_no ,1 ,1 ,1 ,0 ,30 ,0 , , ,000000000100000000020000000003
scr_dsc ,1 ,1 ,1 ,0 ,100 ,0 , , ,
usr_id ,1 ,1 ,1 ,0 ,10 ,0 , , ,USER000001
ip_addr ,1 ,1 ,1 ,0 ,47 ,0 , , ,
ip_mac ,1 ,1 ,1 ,0 ,12 ,0 , , ,
com_code ,1 ,1 ,1 ,0 ,4 ,0 , , ,EACT
head_code ,1 ,1 ,1 ,0 ,7 ,0 , , ,EACT001
dept_cd ,1 ,1 ,1 ,0 ,7 ,0 , , ,ELINK01
conn_tp ,1 ,1 ,1 ,0 ,2 ,0 , , ,CH
Inter_chn ,1 ,1 ,1 ,0 ,2 ,0 , , ,EA
recv_tm ,1 ,1 ,1 ,0 ,17 ,0 , , ,20220928000000000
send_tm ,1 ,1 ,1 ,0 ,17 ,0 , , ,
return_gubun ,1 ,1 ,1 ,0 ,1 ,0 , , ,S
return_value ,1 ,1 ,1 ,0 ,1 ,0 , , ,
msg_id ,1 ,1 ,1 ,0 ,7 ,0 , , ,
msg_nm ,1 ,1 ,1 ,0 ,250 ,0 , , ,
filler ,1 ,1 ,1 ,0 ,125 ,0 , , ,
bizData ,1 ,9 ,0 ,0 ,0 ,0 , , ,
1 #-----------------------------------------------------------------------------
2 # comment start with #
3 # level; // 0 : root ~ n
4 # type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
5 # size // 0 : variable, > 0 fixed
6 # fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
7 # length;
8 # dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
9 #-----------------------------------------------------------------------------
10 # name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
11 #-----------------------------------------------------------------------------
12 # name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
13 STD_HNCPHEADER_REQ ,0 ,0 ,1 ,0 ,0 ,0 , , ,
14 msg_len ,1 ,1 ,1 ,0 ,6 ,1 , , ,199
15 global_id ,1 ,1 ,1 ,0 ,29 ,0 , , ,GIDNO00000000001111
16 service_id ,1 ,1 ,1 ,0 ,10 ,0 , , ,ELINKSVC01
17 service_cmt ,1 ,1 ,1 ,0 ,100 ,0 , , ,ELINK TEST Service
18 service_tn ,1 ,1 ,1 ,0 ,1 ,0 , , ,0
19 Session_id ,1 ,1 ,1 ,0 ,100 ,0 , , ,SESSIONID001
20 encrypt_yn ,1 ,1 ,1 ,0 ,2 ,0 , , ,NO
21 http_url ,1 ,1 ,1 ,0 ,100 ,0 , , ,
22 screen_id ,1 ,1 ,1 ,0 ,13 ,0 , , ,SCREEN0000001
23 scr_no ,1 ,1 ,1 ,0 ,30 ,0 , , ,000000000100000000020000000003
24 scr_dsc ,1 ,1 ,1 ,0 ,100 ,0 , , ,
25 usr_id ,1 ,1 ,1 ,0 ,10 ,0 , , ,USER000001
26 ip_addr ,1 ,1 ,1 ,0 ,47 ,0 , , ,
27 ip_mac ,1 ,1 ,1 ,0 ,12 ,0 , , ,
28 com_code ,1 ,1 ,1 ,0 ,4 ,0 , , ,EACT
29 head_code ,1 ,1 ,1 ,0 ,7 ,0 , , ,EACT001
30 dept_cd ,1 ,1 ,1 ,0 ,7 ,0 , , ,ELINK01
31 conn_tp ,1 ,1 ,1 ,0 ,2 ,0 , , ,CH
32 Inter_chn ,1 ,1 ,1 ,0 ,2 ,0 , , ,EA
33 recv_tm ,1 ,1 ,1 ,0 ,17 ,0 , , ,20220928000000000
34 send_tm ,1 ,1 ,1 ,0 ,17 ,0 , , ,
35 return_gubun ,1 ,1 ,1 ,0 ,1 ,0 , , ,S
36 return_value ,1 ,1 ,1 ,0 ,1 ,0 , , ,
37 msg_id ,1 ,1 ,1 ,0 ,7 ,0 , , ,
38 msg_nm ,1 ,1 ,1 ,0 ,250 ,0 , , ,
39 filler ,1 ,1 ,1 ,0 ,125 ,0 , , ,
40 bizData ,1 ,9 ,0 ,0 ,0 ,0 , , ,
@@ -1,11 +0,0 @@
layout.file.type=CSV
layout.file.path=./resources/standard-layout-sample.csv
mapper.class=com.eactive.eai.message.test.TestInterfaceMapper
mapper.definition=./resources/standard-message-mapping-config.properties
reader.JSON=com.eactive.eai.message.parser.JsonReader
reader.JSN=com.eactive.eai.message.parser.JsonReader
reader.UJN=com.eactive.eai.message.parser.JsonReader
reader.XML=com.eactive.eai.message.parser.XmlReader
reader.UXL=com.eactive.eai.message.parser.XmlReader
reader.ASC=com.eactive.eai.message.parser.FlatReader
reader.FLAT=com.eactive.eai.message.parser.FlatReader
@@ -1,27 +0,0 @@
# layout : StandardMessage layout definition
#layout.file.type=CSV
layout.file.type=DB
#layout.file.path=standard-layout-sbi.csv
#layout.file.path=standard-layout-elk.csv
#layout.filter.FLAT=com.eactive.eai.custom.message.FlatMessageFilterSBI
layout.filter.FLAT=com.eactive.eai.message.filter.FlatMessageFilter
# mapper : StandardMessage's fields getter/setter interface
#mapper.class=com.eactive.eai.custom.message.InterfaceMapperSBI
mapper.class=com.eactive.eai.message.service.DefaultInterfaceMapper
#mapper.definition=standard-message-mapping-config-sbi.properties
#mapper.definition=standard-message-mapping-config-elk.properties
mapper.definition=standard-message-mapping-config-elk.properties
# StandardMessage Coordinator implementation
#message.coordinator.class=com.eactive.eai.custom.message.StandardMessageCoordinatorSBI
# RequestProcessor implementation
#requestProcessor.class=com.eactive.eai.inbound.processor.RequestProcessor
# reader : parsing input data to StandardMessage
reader.JSON=com.eactive.eai.message.parser.JsonReader
reader.JSN=com.eactive.eai.message.parser.JsonReader
reader.UJN=com.eactive.eai.message.parser.JsonReader
reader.XML=com.eactive.eai.message.parser.XmlReader
reader.UXL=com.eactive.eai.message.parser.XmlReader
reader.ASC=com.eactive.eai.message.parser.FlatReader
reader.FLAT=com.eactive.eai.message.parser.FlatReader
encode.flat=euc-kr
encode.xml=utf-8
@@ -1,16 +0,0 @@
# layout : StandardMessage layout definition
layout.file.type=DB
layout.db.testLayoutName=
layout.file.path=/development/intellij/elink-4.5/elink-online-multi/resources/standard-layout.csv
# mapper : StandardMessage's fields getter/setter interface
mapper.class=com.eactive.eai.message.service.DefaultInterfaceMapper
mapper.definition=/development/intellij/elink-4.5/elink-online-multi/resources/standard-message-mapping-config-elk.properties
# reader : parsing input data to StandardMessage
reader.JSON=com.eactive.eai.message.parser.JsonReader
reader.JSN=com.eactive.eai.message.parser.JsonReader
reader.UJN=com.eactive.eai.message.parser.JsonReader
reader.XML=com.eactive.eai.message.parser.XmlReader
reader.UXL=com.eactive.eai.message.parser.XmlReader
reader.ASC=com.eactive.eai.message.parser.FlatReader
reader.FLAT=com.eactive.eai.message.parser.FlatReader
@@ -1,26 +0,0 @@
REQ_SYS_CODE=commonHeader.firstReqSystemCode
CHANNEL_TYPE_CD=
CHANNEL_DETAIL_CD=
SEND_TIME=
GUID=commonHeader.globalId
SYSTEM_TYPE=
RECV_TIME=
RETURN_VALUE=
GUID_ORG=
GUID_SEQ=commonHeader.traceSeqNo
SERVICE_ID=commonHeader.serviceCode
RETURN_SERVICE_ID=
INTERFACE_ID=commonHeader.serviceCode
SESSION_ID=
SEND_RECV_DIVISION=commonHeader.reqResTypeCode
IN_EX_DIVISION=
OPERATION_ENV=
FIRST_REQ_IP=commonHeader.firstReqSystemIp
RECOVER_YN=
INST_CODE=
TIMEOUT=
ERROR_CODE=commonHeader.msgList[0].resultCode
ERROR_MSG=commonHeader.msgList[0].resultMsg
USER_ID=
RESPONSE_TYPE=
SYNC_ASYNC_TYPE=
@@ -1,29 +0,0 @@
REQ_SYS_CODE=systemHeader.DMND_SYS_CD
CHANNEL_TYPE_CD=stdcommon.chnlTycd
CHANNEL_DETAIL_CD=stdcommon.chnlDtlsClcd
SEND_TIME=stdheader.send_tm
GUID=stdheader.global_id
SYSTEM_TYPE=stdheader.Inter_chn
RECV_TIME=stdheader.recv_tm
RETURN_TYPE=stdheader.return_gubun
RETURN_VALUE=stdheader.return_value
GUID_ORG=stdcommon.ortrGuid
GUID_SEQ=stdheader.global_id
#SERVICE_ID=stdheader.service_id
SERVICE_ID=service_id
RETURN_SERVICE_ID=stdcommon.procsRsltRcmsSrvcId
INTERFACE_ID=stdheader.service_id
SESSION_ID=stdheader.Session_id
#SEND_RECV_DIVISION=stdheader.return_gubun
SEND_RECV_DIVISION=service_tn
IN_EX_DIVISION=stdcommon.hmabDvcd
OPERATION_ENV=stdcommon.sysOprtEnvDvcd
FIRST_REQ_IP=stdheader.ip_addr
RECOVER_YN=stdcommon.ortrRestrYn
INST_CODE=stdheader.com_code
TIMEOUT=stdheader.gnrzTmotTktm
ERROR_CODE=stdheader.msg_id
ERROR_MSG=stdheader.msg_nm
USER_ID=stdheader.usr_id
RESPONSE_TYPE=stdcommon.procsRsltDvcd
SYNC_ASYNC_TYPE=stdcommon.txSynzDvcd
@@ -1,27 +0,0 @@
REQ_SYS_CODE=Inter_chn
CHANNEL_TYPE_CD=
CHANNEL_DETAIL_CD=conn_tp
SEND_TIME=send_tm
GUID=global_id
SYSTEM_TYPE=service_tn
RECV_TIME=recv_tm
RETURN_TYPE=return_gubun
RETURN_VALUE=return_value
GUID_ORG=stdcommon.ortrGuid
GUID_SEQ=stdheader.global_id
SERVICE_ID=service_id
RETURN_SERVICE_ID=stdcommon.procsRsltRcmsSrvcId
INTERFACE_ID=stdheader.service_id
SESSION_ID=Session_id
SEND_RECV_DIVISION=service_tn
IN_EX_DIVISION=stdcommon.hmabDvcd
OPERATION_ENV=stdcommon.sysOprtEnvDvcd
FIRST_REQ_IP=ip_addr
RECOVER_YN=stdcommon.ortrRestrYn
INST_CODE=stdheader.com_code
TIMEOUT=stdheader.gnrzTmotTktm
ERROR_CODE=msg_id
ERROR_MSG=msg_nm
USER_ID=usr_id
RESPONSE_TYPE=stdcommon.procsRsltDvcd
SYNC_ASYNC_TYPE=stdcommon.txSynzDvcd
@@ -1,26 +0,0 @@
REQ_SYS_CODE=Inter_chn
CHANNEL_TYPE_CD=
CHANNEL_DETAIL_CD=conn_tp
SEND_TIME=send_tm
GUID=global_id
SYSTEM_TYPE=service_tn
RECV_TIME=recv_tm
RETURN_VALUE=return_value
GUID_ORG=stdcommon.ortrGuid
GUID_SEQ=stdheader.global_id
SERVICE_ID=service_id
RETURN_SERVICE_ID=stdcommon.procsRsltRcmsSrvcId
INTERFACE_ID=stdheader.service_id
SESSION_ID=Session_id
SEND_RECV_DIVISION=service_tn
IN_EX_DIVISION=return_gubun
OPERATION_ENV=stdcommon.sysOprtEnvDvcd
FIRST_REQ_IP=ip_addr
RECOVER_YN=stdcommon.ortrRestrYn
INST_CODE=stdheader.com_code
TIMEOUT=stdheader.gnrzTmotTktm
ERROR_CODE=msg_id
ERROR_MSG=msg_nm
USER_ID=usr_id
RESPONSE_TYPE=stdcommon.procsRsltDvcd
SYNC_ASYNC_TYPE=stdcommon.txSynzDvcd
@@ -21,6 +21,9 @@ import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager;
import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri;
import com.eactive.eai.common.stdmessage.STDMessageManager; import com.eactive.eai.common.stdmessage.STDMessageManager;
import com.eactive.eai.common.stdmessage.STDMsgInfoAddOnVO; import com.eactive.eai.common.stdmessage.STDMsgInfoAddOnVO;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
public class ApiRequestBodyFilter extends OncePerRequestFilter { public class ApiRequestBodyFilter extends OncePerRequestFilter {
@@ -32,17 +35,12 @@ public class ApiRequestBodyFilter extends OncePerRequestFilter {
HttpServletResponse response, HttpServletResponse response,
FilterChain filterChain) FilterChain filterChain)
throws ServletException, IOException { throws ServletException, IOException {
System.out.println("ApiRequestBodyFilter : " + request.getRequestURI());
if (!isTarget(request)) { if (!isTarget(request)) {
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
return; return;
} }
String encoding = getInboundGroupAdapterEncoding(request);
//원본 바디를 byte[]로 읽기 (개행 포함 그대로) 왜? 뒤에 필터에서 HMAC값 계산할수도 있어서 변조되면 안됨. 개행문자도 그대로 가야함. //원본 바디를 byte[]로 읽기 (개행 포함 그대로) 왜? 뒤에 필터에서 HMAC값 계산할수도 있어서 변조되면 안됨. 개행문자도 그대로 가야함.
byte[] rawBody = readBodyAsBytes(request); byte[] rawBody = readBodyAsBytes(request);
@@ -54,7 +52,8 @@ public class ApiRequestBodyFilter extends OncePerRequestFilter {
byte[] finalBody = rawBody; byte[] finalBody = rawBody;
try { try {
if(isJsonArray(rawBody)) {
String encoding = getInboundGroupAdapterEncoding(request);
String bodyStr = new String(rawBody, encoding); String bodyStr = new String(rawBody, encoding);
Object json = JSONValue.parse(bodyStr); Object json = JSONValue.parse(bodyStr);
@@ -62,6 +61,7 @@ public class ApiRequestBodyFilter extends OncePerRequestFilter {
bodyStr = DJB_ROOTLESS_ARRAY + bodyStr + "}"; bodyStr = DJB_ROOTLESS_ARRAY + bodyStr + "}";
finalBody = bodyStr.getBytes(encoding); finalBody = bodyStr.getBytes(encoding);
} }
}
} catch (Exception e) { } catch (Exception e) {
// JSON 파싱 실패 시 원본 유지 // JSON 파싱 실패 시 원본 유지
@@ -75,6 +75,14 @@ public class ApiRequestBodyFilter extends OncePerRequestFilter {
filterChain.doFilter(wrapped, response); filterChain.doFilter(wrapped, response);
} }
public static boolean isJsonArray(byte[] json) {
try (JsonParser parser = new JsonFactory().createParser(json)) {
return parser.nextToken() == JsonToken.START_ARRAY;
} catch (Exception e) {
return false;
}
}
private boolean isTarget(HttpServletRequest request) { private boolean isTarget(HttpServletRequest request) {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
// token 이 포함되면 무조건 제외 // token 이 포함되면 무조건 제외
@@ -1,7 +1,6 @@
package com.eactive.eai.adapter.controller; package com.eactive.eai.adapter.controller;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@@ -9,13 +8,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
// jwhong
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -23,24 +19,23 @@ import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager; import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.AdapterPropManager;
import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.adapter.handler.AdapterErrorMessageHandler;
import com.eactive.eai.adapter.handler.AdapterErrorMessageHandlerFactory;
import com.eactive.eai.adapter.http.HttpStatusException; import com.eactive.eai.adapter.http.HttpStatusException;
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager;
import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri; import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri;
import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter;
import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterFactoryKjb;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
import com.eactive.eai.adapter.service.DJErpApiAdapterService; import com.eactive.eai.adapter.service.DJErpApiAdapterService;
import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.stdmessage.STDMessageManager;
import com.eactive.eai.common.stdmessage.STDMsgInfoAddOnVO;
import com.eactive.eai.common.util.DatetimeUtil; import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.InboundErrorLogger; import com.eactive.eai.common.util.InboundErrorLogger;
import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil; import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.common.util.TxFileLogger;
import com.eactive.eai.common.util.TxSiftContext;
import com.eactive.eai.common.util.UUIDGenerator; import com.eactive.eai.common.util.UUIDGenerator;
import com.eactive.eai.inbound.error.InboundErrorInfoVO; import com.eactive.eai.inbound.error.InboundErrorInfoVO;
@@ -57,7 +52,16 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey {
* @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer * @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer
* endpoints) * endpoints)
*/ */
@RequestMapping(value = { "/dj/{path:^(?!oauth).*$}", "/dj/{path:^(?!oauth).*$}/**" }) @RequestMapping(value = {
"/dj/{path:^(?!oauth).*$}", "/dj/{path:^(?!oauth).*$}/**",
"/kp/{path:^(?!oauth).*$}", "/kp/{path:^(?!oauth).*$}/**",
"/kkb/{path:^(?!oauth).*$}", "/kkb/{path:^(?!oauth).*$}/**",
"/nf/{path:^(?!oauth).*$}", "/nf/{path:^(?!oauth).*$}/**",
"/bsd/{path:^(?!oauth).*$}", "/bsd/{path:^(?!oauth).*$}/**",
"/tss/{path:^(?!oauth).*$}", "/tss/{path:^(?!oauth).*$}/**",
"/tsb/{path:^(?!oauth).*$}", "/tsb/{path:^(?!oauth).*$}/**",
"/shb/{path:^(?!oauth).*$}", "/shb/{path:^(?!oauth).*$}/**",
})
public ResponseEntity<String> callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) public ResponseEntity<String> callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
throws Exception { throws Exception {
// /ONLWeb/api/v1/public/getUserInfo.svc // /ONLWeb/api/v1/public/getUserInfo.svc
@@ -101,82 +105,20 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey {
MediaType mediaType = MediaType.valueOf("application/json;charset=" + encode); MediaType mediaType = MediaType.valueOf("application/json;charset=" + encode);
String errorResponseFormat = httpProp.getProperty(ERROR_RESPONSE_FORMAT); String errorResponseFormat = httpProp.getProperty(ERROR_RESPONSE_FORMAT);
String responseType = httpProp.getProperty(RESPONSE_TYPE, "SYNC"); ResponseEntity<String> responseEntity = null;
ResponseEntity responseEntity = null;
Properties transactionProp = new Properties(); Properties transactionProp = new Properties();
String uuid = UUIDGenerator.getUUID().toString().replaceAll("-", "");
transactionProp.setProperty(TransactionContextKeys.TRANSACTION_UUID, uuid);
TxSiftContext.begin(uuid);
// jwhong, put api received time, eaiSvcCode // jwhong, put api received time, eaiSvcCode
transactionProp.put(INBOUND_REQUESTED_TIME, receivedTimeStr); transactionProp.put(INBOUND_REQUESTED_TIME, receivedTimeStr);
// ** jwhong TSEAIHS04의 api full path와 비교하여 adapter를 가져온다 String responseData = "";
// String bzwkSvcKeyName = ""; // Adapter Group별 Action Class에 따라 구성이 달라짐. 예)
// // _AGW_IN_RST_SyS:POST/account/{acc_no}
// String adapterGrpName = ""; // Adapter Group명 예) _AGW_IN_RST_SyS : API_PATH(/api/test)
String apiSvcCode = ""; // eaiSvcCd 예) LONNCHCON00005S2
String apiFullPathKey = ""; // 예) POST|/api/test/account/list, POST|/api/test/account/{acc_no}
Map<String, String> pathVariables = null;
try { try {
// PathVariable(ex:/api/test/account/{acc_no}) 대응 및 DAO조회 제거. responseData = service.callApi(servletRequest, servletResponse, httpProp, adapterGroupVO, adapterVO,
// /api/test/account/1234567 호출시 /api/test/account/{acc_no} API 로 식별.
// String methodAndUri = getRequestRuledPath(servletRequest, apiUri, adapterVO, transactionProp);
String methodAndUri = servletRequest.getMethod() + "|" + apiUri;
STDMessageManager manager = STDMessageManager.getInstance();
STDMsgInfoAddOnVO stdMsgInfo = manager.getStdMsgInfoAddOn(methodAndUri);
// bzwkSvcKeyName = stdMsgInfo.getBzwksvckeyname();
apiSvcCode = stdMsgInfo.getEaiSvcCd();
transactionProp.put(API_SERVICE_CODE, apiSvcCode);
// adapterGrpName = stdMsgInfo.gAdapterGroupName();
apiFullPathKey = stdMsgInfo.getApiFullPath();
if (STDMessageManager.isPathVariable(apiFullPathKey)) {
pathVariables = new AntPathMatcher().extractUriTemplateVariables(apiFullPathKey, methodAndUri);
}
// adptUri = findAdptUri(apiUri, HttpDynamicInAdapterManager.getInstance(), adapterGrpName);
} catch (Exception e) {
// adptUri = null;
}
// ***
if (pathVariables != null) {
transactionProp.put(INBOUND_PATH_VARIABLES, pathVariables);
}
try {
String responseData = service.callApi(servletRequest, servletResponse, httpProp, adapterGroupVO, adapterVO,
transactionProp); transactionProp);
// if (RESPONSE_TYPE_ASYNC.equals(responseType)) { // table의 값이 ASYNC 로 들어가 있는데
// response_type_async는 ASYN 로 되어 있어 아래처럼 비교함 jwhong 2025
if ("ASYNC".equals(responseType)) {
// responseEntity = ResponseEntity.ok("dummy"); // comment by jwhong
// servletResponse.addHeader("traceId", responseData); // uuid를 response header에
servletResponse.addHeader("traceId",
transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에
int httpStatus = servletResponse.getStatus();
if (httpStatus == 200) {
// 업체별 aync response message 가 다르다.
String asyncMsgStyle = httpProp.getProperty("ASYNC_RTNMSG_TYPE", "");
String responseBody = "";
boolean encryptAsyncAckApply = StringUtils
.equalsIgnoreCase(httpProp.getProperty("ASYNC_ENCRYPT_ACK", "N"), "Y");
if (asyncMsgStyle == null || asyncMsgStyle.trim().isEmpty()) {
responseBody = makeResponseBodyMsg();
} else {
responseBody = asyncMsgStyle;
}
if (encryptAsyncAckApply) {
responseBody = service.doPostEncryption(responseBody, transactionProp, servletRequest);
}
responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseBody);
// jwhong
} else {
responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseData);
}
} else {
// responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData);
// 버즈빌 포인트 적립 처리하기 위하여 정상응답이더라도 응답코드(apiRsltCd) 값이 200이 아닌 경우 처리를 위하여 수정
// Filter에서 설정한 response status값을 responseEntity 생성시 적용 modify by lwk 2025.03.24
servletResponse.addHeader("traceId", servletResponse.addHeader("traceId",
transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에 transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에
@@ -186,44 +128,26 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey {
} else { } else {
responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData); responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData);
} }
}
} catch (Exception e) { } catch (Exception e) {
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
String errorMsg = null; String errorMsg = null;
errorMsg = genErrorResponseMessage(adapterGroupName, adapterName,
transactionProp, e, adptMsgType, encode, errorResponseFormat);
if (e instanceof HttpStatusException) { if (e instanceof HttpStatusException) {
logger.warn("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage()); logger.warn("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage());
HttpStatusException e1 = (HttpStatusException) e; HttpStatusException e1 = (HttpStatusException) e;
errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode,
MessageUtil.ERROR_CODE_AP_ERROR, e1.getMessage(), errorResponseFormat);
responseEntity = ResponseEntity.status(e1.getStatus()).contentType(mediaType).body(errorMsg); responseEntity = ResponseEntity.status(e1.getStatus()).contentType(mediaType).body(errorMsg);
} } else if (e instanceof JwtAuthException) {
else if( e instanceof JwtAuthException )
{
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode,
MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage(), errorResponseFormat);
responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(errorMsg); responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(errorMsg);
} } else {
else
{
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e); logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType).body(errorMsg);
MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage(), errorResponseFormat);
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType)
.body(errorMsg);
} }
String postFilterNames = httpProp.getProperty("POST_FILTERS",""); responseData = errorMsg;
if( postFilterNames.contains("HMAC_SHA256") ) {
HttpAdapterFilter filter = HttpAdapterFilterFactoryKjb.createFilter("HMAC_SHA256");
filter.doPostFilter(adapterGroupName, postFilterNames, errorMsg, transactionProp, servletRequest, servletResponse);
}
} finally { } finally {
/** /**
@@ -231,32 +155,40 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey {
* 추후 더 좋은방법이 생길경우 개선 요망 * 추후 더 좋은방법이 생길경우 개선 요망
*/ */
try { try {
TxFileLogger.logTxFile(transactionProp, responseData, "[IN_SEND]");
servletRequest.setAttribute(TransactionContextKeys.TRANSACTION_PROP, transactionProp); servletRequest.setAttribute(TransactionContextKeys.TRANSACTION_PROP, transactionProp);
if (!"ASYNC".equals(responseType)) {
String uuid = transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID);
String url = transactionProp.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI);
String method = transactionProp.getProperty(HttpClientAdapterServiceKey.INBOUND_METHOD);
int httpStatusCode = servletResponse.getStatus();
Map<Object, Object> headerMap = new HashMap<>();
// 응답 헤더 로깅
for (String headerName : servletResponse.getHeaderNames()) {
String headerValue = servletResponse.getHeader(headerName);
logger.debug(String.format("httpHeader logging headerKey=%s, headerValue=%s",
headerName, headerValue));
headerMap.put(headerName, headerValue);
}
//HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName,adapterName, headerMap, url, method, httpStatusCode);
}
} catch (Exception e) { } catch (Exception e) {
logger.warn("http header db logging fail.", e); logger.warn("http header db logging fail.", e);
} finally {
TxSiftContext.end();
} }
} }
return responseEntity; return responseEntity;
} }
private String genErrorResponseMessage(String adapterGroupName, String adapterName,
Properties callProp, Throwable e, String adptMsgType, String encode, String errorResponseFormat) {
String errorHandlerClass = AdapterPropManager.getInstance().getProperty(adapterName, "ERR_MSG_HANDLER");
if (StringUtils.isNotBlank(errorHandlerClass)) {
if (logger.isInfo())
logger.info("ExceptionHandler] errorSyncSend ERR_MSG_HANDLER=" + errorHandlerClass);
AdapterErrorMessageHandler handler = AdapterErrorMessageHandlerFactory.createHandler(errorHandlerClass);
if (handler != null) {
Object resposne;
try {
resposne = handler.generateNonStandardInboundErrorResponseMessage(adapterGroupName, adapterName,
callProp, null, null, e);
return (String)resposne;
} catch (Exception e1) {
logger.warn("AdapterErrorMessageHandler error.", e);
// handler 실패시 아래에서 처리한
}
}
}
return MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode,
MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage(), errorResponseFormat);
}
/** /**
* url에서 뒤쪽 /이후를 제거하면서 찾는다.<br> * url에서 뒤쪽 /이후를 제거하면서 찾는다.<br>
* /api/v1/public/getUserInfo.svc * /api/v1/public/getUserInfo.svc
@@ -335,21 +267,21 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey {
InboundErrorLogger.error(errorInfoVO); InboundErrorLogger.error(errorInfoVO);
} }
private String makeResponseBodyMsg() { // private String makeResponseBodyMsg() {
//
Map<String, Object> dataMap = new HashMap<>(); // Map<String, Object> dataMap = new HashMap<>();
dataMap.put("result", 1); // dataMap.put("result", 1);
Map<String, Object> map = new HashMap<>(); // Map<String, Object> map = new HashMap<>();
//
map.put("code", "200"); // map.put("code", "200");
map.put("data", dataMap); // map.put("data", dataMap);
map.put("message", "정상 처리 되었습니다."); // map.put("message", "정상 처리 되었습니다.");
//
JSONObject json = new JSONObject(); // JSONObject json = new JSONObject();
json.putAll(map); // json.putAll(map);
//
return json.toJSONString(); // return json.toJSONString();
} // }
/* /*
* private String makeResponseBodyMsg(String asyncMsgStyle) { * private String makeResponseBodyMsg(String asyncMsgStyle) {
@@ -1,17 +1,56 @@
package com.eactive.eai.adapter.service; package com.eactive.eai.adapter.service;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.mina.common.ByteBuffer;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterPropManager;
import com.eactive.eai.adapter.AdapterVO; import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.adapter.Keys; import com.eactive.eai.adapter.Keys;
import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpMemoryLogger;
import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.HttpMethodType;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthFilter; import com.eactive.eai.adapter.http.dynamic.filter.ApiKeyExtractFilter;
import com.eactive.eai.adapter.http.filter.AbstractCryptoFilter;
import com.eactive.eai.common.context.ElinkTransactionContext;
import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.message.MessageType;
import com.eactive.eai.common.util.CommonLib; import com.eactive.eai.common.util.CommonLib;
import com.eactive.eai.common.util.JSONUtils;
import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.TxFileLogger;
import com.eactive.eai.common.util.XMLUtils;
import com.eactive.eai.inbound.action.ActionFactory; import com.eactive.eai.inbound.action.ActionFactory;
import com.eactive.eai.inbound.action.RequestAction; import com.eactive.eai.inbound.action.RequestAction;
import com.eactive.eai.inbound.processor.Processor; import com.eactive.eai.inbound.processor.Processor;
@@ -20,43 +59,11 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.mina.common.ByteBuffer;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.*;
//for encrypt/decrypt jwhong
import com.eactive.eai.authserver.service.OAuth2Manager;
import com.kjbank.encrypt.exchange.crypto.AES256Cipher;
import com.kjbank.encrypt.exchange.crypto.AESCipher;
import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher;
import java.nio.charset.StandardCharsets;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import org.springframework.security.oauth2.provider.ClientDetails;
import com.nimbusds.jwt.SignedJWT;
import com.eactive.eai.common.context.ElinkTransactionContext;
@Service @Service
public class DJErpApiAdapterService extends HttpAdapterServiceSupport { public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
static Logger siftLogger = Logger.getLogger(Logger.LOGGER_SIFT);
public static final String HEADER_GROUP = "HEADER_GROUP"; public static final String HEADER_GROUP = "HEADER_GROUP";
public static final String HTTP_STATUS = "HTTP_STATUS"; // jwhong public static final String HTTP_STATUS = "HTTP_STATUS"; // jwhong
@@ -64,17 +71,12 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
public static final String HEADER_KEYS = "HEADER_KEYS"; public static final String HEADER_KEYS = "HEADER_KEYS";
public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod";
private static final String JSON_CONTENT_TYPE = "application/json";
private static final String JSON_FIELD_NAME = "json-body";
private static final String FILE_GROUP_NAME = "image-file";
private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH";
public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong
private boolean encryptResponseApply; // inbound에 대한 응답 암호화 여부 flag
public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp, AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception { public String callApi(HttpServletRequest request, HttpServletResponse response, Properties httpProp,
AdapterGroupVO adapterGroupVO, AdapterVO adapterVO, Properties transactionProp) throws Exception {
int traceLevel = 0; int traceLevel = 0;
AdapterPropManager manager = null;
String adptGrpName = adapterGroupVO.getName(); String adptGrpName = adapterGroupVO.getName();
String adptName = adapterVO.getName(); String adptName = adapterVO.getName();
@@ -91,10 +93,11 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
String paramValue = null; String paramValue = null;
String adptMsgType = null; String adptMsgType = null;
Properties inboundHeaderProp = getHeaders(request);
transactionProp.put(INBOUND_METHOD, request.getMethod()); transactionProp.put(INBOUND_METHOD, request.getMethod());
transactionProp.put(INBOUND_URI, request.getRequestURI()); transactionProp.put(INBOUND_URI, request.getRequestURI());
transactionProp.put(INBOUND_QUERY_STRING, StringUtils.defaultString(request.getQueryString())); transactionProp.put(INBOUND_QUERY_STRING, StringUtils.defaultString(request.getQueryString()));
transactionProp.put(INBOUND_HEADER, getHeaders(request)); transactionProp.put(INBOUND_HEADER, inboundHeaderProp);
transactionProp.put(INBOUND_EXTPARAMS, StringUtils.defaultString(request.getQueryString())); transactionProp.put(INBOUND_EXTPARAMS, StringUtils.defaultString(request.getQueryString()));
if (StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) if (StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_REST)
|| StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { || StringUtils.equals(adapterVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) {
@@ -129,13 +132,13 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
transactionProp.put(ENC_PATHS, httpProp.getProperty(ENC_PATHS, "")); transactionProp.put(ENC_PATHS, httpProp.getProperty(ENC_PATHS, ""));
transactionProp.put(ENCRYPT_ALGORITHM, httpProp.getProperty(ENCRYPT_ALGORITHM, "")); //jwhong transactionProp.put(ENCRYPT_ALGORITHM, httpProp.getProperty(ENCRYPT_ALGORITHM, "")); //jwhong
if (getHeaders(request).get(HEADER_NAME_CLIENT_ID) != null) { // jwhong if (inboundHeaderProp.get(HEADER_NAME_CLIENT_ID) != null) { // jwhong
transactionProp.put(HEADER_NAME_CLIENT_ID, getHeaders(request).get(HEADER_NAME_CLIENT_ID)); transactionProp.put(HEADER_NAME_CLIENT_ID, inboundHeaderProp.get(HEADER_NAME_CLIENT_ID));
} }
transactionProp.put(ENCRYPT_BASE_TYPE, httpProp.getProperty(ENCRYPT_BASE_TYPE, "")); //jwhong transactionProp.put(ENCRYPT_BASE_TYPE, httpProp.getProperty(ENCRYPT_BASE_TYPE, "")); //jwhong
// //transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN)); // jwhong // //transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN)); // jwhong
// transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN) != null ? getHeaders(request).get(INBOUND_TOKEN) : ""); //jwhong , null 이면 default로 "" put // transactionProp.put(INBOUND_TOKEN, getHeaders(request).get(INBOUND_TOKEN) != null ? getHeaders(request).get(INBOUND_TOKEN) : ""); //jwhong , null 이면 default로 "" put
String inboundToken = getHeaders(request).getOrDefault(INBOUND_TOKEN, "").toString(); String inboundToken = inboundHeaderProp.getOrDefault(INBOUND_TOKEN, "").toString();
if (StringUtils.isNotBlank(inboundToken) && StringUtils.startsWith(inboundToken, "Bearer ")) { if (StringUtils.isNotBlank(inboundToken) && StringUtils.startsWith(inboundToken, "Bearer ")) {
inboundToken = inboundToken.substring(7); inboundToken = inboundToken.substring(7);
} }
@@ -143,9 +146,13 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
transactionProp.put(ENCRYPT_AES256_IV, httpProp.getProperty(ENCRYPT_AES256_IV, "")); //jwhong transactionProp.put(ENCRYPT_AES256_IV, httpProp.getProperty(ENCRYPT_AES256_IV, "")); //jwhong
transactionProp.put(ENCRYPT_AES256_KEY, httpProp.getProperty(ENCRYPT_AES256_KEY, "")); //jwhong transactionProp.put(ENCRYPT_AES256_KEY, httpProp.getProperty(ENCRYPT_AES256_KEY, "")); //jwhong
transactionProp.put(AbstractCryptoFilter.PROP_MODULE_NAME, httpProp.getProperty(AbstractCryptoFilter.PROP_MODULE_NAME, ""));
transactionProp.put(HEADER_GROUP, headerGroupName);
transactionProp.put(HEADER_KEYS, relayRequestHeaderKeys);
// SEED 컬럼암호하 시 Key로 사용함 // SEED 컬럼암호하 시 Key로 사용함
String seedkey = getHeaders(request).getOrDefault("x-obp-partnercode", "").toString(); String seedkey = inboundHeaderProp.getOrDefault("x-obp-partnercode", "").toString();
ElinkTransactionContext.setSeedKey(seedkey); ElinkTransactionContext.setSeedKey(seedkey);
try { try {
@@ -283,6 +290,8 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
message = paramValue; message = paramValue;
} }
TxFileLogger.logTxFile(transactionProp, message, "[IN_RECV]");
if (logger.isDebug()) { if (logger.isDebug()) {
String[] msgArgs = new String[2]; String[] msgArgs = new String[2];
msgArgs[0] = adptGrpName; msgArgs[0] = adptGrpName;
@@ -296,46 +305,51 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
// HttpHeaders responseHeaders = new HttpHeaders(); // HttpHeaders responseHeaders = new HttpHeaders();
// responseHeaders.setContentType(MediaType.valueOf("application/json;charset=" + encode)); // responseHeaders.setContentType(MediaType.valueOf("application/json;charset=" + encode));
// HEADER_GROUP 셋팅 // HEADER_GROUP 셋팅
if (MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName) // if (MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName)
&& StringUtils.isNotBlank(relayRequestHeaderKeys)) { // && StringUtils.isNotBlank(relayRequestHeaderKeys)) {
JSONObject jsonMessage = (JSONObject) JSONValue.parse(message); // JSONObject jsonMessage = (JSONObject) JSONValue.parse(message);
JSONObject headerJson = new JSONObject(); // JSONObject headerJson = new JSONObject();
if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) { // if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) {
for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); ) { // for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); ) {
String key = e.nextElement(); // String key = e.nextElement();
headerJson.put(key, request.getHeader(key)); // headerJson.put(key, request.getHeader(key));
} // }
} else { // } else {
String[] relayKeyArr = org.springframework.util.StringUtils // String[] relayKeyArr = org.springframework.util.StringUtils
.tokenizeToStringArray(relayRequestHeaderKeys, ","); // .tokenizeToStringArray(relayRequestHeaderKeys, ",");
//
// for (String key : relayKeyArr) {
// String headerValue = request.getHeader(key);
// if (StringUtils.isNotBlank(headerValue)) {
// headerJson.put(key, headerValue);
// }
// }
// }
//
// if (headerJson.size() > 0) {
// jsonMessage.put(headerGroupName, headerJson);
// message = jsonMessage.toJSONString();
// }
// }
for (String key : relayKeyArr) { Object reqObject = assignHeaderGroupRequestHeaders(adptGrpName, adptName, message,
String headerValue = request.getHeader(key); transactionProp, request, response, adptMsgType);
if (StringUtils.isNotBlank(headerValue)) {
headerJson.put(key, headerValue);
}
}
}
if (headerJson.size() > 0) {
jsonMessage.put(headerGroupName, headerJson);
message = jsonMessage.toJSONString();
}
}
if (message == null) {
message = "";
}
// 위치변경 : 가공되지 않은 Body값을 저장하기 위하여 위쪽으로 이동. // 위치변경 : 가공되지 않은 Body값을 저장하기 위하여 위쪽으로 이동.
// transactionProp.put(INBOUND_REQUEST_MESSAGE, message); // transactionProp.put(INBOUND_REQUEST_MESSAGE, message);
// 로컬 서비스 호출 ,encoding 처리 추가 // 로컬 서비스 호출 ,encoding 처리 추가
String result = (String) service(adptGrpName, adptName, message, transactionProp, request, response);
ApiKeyExtractFilter apiKeyExtractor = new ApiKeyExtractFilter();
apiKeyExtractor.doPreFilter(adptGrpName, adptName, reqObject, transactionProp, request, response);
String result = (String) service(adptGrpName, adptName, reqObject, transactionProp, request, response);
// bypass만 필요
applyOutboundResponseHeaders(transactionProp, response); applyOutboundResponseHeaders(transactionProp, response);
result = applyHeaderGroupResponseHeaders(adptGrpName, adptName, result, transactionProp, request, response, adptMsgType);
if (logger.isDebug()) { if (logger.isDebug()) {
logger.debug("HttpAdapterServiceRest] result " + encode + " (" + adptGrpName + ") = [" + result + "]"); logger.debug("HttpAdapterServiceRest] result " + encode + " (" + adptGrpName + ") = [" + result + "]");
} }
@@ -365,10 +379,118 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
// if ( encryptResponseApply) { // if ( encryptResponseApply) {
// result = doPostEncryption(result, transactionProp, request); // jwhong Encrypt // result = doPostEncryption(result, transactionProp, request); // jwhong Encrypt
// } // }
return result; return result;
} }
private Object assignHeaderGroupRequestHeaders(String adptGrpName, String adptName, Object message, Properties prop,
HttpServletRequest request, HttpServletResponse response, String adptMsgType) throws DocumentException, IOException {
// XML 지원 개발
String headerGroupName = prop.getProperty(HEADER_GROUP);
String relayRequestHeaderKeys = prop.getProperty(HEADER_KEYS);
if(StringUtils.isNotBlank(headerGroupName) && StringUtils.isNotBlank(relayRequestHeaderKeys)) {
if (MessageType.JSON.equals(adptMsgType)) {
if(message instanceof String && StringUtils.isEmpty((String)message))
message = "{}";
JSONObject jsonMessage = JSONUtils.parseJson(message);
JSONObject headerJson = JSONUtils.getChildJson(jsonMessage, headerGroupName);
if (headerJson == null)
headerJson = new JSONObject();
if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) {
for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); ) {
String key = e.nextElement();
headerJson.put(StringUtils.lowerCase(key), request.getHeader(key));
}
} else {
String[] relayKeyArr = org.springframework.util.StringUtils
.tokenizeToStringArray(relayRequestHeaderKeys, ",");
for (String key : relayKeyArr) {
String headerValue = request.getHeader(key);
if (StringUtils.isNotBlank(headerValue)) {
headerJson.put(StringUtils.lowerCase(key), headerValue);
}
}
}
if (headerJson.size() > 0) {
jsonMessage.put(headerGroupName, headerJson);
message = jsonMessage.toJSONString();
}
} else if(MessageType.XML.equals(adptMsgType)) {
Document document = XMLUtils.convertXmlDocument(message);
if(document != null) {
Element rootElement = document.getRootElement();
Element headerElement = rootElement.element(headerGroupName);
if(headerElement == null)
headerElement = DocumentHelper.createElement(headerGroupName);
boolean hasHeaderValues = false;
if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) {
for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); ) {
String key = e.nextElement();
String value = request.getHeader(key);
/*
* IBK 표준안에 따라 <{key}>{value}</{key}> 형태로 저장, KEY 는 소문자로 변경한다
* 대상 사이트의 표준안에 따라 작성 할 것
*
* HTTP 헤더 변환 예시
*
* 일반적인 HTTP 헤더 변환 예시:
* Content-Type: application/json
* X-Forwarded-For: 10.0.0.1
*
* <root>
* <data> original content </data>
* <httpHeaderGroup>
* <content-type>application/json</content-type>
* <x-forwarded-for>10.0.0.1</x-forwarded-for>
* </httpHeaderGroup>
* </root>
*/
if(StringUtils.isNotBlank(value)) {
Element headerItem = headerElement.addElement(key);
headerItem.setText(value);
hasHeaderValues = true;
}
}
} else {
String[] relayKeyArr = org.springframework.util.StringUtils
.tokenizeToStringArray(relayRequestHeaderKeys, ",");
for (String key : relayKeyArr) {
String headerValue = request.getHeader(key);
if (StringUtils.isNotBlank(headerValue)) {
String value = request.getHeader(key);
String keyName = StringUtils.lowerCase(key);
Element headerItem = headerElement.addElement(keyName);
headerItem.setText(value);
hasHeaderValues = true;
}
}
}
if (hasHeaderValues) {
rootElement.add(headerElement);
OutputFormat format = OutputFormat.createPrettyPrint();
StringWriter writer = new StringWriter();
XMLWriter xmlWriter = new XMLWriter(writer, format);
xmlWriter.write(document);
message = writer.toString();
}
}
}
}
if (message == null) {
message = "";
} // XML 지원 개발
return message;
}
/** /**
* HttpClientAdapterServiceBypass.assignRelayDataToInbound() 에서 * HttpClientAdapterServiceBypass.assignRelayDataToInbound() 에서
* transactionProp에 저장한 OUTBOUND_RESPONSE_HEADERS를 response에 적용한다. * transactionProp에 저장한 OUTBOUND_RESPONSE_HEADERS를 response에 적용한다.
@@ -411,411 +533,94 @@ public class DJErpApiAdapterService extends HttpAdapterServiceSupport {
} }
} }
// jwhong decrypt private String applyHeaderGroupResponseHeaders(String adptGrpName, String adptName, Object resultMessage, Properties prop,
HttpServletRequest request, HttpServletResponse response, String adptMsgType) throws Exception {
// body headergroup -> http header 세팅
String headerGroupName = prop.getProperty(ApiAdapterService.HEADER_GROUP);
private String doPreDecryption(String eaiBody, Properties transactionProp, HttpServletRequest request) throws Exception { if (StringUtils.isNotBlank(headerGroupName)) {
String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, ""); if (resultMessage instanceof Node) {
String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong adptMsgType = MessageType.XML;
String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE); } else if (resultMessage instanceof String) {
//String inboundToken2 = transactionProp.getProperty(INBOUND_TOKEN, ""); // 이건 token 값이 아니고 authorization 값이다 String strMessage = (String) resultMessage;
String inboundToken = ""; if (StringUtils.startsWith(strMessage, "<")) {
adptMsgType = MessageType.XML;
String secretAES256Iv = transactionProp.getProperty("ENCRYPT_AES256_IV");
String secretAES256Key = transactionProp.getProperty("ENCRYPT_AES256_KEY");
if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님
return eaiBody;
} }
} else if (resultMessage instanceof byte[]) {
inboundToken = JwtTokenExtractor(request); String strMessage = new String((byte[]) resultMessage);
xElinkClientId = JwtClientIdExtractor(inboundToken); // token에서 client id를 추출함 if (StringUtils.startsWith(strMessage, "<")) {
adptMsgType = MessageType.XML;
// 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함
// ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함
String clientSecret = "";
if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) {
clientSecret = inboundToken;
} else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) {
OAuth2Manager manager = OAuth2Manager.getInstance();
ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId);
if ( clientDetail != null ) { // 여기서 not null 이라는 것은 apim oauth server에서 발급된 token 임.
// 즉 KJBank 에서 요청이 들어온 것이다.
clientSecret = clientDetail.getClientSecret();
} // 그럼 업체에서 요청이 들어오면?? 업체도 apim oauth server에서 발급된 token을 사용하는것이다.
}
byte[] decryptedMessage = null;
decryptedMessage = doInboundPreDecrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key );
if (decryptedMessage == null) {
throw new Exception("[ApiAdapterService] Decrypt Error : Invalid encrypted message");
}
String resultMessage = new String(decryptedMessage, StandardCharsets.UTF_8 );
return resultMessage;
//return new String(decryptedMessage, StandardCharsets.UTF_8 );
}
// jwhong encrypt
public String doPostEncryption(String eaiBody, Properties transactionProp, HttpServletRequest request) throws Exception {
String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, "");
String xElinkClientId = transactionProp.getProperty(HEADER_NAME_CLIENT_ID, ""); // 이 값이 OAuth의 client id 값이다 . http header 에 포함되어 온다. jwhong
String encryptBaseKeyType = transactionProp.getProperty(ENCRYPT_BASE_TYPE);
String inboundToken = "";
String secretAES256Iv = transactionProp.getProperty("ENCRYPT_AES256_IV");
String secretAES256Key = transactionProp.getProperty("ENCRYPT_AES256_KEY");
if ( decryptAlgorithm == "" ) { // 복호화 대상이 아님
return eaiBody;
}
inboundToken = JwtTokenExtractor(request);
xElinkClientId = JwtClientIdExtractor(inboundToken); // token에서 client id를 추출함
// 암호화 key를 token 내용으로 할지 client secret 내용으로 할지 결정함. adapter property에 정의함
// ENCRYPT_ALGORITHM 을 설정했는데 ENCRYPT_BASE_TYPE을 설정안하면 Decrypt 수행시 Exception 발생함
String clientSecret = "";
if ("TOKEN".equalsIgnoreCase(encryptBaseKeyType)) {
clientSecret = inboundToken;
} else if ( "SECRETKEY".equalsIgnoreCase(encryptBaseKeyType)) {
OAuth2Manager manager = OAuth2Manager.getInstance();
ClientDetails clientDetail = manager.getClientDeatilsStore().get(xElinkClientId);
if ( clientDetail != null ) {
clientSecret = clientDetail.getClientSecret();
} }
} }
String encryptedMessage = null; if (MessageType.JSON.equals(adptMsgType)) {
encryptedMessage = doInboundPostEncrypt(eaiBody, decryptAlgorithm,clientSecret,secretAES256Iv, secretAES256Key ); JSONObject jsonObject = JSONUtils.parseJson(resultMessage);
JSONObject headerGroup = (JSONObject)jsonObject.get(headerGroupName);
if (headerGroup != null) {
Set<Map.Entry<String, Object>> fieldEntrySet = JSONUtils.getField(headerGroup);
if (encryptedMessage == null) { for (Map.Entry<String, Object> fieldEntry : fieldEntrySet) {
throw new Exception("[ApiAdapterService] Encrypt Error : Invalid PlainText message"); logger.info("header group entry : {} , {}", fieldEntry.getKey(), fieldEntry.getValue());
if (fieldEntry.getValue() instanceof String) {
if(fieldEntry.getKey().equalsIgnoreCase("content-type")) {
logger.debug("set content-type {}: {}", fieldEntry.getKey(), fieldEntry.getValue());
response.setContentType((String) fieldEntry.getValue());
} else {
logger.debug("add header {}: {}", fieldEntry.getKey(), fieldEntry.getValue());
response.addHeader(fieldEntry.getKey(), (String) fieldEntry.getValue());
} }
} else {
return encryptedMessage; logger.info("fieldEntry value is not String. {}", fieldEntry.getValue());
//String resultMessage = new String(encryptedMessage, StandardCharsets.UTF_8 );
//return resultMessage;
}
private byte[] convertObjectToBytes(Object obj) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
return bos.toByteArray();
}
private byte[] convertObjectToBase64Bytes(Object obj) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
// 직렬화된 byte[] → Base64 문자열 → 다시 byte[]로 변환
String base64String = Base64.getEncoder().encodeToString(bos.toByteArray());
return base64String.getBytes(StandardCharsets.UTF_8);
}
public static Object convertBytesToObject(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis)) {
return ois.readObject();
} }
} }
} else {
logger.info("headerGroup is null");
private byte[] doInboundPreDecrypt(String eaiStringBody, String decryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) throws Exception {
byte[] decryptedMessage = null;
//String eaiStringBody = new String(eaiBody, StandardCharsets.UTF_8);
eaiStringBody = extractBodyMsg(decryptAlgorithm, eaiStringBody);
if (eaiStringBody == null) {
throw new Exception("[ApiAdapterService] Cannot decrypt Error : input is plain text");
} }
//test source jsonObject.remove(headerGroupName);
logger.debug("Base64 문자열: " + eaiStringBody); return jsonObject.toJSONString();
logger.debug("Base64 문자열 길이: " + eaiStringBody.length()); } else if(MessageType.XML.equals(adptMsgType)) {
logger.debug("Base64 문자열 끝: " + eaiStringBody.substring(eaiStringBody.length() - 10)); Document document = XMLUtils.convertXmlDocument(resultMessage);
if(document != null) {
Element rootElement = document.getRootElement();
Element headerGroupElement = rootElement.element(headerGroupName);
// Base64 디코딩 테스트 if(headerGroupElement != null) {
try { //헤더그룹의 모든 하위 엘리먼트를 HTTP 응답 헤더로 설정
byte[] decoded = Base64.getDecoder().decode(eaiStringBody); for(Iterator<Element> it = headerGroupElement.elementIterator(); it.hasNext();) {
logger.debug("디코딩 성공, 길이: " + decoded.length); Element headerElement = it.next();
} catch (IllegalArgumentException e) { String name = headerElement.getName();
logger.debug("Base64 디코딩 실패: " + e.getMessage()); String value = headerElement.getTextTrim();
}
// end test source
switch (decryptAlgorithm) { if(StringUtils.isNoneBlank(value)) {
case "AES128": if(value.equalsIgnoreCase("content-type")) {
case "AES128-TOSS": response.setContentType(value);
try { } else {
String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네?? logger.debug("add header {}: {}", name, value);
//String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128); response.addHeader(name, value);
String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage());
} }
break; } else {
case "AES128-TOGETHER": logger.info("value is not String. {}", value);
try {
String key128 = clientSecretKey.substring(44,60); //togetherEncoder 경우는 substring(44,60) 이네??
//String decryptedStrMessage = AESCipher.decrypt(eaiStringBody, key128);
String decryptedStrMessage = AESCipher.decryptExistException(eaiStringBody, key128);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES128 Decryption error=" + e.getMessage());
} }
break;
case "AES256":
try {
String key = clientSecretKey.substring(10,42);
String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, key);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage());
} }
break; } else {
case "AES256-KAKAO": logger.info("headerGroup is null");
try {
String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, secretAES256Iv, secretAES256Key);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage());
}
break;
case "AES256-TOSS":
try {
String decryptedStrMessage = AES256Cipher.decrypt(eaiStringBody, secretAES256Iv, secretAES256Key);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Decryption error=" + e.getMessage());
}
break;
case "AES256GCM":
try {
byte[] key = AES256GCMCipher.generateKey();
AES256GCMCipher cipher = new AES256GCMCipher(key);
byte[] aad = "metadata".getBytes();
String decryptedStrMessage = cipher.decrypt(eaiStringBody , aad);
decryptedMessage = decryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage());
}
break;
default:
try {
decryptedMessage = eaiStringBody.getBytes();
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage());
}
break;
} }
return decryptedMessage; // 헤더그룹 삭제
rootElement.remove(headerGroupElement);
return document.asXML();
}
}
} else {
logger.info("headerGroupName is blank");
} }
private String extractBodyMsg(String decryptAlgorithm, String eaiStringBody) { return (String)resultMessage;
String decryptedJsonKey = "";
String decryptedBodyMessage = "";
decryptedJsonKey = getJsonKey(decryptAlgorithm);
try {
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(eaiStringBody);
decryptedBodyMessage = (String) jsonObject.get(decryptedJsonKey);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClient5AdapterServiceRest] extractBodyMsg error : " + e.getMessage());
} }
return decryptedBodyMessage;
}
private String getJsonKey(String Algorithm) {
String jsonKey = "";
switch (Algorithm) {
case "AES128":
case "AES128-TOSS":
jsonKey = "preScreeningRequest";
break;
case "AES128-TOGETHER":
jsonKey = "obpTxData";
break;
case "AES256":
jsonKey = "preScreeningRequest";
break;
case "AES256-KAKAO":
jsonKey = "encrypted_data";
break;
case "AES256-TOSS":
jsonKey = "encryptedData";
break;
case "AES256-NICEON":
jsonKey = "enc_data";
break;
case "AES256GCM":
break;
default:
break;
}
return jsonKey;
}
private String doInboundPostEncrypt(String eaiStringBody, String encryptAlgorithm, String clientSecretKey, String secretAES256Iv, String secretAES256Key) {
//byte[] encryptedMessage = null;
String encryptedStrMessage = null;
String encryptedJsonKey = "";
encryptedJsonKey = getJsonKey(encryptAlgorithm);
switch (encryptAlgorithm) {
case "AES128":
case "AES128-TOSS":
try {
String key128 = clientSecretKey.substring(22,38); //togetherEncoder 경우는 substring(44,60) 이네??
encryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage());
}
break;
case "AES128-TOGETHER":
try {
String key128 = clientSecretKey.substring(44,60); //togetherEncoder 경우는 substring(44,60) 이네??
encryptedStrMessage = AESCipher.encrypt(eaiStringBody, key128);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES128 Encryption error=" + e.getMessage());
}
break;
case "AES256":
try {
String key = clientSecretKey.substring(10,42);
encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, key);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage());
}
break;
case "AES256-KAKAO":
try {
encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage());
}
break;
case "AES256-TOSS":
try {
encryptedStrMessage = AES256Cipher.encrypt(eaiStringBody, secretAES256Iv, secretAES256Key);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256 Encryption error=" + e.getMessage());
}
break;
case "AES256GCM":
try {
byte[] key = AES256GCMCipher.generateKey();
AES256GCMCipher cipher = new AES256GCMCipher(key);
byte[] aad = "metadata".getBytes();
encryptedStrMessage = cipher.encrypt(eaiStringBody , aad);
//encryptedMessage = encryptedStrMessage.getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] AES256GCM Encryption error=" + e.getMessage());
}
break;
default:
try {
encryptedStrMessage = eaiStringBody;
//encryptedMessage = eaiStringBody.getBytes();
} catch (Exception e) {
e.printStackTrace();
logger.error("HttpClientAdapterServiceRest] doOutboundPostFilter Array copy error=" + e.getMessage());
}
break;
}
Map<String, Object> map = new HashMap<>();
map.put(encryptedJsonKey, encryptedStrMessage);
JSONObject json = new JSONObject();
json.putAll(map);
return json.toJSONString();
//return encryptedMessage;
}
private String JwtTokenExtractor(HttpServletRequest request) {
String Token = "";
try {
Token = JwtAuthFilter.extractJWTToken(request);
} catch (Exception e) {
logger.error(e.getMessage());
}
logger.debug("Token is: " + Token);
return Token;
}
private String JwtClientIdExtractor(String inboundToken) {
String tokenClientId ="";
try {
SignedJWT signedJWT = SignedJWT.parse(inboundToken);
tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID);
} catch (Exception e) {
logger.error(e.getMessage());
tokenClientId = "";
}
logger.debug("Token Client ID: " + tokenClientId);
return tokenClientId;
}
// jwhong until here
private Map<String, String[]> assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName, private Map<String, String[]> assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName,
Object requestBytes, Properties prop) { Object requestBytes, Properties prop) {
// PathVariable 체크 // PathVariable 체크
@@ -0,0 +1,60 @@
package com.eactive.eai.agent.inflow;
import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.custom.inflow.ClientDualInflowControlManager;
public class ReloadInflowClientControlCommand extends Command {
private static final long serialVersionUID = 1L;
public ReloadInflowClientControlCommand() {
super("ReloadInflowClientControlCommand");
}
public Object execute() throws CommandException {
Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
if (logger.isInfo())
logger.info(this.name + " is executed");
if (!(args instanceof String)) {
String rspErrorCode = "RECEAIMCM001";
String msg = makeException(rspErrorCode, null);
if (logger.isError())
logger.error(msg);
throw new CommandException(msg);
}
String keyName = (String) args;
try {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
if (!(base instanceof ClientDualInflowControlManager)) {
throw new IllegalStateException("ClientDualInflowControlManager 가 활성화되지 않았습니다.");
}
ClientDualInflowControlManager manager = (ClientDualInflowControlManager) base;
if (keyName != null) {
if ("ALL".equals(keyName)) {
manager.reloadClient();
if (logger.isWarn())
logger.warn(this.name + "] all rule Reload.");
} else {
manager.reloadClient(keyName);
if (logger.isWarn())
logger.warn(this.name + "] " + keyName + " Reload.");
}
}
} catch (Exception e) {
String rspErrorCode = "RECEAIMCM002";
String msg = makeException(rspErrorCode, e);
if (logger.isError())
logger.error(msg, e);
throw new CommandException(msg);
}
return "success";
}
}
@@ -0,0 +1,50 @@
package com.eactive.eai.agent.inflow;
import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.custom.inflow.ClientDualInflowControlManager;
public class RemoveInflowClientControlCommand extends Command {
private static final long serialVersionUID = 1L;
public RemoveInflowClientControlCommand() {
super("RemoveInflowClientControlCommand");
}
public Object execute() throws CommandException {
Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
if (logger.isInfo())
logger.info(this.name + " is executed");
if (!(args instanceof String)) {
String rspErrorCode = "RECEAIMCM001";
String msg = makeException(rspErrorCode, null);
if (logger.isError())
logger.error(msg);
throw new CommandException(msg);
}
String key = (String) args;
try {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
if (!(base instanceof ClientDualInflowControlManager)) {
throw new IllegalStateException("ClientDualInflowControlManager 가 활성화되지 않았습니다.");
}
ClientDualInflowControlManager manager = (ClientDualInflowControlManager) base;
manager.removeClient(key);
if (logger.isWarn())
logger.warn(this.name + "] " + key + " removed.");
} catch (Exception e) {
String rspErrorCode = "RECEAIMCM002";
String msg = makeException(rspErrorCode, e);
if (logger.isError())
logger.error(msg, e);
throw new CommandException(msg);
}
return "success";
}
}
@@ -1,6 +1,8 @@
package com.eactive.eai.authserver.config; package com.eactive.eai.authserver.config;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
@@ -35,6 +37,7 @@ import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory; import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO; import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
import com.eactive.eai.authserver.jwt.PssJwtAccessTokenConverter;
import com.eactive.eai.authserver.service.OAuth2Manager; import com.eactive.eai.authserver.service.OAuth2Manager;
import com.eactive.eai.authserver.vo.ClientVO; import com.eactive.eai.authserver.vo.ClientVO;
import com.eactive.eai.common.dao.DAOException; import com.eactive.eai.common.dao.DAOException;
@@ -139,9 +142,10 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
Resource keystore = new ClassPathResource(keystorePath); Resource keystore = new ClassPathResource(keystorePath);
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(keystore, keystorePassword.toCharArray()); KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(keystore, keystorePassword.toCharArray());
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(keyAlias, keyPassword.toCharArray()); KeyPair keyPair = keyStoreKeyFactory.getKeyPair(keyAlias, keyPassword.toCharArray());
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
converter.setKeyPair(keyPair); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
return converter;
return new PssJwtAccessTokenConverter(privateKey, publicKey);
} }
@@ -1,9 +1,11 @@
package com.eactive.eai.authserver.custom; package com.eactive.eai.authserver.custom;
import java.security.Principal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -28,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.eactive.eai.adapter.http.dynamic.UnkownMessageLogUtils;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
import com.eactive.eai.authserver.config.RequestContextData; import com.eactive.eai.authserver.config.RequestContextData;
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO; import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
@@ -42,8 +45,6 @@ import com.eactive.eai.common.util.UUID;
import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog; import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.security.Principal;
@Controller @Controller
public class DJErpOAuth2Controller { public class DJErpOAuth2Controller {
public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
@@ -160,6 +161,12 @@ public class DJErpOAuth2Controller {
clientId, grantType, scopes); clientId, grantType, scopes);
logger.error(e.getMessage()); logger.error(e.getMessage());
logTokenIssuance(false, false, e.getMessage(), null); logTokenIssuance(false, false, e.getMessage(), null);
Properties logProp = new Properties();
logProp.put("clientId", clientId);
UnkownMessageLogUtils.logUnkownMessage(this.getClass().getSimpleName(), this.getClass().getSimpleName(),
tokenRequest.toString(), logProp, request, response, "RECEAIIRP301", e);
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage()); String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage());
int statusCode = NumberUtils.toInt(StringUtils.left(e.getCode(), 3), HttpStatus.UNAUTHORIZED.value()); int statusCode = NumberUtils.toInt(StringUtils.left(e.getCode(), 3), HttpStatus.UNAUTHORIZED.value());
return ResponseEntity.status(statusCode).body(errorJson); return ResponseEntity.status(statusCode).body(errorJson);
@@ -169,6 +176,12 @@ public class DJErpOAuth2Controller {
clientId, grantType, scopes); clientId, grantType, scopes);
logger.error(e.getMessage()); logger.error(e.getMessage());
logTokenIssuance(false, false, e.getMessage(), null); logTokenIssuance(false, false, e.getMessage(), null);
Properties logProp = new Properties();
logProp.put("clientId", clientId);
UnkownMessageLogUtils.logUnkownMessage(this.getClass().getSimpleName(), this.getClass().getSimpleName(),
tokenRequest.toString(), logProp, request, response, "RECEAIIRP301", e);
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, "Unauthorized. [Unknown]"); String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, "Unauthorized. [Unknown]");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorJson); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorJson);
@@ -1,52 +1,52 @@
package com.eactive.eai.custom.adapter.handler; //package com.eactive.eai.custom.adapter.handler;
//
import java.util.Properties; //import java.util.Properties;
//
import com.eactive.eai.adapter.AdapterGroupVO; //import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager; //import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.handler.AdapterErrorMessageHandler; //import com.eactive.eai.adapter.handler.AdapterErrorMessageHandler;
import com.eactive.eai.common.message.MessageType; //import com.eactive.eai.common.message.MessageType;
import com.eactive.eai.message.StandardMessage; //import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager; //import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.InterfaceMapper; //import com.eactive.eai.message.service.InterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys; //import com.ext.eai.common.stdmessage.STDMessageKeys;
import com.fasterxml.jackson.databind.JsonNode; //import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; //import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; //import com.fasterxml.jackson.databind.node.ObjectNode;
//
public class LonErrorMsgHandler implements AdapterErrorMessageHandler { //public class LonErrorMsgHandler implements AdapterErrorMessageHandler {
//
@Override // @Override
public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, // public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName,
Properties callProp, Object outboundRequestData, StandardMessage resStandardMessage) throws Exception{ // Properties callProp, Object outboundRequestData, StandardMessage resStandardMessage) throws Exception{
//
if(resStandardMessage != null && isErrorMessage(resStandardMessage)) { // if(resStandardMessage != null && isErrorMessage(resStandardMessage)) {
AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(inboudnAdapterGroupName); // AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(inboudnAdapterGroupName);
if(MessageType.JSON.equals(adapterGroupVO.getMessageType())) { // if(MessageType.JSON.equals(adapterGroupVO.getMessageType())) {
ObjectMapper objectMapper = new ObjectMapper(); // ObjectMapper objectMapper = new ObjectMapper();
String requestMessage = (String) outboundRequestData; // String requestMessage = (String) outboundRequestData;
JsonNode requestJson = objectMapper.readTree(requestMessage); // JsonNode requestJson = objectMapper.readTree(requestMessage);
String alncInstCd = requestJson.get("dataCmn").get("alncInstCd").asText(); // String alncInstCd = requestJson.get("dataCmn").get("alncInstCd").asText();
//
ObjectNode responseJson = objectMapper.createObjectNode(); // ObjectNode responseJson = objectMapper.createObjectNode();
ObjectNode dataCmnNode = objectMapper.createObjectNode(); // ObjectNode dataCmnNode = objectMapper.createObjectNode();
responseJson.set("dataCmn", dataCmnNode); // responseJson.set("dataCmn", dataCmnNode);
dataCmnNode.put("fnclInstCd", "KBK"); // dataCmnNode.put("fnclInstCd", "KBK");
dataCmnNode.put("alncInstCd", alncInstCd); // dataCmnNode.put("alncInstCd", alncInstCd);
dataCmnNode.put("tlgrRspnsCd", "0210"); // dataCmnNode.put("tlgrRspnsCd", "0210");
//
return responseJson.toString(); // return responseJson.toString();
} // }
} // }
//
//
return ""; // return "";
} // }
//
private boolean isErrorMessage(StandardMessage standardMessage) { // private boolean isErrorMessage(StandardMessage standardMessage) {
InterfaceMapper mapper = StandardMessageManager.getInstance().getMapper(); // InterfaceMapper mapper = StandardMessageManager.getInstance().getMapper();
String responseType = mapper.getResponseType(standardMessage); // String responseType = mapper.getResponseType(standardMessage);
return STDMessageKeys.RESPONSE_TYPE_CODE_E.equals(responseType); // return STDMessageKeys.RESPONSE_TYPE_CODE_E.equals(responseType);
} // }
//
} //}
@@ -0,0 +1,31 @@
package com.eactive.eai.custom.adapter.http.client.impl.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.client.impl.filter.HttpClientAdapterFilter;
import com.eactive.eai.adapter.http.client.impl.filter.OutCryptoFilter;
/**
* 제주은행 Open API 기본 암복호화 필더
*/
public class EncFieldOutCryptoFilter implements HttpClientAdapterFilter {
private final OutCryptoFilter filter = new OutCryptoFilter();
protected Properties setProp(Properties p) {
p.setProperty(OutCryptoFilter.PROP_DEC_FROM_PATH, "/encryptedData");
p.setProperty(OutCryptoFilter.PROP_ENC_TO_PATH, "/encryptedData");
return p;
}
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
return filter.doPreFilter(adptGrpName, adptName, prop, message, setProp(tempProp));
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return filter.doPostFilter(adptGrpName, adptName, prop, message, setProp(tempProp));
}
}
@@ -0,0 +1,18 @@
package com.eactive.eai.custom.adapter.http.client.impl.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.client.impl.filter.OutCryptoFilter;
/**
* 카카오뱅크 암복호화에 맟추어 커스텀
*/
public class KakaobankEncFieldOutCryptoFilter extends EncFieldOutCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(OutCryptoFilter.PROP_DEC_FROM_PATH, "/encrypted_data");
p.setProperty(OutCryptoFilter.PROP_ENC_TO_PATH, "/encrypted_data");
return p;
}
}
@@ -0,0 +1,17 @@
package com.eactive.eai.custom.adapter.http.client.impl.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.client.impl.filter.OutCryptoFilter;
/**
* 토스 암복호화에 맟추어 커스텀
*/
public class TossEncFieldOutCryptoFilter extends EncFieldOutCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(OutCryptoFilter.PROP_DEC_FROM_PATH, "/encrypted_data");
p.setProperty(OutCryptoFilter.PROP_ENC_TO_PATH, "/encrypted_data");
return p;
}
}
@@ -0,0 +1,17 @@
package com.eactive.eai.custom.adapter.http.client.impl.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.client.impl.filter.OutCryptoFilter;
/**
* 토스뱅크 암복호화에 맟추어 커스텀
*/
public class TossbankEncFieldOutCryptoFilter extends EncFieldOutCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(OutCryptoFilter.PROP_DEC_FROM_PATH, "/encryptedData");
p.setProperty(OutCryptoFilter.PROP_ENC_TO_PATH, "/encryptedData");
return p;
}
}
@@ -0,0 +1,61 @@
package com.eactive.eai.custom.adapter.http.dynamic.filter;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter;
import com.eactive.eai.adapter.http.dynamic.filter.InCryptoFilter;
import com.eactive.eai.common.security.keyderiv.KeyDerivationStrategy;
/**
* 더존 연동용 수신 암복호화 필터.
*
* {@code HttpAdapterServiceKey.INBOUND_HEADER} 프로퍼티로 전달된 수신 헤더 Map에서
* 두 가지 컨텍스트 값을 추출하여 {@link InCryptoFilter}에 위임한다.
*
* x-emp-nm : GCM AAD 값 ({@code CRYPTO_AAD_HEADER} 프로퍼티에 설정)
* x-chnl-nm : DYNAMIC 키 도출 컨텍스트 ({@code contextKey} 프로퍼티에 설정)
* → {@code HsmContextSha256KeyDerivationStrategy}가 채널명 기반으로 키를 동적 생성
*
* 암복호화 필드 경로: {@code /encryptedData}
*
* 필터 타입 등록 (FQCN):
* com.eactive.eai.custom.adapter.http.dynamic.filter.DouzoneEncFieldInCryptoFilter
*/
public class DouzoneEncFieldInCryptoFilter implements HttpAdapterFilter {
private final InCryptoFilter filter = new InCryptoFilter();
protected Properties setProp(Properties p) {
p.setProperty(InCryptoFilter.PROP_DEC_FROM_PATH, "/encryptedData");
p.setProperty(InCryptoFilter.PROP_ENC_TO_PATH, "/encryptedData");
return p;
}
private void setContext(Properties tempProp) {
Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER);
String empNm = inboundHeaders.getProperty("x-emp-nm");
tempProp.setProperty(InCryptoFilter.PROP_AAD_HEADER, empNm);
String chnlNm = inboundHeaders.getProperty("x-chnl-nm");
tempProp.setProperty(KeyDerivationStrategy.PARAM_CONTEXT_KEY, chnlNm);
}
@Override
public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop,
HttpServletRequest request, HttpServletResponse response) throws Exception {
setContext(prop);
return filter.doPreFilter(adptGrpName, adptName, message, setProp(prop), request, response);
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop,
HttpServletRequest request, HttpServletResponse response) throws Exception {
setContext(prop);
return filter.doPostFilter(adptGrpName, adptName, resultMessage, setProp(prop), request, response);
}
}
@@ -0,0 +1,40 @@
package com.eactive.eai.custom.adapter.http.dynamic.filter;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.eactive.eai.adapter.http.dynamic.filter.InCryptoFilter;
import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter;
/**
* InCryptoFilter를 멤버변수로 관리하는 HttpAdapterFilter 구현체.
*
* 멤버변수에 세팅된 값을 Properties로 변환하여 {@link InCryptoFilter}에 위임한다.
* 값이 blank인 멤버변수는 Properties에 포함하지 않으며, InCryptoFilter의 기본값이 적용된다.
*/
public class EncFieldInCryptoFilter implements HttpAdapterFilter {
private final InCryptoFilter filter = new InCryptoFilter();
@Override
public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop,
HttpServletRequest request, HttpServletResponse response) throws Exception {
return filter.doPreFilter(adptGrpName, adptName, message, setProp(prop), request, response);
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop,
HttpServletRequest request, HttpServletResponse response) throws Exception {
return filter.doPostFilter(adptGrpName, adptName, resultMessage, setProp(prop), request, response);
}
protected Properties setProp(Properties p) {
p.setProperty(InCryptoFilter.PROP_DEC_FROM_PATH, "/encryptedData");
p.setProperty(InCryptoFilter.PROP_ENC_TO_PATH, "/encryptedData");
return p;
}
}
@@ -0,0 +1,18 @@
package com.eactive.eai.custom.adapter.http.dynamic.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.dynamic.filter.InCryptoFilter;
/**
* 카카오뱅크 암복호화에 맟추어 커스텀 필요
*/
public class KakaobankEncFieldInCryptoFilter extends EncFieldInCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(InCryptoFilter.PROP_DEC_FROM_PATH, "/encrypted_data");
p.setProperty(InCryptoFilter.PROP_ENC_TO_PATH, "/encrypted_data");
return p;
}
}
@@ -0,0 +1,18 @@
package com.eactive.eai.custom.adapter.http.dynamic.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.dynamic.filter.InCryptoFilter;
/**
* 토스 암복호화에 맟추어 커스텀 필요
*/
public class TossEncFieldInCryptoFilter extends EncFieldInCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(InCryptoFilter.PROP_DEC_FROM_PATH, "/encrypted_data");
p.setProperty(InCryptoFilter.PROP_ENC_TO_PATH, "/encrypted_data");
return p;
}
}
@@ -0,0 +1,18 @@
package com.eactive.eai.custom.adapter.http.dynamic.filter;
import java.util.Properties;
import com.eactive.eai.adapter.http.dynamic.filter.InCryptoFilter;
/**
* 토스뱅크 암복호화에 맟추어 커스텀 필요
*/
public class TossbankEncFieldInCryptoFilter extends EncFieldInCryptoFilter {
protected Properties setProp(Properties p) {
p.setProperty(InCryptoFilter.PROP_DEC_FROM_PATH, "/encryptedData");
p.setProperty(InCryptoFilter.PROP_ENC_TO_PATH, "/encryptedData");
return p;
}
}
@@ -0,0 +1,62 @@
package com.eactive.eai.custom.common.security.keyderiv;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;
import javax.crypto.SecretKey;
import com.eactive.eai.common.hsm.HsmCryptoService;
import com.eactive.eai.common.security.keyderiv.DerivedKey;
import com.eactive.eai.common.security.keyderiv.KeyDerivationStrategy;
import com.eactive.eai.common.util.ApplicationContextProvider;
/**
* HSM 마스터키 + 런타임 컨텍스트값을 연결(concatenate)한 뒤 SHA-256 해싱으로 키를 도출하는 전략.
* SHA-256 출력은 항상 32바이트(AES-256)이므로 별도 keyLength 파라미터가 불필요하다.
*
* key_deriv_params (JSON) 예시:
* {
* "hsmKeyAlias" : "MASTER_KEY_AES",
* "contextKey" : "X-Api-Group-Seq" -- runtimeContext에서 꺼낼 키 이름
* }
*/
public class HsmContextSha256KeyDerivationStrategy implements KeyDerivationStrategy {
@Override
public DerivedKey deriveKey(Map<String, String> params, Map<String, String> runtimeContext) throws Exception {
String hsmKeyAlias = required(params, PARAM_HSM_KEY_ALIAS);
String contextKey = required(params, PARAM_CONTEXT_KEY);
SecretKey masterKey = hsmCryptoService().getSecretKey(hsmKeyAlias);
byte[] masterKeyBytes = masterKey.getEncoded();
byte[] contextBytes = runtimeContext.getOrDefault(contextKey, "")
.getBytes(StandardCharsets.UTF_8);
byte[] combined = new byte[masterKeyBytes.length + contextBytes.length];
System.arraycopy(masterKeyBytes, 0, combined, 0, masterKeyBytes.length);
System.arraycopy(contextBytes, 0, combined, masterKeyBytes.length, contextBytes.length);
byte[] derived = MessageDigest.getInstance("SHA-256").digest(combined);
return new DerivedKey(derived, derived);
}
@Override
public String buildCacheKey(String cryptoName, Map<String, String> params, Map<String, String> runtimeContext) {
String contextKey = params.getOrDefault(PARAM_CONTEXT_KEY, "");
String contextValue = runtimeContext.getOrDefault(contextKey, "");
return cryptoName + ":" + contextValue;
}
private String required(Map<String, String> params, String key) {
String value = params.get(key);
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("key_deriv_params 필수값 누락: " + key);
}
return value;
}
private HsmCryptoService hsmCryptoService() {
return ApplicationContextProvider.getContext().getBean(HsmCryptoService.class);
}
}
@@ -0,0 +1,41 @@
package com.eactive.eai.custom.common.security.keyderiv;
import java.util.Map;
import javax.xml.bind.DatatypeConverter;
import com.eactive.eai.common.security.keyderiv.DerivedKey;
import com.eactive.eai.common.security.keyderiv.strategy.BaseHsmKeyDerivationStrategy;
/**
* HSM에서 키와 IV를 각각 가져오는 전략.
* IV는 HSM에서 가져온 바이트 배열을 hex 문자열로 변환한 뒤 substring(32, 64)를 적용하여 사용한다.
* (32바이트 HSM 키 → 64자 hex → substring(32,64) → 16바이트 IV)
*
* key_deriv_params (JSON) 예시:
* { "hsmKeyAlias" : "MASTER_KEY_AES", "hsmIvAlias" : "MASTER_IV_AES" }
*/
public class HsmKeyAndIvSliceDerivationStrategy extends BaseHsmKeyDerivationStrategy {
private static final int IV_HEX_OFFSET = 32;
private static final int IV_HEX_END = 64;
@Override
public DerivedKey deriveKey(Map<String, String> params, Map<String, String> runtimeContext) throws Exception {
byte[] keyBytes = super.getHsmKey(params);
byte[] rawIv = super.getHsmIv(params);
String ivHex = DatatypeConverter.printHexBinary(rawIv);
if (ivHex.length() < IV_HEX_END) {
throw new IllegalArgumentException(
"hsmIvAlias hex 길이 부족: 최소 " + IV_HEX_END + "자 필요, 실제=" + ivHex.length()
+ " (" + rawIv.length + "바이트)");
}
byte[] iv = DatatypeConverter.parseHexBinary(ivHex.substring(IV_HEX_OFFSET, IV_HEX_END));
return new DerivedKey(keyBytes, keyBytes, iv);
}
@Override
public String buildCacheKey(String cryptoName, Map<String, String> params, Map<String, String> runtimeContext) {
return cryptoName;
}
}
@@ -0,0 +1,169 @@
package com.eactive.eai.custom.inbound.processor;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.inflow.Bucket;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualBucket;
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.custom.inflow.ClientDualBucket;
import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.inbound.processor.RequestProcessor;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
/**
* 어댑터/인터페이스/클라이언트 유량제어 차단 시 어느 버킷(PER_SECOND/THRESHOLD)에서
* 차단됐는지 에러 메시지에 포함하는 RequestProcessor 확장.
*
* <p>ClientDualInflowControlManager와 함께 사용:
* <pre>
* inflow.control.bucket.className=com.eactive.eai.common.inflow.dual.ClientDualInflowControlManager
* </pre>
*
* <p>Spring Bean 등록 후 기존 RequestProcessor 대신 이 클래스를 어댑터에 설정한다.
*/
public class DJBRequestProcessor extends RequestProcessor {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
@Override
protected void afterFoundEaiMessage(EAIMessage eaiMsg, ProcessVO vo, Properties prop) {
logger.debug("DJBRequestProcessor interface found.");
try {
this.resolveStandardHeaderMapping(eaiMsg, prop);
} catch (Exception e) {
logger.warn("DJBRequestProcessor header set failed.", e);
}
}
private void resolveStandardHeaderMapping(EAIMessage eaiMsg, Properties prop) {
StandardMessage standardMessage = eaiMsg.getStandardMessage();
HashMap<String, String> headerMapping = getPropertyMap("DJB_IN_HTTHEAD_STDHEAD_MAPPING", eaiMsg.getSngSysItfTp());
for (Entry<String, String> entry : headerMapping.entrySet()) {
String stdHeaderPath = entry.getKey();
int dotIdx = stdHeaderPath.indexOf('.');
if(dotIdx > 0) {
String firstPath = stdHeaderPath.substring(0, dotIdx);
StandardItem topLevelItem = standardMessage.findItem(firstPath);
topLevelItem.setHidden(false);
}
StandardItem item = standardMessage.findItem(entry.getKey());
String value = resolveNestedValue(prop, entry.getValue());
if (item != null && value != null)
item.setValue(value);
else
logger.debug("header mapping item not found : {} ", entry);
}
}
private HashMap<String, String> getPropertyMap(String propertyGroupName, String prefix) {
Properties prop = PropManager.getInstance().getProperties(propertyGroupName);
Set<String> keys = prop.stringPropertyNames();
HashMap<String, String> tmpToJsonArrayInterface = new HashMap<>();
for (String key : keys) {
if (StringUtils.startsWith(key, prefix + ".")) {
String propValue = prop.getProperty(key);
String replacedKey = StringUtils.replace(key, prefix + ".", "");
tmpToJsonArrayInterface.put(replacedKey, propValue);
}
}
return tmpToJsonArrayInterface;
}
private String resolveNestedValue(Map<?, ?> map, String keyPath) {
int dotIdx = keyPath.indexOf('.');
if (dotIdx < 0) {
Object val = map.get(keyPath);
if (val == null)
return null;
if (val instanceof String)
return (String) val;
return val.toString();
}
String first = keyPath.substring(0, dotIdx);
String rest = keyPath.substring(dotIdx + 1);
Object val = map.get(first);
if (val instanceof Map) {
return resolveNestedValue((Map<?, ?>) val, rest);
}
// 폴백: 전체 keyPath를 단일 키로 조회
Object direct = map.get(keyPath);
if (direct == null)
return null;
if (direct instanceof String)
return (String) direct;
return direct.toString();
}
@Override
protected String checkCustomInflow(Bucket bucket, EAIMessage eaiMsg, Properties prop) {
String clientId = eaiMsg.getClientId();
if (StringUtils.isBlank(clientId)) return null;
if (bucket instanceof ClientDualBucket) {
return ((ClientDualBucket) bucket).isClientPassDetail(clientId);
}
return null;
}
@Override
protected InflowTargetVO resolveCustomInflowThreshold(Bucket bucket, EAIMessage eaiMsg, Properties prop) {
if (bucket instanceof ClientDualBucket) {
return ((ClientDualBucket) bucket).getClientInflowThreshold(eaiMsg.getClientId());
}
return null;
}
@Override
protected String checkAdapterInflow(Bucket bucket, String adapterGroupName) {
if (bucket instanceof DualBucket) {
return ((DualBucket) bucket).isAdapterPassDetail(adapterGroupName);
}
return super.checkAdapterInflow(bucket, adapterGroupName);
}
@Override
protected String checkInterfaceInflow(Bucket bucket, String eaiSvcCd) {
if (bucket instanceof DualBucket) {
return ((DualBucket) bucket).isInterfacePassDetail(eaiSvcCd);
}
return super.checkInterfaceInflow(bucket, eaiSvcCd);
}
/**
* 차단 원인에 따라 에러 메시지에 한도 정보를 포함.
* <ul>
* <li>PER_SECOND: "API 호출 한도 초과 [name: Nreq/sec]"</li>
* <li>THRESHOLD: "API 호출 한도 초과 [name: Nreq/UNIT]"</li>
* <li>그 외: "API 호출 한도 초과 [name]" (기존 동작)</li>
* </ul>
*/
@Override
protected String buildInflowTargetErrorMsg(InflowTargetVO inflowTargetVO, String blockedType) {
if (DualCustomBucket.RESULT_BLOCKED_PER_SECOND.equals(blockedType)) {
return String.format("API 호출 한도 초과 [%s: %dreq/sec]",
inflowTargetVO.getName(),
inflowTargetVO.getThresholdPerSecond());
}
if (DualCustomBucket.RESULT_BLOCKED_THRESHOLD.equals(blockedType)) {
return String.format("API 호출 한도 초과 [%s: %dreq/%s]",
inflowTargetVO.getName(),
inflowTargetVO.getThreshold(),
inflowTargetVO.getThresholdTimeUnit());
}
return super.buildInflowTargetErrorMsg(inflowTargetVO, blockedType);
}
}
@@ -0,0 +1,23 @@
package com.eactive.eai.custom.inflow;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualBucket;
/**
* DualBucket에 클라이언트 유량제어 메서드를 추가한 인터페이스.
* {@link ClientDualInflowControlManager}가 구현한다.
*/
public interface ClientDualBucket extends DualBucket {
/**
* 클라이언트 유량제어 체크 — 차단 원인 포함.
* @return null이면 통과, "PER_SECOND" 또는 "THRESHOLD"이면 해당 버킷에서 차단
*/
String isClientPassDetail(String clientId);
/**
* 클라이언트 유량제어 설정 조회 — 에러 메시지 생성용.
* @return 등록된 설정이 없으면 null
*/
InflowTargetVO getClientInflowThreshold(String clientId);
}
@@ -0,0 +1,114 @@
package com.eactive.eai.custom.inflow;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.stereotype.Component;
import com.eactive.eai.common.inflow.Bucket;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.InflowType;
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.common.util.ApplicationContextProvider;
import com.eactive.eai.common.util.Logger;
/**
* 어댑터/인터페이스 이중 버킷(DualInflowControlManager)에 클라이언트 유량제어를 추가한 관리자.
*
* <p>적용 방법: INFLOW.properties에 아래 한 줄 추가.
* <pre>inflow.control.bucket.className=com.eactive.eai.common.inflow.dual.ClientDualInflowControlManager</pre>
*/
@Component
public class ClientDualInflowControlManager extends DualInflowControlManager implements ClientDualBucket {
private static final Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
public static synchronized Bucket getBucket() {
return ApplicationContextProvider.getContext().getBean(ClientDualInflowControlManager.class);
}
private volatile Map<String, DualCustomBucket> clientBucketMap = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, TargetMetrics> clientMetricsMap = new ConcurrentHashMap<>();
// -------------------------------------------------------------------------
// Lifecycle
// -------------------------------------------------------------------------
@Override
public void start() throws LifecycleException {
super.start();
try {
initClients();
} catch (Exception e) {
throw new LifecycleException("ClientDualInflowControlManager init failed: " + e.getMessage());
}
}
// -------------------------------------------------------------------------
// 초기화 / 리로드
// -------------------------------------------------------------------------
private void initClients() throws Exception {
this.clientBucketMap = loadBucketMap(InflowType.CLIENT);
if (logger.isInfo()) logger.info("ClientDualInflowControlManager] initClients: " + clientBucketMap.size() + " buckets");
}
public synchronized void reloadClient() throws Exception {
initClients();
clientMetricsMap.clear();
}
public synchronized void reloadClient(String clientId) throws Exception {
reloadBucketMap(clientBucketMap, InflowType.CLIENT, clientId);
TargetMetrics m = clientMetricsMap.get(clientId);
if (m != null) m.reset();
}
public synchronized void removeClient(String clientId) {
clientBucketMap.remove(clientId);
clientMetricsMap.remove(clientId);
}
// -------------------------------------------------------------------------
// 클라이언트 메트릭 접근자
// -------------------------------------------------------------------------
public TargetMetrics getClientMetrics(String clientId) { return clientMetricsMap.get(clientId); }
public Map<String, TargetMetrics> getAllClientMetrics() { return Collections.unmodifiableMap(clientMetricsMap); }
public void resetClientMetrics(String clientId) { TargetMetrics m = clientMetricsMap.get(clientId); if (m != null) m.reset(); }
public void resetAllClientMetrics() { clientMetricsMap.values().forEach(TargetMetrics::reset); }
// -------------------------------------------------------------------------
// ClientDualBucket — 클라이언트 유량제어
// -------------------------------------------------------------------------
@Override
public String isClientPassDetail(String clientId) {
DualCustomBucket b = clientBucketMap.get(clientId);
if (b == null) return DualCustomBucket.RESULT_PASS;
String result = b.tryConsume();
recordMetrics(clientMetricsMap, clientId, result);
return result;
}
@Override
public InflowTargetVO getClientInflowThreshold(String clientId) {
DualCustomBucket b = clientBucketMap.get(clientId);
return (b == null) ? null : b.getInflowTargetVo();
}
// -------------------------------------------------------------------------
// 모니터링용 접근자
// -------------------------------------------------------------------------
public DualCustomBucket getClientBucket(String clientId) {
return clientBucketMap.get(clientId);
}
public Map<String, DualCustomBucket> getClientBucketMap() {
return clientBucketMap;
}
}
@@ -0,0 +1,63 @@
package com.eactive.eai.custom.inflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
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.RestController;
import com.eactive.eai.manage.inflow.TargetBucketStatusDTO;
/**
* 클라이언트 버킷 상태 모니터링 API.
*
* ClientDualInflowControlManager 가 활성화된 환경에서만 정상 응답한다.
*
* GET /manage/inflow/client/bucket-status → 전체 클라이언트 버킷 상태
* GET /manage/inflow/client/{clientId}/bucket-status → 특정 클라이언트 버킷 상태
*/
@RestController
@RequestMapping("/manage/inflow")
public class ClientInflowTargetBucketController {
@Autowired
private ClientInflowTargetBucketService bucketService;
@GetMapping("/client/bucket-status")
public ResponseEntity<?> getAllClientBucketStatus() {
List<TargetBucketStatusDTO> list = bucketService.getAllClientBucketStatus();
return ok(list);
}
@GetMapping("/client/{clientId}/bucket-status")
public ResponseEntity<?> getClientBucketStatus(@PathVariable String clientId) {
TargetBucketStatusDTO dto = bucketService.getClientBucketStatus(clientId);
return single(dto, "클라이언트를 찾을 수 없습니다: " + clientId);
}
private ResponseEntity<?> ok(List<TargetBucketStatusDTO> list) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", list);
result.put("count", list.size());
return ResponseEntity.ok(result);
}
private ResponseEntity<?> single(TargetBucketStatusDTO dto, String notFoundMsg) {
if (dto == null) {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("message", notFoundMsg);
return ResponseEntity.ok(error);
}
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", dto);
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,78 @@
package com.eactive.eai.custom.inflow;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
import com.eactive.eai.manage.inflow.GroupBucketStatusDTO;
import com.eactive.eai.manage.inflow.TargetBucketStatusDTO;
/**
* 클라이언트 버킷 상태 조회 서비스.
*
* ClientDualInflowControlManager 가 활성화된 경우에만 동작한다.
*/
@Service
public class ClientInflowTargetBucketService {
public TargetBucketStatusDTO getClientBucketStatus(String clientId) {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getClientBucket(clientId);
if (bucket == null) return null;
return toDto(clientId, "CLIENT", bucket);
}
public List<TargetBucketStatusDTO> getAllClientBucketStatus() {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("CLIENT", manager.getClientBucketMap());
}
protected ClientDualInflowControlManager getClientDualManager() {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
return (base instanceof ClientDualInflowControlManager) ? (ClientDualInflowControlManager) base : null;
}
private TargetBucketStatusDTO toDto(String targetId, String targetType, DualCustomBucket bucket) {
InflowTargetVO vo = bucket.getInflowTargetVo();
List<GroupBucketStatusDTO.BucketInfo> buckets = new ArrayList<>();
if (vo.getThresholdPerSecond() > 0) {
long capacity = vo.getThresholdPerSecond();
long available = bucket.getPerSecondAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"perSecond", capacity, Math.min(available, capacity), "SEC"));
}
if (vo.getThreshold() > 0) {
long capacity = vo.getThreshold();
long available = bucket.getThresholdAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"threshold", capacity, Math.min(available, capacity), vo.getThresholdTimeUnit()));
}
TargetBucketStatusDTO dto = new TargetBucketStatusDTO();
dto.setTargetId(targetId);
dto.setTargetType(targetType);
dto.setActivate(vo.isActivate());
dto.setBuckets(buckets);
return dto;
}
private List<TargetBucketStatusDTO> toDtoList(String targetType, Map<String, DualCustomBucket> bucketMap) {
List<TargetBucketStatusDTO> result = new ArrayList<>();
for (Map.Entry<String, DualCustomBucket> entry : bucketMap.entrySet()) {
result.add(toDto(entry.getKey(), targetType, entry.getValue()));
}
return result;
}
}
@@ -0,0 +1,94 @@
package com.eactive.eai.custom.inflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.eactive.eai.manage.inflow.TargetMetricDTO;
/**
* 클라이언트 유량제어 메트릭 API.
*
* ClientDualInflowControlManager 가 활성화된 환경에서만 정상 응답한다.
*
* GET /manage/inflow/client/metric → 전체 클라이언트 메트릭
* GET /manage/inflow/client/{clientId}/metric → 특정 클라이언트 메트릭
* POST /manage/inflow/client/metric/reset → 전체 클라이언트 메트릭 초기화
* POST /manage/inflow/client/{clientId}/metric/reset → 특정 클라이언트 메트릭 초기화
*/
@RestController
@RequestMapping("/manage/inflow")
public class ClientInflowTargetMetricController {
@Autowired
private ClientInflowTargetMetricService metricService;
@GetMapping("/client/metric")
public ResponseEntity<?> getAllClientMetrics() {
List<TargetMetricDTO> list = metricService.getAllClientMetrics();
return okList(list);
}
@GetMapping("/client/{clientId}/metric")
public ResponseEntity<?> getClientMetric(@PathVariable String clientId) {
TargetMetricDTO dto = metricService.getClientMetric(clientId);
return okSingle(dto, "클라이언트를 찾을 수 없습니다: " + clientId);
}
@PostMapping("/client/metric/reset")
public ResponseEntity<?> resetAllClientMetrics() {
metricService.resetAllClientMetrics();
return okReset("전체 클라이언트 메트릭 초기화 완료");
}
@PostMapping("/client/{clientId}/metric/reset")
public ResponseEntity<?> resetClientMetric(@PathVariable String clientId) {
boolean ok = metricService.resetClientMetric(clientId);
return okResetSingle(ok, clientId, "클라이언트");
}
private ResponseEntity<?> okList(List<TargetMetricDTO> list) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", list);
result.put("count", list.size());
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okSingle(TargetMetricDTO dto, String notFoundMsg) {
if (dto == null) {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("message", notFoundMsg);
return ResponseEntity.ok(error);
}
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", dto);
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okReset(String message) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", message);
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okResetSingle(boolean ok, String targetId, String targetLabel) {
Map<String, Object> result = new HashMap<>();
result.put("success", ok);
result.put("message", ok
? "초기화 완료: " + targetId
: targetLabel + "를 찾을 수 없습니다: " + targetId);
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,78 @@
package com.eactive.eai.custom.inflow;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
import com.eactive.eai.manage.inflow.TargetMetricDTO;
@Service
public class ClientInflowTargetMetricService {
public TargetMetricDTO getClientMetric(String clientId) {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager == null) return null;
InflowTargetVO vo = manager.getClientInflowThreshold(clientId);
if (vo == null) return null;
return buildDTO(clientId, "CLIENT", vo, manager.getClientMetrics(clientId));
}
public List<TargetMetricDTO> getAllClientMetrics() {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager == null) return new ArrayList<>();
List<TargetMetricDTO> result = new ArrayList<>();
for (String id : manager.getClientBucketMap().keySet()) {
TargetMetricDTO dto = getClientMetric(id);
if (dto != null) result.add(dto);
}
return result;
}
public boolean resetClientMetric(String clientId) {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager == null) return false;
if (manager.getClientInflowThreshold(clientId) == null) return false;
manager.resetClientMetrics(clientId);
return true;
}
public void resetAllClientMetrics() {
ClientDualInflowControlManager manager = getClientDualManager();
if (manager != null) manager.resetAllClientMetrics();
}
protected ClientDualInflowControlManager getClientDualManager() {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
return (base instanceof ClientDualInflowControlManager) ? (ClientDualInflowControlManager) base : null;
}
private TargetMetricDTO buildDTO(String targetId, String targetType,
InflowTargetVO vo,
DualInflowControlManager.TargetMetrics m) {
TargetMetricDTO dto = new TargetMetricDTO();
dto.setTargetId(targetId);
dto.setTargetType(targetType);
dto.setActivate(vo.isActivate());
if (m != null) {
long allowed = m.allowed.get();
long rejPs = m.rejectedPerSecond.get();
long rejTh = m.rejectedThreshold.get();
long total = allowed + rejPs + rejTh;
dto.setAllowed(allowed);
dto.setRejectedPerSecond(rejPs);
dto.setRejectedThreshold(rejTh);
dto.setTotalRequests(total);
dto.setRejectRatio(total > 0
? Math.round((double)(rejPs + rejTh) / total * 10000) / 100.0
: 0.0);
dto.setLastResetTime(m.lastResetTime);
}
return dto;
}
}
@@ -1,123 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class AllHeaderFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String PROPERTIES_GROUP_NAME = "HttpHeaderFilter";
public static final String HEADER_KEY_NAMES = "AllHeaderFilter.blackList";
String[] HttpHeaderRelayBlackList = {
"Content-Length",
"Transfer-Encoding",
"Host",
"Authorization",
"Accept",
"Host",
"Cookie",
"Connection",
"Keep-Alive",
"Proxy-Authenticate",
"Proxy-Authorization",
"TE",
"Trailer",
"Transfer-Encoding",
"Upgrade",
"Content-Type",
"Content-Encoding",
"Content-Language",
"Content-Location",
"Content-MD5",
"Expect",
};
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("doPreFilter Processing Start.");
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
String propValue = PropManager.getInstance().getProperty(PROPERTIES_GROUP_NAME, HEADER_KEY_NAMES, "").trim();
String[] userSettingBlackList = propValue.split(",");
if( userSettingBlackList.length > 0 ) {
HttpHeaderRelayBlackList = Stream
.concat(Arrays.stream(HttpHeaderRelayBlackList), Arrays.stream(userSettingBlackList))
.toArray(String[]::new);
}
for(String keyName : inboundHeaderMap.keySet() ) {
if( StringUtils.equalsAnyIgnoreCase( keyName, HttpHeaderRelayBlackList ) ) {
logger.debug("Skip Processing Key ["+keyName+"], value ["+inboundHeaderMap.get(keyName)+"] in HttpHeaderRelayBlackList");
continue;
}
filterHeaders.put(keyName, inboundHeaderMap.get(keyName));
logger.debug("Processing Key ["+keyName+"], value ["+inboundHeaderMap.get(keyName)+"]");
}
logger.debug("doPreFilter Processing End.");
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,118 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class AsyncReponseFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String X_TRACE_ID = "partnerTraceId";
public static final String TRACE_ID = "traceId";
public static final String PROPERTIES_GROUP_NAME = "HttpHeaderFilter";
public static final String HEADER_KEY_NAMES = "AsyncReponseFilter";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("AsyncReponseFilter] PreFilter Processing Start!!");
String traceId = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
String propValue = PropManager.getInstance().getProperty(PROPERTIES_GROUP_NAME, HEADER_KEY_NAMES, "").trim();
String[] headerKeyNames = propValue.split(",");
headerKeyNames = Arrays.stream(headerKeyNames)
.map(String::trim)
.toArray(String[]::new);
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(X_TRACE_ID)) {
filterHeaders.put(X_TRACE_ID, inboundHeaderMap.get(X_TRACE_ID));
logger.debug("AsyncReponseFilter] Processing Key ["+X_TRACE_ID+"], value ["+inboundHeaderMap.get(X_TRACE_ID)+"]");
}
if (inboundHeaderMap.containsKey(TransactionContextKeys.X_LOAN_TOKEN)) {
filterHeaders.put(TransactionContextKeys.X_LOAN_TOKEN, inboundHeaderMap.get(TransactionContextKeys.X_LOAN_TOKEN));
logger.debug("AsyncReponseFilter] Processing Key ["+TransactionContextKeys.X_LOAN_TOKEN+"], value ["+inboundHeaderMap.get(TransactionContextKeys.X_LOAN_TOKEN)+"]");
}
}
filterHeaders.setProperty(TRACE_ID, traceId);
logger.debug("AsyncReponseFilter] Processing Key ["+TRACE_ID+"], value ["+traceId+"]");
for (String keyName : inboundHeaderMap.keySet()) {
if (StringUtils.equalsAnyIgnoreCase(keyName, headerKeyNames)) {
String value = inboundHeaderMap.get(keyName);
filterHeaders.put(keyName, value);
logger.debug("AsyncReponseFilter] Processing Key [" + keyName + "], value [" + value + "]");
}
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,115 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.concurrent.ConcurrentHashMap;
import com.eactive.eai.common.util.Logger;
public class HttpClient5AdapterFilterFactory {
static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
static String basePackage = "com.eactive.eai.custom.kjb.adapter.http.client.filter";
private static ConcurrentHashMap<String, HttpClientAdapterFilter> h = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, HttpClientAdapterExceptionFilter> eh = new ConcurrentHashMap<>();
private HttpClient5AdapterFilterFactory() {
throw new IllegalStateException("Utility class");
}
public static HttpClientAdapterFilter createFilter(String type) {
if (h.containsKey(type)) {
return h.get(type);
}
HttpClientAdapterFilter filter = null;
switch (HttpClient5AdapterFilterType.getValue(type)) {
case SIMPLEFRAMEWORK:
filter = new SimpleFrameworkFilter();
break;
case SIMPLEFRAMEWORKBODY:
filter = new SimpleframeworkBodyFilter();
break;
case JBOBP:
filter = new JBOBPFilter();
break;
case KFTCFACE:
filter = new KFTCFaceFilter();
break;
case KFTCP2P:
filter = new KFTCP2PFilter();
break;
case KAKAOBANK:
filter = new KAKAOBankFilter();
break;
case NAVERFIN:
filter = new NAVERFinFilter();
break;
case NICECREDIT:
filter = new NICECreditFilter();
break;
case TRACEBODY:
filter = new TraceBodyFilter();
break;
case TOSSBANK:
filter = new TOSSBankFilter();
break;
case ASYNCRESPONSE:
filter = new AsyncReponseFilter();
break;
case ALLHEADER:
filter = new AllHeaderFilter();
break;
default:
filter = classForName(type);
if (filter == null) {
filter = classForName(basePackage + "." + type);
}
break;
}
if (filter != null) {
h.put(type, filter);
return filter;
} else {
return null;
}
}
private static HttpClientAdapterFilter classForName(String type) {
try {
Class<?> cl = Class.forName(type);
return (HttpClientAdapterFilter) cl.newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
logger.error("Cannot create a HttpClientAdapterFilter. - {}", type);
return null;
}
}
public static HttpClientAdapterExceptionFilter createExceptionFilter(String type) {
if (eh.containsKey(type)) {
return eh.get(type);
}
HttpClientAdapterExceptionFilter filter = classForExceptionFilterName(type);
if (filter == null) {
filter = classForExceptionFilterName(basePackage + "." + type);
}
if (filter != null) {
eh.put(type, filter);
return filter;
} else {
return null;
}
}
private static HttpClientAdapterExceptionFilter classForExceptionFilterName(String type) {
try {
Class<?> cl = Class.forName(type);
return (HttpClientAdapterExceptionFilter) cl.newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
logger.error("Cannot create a HttpClientAdapterExceptionFilter. - {}", type);
return null;
}
}
}
@@ -1,27 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
public enum HttpClient5AdapterFilterType {
SIMPLEFRAMEWORK,
SIMPLEFRAMEWORKBODY,
JBOBP,
KFTCFACE,
KFTCP2P,
KAKAOBANK,
NAVERFIN,
NICECREDIT,
TOSSBANK,
TRACEBODY,
ASYNCRESPONSE,
ALLHEADER,
UNKNOWN;
public static HttpClient5AdapterFilterType getValue(String type) {
try {
return valueOf(type.toUpperCase());
} catch (NullPointerException e) {
return UNKNOWN;
} catch (Exception e) {
return UNKNOWN;
}
}
}
@@ -1,62 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.eactive.eai.common.util.Logger;
public abstract class HttpClientAdapterBaseFilter implements HttpClientAdapterFilter {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
protected String filterName = "";
protected List<HttpClientAdapterFilter> filters;
protected HttpClientAdapterBaseFilter(String filterName) {
this.filterName = filterName;
filters = new ArrayList<>();
logger.info("{}] filter created.", filterName);
}
protected void addFilter(HttpClientAdapterFilter filter) {
filters.add(filter);
logger.info("{}] sub filter({}) added. filters= {}", filterName, filter, filters);
}
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
try {
Object filteredMessage = message;
for(HttpClientAdapterFilter subFilter : filters) {
logger.debug("{}] sub filter({}) doPreFilter start.", filterName, subFilter);
filteredMessage = subFilter.doPreFilter(adptGrpName, adptName, prop, filteredMessage, tempProp);
logger.debug("{}] sub filter({}) doPreFilter end.", filterName, subFilter);
}
return filteredMessage;
} catch (Exception e) {
logger.error(this.filterName + "] doPreFilter error.", e);
throw e;
}
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
try {
Object filteredMessage = message;
for(HttpClientAdapterFilter subFilter : filters) {
logger.debug("{}] sub filter({}) doPostFilter start.", filterName, subFilter);
filteredMessage = subFilter.doPostFilter(adptGrpName, adptName, prop, filteredMessage, tempProp);
logger.debug("{}] sub filter({}) doPostFilter end.", filterName, subFilter);
}
return filteredMessage;
} catch (Exception e) {
logger.error(this.filterName + "] doPostFilter error.", e);
throw e;
}
}
}
@@ -1,10 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Properties;
public interface HttpClientAdapterExceptionFilter {
public Object doExceptionFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp, Exception e) throws Exception;
}
@@ -1,12 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Properties;
public interface HttpClientAdapterFilter {
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception;
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception;
}
@@ -1,35 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Properties;
import lombok.Getter;
public class HttpClientAdapterFilterException extends RuntimeException {
private static final long serialVersionUID = -1208983360831093751L;
@Getter
private final String code;
@Getter
private final Properties prop;
@Getter
private final Properties tempProp;
public HttpClientAdapterFilterException(String code, String msg, Properties prop, Properties tmepProp) {
super(msg);
this.code = code;
this.prop = prop;
this.tempProp = tmepProp;
}
public HttpClientAdapterFilterException(String code, String msg, Properties prop, Properties tempProp, Throwable cause) {
super(msg, cause);
this.code = code;
this.prop = prop;
this.tempProp = tempProp;
}
@Override
public String toString() {
return "HttpClientAdapterFilterException [code=" + code + ", prop=" + prop + ", tempProp=" + tempProp + ", parent=" + super.toString() + "]";
}
}
@@ -1,106 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class JBOBPFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String X_OBP_PARTNERCODE = "x-obp-partnercode";
public static final String X_OBP_TXID = "x-obp-txid";
public static final String X_OBP_TRUST_SYSTEM = "x-obp-trust-system";
String systemTrustKey = "APIMGW-0001-QVBJTUdXLTAwMDE=";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("JBOBPFilter] PreFilter Processing Start!!");
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) systemTrustKey = propGroupVo.getProperty(X_OBP_TRUST_SYSTEM, systemTrustKey);
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
String obpPartnerCode = "000000-00";
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(X_OBP_PARTNERCODE)) {
filterHeaders.put(X_OBP_PARTNERCODE, inboundHeaderMap.get(X_OBP_PARTNERCODE));
logger.debug("JBOBPFilter] Processing Key ["+X_OBP_PARTNERCODE+"], value ["+inboundHeaderMap.get(X_OBP_PARTNERCODE)+"]");
} else {
filterHeaders.put(X_OBP_PARTNERCODE, obpPartnerCode);
logger.debug("JBOBPFilter] Processing Key ["+X_OBP_PARTNERCODE+"], value ["+obpPartnerCode+"]");
}
} else {
filterHeaders.put(X_OBP_PARTNERCODE, obpPartnerCode);
logger.debug("JBOBPFilter] Processing Key ["+X_OBP_PARTNERCODE+"], value ["+obpPartnerCode+"]");
}
String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
if (StringUtils.isNotBlank(uuid)) {
filterHeaders.setProperty(X_OBP_TXID, uuid); // JB OBP Framework용
logger.debug("JBOBPFilter] Processing Key ["+X_OBP_TXID+"], value ["+uuid+"]");
}
if (StringUtils.isNotBlank(systemTrustKey)) {
filterHeaders.setProperty(X_OBP_TRUST_SYSTEM, systemTrustKey); // JB OBP Framework용
logger.debug("JBOBPFilter] Processing Key ["+X_OBP_TRUST_SYSTEM+"], value ["+systemTrustKey+"]");
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,135 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class KAKAOBankFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "kakaobank";
public static final String X_KKB_PARTNER_CODE = "X-KKB-PARTNER-CODE";
public static final String X_KKB_API_NAME = "X-KKB-API-NAME";
public static final String X_KKB_API_TX_ID = "X-KKB-API-TX-ID";
public static final String X_KKB_TX_TIME = "X-KKB-TX-TIME";
public static final String X_KKB_CMPR_MGMT_NO = "X-KKB-CMPR-MGMT-NO";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("KAKAOBankFilter] PreFilter Processing Start!!");
Object returnMessage = message;
String partnerCode = "KJB";
String apiName = "status_change";
String apiTxId = "0";
String txTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String cmprMgmtNo = "0";
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
partnerCode = propGroupVo.getProperty(PROP_PREFIX + "." + X_KKB_PARTNER_CODE);
apiName = propGroupVo.getProperty(PROP_PREFIX + "." + X_KKB_API_NAME);
apiTxId = propGroupVo.getProperty(PROP_PREFIX + "." + X_KKB_API_TX_ID);
cmprMgmtNo = propGroupVo.getProperty(PROP_PREFIX + "." + X_KKB_CMPR_MGMT_NO);
}
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(X_KKB_PARTNER_CODE)) {
filterHeaders.put(X_KKB_PARTNER_CODE, inboundHeaderMap.get(X_KKB_PARTNER_CODE));
} else {
filterHeaders.put(X_KKB_PARTNER_CODE, partnerCode);
}
if (inboundHeaderMap.containsKey(X_KKB_API_NAME)) {
filterHeaders.put(X_KKB_API_NAME, inboundHeaderMap.get(X_KKB_API_NAME));
} else {
filterHeaders.put(X_KKB_API_NAME, apiName);
}
if (inboundHeaderMap.containsKey(X_KKB_API_TX_ID)) {
filterHeaders.put(X_KKB_API_TX_ID, inboundHeaderMap.get(X_KKB_API_TX_ID));
} else {
filterHeaders.put(X_KKB_API_TX_ID, apiTxId);
}
if (inboundHeaderMap.containsKey(X_KKB_TX_TIME)) {
filterHeaders.put(X_KKB_TX_TIME, inboundHeaderMap.get(X_KKB_TX_TIME));
} else {
filterHeaders.put(X_KKB_TX_TIME, txTime);
}
if (inboundHeaderMap.containsKey(X_KKB_CMPR_MGMT_NO)) {
filterHeaders.put(X_KKB_CMPR_MGMT_NO, inboundHeaderMap.get(X_KKB_CMPR_MGMT_NO));
} else {
filterHeaders.put(X_KKB_CMPR_MGMT_NO, cmprMgmtNo);
}
} else {
filterHeaders.put(X_KKB_PARTNER_CODE, partnerCode);
filterHeaders.put(X_KKB_API_NAME, apiName);
filterHeaders.put(X_KKB_API_TX_ID, apiTxId);
filterHeaders.put(X_KKB_TX_TIME, txTime);
filterHeaders.put(X_KKB_CMPR_MGMT_NO, cmprMgmtNo);
}
logger.debug("KAKAOBankFilter] Processing Key ["+X_KKB_PARTNER_CODE+"], value ["+filterHeaders.getProperty(X_KKB_PARTNER_CODE)+"]");
logger.debug("KAKAOBankFilter] Processing Key ["+X_KKB_API_NAME+"], value ["+filterHeaders.getProperty(X_KKB_API_NAME)+"]");
logger.debug("KAKAOBankFilter] Processing Key ["+X_KKB_API_TX_ID+"], value ["+filterHeaders.getProperty(X_KKB_API_TX_ID)+"]");
logger.debug("KAKAOBankFilter] Processing Key ["+X_KKB_TX_TIME+"], value ["+filterHeaders.getProperty(X_KKB_TX_TIME)+"]");
logger.debug("KAKAOBankFilter] Processing Key ["+X_KKB_CMPR_MGMT_NO+"], value ["+filterHeaders.getProperty(X_KKB_CMPR_MGMT_NO)+"]");
} catch (Exception e) {
logger.error(e.getMessage());
}
return returnMessage;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,154 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.Logger;
public class KFTCFaceFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "kftcface";
public static final String H_CLIENT_ID = "Client-Id";
public static final String B_ORG_CODE = "org_code";
public static final String B_TRANSACTION_ID = "transaction_id";
public static final String B_REQUEST_DATETIME = "request_datetime";
public static String instId = null;
static {
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
instId = eaiServerManager.getInstId();
}
@SuppressWarnings({ "unchecked" })
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("KFTCFaceFilter] PreFilter Processing Start!!");
JSONObject returnMessage = null;
String clientId = "";
String orgCode = "034"; // 광주은행 행코드
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
if (StringUtils.isEmpty(clientId))
clientId = propGroupVo.getProperty(PROP_PREFIX + "." + H_CLIENT_ID);
orgCode = propGroupVo.getProperty(PROP_PREFIX + "." + B_ORG_CODE);
}
String request_datetime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String reqDate = new SimpleDateFormat("yyMMdd").format(new Date());
String reqTime = new SimpleDateFormat("HHmmss").format(new Date());
// 기관코드(3) + 요청일자(6) -- 금결원 표준화 항목, 고정 9자리.
// 요청시간(6) + 인스턴스ID(2) + RandomString(3) -- 기관별 생성 거래고유번호(11자리)
// 기관코드(3) + 요청일자(6) + 요청시간(6) + 인스턴스ID(2) + RandomString(3) -- 20자리.
String transaction_id = orgCode + reqDate + reqTime + instId + RandomStringUtils.random(3, true, true).toUpperCase();
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(H_CLIENT_ID)) {
filterHeaders.put(H_CLIENT_ID, inboundHeaderMap.get(H_CLIENT_ID));
logger.debug("KFTCFaceFilter] Processing Key ["+H_CLIENT_ID+"], value ["+inboundHeaderMap.get(H_CLIENT_ID)+"]");
} else {
filterHeaders.put(H_CLIENT_ID, clientId);
logger.debug("KFTCFaceFilter] Processing Key ["+H_CLIENT_ID+"], value ["+clientId+"]");
}
} else {
filterHeaders.setProperty(H_CLIENT_ID, clientId);
logger.debug("KFTCFaceFilter] Processing Key ["+H_CLIENT_ID+"], value ["+clientId+"]");
}
} catch (Exception e) {
logger.error(e.getMessage());
}
AdapterManager adapterManager = AdapterManager.getInstance();
AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adptGrpName);
String encode = adptGrpVO.getMessageEncode();
if (message == null) {
returnMessage = new JSONObject();
} else {
if (message instanceof JSONObject) {
returnMessage = (JSONObject) message;
} else if (message instanceof String) {
returnMessage = parseJson((String) message);
} else if (message instanceof byte[]) {
returnMessage = parseJson(new String((byte[]) message, encode));
}
}
returnMessage.put(B_ORG_CODE, orgCode);
returnMessage.put(B_TRANSACTION_ID, transaction_id);
returnMessage.put(B_REQUEST_DATETIME, request_datetime);
return returnMessage.toJSONString();
}
private JSONObject parseJson(String message) throws Exception {
if (message == null) {
return null;
}
return (JSONObject) JSONValue.parse(message);
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,122 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.RandomStringUtils;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.Logger;
public class KFTCP2PFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "kftcp2p";
public static final String H_ORG_CODE = "org_code";
public static final String H_TRX_NO = "api_trx_no";
public static final String H_TRX_DTM = "api_trx_dtm";
public static String instId = null;
static {
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
instId = eaiServerManager.getInstId();
}
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("KFTCP2PFilter] PreFilter Processing Start!!");
String orgCode = "D210400012"; // 광주은행 개발 기관코드(운영: K210800020)
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
orgCode = propGroupVo.getProperty(PROP_PREFIX + "." + H_ORG_CODE);
}
String apiTrxDtm = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
String apiTrxTm = new SimpleDateFormat("HHmmss").format(new Date());
// 기관코드(10) + 인스턴스ID(2) + 일시(6) + RandomString(2) -- 총 20자리
String apiTrxNo = orgCode + instId + apiTrxTm + RandomStringUtils.random(2, true, true).toUpperCase();
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(H_TRX_NO)) {
filterHeaders.put(H_TRX_NO, inboundHeaderMap.get(H_TRX_NO));
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_NO+"], value ["+inboundHeaderMap.get(H_TRX_NO)+"]");
} else {
filterHeaders.put(H_TRX_NO, apiTrxNo);
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_NO+"], value ["+apiTrxNo+"]");
}
if (inboundHeaderMap.containsKey(H_TRX_DTM)) {
filterHeaders.put(H_TRX_DTM, inboundHeaderMap.get(H_TRX_DTM));
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_DTM+"], value ["+inboundHeaderMap.get(H_TRX_DTM)+"]");
} else {
filterHeaders.put(H_TRX_DTM, apiTrxDtm);
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_DTM+"], value ["+apiTrxDtm+"]");
}
} else {
filterHeaders.put(H_TRX_NO, apiTrxNo);
filterHeaders.put(H_TRX_DTM, apiTrxDtm);
}
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_NO+"], value ["+filterHeaders.getProperty(H_TRX_NO)+"]");
logger.debug("KFTCP2PFilter] Processing Key ["+H_TRX_DTM+"], value ["+filterHeaders.getProperty(H_TRX_DTM)+"]");
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,107 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class NAVERFinFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "naverfin";
public static final String X_PARTNER_ID = "X-Partner-Id";
public static final String X_FINTECH_ID = "X-Fintech-Id";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("NAVERFinFilter] PreFilter Processing Start!!");
String partnerID = "r0jtqwC9gAW5";
String fintechId = "NF";
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
partnerID = propGroupVo.getProperty(PROP_PREFIX + "." + X_PARTNER_ID);
fintechId = propGroupVo.getProperty(PROP_PREFIX + "." + X_FINTECH_ID);
}
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(X_PARTNER_ID)) {
filterHeaders.put(X_PARTNER_ID, inboundHeaderMap.get(X_PARTNER_ID));
logger.debug("NAVERFinFilter] Processing Key ["+X_PARTNER_ID+"], value ["+inboundHeaderMap.get(X_PARTNER_ID)+"]");
} else {
filterHeaders.put(X_PARTNER_ID, partnerID);
logger.debug("NAVERFinFilter] Processing Key ["+X_PARTNER_ID+"], value ["+partnerID+"]");
}
if (inboundHeaderMap.containsKey(X_FINTECH_ID)) {
filterHeaders.put(X_FINTECH_ID, inboundHeaderMap.get(X_FINTECH_ID));
logger.debug("NAVERFinFilter] Processing Key ["+X_FINTECH_ID+"], value ["+inboundHeaderMap.get(X_FINTECH_ID)+"]");
} else {
filterHeaders.put(X_FINTECH_ID, fintechId);
logger.debug("NAVERFinFilter] Processing Key ["+X_FINTECH_ID+"], value ["+fintechId+"]");
}
} else {
filterHeaders.put(X_PARTNER_ID, partnerID);
filterHeaders.put(X_FINTECH_ID, fintechId);
}
logger.debug("NAVERFinFilter] Processing Key ["+X_PARTNER_ID+"], value ["+filterHeaders.getProperty(X_PARTNER_ID)+"]");
logger.debug("NAVERFinFilter] Processing Key ["+X_FINTECH_ID+"], value ["+filterHeaders.getProperty(X_FINTECH_ID)+"]");
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,138 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Map.Entry;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class NICECreditFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "nicecredit";
public static final String H_PRODUCTID = "ProductID";
public static final String B_REQ_DTM = "req_dtm";
public static final String B_GOODS_CLS = "goods_cls";
@SuppressWarnings({ "unchecked" })
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
JSONObject returnMessage = null;
String productId = "2303102120";
String reqDtm = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String goodsCls = "KJBAPI0001";
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
productId = propGroupVo.getProperty(PROP_PREFIX + "." + H_PRODUCTID);
goodsCls = propGroupVo.getProperty(PROP_PREFIX + "." + B_GOODS_CLS);
}
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (inboundHeaderMap != null && inboundHeaderMap.containsKey(H_PRODUCTID)) {
for (Entry<String, String> e : inboundHeaderMap.entrySet()) {
String key = (String) e.getKey();
String value = (String) e.getValue();
if (StringUtils.equalsIgnoreCase(key, H_PRODUCTID)) {
filterHeaders.setProperty(key, value);
}
if (logger.isDebugEnabled()) {
logger.debug("Request Header :" + key + "=[" + value + "]");
}
}
} else {
filterHeaders.setProperty(H_PRODUCTID, productId);
}
} catch (Exception e) {
logger.error(e.getMessage());
}
AdapterManager adapterManager = AdapterManager.getInstance();
AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adptGrpName);
String encode = adptGrpVO.getMessageEncode();
if (message == null) {
returnMessage = new JSONObject();
} else {
if (message instanceof JSONObject) {
returnMessage = (JSONObject) message;
} else if (message instanceof String) {
returnMessage = parseJson((String) message);
} else if (message instanceof byte[]) {
returnMessage = parseJson(new String((byte[]) message, encode));
}
}
returnMessage.put(B_REQ_DTM, reqDtm);
returnMessage.put(B_GOODS_CLS, goodsCls);
return returnMessage.toJSONString();
}
private JSONObject parseJson(String message) throws Exception {
if (message == null) {
return null;
}
return (JSONObject) JSONValue.parse(message);
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,109 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.util.Logger;
public class SimpleFrameworkFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String CLIENTID = "clientId";
public static final String TRACEID = "traceId";
public static final String GUID = "guid";
public static final String RECEIVEDTIMESTAMP = "receivedTimestamp";
public static final String PARTNER_TRACE_ID = "partnerTraceId";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("SimpleFrameworkFilter] PreFilter Processing Start!!");
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
try {
/* 업체정보 */
String clientId = tempProp.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID);
if (StringUtils.isEmpty(clientId)) clientId = "";
filterHeaders.put(CLIENTID, clientId);
logger.debug("SimpleFrameworkFilter] Processing Key ["+CLIENTID+"], value ["+clientId+"]");
/* APIM 거래추적자 */
String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
filterHeaders.put(TRACEID, uuid);
logger.debug("SimpleFrameworkFilter] Processing Key ["+TRACEID+"], value ["+uuid+"]");
/* GUID */
String guid = tempProp.getProperty(TransactionContextKeys.GUID, "");
filterHeaders.put(GUID, guid);
logger.debug("SimpleFrameworkFilter] Processing Key ["+GUID+"], value ["+guid+"]");
/* 최초요청시간 */
String receivedTimestamp = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REQUESTED_TIME, "");
filterHeaders.put(RECEIVEDTIMESTAMP, receivedTimestamp);
logger.debug("SimpleFrameworkFilter] Processing Key ["+RECEIVEDTIMESTAMP+"], value ["+receivedTimestamp+"]");
String partnerTraceId = inboundHeaderMap.getOrDefault(PARTNER_TRACE_ID, "");
filterHeaders.put(PARTNER_TRACE_ID, partnerTraceId);
logger.debug("SimpleFrameworkFilter] Processing Key ["+PARTNER_TRACE_ID+"], value ["+partnerTraceId+"]");
String x_loan_token = inboundHeaderMap.getOrDefault(TransactionContextKeys.X_LOAN_TOKEN, "");
filterHeaders.put(TransactionContextKeys.X_LOAN_TOKEN, x_loan_token);
logger.debug("SimpleFrameworkFilter] Processing Key ["+TransactionContextKeys.X_LOAN_TOKEN+"], value ["+x_loan_token+"]");
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,28 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Properties;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.eactive.eai.common.TransactionContextKeys;
public class SimpleframeworkBodyFilter extends SimpleFrameworkFilter {
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
Object returnMessage = super.doPreFilter(adptGrpName, adptName, prop, message, tempProp);
JSONObject bizJsonStr = null;
if ( returnMessage instanceof String ) {
bizJsonStr = (JSONObject) JSONValue.parse( (String)returnMessage);
if( bizJsonStr != null ) {
bizJsonStr.put("GUID", tempProp.getOrDefault(TransactionContextKeys.GUID, "") );
}
}
return bizJsonStr != null ? bizJsonStr.toJSONString() : returnMessage;
}
}
@@ -1,97 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.property.PropGroupVO;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;
public class TOSSBankFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String KJB_HEADER = "KJB_Header";
public static final String PROP_PREFIX = "tossbank";
public static final String X_TOSSBANK_LOAN_TRACE_ID = "X-TOSSBANK-LOAN-TRACE-ID";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
logger.debug("TOSSBankFilter] PreFilter Processing Start!!");
String traceId = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
PropGroupVO propGroupVo = PropManager.getInstance().getPropGroupVO(KJB_HEADER);
if (propGroupVo != null) {
}
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
if (filterHeaders == null) {
filterHeaders = new Properties();
tempProp.put("FILTERHEADER", filterHeaders);
}
try {
Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
if (!inboundHeaderMap.isEmpty()) {
if (inboundHeaderMap.containsKey(X_TOSSBANK_LOAN_TRACE_ID)) {
filterHeaders.put(X_TOSSBANK_LOAN_TRACE_ID, inboundHeaderMap.get(X_TOSSBANK_LOAN_TRACE_ID));
logger.debug("TOSSBankFilter] Processing Key ["+X_TOSSBANK_LOAN_TRACE_ID+"], value ["+inboundHeaderMap.get(X_TOSSBANK_LOAN_TRACE_ID)+"]");
} else {
filterHeaders.put(X_TOSSBANK_LOAN_TRACE_ID, traceId);
logger.debug("TOSSBankFilter] Processing Key ["+X_TOSSBANK_LOAN_TRACE_ID+"], value ["+traceId+"]");
}
} else {
/* APIM 거래추적자 */
filterHeaders.setProperty(X_TOSSBANK_LOAN_TRACE_ID, traceId);
logger.debug("TOSSBankFilter] Processing Key ["+X_TOSSBANK_LOAN_TRACE_ID+"], value ["+traceId+"]");
}
logger.debug("TOSSBankFilter] Processing Key ["+X_TOSSBANK_LOAN_TRACE_ID+"], value ["+filterHeaders.getProperty(X_TOSSBANK_LOAN_TRACE_ID)+"]");
} catch (Exception e) {
logger.error(e.getMessage());
}
return message;
}
public Map<String, String> getInboundHeaderProp(Properties prop) {
Properties header = new Properties();
Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
try {
Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
if (headerObj instanceof Properties) { //tomcat
header = (Properties) headerObj;
for (String name : header.stringPropertyNames()) {
inboundHeaderMap.put(name, header.getProperty(name));
}
} else if (headerObj instanceof String) { //weblogic
String str = (String) headerObj;
str = str.substring(1, str.length() - 1);
// key=value 쌍 분리
String[] entries = str.split(",");
for (String entry : entries) {
String[] kv = entry.split("=", 2);
if (kv.length == 2) {
inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return inboundHeaderMap;
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
return message;
}
}
@@ -1,71 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
import java.util.Properties;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.TransactionContextKeys;
import com.eactive.eai.common.util.Logger;
import com.nimbusds.jose.shaded.gson.JsonObject;
public class TraceBodyFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
public static final String BIZ_HEADER = "header";
public static final String GUID = "guid";
public static final String TRACEID = "traceId";
@Override
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
throws Exception {
JSONObject bizJsonStr = null;
if (message instanceof String) {
bizJsonStr = (JSONObject) JSONValue.parse((String) message);
if ( bizJsonStr == null ) return message; //json string이 아님.
if (bizJsonStr.containsKey(BIZ_HEADER)) {
JSONObject bizHeader = (JSONObject) bizJsonStr.get(BIZ_HEADER);
putBizHeaderData(bizHeader, tempProp);
}else {
JSONObject bizHeader = new JSONObject();
bizJsonStr.put(BIZ_HEADER, bizHeader);
putBizHeaderData(bizHeader, tempProp);
}
}
return bizJsonStr != null ? bizJsonStr.toJSONString() : message;
}
static private void putBizHeaderData(JSONObject bizHeader, Properties tempProp) {
String traceId = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
String guid = tempProp.getProperty(TransactionContextKeys.GUID, "");
bizHeader.put(GUID, guid);
logger.debug("Processing Key [" + GUID + "], value [" + guid + "]");
bizHeader.put(TRACEID, traceId);
logger.debug("Processing Key [" + TRACEID + "], value [" + traceId + "]");
}
@Override
public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
// TODO Auto-generated method stub
return message;
}
}
@@ -1,222 +0,0 @@
package com.eactive.eai.custom.kjb.adapter.http.client.impl;
import java.util.Properties;
//import java.util.concurrent.Callable;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Node;
import org.json.simple.JSONObject;
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.client.impl.HttpClient5AdapterServiceRest;
import com.eactive.eai.custom.kjb.adapter.http.client.filter.HttpClient5AdapterFilterFactory;
//import com.eactive.eai.custom.kjb.adapter.http.client.filter.HttpClientAdapterExceptionFilter;
import com.eactive.eai.custom.kjb.adapter.http.client.filter.HttpClientAdapterFilter;
//import com.eactive.eai.custom.kjb.adapter.http.client.filter.IBKOutCommonFilter;
//import com.eactive.eai.custom.kjb.adapter.http.client.filter.IBKOutExceptionFilter;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.ibk.eai.common.circuitbreaker.url.UrlCircuitBreakerManager;
//import io.github.resilience4j.circuitbreaker.CircuitBreaker;
/**
* 1. 기능 : HttpClient5AdapterServiceRest 호출 전후 Filter 적용할 수 있는 기능을 제공한다.<br>
* 2. 처리 개요 : <br>
* 3. 주의사항 <br>
*
* @author :
* @version : v 1.0.0
* @see : HttpClientAdapterServiceFactory.java,
* HttpClientAdapterServiceSupport.java, HttpClient5AdapterServiceRest.java
* @since :
*
*/
public class HttpClient5AdapterServiceRestAddFilter extends HttpClient5AdapterServiceRest
implements HttpClientAdapterServiceKey {
// 요청전 수행할 필터(쉼표(,)로 구분)
static final String PRE_FILTERS = "PRE_FILTERS";
// 요청후 수행할 필터(쉼표(,)로 구분)
static final String POST_FILTERS = "POST_FILTERS";
// // Adapter에서 Exception이 발생한 경우, 처리할 필터
// static final String EXCEPTION_FILTER = "EXCEPTION_FILTER";
/**
* 1. 기능 : HttpClient 호출 전후 Filter 적용용 2. 처리 개요 : <br>
* 3. 주의사항 <br>
*
* @param prop Http Adapter 속성 정보
* @return 반환 된 Object
* @exception Exception 수동 시스템 간 통신 중 발생
*/
public Object execute(Properties prop, Object data, Properties tempProp) throws Exception {
String adptGrpName = tempProp.getProperty(ADAPTER_GROUP_NAME);
String adptName = tempProp.getProperty(ADAPTER_NAME);
data = doPreFilters(adptGrpName, adptName, prop, data, tempProp);
Object adapterResponse = super.execute(prop, data, tempProp);
// //원본 url를 찾아서 있으면, 그것을 사용한다.
// String url = tempProp.getProperty("URL_ORG");
// if(StringUtils.isEmpty(url))
// url = tempProp.getProperty(HttpClientAdapterServiceKey.URL);
//
// UrlCircuitBreakerManager cManager = UrlCircuitBreakerManager.getInstance();
// CircuitBreaker circuitBreaker = cManager.getCircuitBreaker(url);
// try {
// if (circuitBreaker != null) {
// if (logger.isDebugEnabled()) {
// // ObjectMapper 인스턴스 생성
// ObjectMapper objectMapper = new ObjectMapper();
// // 서킷 브레이커의 메트릭 정보와 상태 정보를 직접 Node로 변환
// ObjectNode combinedNode = objectMapper.createObjectNode();
// combinedNode.put("state", circuitBreaker.getState().toString());
// combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics()));
// logger.debug("CircuitBreaker state [" + circuitBreaker.getName() + "] - " + combinedNode.toString());
// }
// adapterResponse = circuitBreaker.executeCallable(new HttpClientAdapterCallable(prop, data, tempProp, this));
// } else {
// adapterResponse = super.execute(prop, data, tempProp);
// }
// } catch (Exception e) {
// adapterResponse = doExceptionFilters(adptGrpName, adptName, prop, adapterResponse, tempProp, e);
//
// if (adapterResponse instanceof JSONObject)
// adapterResponse = ((JSONObject) adapterResponse).toJSONString();
//
// if (adapterResponse instanceof Node)
// adapterResponse = ((Node) adapterResponse).asXML();
//
// return adapterResponse;
// }
adapterResponse = doPostFilters(adptGrpName, adptName, prop, adapterResponse, tempProp);
if (adapterResponse instanceof JSONObject)
adapterResponse = ((JSONObject) adapterResponse).toJSONString();
if (adapterResponse instanceof Node)
adapterResponse = ((Node) adapterResponse).asXML();
return adapterResponse;
}
// protected Object callSuper(Properties prop, Object data, Properties tempProp) throws Exception {
// return super.execute(prop, data, tempProp);
// }
// private class HttpClientAdapterCallable implements Callable<Object> {
// Properties prop;
// Object data;
// Properties tempProp;
// HttpClient5AdapterServiceRestAddFilter clientService;
//
// public HttpClientAdapterCallable(Properties prop, Object data, Properties tempProp,
// HttpClient5AdapterServiceRestAddFilter clientService) {
// this.prop = prop;
// this.data = data;
// this.tempProp = tempProp;
// this.clientService = clientService;
// }
//
// @Override
// public Object call() throws Exception {
// return clientService.callSuper(prop, data, tempProp);
// }
//
// }
protected Object doPreFilters(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
// boolean isSetCommonFilterInAdapterProp = false;
// 1. adapter에 설정된 필터 수행
String preFiltersStr = prop.getProperty(PRE_FILTERS);
if (StringUtils.isNotEmpty(preFiltersStr)) {
String[] preFilters = StringUtils.split(preFiltersStr, ",");
for (String filterName : preFilters) {
if (StringUtils.isBlank(filterName)) {
continue;
}
logger.debug("HttpClient5AdapterServiceRestAddFilter] Processing Start [" + filterName + "]");
HttpClientAdapterFilter adapterFilter = HttpClient5AdapterFilterFactory.createFilter(filterName.trim());
if (adapterFilter != null) {
// if (adapterFilter instanceof IBKOutCommonFilter)
// isSetCommonFilterInAdapterProp = true;
message = adapterFilter.doPreFilter(adptGrpName, adptName, prop, message, tempProp);
} else {
throw new Exception("Failed get Filter Class: " + filterName);
}
}
}
// // 2. IBKOutCommonFilter 필터 수행(adapter 필터에서 수행하지 않을 때만)
// if (!isSetCommonFilterInAdapterProp) {
// HttpClientAdapterFilter ibkFilter = HttpClient5AdapterFilterFactory
// .createFilter(IBKOutCommonFilter.class.getName());
// if (ibkFilter != null) {
// message = ibkFilter.doPreFilter(adptGrpName, adptName, prop, message, tempProp);
// }
// } else {
// logger.debug("IBKOutCommonFilter isSetCommonFilterInAdapterProp 'POST_FILTERS'. already in adapter filters");
// }
return message;
}
protected Object doPostFilters(String adptGrpName, String adptName, Properties prop, Object message,
Properties tempProp) throws Exception {
// boolean isSetCommonFilterInAdapterProp = false;
// 1. adapter에 설정된 필터 수행
String postFiltersStr = prop.getProperty(POST_FILTERS);
if (StringUtils.isNotEmpty(postFiltersStr)) {
String[] postFilters = StringUtils.split(postFiltersStr, ",");
for (String filterName : postFilters) {
if (StringUtils.isBlank(filterName)) {
continue;
}
HttpClientAdapterFilter adapterFilter = HttpClient5AdapterFilterFactory.createFilter(filterName.trim());
if (adapterFilter != null) {
// if (adapterFilter instanceof IBKOutCommonFilter)
// isSetCommonFilterInAdapterProp = true;
message = adapterFilter.doPostFilter(adptGrpName, adptName, prop, message, tempProp);
} else {
throw new Exception("Failed get Filter Class: " + filterName);
}
}
}
// // 2. IBKOutCommonFilter 필터 수행
// if (!isSetCommonFilterInAdapterProp) {
// HttpClientAdapterFilter ibkFilter = HttpClient5AdapterFilterFactory
// .createFilter(IBKOutCommonFilter.class.getName());
// if (ibkFilter != null) {
// message = ibkFilter.doPostFilter(adptGrpName, adptName, prop, message, tempProp);
// }
// } else {
// logger.debug("IBKOutCommonFilter isSetCommonFilterInAdapterProp 'PRE_FILTERS'. already in adapter filters");
// }
return message;
}
// protected Object doExceptionFilters(String adptGrpName, String adptName, Properties prop, Object message,
// Properties tempProp, Exception e) throws Exception {
// String exceptionFilterName = prop.getProperty(EXCEPTION_FILTER);
// if (StringUtils.isEmpty(exceptionFilterName))
// exceptionFilterName = IBKOutExceptionFilter.class.getSimpleName();
//
// HttpClientAdapterExceptionFilter exceptionFilter = HttpClient5AdapterFilterFactory.createExceptionFilter(exceptionFilterName.trim());
// return exceptionFilter.doExceptionFilter(adptGrpName, adptName, prop, message, tempProp, e);
//
// }
}
@@ -1,81 +0,0 @@
package com.eactive.eai.custom.message;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.common.util.UUID;
/**
* 1. 기능 : UUID Generation Class 2. 처리 개요 : * - 3. 주의사항
*
* @author :
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since : :
*/
public final class GUIDGeneratorKAKAOCARD {
private static final DateTimeFormatter SDF_YYYYMMDDHHMMSSMS = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
/*
* 날짜(17) + "-"(1) + 시스템코드(3) + hostname(6) + 일련번호(5) + "-"(1) + 001(3)
*
*/
public static final int GUID_LENGTH = 33; // seq값 제외부분
/**
* 1. 기능 : Private 생성자 2. 처리 개요 : - 3. 주의사항 - Instance 생성하지 못함
**/
private GUIDGeneratorKAKAOCARD() {
}
public synchronized static String getGUID(String systemCode) {
StringBuilder sb = new StringBuilder();
sb.append(SDF_YYYYMMDDHHMMSSMS.format(ZonedDateTime.now()));
sb.append("-");
sb.append(systemCode);
sb.append(UNIQUE_NUM);
char[] formatSeq = { '0', '0', '0', '0', '0' };
char[] seqCharArray = String.valueOf(seq).toCharArray();
int destPos = formatSeq.length - seqCharArray.length;
System.arraycopy(seqCharArray, 0, formatSeq, destPos, seqCharArray.length);
sb.append(formatSeq);
seq++;
if (seq > 99999) {
seq = 1;
}
return sb.toString() + "-" + "001";
}
private static String UNIQUE_NUM;
private static int seq = 1;
private static int hostlength = 6;
static {
String uniqueValue = System.getProperty(Keys.SERVER_KEY);
if (StringUtils.isBlank(uniqueValue)) {
try {
uniqueValue = java.net.InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
uniqueValue = StringUtil.stringFormat("", false, 'X', hostlength);
}
}
if (uniqueValue.length() > hostlength) {
uniqueValue = uniqueValue.substring(uniqueValue.length() - hostlength, uniqueValue.length());
} else if (uniqueValue.length() < hostlength) {
uniqueValue = StringUtil.stringFormat(uniqueValue, false, 'X', hostlength);
}
UNIQUE_NUM = uniqueValue.toUpperCase();
}
public static void main(String[] args) {
String guid = getGUID("FEP");
// System.out.println("[" + guid.length() + "]" + guid);
}
}
@@ -1,40 +0,0 @@
package com.eactive.eai.custom.message;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.StringUtil;
public class GUIDGeneratorKBANK {
private static String UNIQUE_NUM;
private static int seq = 1;
static {
String uniqueValue = System.getProperty(Keys.SERVER_KEY);
if(uniqueValue.length() < 8) {
uniqueValue = StringUtil.stringFormat(uniqueValue, false, '0', 8);
}else if(uniqueValue.length() > 8){
uniqueValue = uniqueValue.substring(uniqueValue.length() - 8);
}
UNIQUE_NUM = uniqueValue.toUpperCase();
}
public synchronized static String makeGUID() {
StringBuilder sb = new StringBuilder();
sb.append(DatetimeUtil.getCurrentDateTime());
sb.append(UNIQUE_NUM);
char[] formatSeq = {'0','0','0','0','0','0','0','0'};
char[] seqCharArray = String.valueOf(seq).toCharArray();
int destPos = formatSeq.length - seqCharArray.length;
System.arraycopy(seqCharArray, 0, formatSeq, destPos, seqCharArray.length);
sb.append(formatSeq);
seq ++;
if(seq > 99999999) {
seq = 1;
}
return sb.toString() ;
}
}
@@ -1,98 +0,0 @@
package com.eactive.eai.custom.message;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import com.eactive.eai.common.util.DatetimeUtil;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.common.util.UUID;
/**
* 1. 기능 : UUID Generation Class 2. 처리 개요 : * - 3. 주의사항
*
* @author :
* @version : v 1.0.0
* @see : 관련 기능을 참조
* @since : :
*/
public final class GUIDGeneratorKJB {
/*
* 그룹사코드(3) + 호스트명(8) + 서버구분번호(2) + 일자(8) + 전문생성시간(6) + 일련번호(6) + 시스템경로번호(3, '001')
*/
public static final int GUID_LENGTH = 33; // 시스템경로번호 제외부분
/**
* 1. 기능 : Private 생성자 2. 처리 개요 : - 3. 주의사항 - Instance 생성하지 못함
**/
private GUIDGeneratorKJB() {
}
public synchronized static String getGUID(String groupCmpCd) {
String guid = groupCmpCd + UNIQUE_NUM;
guid = guid + DatetimeUtil.getCurrentDateTime();
if(seq < 10) {
guid = guid + "00000" + seq;
}
else if(seq < 100) {
guid = guid + "0000" + seq;
}
else if(seq < 1000) {
guid = guid + "000" + seq;
}
else if(seq < 10000) {
guid = guid + "00" + seq;
}
else if(seq < 100000) {
guid = guid + "0" + seq;
}
else {
guid = guid + seq;
}
seq ++;
if(seq > 999999) {
seq = 1;
}
return guid + "001";
}
private static String UNIQUE_NUM;
private static int seq = 1;
static {
String hostname = "";
try {
hostname = java.net.InetAddress.getLocalHost().getHostName();
}
catch(Exception e) {
hostname = "________";
}
if(hostname.getBytes().length != 8) {
if(hostname.getBytes().length < 8) {
hostname = StringUtils.leftPad(hostname, 8, '_');
} else if(hostname.getBytes().length > 8) {
hostname = StringUtils.substring(hostname, 0, 8);
}
}
String serverName = System.getProperty(Keys.SERVER_KEY);
String instid = "00";
if(serverName != null && serverName.length() > 2) {
instid = serverName.substring(serverName.length()-2, serverName.length());
}
UNIQUE_NUM = hostname.toUpperCase() + instid;
}
public static void main(String[] args) {
String guid = getGUID("051");
// System.out.println("[" + guid.length() + "]" + guid);
}
}
@@ -1,60 +0,0 @@
package com.eactive.eai.custom.message;
import java.text.SimpleDateFormat;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.StringUtil;
public final class GUIDGeneratorSBI {
private static final SimpleDateFormat SDF_YYYYMMDDHHMMSSMI = new SimpleDateFormat("yyyyMMddHHmmssSSS");
private GUIDGeneratorSBI() {
}
/**
* 시스템일시(17)+시스템환경코드(1)+시스템코드(3)+시스템고유번호(9)+일련번호(2)
*
* @param envDvcd
* @return
*/
public synchronized static String getGUID(String envDvcd, String systemType) {
String guid = (SDF_YYYYMMDDHHMMSSMI).format(new java.util.Date()) + envDvcd + systemType + UNIQUE_NUM;
if (seq < 10) {
guid = guid + "0" + seq;
} else {
guid = guid + seq;
}
seq++;
if (seq > 99) {
seq = 1;
}
return guid;
}
private static String UNIQUE_NUM;
private static int seq = 1;
static {
String hostname = "";
try {
hostname = java.net.InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
hostname = "_______";
}
if (hostname.getBytes().length != 7) {
hostname = StringUtil.stringFormat(hostname, false, '_', 7);
}
String serverName = System.getProperty(Keys.SERVER_KEY); // inst.Name
String instid = "11";
if (serverName != null && serverName.length() > 2) {
instid = serverName.substring(serverName.length() - 2, serverName.length());
}
UNIQUE_NUM = hostname.toUpperCase() + instid;
}
}
@@ -2,6 +2,7 @@ package com.eactive.eai.custom.message;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper; import com.eactive.eai.message.service.DefaultInterfaceMapper;
@@ -29,16 +30,23 @@ public class InterfaceMapperDJB extends DefaultInterfaceMapper {
private static final String PROCS_RSLT_SUCCESS = "S"; private static final String PROCS_RSLT_SUCCESS = "S";
private static final String PROCS_RSLT_FAIL = "F"; private static final String PROCS_RSLT_FAIL = "F";
private static String API_ID_PREFIX = StringUtils
.defaultString(PropManager.getInstance().getProperty("API_ID_PREFIX"));
@Override @Override
public String getEaiSvcCode(StandardMessage standardMessage) { public String getEaiSvcCode(StandardMessage standardMessage) {
String interfaceId = getInterfaceId(standardMessage); if(StringUtils.isNotBlank(standardMessage.getEaiSvcCd()))
return standardMessage.getEaiSvcCd();
// String interfaceId = getInterfaceId(standardMessage);
String txId = getServiceId(standardMessage);
String sendRecvDvcd = getSendRecvDivision(standardMessage); // S | R String sendRecvDvcd = getSendRecvDivision(standardMessage); // S | R
String inExDivision = getInExDivision(standardMessage); // 1 | 2 String inExDivision = getInExDivision(standardMessage); // 1 | 2
if (interfaceId == null) interfaceId = ""; if(StringUtils.isEmpty(txId))
interfaceId = interfaceId.trim(); throw new RuntimeException("not found txid");
return interfaceId + sendRecvDvcd + StringUtils.defaultString(inExDivision); return API_ID_PREFIX + txId + sendRecvDvcd + StringUtils.defaultString(inExDivision);
} }
// ---------------------------------------------------------------- // ----------------------------------------------------------------
@@ -1,202 +0,0 @@
package com.eactive.eai.custom.message;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
@SuppressWarnings("serial")
public class InterfaceMapperKAKAOCARD extends DefaultInterfaceMapper {
private static String SESSION_ID = "INTERFACE_COMMON.MCI_SESN_ID";
private static String INSTANCE_ID = "INTERFACE_COMMON.MCI_INSTNC_ID";
@Override
public String getEaiSvcCode(StandardMessage standardMessage) {
String eaiSvcCode = null;
String interfaceId = getInterfaceId(standardMessage);
String returnType = getSendRecvDivision(standardMessage); // S | R
String inExDivision = getInExDivision(standardMessage); // 1 | 2
if (interfaceId == null)
interfaceId = "";
interfaceId = interfaceId.trim();
// TODO : site에 맞게 조합해야 함.
eaiSvcCode = interfaceId + returnType + StringUtils.defaultString(inExDivision);
return eaiSvcCode;
}
@Override
public void setGuid(StandardMessage standardMessage, String guid) {
if (guid == null)
throw new RuntimeException("guid is null");
if (guid.length() != 36)
throw new RuntimeException("The length of guid is not 36");
setItemValue(standardMessage, getPath(GUID), guid);
}
@Override
public String getGuid(StandardMessage standardMessage) {
String guid = getItemValue(standardMessage, getPath(GUID));
if (guid.length() == 36) {
guid = guid.substring(0, 33);
}
return guid;
}
@Override
public String getGuidSeq(StandardMessage standardMessage) {
String guidseq = null;
String guid = getItemValue(standardMessage, getPath(GUID));
if (guid.length() == 36) {
guidseq = guid.substring(33);
} else {
guidseq = "000";
}
return guidseq;
}
@Override
public void setGuidSeq(StandardMessage standardMessage, String guidSeq) {
setItemValue(standardMessage, getPath(GUID), getGuid(standardMessage) + guidSeq);
}
@Override
public String getOrgGuid(StandardMessage standardMessage) {
String orgGuid = getItemValue(standardMessage, getPath(GUID_ORG));
if (orgGuid.length() == 36) {
orgGuid = orgGuid.substring(0, 33);
}
return orgGuid;
}
@Override
public void setOrgGuid(StandardMessage standardMessage, String orgGuid) {
if (orgGuid.length() == 36) {
orgGuid = orgGuid.substring(0, 33);
}
setItemValue(standardMessage, getPath(GUID_ORG), orgGuid);
}
@Override
public String nextGuidSeq(StandardMessage standardMessage) {
String guidSeq = getGuidSeq(standardMessage);
if (guidSeq == null)
return "";
int seq = 0;
try {
seq = Integer.parseInt(guidSeq) + 1;
} catch (NumberFormatException e) {
seq = 1;
}
guidSeq = StringUtil.stringFormat(Integer.toString(seq), true, '0', 3);
setGuidSeq(standardMessage, guidSeq);
return guidSeq;
}
/**
* 표준전문의 복원은 COMMON.ORTR_RESTR_YN 의 value는 (Y/N) 엔진에서 복원여부 의 value는 (1/0)
*/
@Override
public String getRecoverYn(StandardMessage standardMessage) {
String data = getItemValue(standardMessage, getPath(RECOVER_YN));
if ("Y".equals(data)) {
return "1";
} else {
return "0";
}
}
@Override
public void setRecoverYn(StandardMessage standardMessage, String recoverYn) {
if ("1".equals(recoverYn)) {
setItemValue(standardMessage, getPath(RECOVER_YN), "Y");
} else {
setItemValue(standardMessage, getPath(RECOVER_YN), "N");
}
}
@Override
public String getInstCode(StandardMessage standardMessage) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
return getItemValue(standardMessage, INSTANCE_ID);
} else {
return "";
}
}
@Override
public void setInstCode(StandardMessage standardMessage, String instCode) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
setItemValue(standardMessage, INSTANCE_ID, instCode);
}
}
@Override
public String getSessionId(StandardMessage standardMessage) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
return getItemValue(standardMessage, SESSION_ID);
} else {
return "";
}
}
@Override
public void setSessionId(StandardMessage standardMessage, String sessionId) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
setItemValue(standardMessage, SESSION_ID, sessionId);
}
}
/*
* 엔진 에서는 public static final String RESPONSE_TYPE_CODE_N = "0";//정상(normal)
* public static final String RESPONSE_TYPE_CODE_E = "1";//오류(error)
*/
@Override
public void setResponseType(StandardMessage standardMessage, String responseType) {
if (responseType != null && (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)
|| STDMessageKeys.RESPONSE_TYPE_CODE_E.equals(responseType))) {
if (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)) {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), "NR");
} else {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), "ER");
}
} else {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), responseType);
}
}
@Override
public String getInterfaceId(StandardMessage standardMessage) {
String interfaceId = getItemValue(standardMessage, getPath(INTERFACE_ID));
if (interfaceId == null)
return "";
interfaceId = interfaceId.trim();
return interfaceId;
}
@Override
public String getReqSysCode(StandardMessage standardMessage) {
// apiPath의 값에서 추출할 예정 : serviceId = api_path
String apiPath = getItemValue(standardMessage, getPath(SERVICE_ID));
if (apiPath != null) {
String[] split = apiPath.split("/");
if (split.length > 2) {
String route = split[1].toUpperCase();
if (route.length() > 3) {
route = route.substring(0, 3);
}
return route;
}
}
return null;
}
}
@@ -1,50 +0,0 @@
package com.eactive.eai.custom.message;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
public class InterfaceMapperKBANK extends DefaultInterfaceMapper {
private static final long serialVersionUID = 1L;
//전문작성일시
String ITEM_TLGR_WRTN_DT = "header_part.tlgrWrtnDt";
//전문생성시스템
String ITEM_TLGR_CRTN_SYS_NM = "header_part.tlgrCrtnSysNm";
//전문일련번호
String ITEM_TLGR_SRL_NO = "header_part.tlgrSrlNo";
@Override
public String getInExDivision(StandardMessage standardMessage) {
return "2";
}
@Override
public void setGuid(StandardMessage standardMessage, String guid) {
String tlgrWrtnDt = StringUtils.substring(guid, 0, 14);
String tlgrCrtnSysNm = StringUtils.substring(guid, 14, 22);
String tlgrSrlNo = StringUtils.substring(guid, 22, 30);
setItemValue(standardMessage, ITEM_TLGR_WRTN_DT, tlgrWrtnDt);
setItemValue(standardMessage, ITEM_TLGR_CRTN_SYS_NM, tlgrCrtnSysNm);
setItemValue(standardMessage, ITEM_TLGR_SRL_NO, tlgrSrlNo);
}
@Override
public void setGuidSeq(StandardMessage standardMessage, String guidSeq) {
if(guidSeq.length() == 1) {
guidSeq = "0"+guidSeq;
}
super.setGuidSeq(standardMessage, guidSeq);
}
@Override
public String getGuid(StandardMessage standardMessage) {
String tlgrWrtnDt = getItemValue(standardMessage, ITEM_TLGR_WRTN_DT);
String tlgrCrtnSysNm = getItemValue(standardMessage, ITEM_TLGR_CRTN_SYS_NM);
String tlgrSrlNo = getItemValue(standardMessage, ITEM_TLGR_SRL_NO);
return tlgrWrtnDt+tlgrCrtnSysNm+tlgrSrlNo;
}
}
@@ -1,202 +0,0 @@
package com.eactive.eai.custom.message;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
@SuppressWarnings("serial")
public class InterfaceMapperKJB extends DefaultInterfaceMapper {
private static String SESSION_ID = "INTERFACE_COMMON.MCI_SESN_ID";
private static String INSTANCE_ID = "INTERFACE_COMMON.MCI_INSTNC_ID";
@Override
public String getEaiSvcCode(StandardMessage standardMessage) {
String eaiSvcCode = null;
String interfaceId = getInterfaceId(standardMessage);
String returnType = getSendRecvDivision(standardMessage); // S | R
String inExDivision = getInExDivision(standardMessage); // 1 | 2
if (interfaceId == null)
interfaceId = "";
interfaceId = interfaceId.trim();
// TODO : site에 맞게 조합해야 함.
eaiSvcCode = interfaceId + returnType + StringUtils.defaultString(inExDivision);
return eaiSvcCode;
}
@Override
public void setGuid(StandardMessage standardMessage, String guid) {
if (guid == null)
throw new RuntimeException("guid is null");
if (guid.length() != 36)
throw new RuntimeException("The length of guid is not 36");
setItemValue(standardMessage, getPath(GUID), guid);
}
@Override
public String getGuid(StandardMessage standardMessage) {
String guid = getItemValue(standardMessage, getPath(GUID));
if (guid.length() == 36) {
guid = guid.substring(0, 33);
}
return guid;
}
@Override
public String getGuidSeq(StandardMessage standardMessage) {
String guidseq = null;
String guid = getItemValue(standardMessage, getPath(GUID));
if (guid.length() == 36) {
guidseq = guid.substring(33);
} else {
guidseq = "000";
}
return guidseq;
}
@Override
public void setGuidSeq(StandardMessage standardMessage, String guidSeq) {
setItemValue(standardMessage, getPath(GUID), getGuid(standardMessage) + guidSeq);
}
@Override
public String getOrgGuid(StandardMessage standardMessage) {
String orgGuid = getItemValue(standardMessage, getPath(GUID));
if (orgGuid.length() == 36) {
orgGuid = orgGuid.substring(0, 33);
}
return orgGuid;
}
@Override
public void setOrgGuid(StandardMessage standardMessage, String orgGuid) {
if (orgGuid.length() == 36) {
orgGuid = orgGuid.substring(0, 33);
}
setItemValue(standardMessage, getPath(GUID_ORG), orgGuid);
}
@Override
public String nextGuidSeq(StandardMessage standardMessage) {
String guidSeq = getGuidSeq(standardMessage);
if (guidSeq == null)
return "";
int seq = 0;
try {
seq = Integer.parseInt(guidSeq) + 1;
} catch (NumberFormatException e) {
seq = 1;
}
guidSeq = StringUtil.stringFormat(Integer.toString(seq), true, '0', 3);
setGuidSeq(standardMessage, guidSeq);
return guidSeq;
}
/**
* 표준전문의 복원은 COMMON.ORTR_RESTR_YN 의 value는 (Y/N) 엔진에서 복원여부 의 value는 (1/0)
*/
@Override
public String getRecoverYn(StandardMessage standardMessage) {
String data = getItemValue(standardMessage, getPath(RECOVER_YN));
if ("Y".equals(data)) {
return "1";
} else {
return "0";
}
}
@Override
public void setRecoverYn(StandardMessage standardMessage, String recoverYn) {
if ("1".equals(recoverYn)) {
setItemValue(standardMessage, getPath(RECOVER_YN), "Y");
} else {
setItemValue(standardMessage, getPath(RECOVER_YN), "N");
}
}
@Override
public String getInstCode(StandardMessage standardMessage) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
return getItemValue(standardMessage, INSTANCE_ID);
} else {
return "";
}
}
@Override
public void setInstCode(StandardMessage standardMessage, String instCode) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
setItemValue(standardMessage, INSTANCE_ID, instCode);
}
}
@Override
public String getSessionId(StandardMessage standardMessage) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
return getItemValue(standardMessage, SESSION_ID);
} else {
return "";
}
}
@Override
public void setSessionId(StandardMessage standardMessage, String sessionId) {
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) {
setItemValue(standardMessage, SESSION_ID, sessionId);
}
}
/*
* 엔진 에서는 public static final String RESPONSE_TYPE_CODE_N = "0";//정상(normal)
* public static final String RESPONSE_TYPE_CODE_E = "1";//오류(error)
*/
@Override
public void setResponseType(StandardMessage standardMessage, String responseType) {
if (responseType != null && (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)
|| STDMessageKeys.RESPONSE_TYPE_CODE_E.equals(responseType))) {
if (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)) {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), "NR");
} else {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), "ER");
}
} else {
setItemValue(standardMessage, getPath(RESPONSE_TYPE), responseType);
}
}
@Override
public String getInterfaceId(StandardMessage standardMessage) {
String interfaceId = getItemValue(standardMessage, getPath(INTERFACE_ID));
if (interfaceId == null)
return "";
interfaceId = interfaceId.trim();
return interfaceId;
}
@Override
public String getReqSysCode(StandardMessage standardMessage) {
// apiPath의 값에서 추출할 예정 : serviceId = api_path
String apiPath = getItemValue(standardMessage, getPath(SERVICE_ID));
if (apiPath != null) {
String[] split = apiPath.split("/");
if (split.length > 2) {
String route = split[1].toUpperCase();
if (route.length() > 3) {
route = route.substring(0, 3);
}
return route;
}
}
return null;
}
}
@@ -1,21 +0,0 @@
package com.eactive.eai.custom.message;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.service.DefaultInterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
@SuppressWarnings("serial")
public class InterfaceMapperSBI extends DefaultInterfaceMapper {
@Override
public String getSendRecvDivision(StandardMessage standardMessage) {
String sendRecvDivision = super.getSendRecvDivision(standardMessage);
if (StringUtils.equals(sendRecvDivision, "Q")) {
return STDMessageKeys.SEND_RECV_CD_SEND;
} else {
return sendRecvDivision;
}
}
}
@@ -5,7 +5,10 @@ import java.net.NetworkInterface;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -15,6 +18,7 @@ import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.inbound.processor.ProcessVO; import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.message.StandardItem; import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage; import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.StandardType;
import com.eactive.eai.message.manager.StandardMessageManager; import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator; import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper; import com.eactive.eai.message.service.InterfaceMapper;
@@ -36,6 +40,10 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
private static final DateTimeFormatter FMT_DATE = DateTimeFormatter.ofPattern("yyyyMMdd"); private static final DateTimeFormatter FMT_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");
private static final DateTimeFormatter FMT_TIME_MILLIS = DateTimeFormatter.ofPattern("HHmmssSSS"); private static final DateTimeFormatter FMT_TIME_MILLIS = DateTimeFormatter.ofPattern("HHmmssSSS");
// ${callProp.key} 또는 ${callProp.key:기본값} 패턴
private static final Pattern CALL_PROP_PATTERN =
Pattern.compile("\\$\\{callProp\\.([^}:]+)(?::([^}]*))?\\}");
// HEAD 필드 경로 // HEAD 필드 경로
private static final String HEAD_FRST_MESG_DMAN_DT = "HEAD.frst_mesg_dman_dt"; private static final String HEAD_FRST_MESG_DMAN_DT = "HEAD.frst_mesg_dman_dt";
private static final String HEAD_FRST_MESG_DMAN_TIME = "HEAD.frst_mesg_dman_time"; private static final String HEAD_FRST_MESG_DMAN_TIME = "HEAD.frst_mesg_dman_time";
@@ -68,8 +76,14 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
// DATA 영역 경로 // DATA 영역 경로
private static final String DATA_SCOP_LEN = "DATA.data_scop_len"; private static final String DATA_SCOP_LEN = "DATA.data_scop_len";
private String[] netInfo;
@Override @Override
public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) { public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
// TODO 표준전문을 수신할 경우, 전문의 interface id로 가져온 eaiSvcCd가 다른 값으로 치환되어야 할 수도 있다.
// 수신한 if_id를 기준으로 api gw의 eaiSvcCd를 매핑하는 프러퍼티가 있어야 한다.
// PropGroup : DJB_IN_STDHEAD_IFID_MAPPING, DJB_IN_HTTHEAD_STDHEAD_MAPPING
// standardMessage.setEaiSvcCd(mappedIfId);
} }
@Override @Override
@@ -78,7 +92,7 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
InterfaceMapper mapper = manager.getMapper(); InterfaceMapper mapper = manager.getMapper();
// GUID 생성 (40자) 및 설정 // GUID 생성 (40자) 및 설정
String guid = GUIDGeneratorDJB.getGUID("EAI"); String guid = GUIDGeneratorDJB.getGUID("OPA");
mapper.setGuid(standardMessage, guid); mapper.setGuid(standardMessage, guid);
// GUID 진행번호 초기화 (최초=001) // GUID 진행번호 초기화 (최초=001)
@@ -112,6 +126,9 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
if (ezdataItem != null && evaluateBlockCondition(standardMessage, ezdataItem)) { if (ezdataItem != null && evaluateBlockCondition(standardMessage, ezdataItem)) {
setEzdataFields(standardMessage, ezdataItem, ipv4, mac); setEzdataFields(standardMessage, ezdataItem, ipv4, mac);
} }
// refValue="${callProp.키}" 필드에 Properties 값 주입
resolveCallPropRefValues(standardMessage, prop);
} }
@Override @Override
@@ -230,6 +247,67 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
// private helpers // private helpers
// ---------------------------------------------------------------- // ----------------------------------------------------------------
private void resolveCallPropRefValues(StandardMessage standardMessage, Properties prop) {
if (prop == null) return;
resolveCallPropInChilds(standardMessage.getChilds(), prop);
}
private void resolveCallPropInChilds(LinkedHashMap<String, StandardItem> childs, Properties prop) {
if (childs == null) return;
for (StandardItem item : childs.values()) {
int type = item.getType();
if (type == StandardType.FIELD) {
String refValue = item.getRefValue();
if (refValue == null) continue;
Matcher m = CALL_PROP_PATTERN.matcher(refValue);
if (m.matches()) {
String key = m.group(1);
String defaultVal = m.group(2) != null ? m.group(2) : "";
String resolved = resolveCallPropValue(prop, key);
item.setValue(resolved != null ? resolved : defaultVal);
}
} else if (type == StandardType.GROUP) {
resolveCallPropInChilds(item.getChilds(), prop);
}
// GRID, FARRAY, BIZDATA: 배열/업무데이터 영역은 건너뜀
}
}
/**
* Properties/Map 중첩 구조에서 점(.) 구분 keyPath로 값을 탐색한다.
* Properties는 Map을 구현하므로 Map<?,?> 단일 메서드로 통일한다.
* - "aaa.bbb" : map.get("aaa")가 Map(Properties 포함)이면 그 안에서 "bbb" 재귀 조회
* - 중간 값이 Map이 아니면 전체 keyPath로 폴백 조회
* - 값을 찾지 못하면 null 반환
*/
private String resolveCallPropValue(Properties props, String keyPath) {
return resolveNestedValue(props, keyPath);
}
@SuppressWarnings("unchecked")
private String resolveNestedValue(Map<?, ?> map, String keyPath) {
int dotIdx = keyPath.indexOf('.');
if (dotIdx < 0) {
Object val = map.get(keyPath);
if (val == null) return null;
if (val instanceof String) return (String) val;
return val.toString();
}
String first = keyPath.substring(0, dotIdx);
String rest = keyPath.substring(dotIdx + 1);
Object val = map.get(first);
if (val instanceof Map) {
return resolveNestedValue((Map<?, ?>) val, rest);
}
// 폴백: 전체 keyPath를 단일 키로 조회
Object direct = map.get(keyPath);
if (direct == null) return null;
if (direct instanceof String) return (String) direct;
return direct.toString();
}
private String getSysEnvDvcd(EAIServerManager server) { private String getSysEnvDvcd(EAIServerManager server) {
if (server.isPEAIServer()) return "P"; // 운영 if (server.isPEAIServer()) return "P"; // 운영
if (server.isSEAIServer()) return "T"; // 검증/테스트 if (server.isSEAIServer()) return "T"; // 검증/테스트
@@ -237,6 +315,9 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
} }
private String[] collectNetworkInfo() { private String[] collectNetworkInfo() {
if(this.netInfo != null)
return this.netInfo;
String ipv4 = ""; String ipv4 = "";
String mac = ""; String mac = "";
try { try {
@@ -257,7 +338,8 @@ public class StandardMessageCoordinatorDJB extends DefaultStandardMessageCoordin
} catch (Exception e) { } catch (Exception e) {
if (logger.isWarn()) logger.warn("Failed to collect network info", e); if (logger.isWarn()) logger.warn("Failed to collect network info", e);
} }
return new String[]{ipv4, mac}; this.netInfo = new String[]{ipv4, mac};
return this.netInfo;
} }
private void setEzdataFields(StandardMessage standardMessage, StandardItem ezdataItem, String ipv4, String mac) { private void setEzdataFields(StandardMessage standardMessage, StandardItem ezdataItem, String ipv4, String mac) {
@@ -1,419 +0,0 @@
package com.eactive.eai.custom.message;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.custom.stderrorcode.ChannelErrorCodeManager;
import com.eactive.eai.custom.stderrorcode.ChannelErrorCodeVO;
import com.eactive.eai.custom.stderrorcode.StdErrorCodeManager;
import com.eactive.eai.custom.stderrorcode.StdErrorCodeVO;
import com.eactive.eai.inbound.error.InboundErrorKeys;
import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageErrorKeys;
import com.ext.eai.common.stdmessage.STDMessageKeys;
public class StandardMessageCoordinatorKAKAOCARD extends DefaultStandardMessageCoordinator {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
//private static int defaultTimeout = 30;
private static String GW_SESSION_ID = "INTERFACE_COMMON.GTWY_SESN_ID";
private static String GW_INSTANCE_ID = "INTERFACE_COMMON.GTWY_INSTNC_ID";
private static String MESSAGE_OUT_ATRB_CD = "MESSAGE.OUT_ATRB_CD";//출력속성코드
private static String MESSAGE_OUT_MSG_DESC = "MESSAGE.OUT_MSG_DESC";//출력메시지설명
private static String COMMON_OUT_FMSG_DSTCD = "COMMON.OUT_FMSG_DSTCD";//출력전문구별코드
private static String MESSAGE = "MESSAGE";//메시지부
@Override
public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
//표준에서 들어올때 표준전문의 값을 header에 셋팅
//표준전문 to prop
if (EAIServerManager.getInstance().isFEP()) {
StandardItem gwSesnId = standardMessage.findItem(GW_SESSION_ID);//transactionId
StandardItem gwNodeNo = standardMessage.findItem(GW_INSTANCE_ID);//instanceId
if (gwSesnId != null && gwNodeNo != null && StringUtils.isNotBlank(gwSesnId.getValue()) && StringUtils.isNotBlank(gwNodeNo.getValue())) {
prop.put(HttpClientAdapterServiceKey.TRANSACTION_ID, gwSesnId.getValue());
prop.put(HttpClientAdapterServiceKey.INSTANCE_ID, gwNodeNo.getValue());
}
}
// REST용 전달값 중 api_path 이후의 값을 표준전문 API_PATH에 셋팅
String adapterApiPath = prop.getProperty(HttpAdapterServiceKey.API_PATH);
if (StringUtils.isNotBlank(adapterApiPath)) {
String adapterExtUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_EXTURI);
/*
* apiPath 나머지를 추출하기 위해서
* 예) 어댑터에 설정되어 있는 API_PATH = /api/cts
* 어댑터에 들어온 INBOUND_EXTURI = /api/cts/cmb/api/user/custom
* 표준전문에 셋팅하고 싶은값 /cmb/api/user/custom
*/
String standardApiPath = adapterExtUri.replaceAll(adapterApiPath, "");
if (!standardApiPath.startsWith("/")) {
standardApiPath = standardApiPath + "/";
}
if (standardApiPath.length() > 1) {
mapper.setServiceId(standardMessage,standardApiPath);
}
}
//아래로직은 표준전문에서 요청일때 MESSAGE부가 안보이고 응답일때 MESSAGE부 보이게 설정
String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
StandardItem msg = standardMessage.findItem(MESSAGE);
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
msg.setHidden(true);
}
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
msg.setHidden(false);
}
//mci이고 요청 거래시에 설정 인스턴스ID설정
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI() && (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND))) {
//인스턴스ID설정
String instCode = mapper.getInstCode(standardMessage);
String localServer = server.getLocalServerName();
if (instCode != null && localServer != null) {
mapper.setInstCode(standardMessage, localServer);
}
//타임아웃값이 없을경우 default값 설정
String timeout = mapper.getTimeout(standardMessage);
int defaultTimeout = getDefaultTimeout();
if (StringUtils.isBlank(timeout)) {
mapper.setTimeout(standardMessage, Integer.toString(defaultTimeout));
}else {
try {
Integer.parseInt(timeout);
}catch(Exception e) {
mapper.setTimeout(standardMessage, Integer.toString(defaultTimeout));
}
}
}
//TODO 표준전문 메시지 설정해야됨
//표준전문에 메시지 부에 값이 있을경우 처리
if (!msg.isHidden()) {
String errmsg = mapper.getErrorMsg(standardMessage);
if (StringUtils.isBlank(errmsg)) {
String errCode = mapper.getErrorCode(standardMessage);
if (StringUtils.isNotBlank(errCode)) {
StdErrorCodeManager manager = StdErrorCodeManager.getInstance();
StdErrorCodeVO vo = manager.getSTDErrorCode(errCode);
if (vo != null) {
mapper.setErrorMsg(standardMessage, vo.getErrMsg());
if (server != null && server.isMCI()) {
String type = mapper.getChannelDetailCd(standardMessage);
//채널오류코드 셋팅
ChannelErrorCodeManager cmanager = ChannelErrorCodeManager.getInstance();
ChannelErrorCodeVO cvo = cmanager.getChannelErrorCode(errCode+"_"+type);
if (cvo != null) {
mapper.setErrorMsg(standardMessage, cvo.getErrMsg());
}
}
}
}
}
}
}
@Override
//비표준처리
public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) {
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
//비표준에서 들어올때 header값을 표준전문에 셋팅
//prop to 표준전문
if (EAIServerManager.getInstance().isFEP()) {
String trandactionId = prop.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID);
String instanceId = prop.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID);
if (StringUtils.isNotBlank(trandactionId) && StringUtils.isNotBlank(instanceId)) {
StandardItem gwSesnId = standardMessage.findItem(GW_SESSION_ID);//transactionId
if (gwSesnId != null) {
gwSesnId.setValue(trandactionId);
}
StandardItem gwNodeNo = standardMessage.findItem(GW_INSTANCE_ID);//instanceId
if (gwNodeNo != null) {
gwNodeNo.setValue(instanceId);
}
}
}
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
//HEADER.GUID설정
mapper.setGuid(standardMessage,GUIDGeneratorKAKAOCARD.getGUID(eaiServerManager.getSystemType()));
//HEADER.FMSG_REQ_RES_DSTCD 전문요청응답구별코드 : 표준전문값
//HEADER.FRST_TRNM_IPAD 최초전송IP주소
mapper.setFirstReqIp(standardMessage, "0.0.0.0");
//HEADER.GNRZ_TMOT_TM 총괄타임아웃시간
mapper.setTimeout(standardMessage, "180");
// HEADER.SYS_ENV_DSTCD 시스템운영환경구분코드
String operationEnv = mapper.getOperationEnv(standardMessage);
if (operationEnv != null && StringUtils.isBlank(operationEnv)) {
mapper.setOperationEnv(standardMessage, getSysOprtEnvDvcd(eaiServerManager));
}
// HEADER.CARD_TX_TYP_DSTCD 거래유형구별코드
StandardItem cardTxTypDstcd = standardMessage.findItem("HEADER.CARD_TX_TYP_DSTCD");
if (cardTxTypDstcd != null ) {
cardTxTypDstcd.setValue("O");
}
//COMMON.GROUP_CMP_CD 그룹회사코드
StandardItem groupCmpCd = standardMessage.findItem("COMMON.GROUP_CMP_CD");
if (groupCmpCd != null ) {
groupCmpCd.setValue("090");
}
//COMMON.TX_BRCD 거래부점코드
StandardItem txBrcd = standardMessage.findItem("COMMON.TX_BRCD");
if (txBrcd != null ) {
txBrcd.setValue("0000");
}
//COMMON.RLTR_BRCD 실거래부점코드
StandardItem rltrBrcd = standardMessage.findItem("COMMON.RLTR_BRCD");
if (rltrBrcd != null ) {
rltrBrcd.setValue("0000");
}
//COMMON.TLRNO 텔러번호
StandardItem tlrno = standardMessage.findItem("COMMON.TLRNO");
if (tlrno != null ) {
tlrno.setValue("000000");
}
//COMMON.TX_DT 거래일자
StandardItem txDt = standardMessage.findItem("COMMON.TX_DT");
if (txDt != null ) {
txDt.setValue(DatetimeUtil.getFormattedDate("yyyyMMdd"));
}
//COMMON.TX_TM 거래시간
StandardItem txTm = standardMessage.findItem("COMMON.TX_TM");
if (txTm != null ) {
txTm.setValue(DatetimeUtil.getFormattedDate("HHmmssSSS"));
}
//아래로직은 표준전문에서 요청일때 MESSAGE부가 안보이고 응답일때 MESSAGE부 보이게 설정
String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
StandardItem msg = standardMessage.findItem(MESSAGE);
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
msg.setHidden(true);
}
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
msg.setHidden(false);
}
//TODO 표준전문 메시지 설정해야됨
//응답일경우 MESSAGE부에 정상 메시지 헤더를 설정하기 위해서
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
StandardItem outputAtrbCd = standardMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
outputAtrbCd.setValue("1");
mapper.setErrorCode(standardMessage, STDMessageErrorKeys.SUCCESS_CODE_VALUE);
mapper.setErrorMsg(standardMessage, STDMessageErrorKeys.SUCCESS_MSG_VALUE);
mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N);
}
}
@Override
public void coordinateInReturnObject(StandardMessage standardMessage) {
//아래로직은 표준전문에서 응답일때 MESSAGE부가 보이게 하기위해서
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
StandardItem msg = standardMessage.findItem(MESSAGE);
msg.setHidden(false);
}
public String getSysOprtEnvDvcd(EAIServerManager eaiServerManager) {
String result = "";
if (eaiServerManager.isPEAIServer()) { // 운영
result = "R";
} else if (eaiServerManager.isDEAIServer()) { // 개발
result = "D";
} else if (eaiServerManager.isSEAIServer()) { // 테스트/검증
result = "T";
}
return result;
}
@Override
public void coordinateBeforeInboundErrorResponse(StandardMessage standardMessage) {
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
StandardItem msg = standardMessage.findItem(MESSAGE);
msg.setHidden(false);
}
@Override
public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper,
String errCode, String errMsg) {
String siteErrCode = null;
String siteErrMessage = null;
if(errCode != null) {
siteErrCode = MessageUtil.getTobeCode(errCode);
siteErrMessage = MessageUtil.getTobeMessage(errCode);
}
String sendRecvDivision = mapper.getSendRecvDivision(standardMessage);
if (StringUtils.equals(sendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
StandardItem msg = standardMessage.findItem(MESSAGE);
msg.setHidden(false);
}
StandardItem outputAtrbCd = standardMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
outputAtrbCd.setValue("1");
if (siteErrCode != null) {
mapper.setErrorCode(standardMessage, siteErrCode);
}else if (errCode != null) {
mapper.setErrorCode(standardMessage, errCode);
}
if (siteErrMessage != null) {
mapper.setErrorMsg(standardMessage, siteErrMessage);
}else if (errMsg != null){
mapper.setErrorMsg(standardMessage, errMsg);
}
StandardItem outputMsgDesc = standardMessage.findItem(MESSAGE_OUT_MSG_DESC);//출력메시지설명
if (errMsg != null){
outputMsgDesc.setValue(errMsg);
}
mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E);
return false;
}
@Override
//복원시
public void coordinateAfterRestored(StandardMessage dbMessage, StandardMessage responseMessage) {
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
String interfaceId = mapper.getInterfaceId(responseMessage);
mapper.setInterfaceId(dbMessage, interfaceId);
String sendRecvDivision = mapper.getSendRecvDivision(responseMessage);
mapper.setSendRecvDivision(dbMessage, sendRecvDivision);
String inExDivision = mapper.getInExDivision(responseMessage);
mapper.setInExDivision(dbMessage, inExDivision);
String recoverYn = mapper.getRecoverYn(responseMessage);
mapper.setRecoverYn(dbMessage, recoverYn);
//복원시 처리결과수신 서비스코드를 서비스코드에 셋팅한다.
//처리결과수신값이 없을경우 원거래 서비스ID를 셋팅한다.
String returnServiceId = mapper.getReturnServiceId(dbMessage);
if (StringUtils.isBlank(returnServiceId)){
returnServiceId = mapper.getServiceId(dbMessage);
}
mapper.setServiceId(dbMessage, returnServiceId);
//표준전문 메시지 관련 설정
String dbSendRecvDivision = mapper.getSendRecvDivision(dbMessage);
StandardItem msg = dbMessage.findItem(MESSAGE);
if ( StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_SEND)) {
msg.setHidden(true);
}
if (StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
msg.setHidden(false);
}
//응답일경우 MESSAGE부 정상설정
if (StringUtils.equals(dbSendRecvDivision, STDMessageKeys.SEND_RECV_CD_RECV)) {
StandardItem outputAtrbCd = dbMessage.findItem(MESSAGE_OUT_ATRB_CD);//출력속성코드
outputAtrbCd.setValue("1");
mapper.setErrorCode(dbMessage, STDMessageErrorKeys.SUCCESS_CODE_VALUE);//출력메시지코드
mapper.setErrorMsg(dbMessage, STDMessageErrorKeys.SUCCESS_MSG_VALUE);//출력메시지내용
mapper.setResponseType(dbMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N);
}
}
@Override
public boolean coordinateIsWaitCheckForSync(StandardMessage responseMessage) {
StandardItem outputMesgTycd = responseMessage.findItem(COMMON_OUT_FMSG_DSTCD);
if (outputMesgTycd != null && StringUtils.equals(outputMesgTycd.getValue(), "9")) {
return true;
}
return false;
}
@Override
public int coordinateForTimeoutCodeToValue(EAIMessage eaiMessage) {
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
EAIServerManager server = EAIServerManager.getInstance();
if (server != null && server.isMCI()) { //MCI 일경우 처리
StandardMessage standardMessage = eaiMessage.getStandardMessage();
String timeout = mapper.getTimeout(standardMessage);
int defaultTimeout = getDefaultTimeout();
if (StringUtils.isBlank(timeout)) {
return defaultTimeout;
}else {
try {
return Integer.parseInt(timeout);
}catch(Exception e) {
return defaultTimeout;
}
}
}else { //MCI 이외일 경우 처리 (인터페이스에 있는 타임아웃기준)
return eaiMessage.getCurrentSvcMsg().getTmoVl();
}
}
private int getDefaultTimeout() {
PropManager manager = PropManager.getInstance();
int defaultTimeout = 30;
try {
String sdefaultTimeout = manager.getProperty("KAKAO_CARD", "DEFAULT_TIMEOUT", Integer.toString(defaultTimeout));
defaultTimeout = Integer.parseInt(sdefaultTimeout);
}catch(Exception e) {
}
return defaultTimeout;
}
@Override
public boolean coordinateValidation(StandardMessage standardMessage, ProcessVO vo) {
// RECEAIIRP110 인터페이스 ({1}) 에 표준전문 항목 ({2}) 의 값이 없습니다.
// RECEAIIRP120 인터페이스 ({1}) 에 표준전문 항목 ({2}) 의 값을 확인하세요.
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
String interfaceId = mapper.getInterfaceId(standardMessage);
String guid = mapper.getGuid(standardMessage);
if (StringUtils.isBlank(guid)) {
vo.setRspErrorCode("RECEAIIRP110");
vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
return false;
}
String guidSeq = mapper.getGuidSeq(standardMessage);
if (StringUtils.isBlank(guidSeq)) {
vo.setRspErrorCode("RECEAIIRP110");
vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
return false;
}
if (guid.length() + guidSeq.length() != 36) {
vo.setRspErrorCode("RECEAIIRP120");
vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { interfaceId, "GUID" }));
vo.setErrTypeCode(InboundErrorKeys.IN_ERROR);
return false;
}
return true;
}
}
@@ -1,90 +0,0 @@
package com.eactive.eai.custom.message;
import java.util.Properties;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.server.Keys;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
public class StandardMessageCoordinatorKBANK extends DefaultStandardMessageCoordinator {
private static final String MESSAGE_PART_SUB_MSG_GOUP = "message_part.subMsgGoup";
private static final String MESSAGE_PART_MSG_TYPE = "message_part.msgType";
private static final String MESSAGE_PART = "message_part";
@Override
public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
}
@Override
public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) {
// guid 설정
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
String guid = GUIDGeneratorKBANK.makeGUID();
mapper.setGuid(standardMessage, guid);
String orgGuid = guid + mapper.getGuidSeq(standardMessage);
mapper.setOrgGuid(standardMessage, orgGuid);
mapper.setOperationEnv(standardMessage, System.getProperty(Keys.EAI_SYSTEMMODE));
mapper.setFirstReqIp(standardMessage, EAIServerManager.getInstance().getServerIp());
}
@Override
public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper,
String errCode, String errMsg) {
mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E);
StandardItem messagePart = standardMessage.findItem(MESSAGE_PART);
messagePart.setHidden(false);
messagePart.setSize(1);
StandardItem messageType = standardMessage.findItem(MESSAGE_PART_MSG_TYPE);
messageType.setValue("99");
StandardItem subMsgGoup = standardMessage.findItem(MESSAGE_PART_SUB_MSG_GOUP);
subMsgGoup.getList().clear();
subMsgGoup.setRefValue("0");
if(errCode != null) {
String siteErrCode = MessageUtil.getTobeCode(errCode);
String siteErrMessage;
switch(errCode) {
case("RECEAIIRP070"):
siteErrMessage = "거래 통제 되었습니다.";
break;
default:
siteErrMessage = MessageUtil.getTobeMessage(errCode); break;
}
mapper.setErrorCode(standardMessage, siteErrCode);
mapper.setErrorMsg(standardMessage, siteErrMessage);
}
return false;
}
@Override
public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage) {
StandardItem messagePart = responseMessage.findItem(MESSAGE_PART);
messagePart.setHidden(false);
messagePart.setSize(1);
StandardItem subMsgGoup = responseMessage.findItem(MESSAGE_PART_SUB_MSG_GOUP);
subMsgGoup.getList().clear();
subMsgGoup.setRefValue("0");
}
}
@@ -1,198 +0,0 @@
package com.eactive.eai.custom.message;
import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.common.dao.Keys;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.inbound.processor.Processor;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper;
import com.ext.eai.common.stdmessage.STDMessageKeys;
import org.apache.commons.lang.StringUtils;
import java.net.UnknownHostException;
import java.util.LinkedHashMap;
import java.util.Properties;
public class StandardMessageCoordinatorKJB extends DefaultStandardMessageCoordinator {
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private static final String MESSAGE_PART = "Message";
private static final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header";
private static final String MESSAGE_PART_MSG_HEDR_KNCD = "Message.Msg_Header.MSG_HEDR_KNCD";
private static final String MESSAGE_PART_MSG_HEDR_LEN = "Message.Msg_Header.MSG_HEDR_LEN";
private static final String MESSAGE_PART_BODY_PART = "Message.Msg_Body";
private static final String MESSAGE_PART_OUTPUT_MSG_CD = "Message.Msg_Body.OUTPUT_MSG_CD";
private static final String MESSAGE_PART_OUTPUT_MSG_CTNT = "Message.Msg_Body.OUTPUT_MSG_CTNT";
private static final String MESSAGE_PART_OUTPUT_MSG_GRID = "Message.Msg_Body.Output_Msg_Grid";
private static final String COMMON_PART_GROUP_CMD_CD = "Common.Service_info.GROUP_CMP_CD";
private static final String COMMON_PART_OTSD_CHNL_INST_CD = "Common.Service_info.OTSD_CHNL_INST_CD";
private static final String DATA_HEADER_DATA_HEDR_LEN = "Data_Part.Data_Header.DATA_HEDR_LEN";
@Override
public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
}
@Override
public void coordinateBeforeStandardMessageSend(StandardMessage standardMessage, String msgType, String charset) {
makeupDataHeaderLength(standardMessage, charset);
}
@Override
public void coordinateBeforeResponse(StandardMessage standardMessage, ProcessVO processVO, Properties prop, String charset) {
makeupDataHeaderLength(standardMessage, charset);
}
@Override
public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) {
// guid 설정
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
//GUID 설정
String groupCmdCd = standardMessage.findItemValue(COMMON_PART_GROUP_CMD_CD);
String guid = GUIDGeneratorKJB.getGUID(groupCmdCd);
mapper.setGuid(standardMessage, guid);
StandardItem dataHeaderEtc = standardMessage.findItem("Data_Part.Data_Header_Etc");
dataHeaderEtc.setHidden(true);
//기관코드, 텔러번호 설정
//Adapter에 셋팅된 기관코드를 셋팅한다.
String adapterGroupName = prop.getProperty(Processor.ADAPTER_GROUP_NAME);
AdapterManager adapterManager = AdapterManager.getInstance();
AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName);
// Adapter의 기관코드를 얻어온다.
//TODO: 기관코드의 경우 현재 EAPIM 시스템에 컬럼은 있으나 설정을 사용하지 않고있으므로 불필요 할 경우 사용하지 않는다, 필요 할 경우 추가한다.
String inAdapterOsidInstiNo = adptGrpVO.getOsidInstiNo();
if(inAdapterOsidInstiNo != null && inAdapterOsidInstiNo.trim().length() > 0) {
standardMessage.setData(COMMON_PART_OTSD_CHNL_INST_CD, inAdapterOsidInstiNo);
if (logger.isDebug()) {
logger.debug("FIELD SET " + COMMON_PART_OTSD_CHNL_INST_CD + " << "+inAdapterOsidInstiNo);
}
}
//2012-12-17 나영채 차장 타발요청에만 셋팅해달라고 요청
//전문요청일자
standardMessage.setData("Common.BizProc_Info.MESG_DMAN_DT", DatetimeUtil.getCurrentDate());
//전문요청시간
standardMessage.setData("Common.BizProc_Info.MESG_DMAN_TKTM", DatetimeUtil.getFormattedDate("HHmmssSSS"));
//2012-07-24 임의 로 영업일자에 system시간 설정
standardMessage.setData("Common.BizProc_Info.BZOP_DT", DatetimeUtil.getCurrentDate());
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
//비표준일경우 시스템 운영환경 구분코드를 셋팅한다.
standardMessage.setData("Common.Service_info.SYS_OPRT_ENV_DVCD", getSysOprtEnvDvcd(eaiServerManager));
//헤더부 최초전송IP주소 FRST_TRNM_IPAD
try {
standardMessage.setData("Header.Src_System.FRST_TRNM_IPAD", java.net.InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
}
}
@Override
public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper,
String errCode, String errMsg) {
mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E);
mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
StandardItem messagePart = standardMessage.findItem(MESSAGE_PART);
messagePart.setHidden(false);
messagePart.setSize(1);
StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART);
messageHeaderPart.setSize(1);
StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART);
messageBodyPart.setSize(1);
errCode = StringUtils.defaultString(errCode);
String siteErrCode = MessageUtil.getTobeCode(errCode);
String siteErrMessage;
switch(errCode) {
case("RECEAIIRP070"):
siteErrMessage = "거래 통제 되었습니다.";
break;
default:
siteErrMessage = MessageUtil.getTobeMessage(errCode);
break;
}
mapper.setErrorCode(standardMessage, siteErrCode);
standardMessage.setData(MESSAGE_PART_MSG_HEDR_KNCD, "EM");
standardMessage.setData(MESSAGE_PART_OUTPUT_MSG_CD, siteErrCode);
StandardItem msgGrid = standardMessage.findItem(MESSAGE_PART_OUTPUT_MSG_GRID);
LinkedHashMap<String, StandardItem> msgGridFirstChilds = msgGrid.getArrayChilds(0, true);
msgGridFirstChilds.get("OUTPUT_MSG_CD").setValue(siteErrCode);
msgGridFirstChilds.get("OUTPUT_MSG_CTNT").setValue(siteErrMessage);
//Message.Msg_Body.OUTPUT_MSG_CTNT
mapper.setErrorMsg(standardMessage, siteErrMessage);
int len = standardMessage.getBytesDataLengthForPath(MESSAGE_PART_BODY_PART);
String lenStr = StringUtils.leftPad(String.valueOf(len), 8, '0');
standardMessage.setData(MESSAGE_PART_MSG_HEDR_LEN, lenStr);
return false;
}
@Override
public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage) {
StandardItem messagePart = responseMessage.findItem(MESSAGE_PART);
messagePart.setHidden(false);
messagePart.setSize(1);
StandardItem messageHeaderPart = responseMessage.findItem(MESSAGE_PART_HEADER_PART);
messageHeaderPart.setSize(1);
StandardItem messageBodyPart = responseMessage.findItem(MESSAGE_PART_BODY_PART);
messageBodyPart.setSize(1);
responseMessage.setData(MESSAGE_PART_MSG_HEDR_KNCD, "NM");
responseMessage.setData(MESSAGE_PART_OUTPUT_MSG_CD, "100000 ");
responseMessage.setData(MESSAGE_PART_OUTPUT_MSG_CTNT, "정상처리");
StandardItem msgGrid = responseMessage.findItem(MESSAGE_PART_OUTPUT_MSG_GRID);
LinkedHashMap<String, StandardItem> msgGridFirstChilds = msgGrid.getArrayChilds(0, true);
msgGridFirstChilds.get("OUTPUT_MSG_CD").setValue("100000 ");
msgGridFirstChilds.get("OUTPUT_MSG_CTNT").setValue("정상처리");
int len = responseMessage.getBytesDataLengthForPath(MESSAGE_PART_BODY_PART);
String lenStr = StringUtils.leftPad(String.valueOf(len), 8, '0');
responseMessage.setData(MESSAGE_PART_MSG_HEDR_LEN, lenStr);
}
public String getSysOprtEnvDvcd(EAIServerManager eaiServerManager) {
String result = "";
if (eaiServerManager.isPEAIServer()){ //운영
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_ONLINE;
}else if (eaiServerManager.isDEAIServer()){ //개발
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_DEV;
}else if (eaiServerManager.isSEAIServer()){ //테스트/검증
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_TESTSTAGE;
}
return result;
}
private static void makeupDataHeaderLength(StandardMessage standardMessage, String charset) {
String dataBytesLengthStr = null;
try {
dataBytesLengthStr = String.valueOf(standardMessage.getBizDataBytes(charset).length);
String dataHeaderLength = StringUtils.leftPad(dataBytesLengthStr, 8, '0');
standardMessage.setData(DATA_HEADER_DATA_HEDR_LEN, dataHeaderLength);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -1,142 +0,0 @@
package com.eactive.eai.custom.message;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import com.eactive.eai.common.server.EAIServerManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.inbound.processor.ProcessVO;
import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
import com.eactive.eai.message.service.InterfaceMapper;
import com.eactive.eai.message.service.StandardMessageCoordinator;
public class StandardMessageCoordinatorSBI extends DefaultStandardMessageCoordinator {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
@Override
public void coordinateAfterCreateMessageByRule(StandardMessage message, Object paramObject, Properties prop) {
// STD_HEADER.mesgDvcd 설정
StandardItem mesgDvcdItem = message.findItem("STD_HEADER.mesgDvcd");
if (mesgDvcdItem != null && StringUtils.equals(mesgDvcdItem.getValue(), "S")) {
mesgDvcdItem.setValue("Q");
}
// STD_HEADER.mesgKind 설정
StandardItem mesgKindItem = message.findItem("STD_HEADER.mesgKind");
if (mesgKindItem != null && StringUtils.isBlank(mesgKindItem.getValue())) {
mesgKindItem.setValue("3"); // 3:데이터 4:시스템
}
// STD_HEADER.envDvcd 설정
StandardItem envDvcdItem = message.findItem("STD_HEADER.envDvcd");
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
if (envDvcdItem != null && StringUtils.isBlank(envDvcdItem.getValue())) {
envDvcdItem.setValue(getSysOprtEnvDvcd(eaiServerManager));
}
// guid 설정
StandardMessageManager standardManager = StandardMessageManager.getInstance();
InterfaceMapper mapper = standardManager.getMapper();
mapper.setGuid(message,
GUIDGeneratorSBI.getGUID(getSysOprtEnvDvcd(eaiServerManager), eaiServerManager.getSystemType()));
// STD_HEADER.frstTrnmChnlCd 설정
StandardItem frstTrnmChnlCdItem = message.findItem("STD_HEADER.frstTrnmChnlCd");
if (frstTrnmChnlCdItem != null && StringUtils.isBlank(frstTrnmChnlCdItem.getValue())) {
frstTrnmChnlCdItem.setValue(eaiServerManager.getSystemType());
}
// STD_HEADER.trnmChnlCd 설정
StandardItem trnmChnlCdItem = message.findItem("STD_HEADER.trnmChnlCd");
if (trnmChnlCdItem != null && StringUtils.isBlank(trnmChnlCdItem.getValue())) {
trnmChnlCdItem.setValue(eaiServerManager.getSystemType());
}
// STD_HEADER.userNo 설정
StandardItem userNoItem = message.findItem("STD_HEADER.userNo");
if (userNoItem != null && StringUtils.isBlank(userNoItem.getValue())) {
ProcessVO processVo = (ProcessVO) paramObject;
if (StringUtils.isNotBlank(processVo.getInAdapterUserEmpid())) {
userNoItem.setValue(eaiServerManager.getSystemType());
}
}
// STD_HEADER.mesgDmndDttm 설정
StandardItem mesgDmndDttmItem = message.findItem("STD_HEADER.mesgDmndDttm");
if (mesgDmndDttmItem != null && StringUtils.isBlank(mesgDmndDttmItem.getValue())) {
mesgDmndDttmItem.setValue(DatetimeUtil.getCurrentTimeMillis());
}
// STD_HEADER.ipAd 설정
StandardItem ipAdItem = message.findItem("STD_HEADER.ipAd");
if (ipAdItem != null && StringUtils.isBlank(ipAdItem.getValue())) {
try {
ipAdItem.setValue(InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
logger.error(e.getMessage());
}
}
// STD_HEADER.mesgTycd 설정
StandardItem mesgTycdItem = message.findItem("STD_HEADER.mesgTycd");
if (mesgTycdItem != null && StringUtils.isBlank(mesgTycdItem.getValue())) {
mesgTycdItem.setValue("1");
}
// STD_HEADER.mesgCntySrno 설정
StandardItem mesgCntySrnoItem = message.findItem("STD_HEADER.mesgCntySrno");
if (mesgCntySrnoItem != null && StringUtils.isBlank(mesgCntySrnoItem.getValue())) {
mesgCntySrnoItem.setValue("00");
}
// STD_HEADER.bfrDtLoinYn 설정
StandardItem bfrDtLoinYnItem = message.findItem("STD_HEADER.bfrDtLoinYn");
if (bfrDtLoinYnItem != null && StringUtils.isBlank(bfrDtLoinYnItem.getValue())) {
bfrDtLoinYnItem.setValue("N");
}
// STD_HEADER.canCrctDvcd 설정
StandardItem canCrctDvcdItem = message.findItem("STD_HEADER.canCrctDvcd");
if (canCrctDvcdItem != null && StringUtils.isBlank(canCrctDvcdItem.getValue())) {
canCrctDvcdItem.setValue("0");
}
// STD_HEADER.cmpgRelmUseDvcd 설정
StandardItem cmpgRelmUseDvcdItem = message.findItem("STD_HEADER.cmpgRelmUseDvcd");
if (cmpgRelmUseDvcdItem != null && StringUtils.isBlank(cmpgRelmUseDvcdItem.getValue())) {
cmpgRelmUseDvcdItem.setValue("0");
}
// STD_HEADER.bzwrSvrCd 설정
StandardItem bzwrSvrCdItem = message.findItem("STD_HEADER.bzwrSvrCd");
if (bzwrSvrCdItem != null && StringUtils.isBlank(bzwrSvrCdItem.getValue())) {
String serverName = eaiServerManager.getLocalServerName();
if (StringUtils.isNotBlank(serverName)) {
String instanceid1 = serverName.substring(0, 2);
String instanceid2 = serverName.substring(serverName.length() - 2, serverName.length());
bzwrSvrCdItem.setValue(StringUtils.upperCase(instanceid1 + instanceid2));
}
}
}
public String getSysOprtEnvDvcd(EAIServerManager eaiServerManager) {
String result = "";
if (eaiServerManager.isPEAIServer()) { // 운영
result = "R";
} else if (eaiServerManager.isDEAIServer()) { // 개발
result = "D";
} else if (eaiServerManager.isSEAIServer()) { // 테스트/검증
result = "T";
}
return result;
}
}
@@ -63,10 +63,11 @@ public class HourStatsAggregator {
// 로그 시퀀스 100: 총 건수만 증가 (첫 호출) // 로그 시퀀스 100: 총 건수만 증가 (첫 호출)
if (logSeq == 100) { if (logSeq == 100) {
totalCnt.incrementAndGet(); // totalCnt.incrementAndGet();
} }
// 로그 시퀀스 400: 응답시간 및 에러 타입 기록 // 로그 시퀀스 400: 응답시간 및 에러 타입 기록
else if (logSeq == 400) { else if (logSeq == 400) {
totalCnt.incrementAndGet();
// 성공 여부 카운트 // 성공 여부 카운트
if (event.isSuccess()) { if (event.isSuccess()) {
successCnt.incrementAndGet(); successCnt.incrementAndGet();
@@ -63,10 +63,11 @@ public class MinuteStatsAggregator {
// 로그 시퀀스 100: 총 건수만 증가 (첫 호출) // 로그 시퀀스 100: 총 건수만 증가 (첫 호출)
if (logSeq == 100) { if (logSeq == 100) {
totalCnt.incrementAndGet(); // totalCnt.incrementAndGet();
} }
// 로그 시퀀스 400: 응답시간 및 에러 타입 기록 // 로그 시퀀스 400: 응답시간 및 에러 타입 기록
else if (logSeq == 400) { else if (logSeq == 400) {
totalCnt.incrementAndGet();
// 성공 여부 카운트 // 성공 여부 카운트
if (event.isSuccess()) { if (event.isSuccess()) {
successCnt.incrementAndGet(); successCnt.incrementAndGet();
@@ -22,7 +22,7 @@ public class ApiStatsConfig {
/** 기본값 상수 */ /** 기본값 상수 */
private static final boolean DEFAULT_ENABLED = true; private static final boolean DEFAULT_ENABLED = true;
private static final boolean DEFAULT_MINUTE_ENABLED = true; private static final boolean DEFAULT_MINUTE_ENABLED = true;
private static final boolean DEFAULT_HOUR_ENABLED = true; private static final boolean DEFAULT_HOUR_ENABLED = false;
private final PropManager propManager; private final PropManager propManager;
@@ -0,0 +1,52 @@
package com.eactive.eai.custom.transformer.function;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Stack;
import org.nfunk.jep.ParseException;
import org.nfunk.jep.function.PostfixMathCommand;
import com.eactive.eai.common.security.CryptoModuleService;
/**
* JEP 트랜스포머 함수 — DJB ERP 연동 복호화.
*
* 사용법: DJBErpDecryt(encBase64, moduleName)
*
* 파라미터:
* encBase64 : Base64 인코딩된 암호문
* moduleName : DB에 등록된 암호화 모듈명
*
* 반환값: 복호화된 평문 (String)
*/
public class DJBDecrypt extends PostfixMathCommand {
public DJBDecrypt() {
numberOfParameters = -1;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public void run(Stack inStack) throws ParseException {
checkStack(inStack);
if (curNumberOfParameters != 2) {
throw new ParseException("DJBErpDecryt: 파라미터는 2개개여야 합니다 (encBase64, moduleName");
}
String moduleName = inStack.pop().toString();
String encBase64 = inStack.pop().toString();
try {
byte[] cipherBytes = Base64.getDecoder().decode(encBase64.trim());
byte[] plainBytes = CryptoModuleService.getInstance().decrypt(moduleName, new HashMap<>(), null, cipherBytes);
inStack.push(new String(plainBytes, StandardCharsets.UTF_8));
} catch (ParseException e) {
throw e;
} catch (Exception e) {
throw new ParseException("DJBErpDecryt 복호화 실패: " + e.getMessage());
}
}
}
@@ -0,0 +1,52 @@
package com.eactive.eai.custom.transformer.function;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Stack;
import org.nfunk.jep.ParseException;
import org.nfunk.jep.function.PostfixMathCommand;
import com.eactive.eai.common.security.CryptoModuleService;
/**
* JEP 트랜스포머 함수 — DJB ERP 연동 암호화.
*
* 사용법: DJBErpEncryt(plainText, moduleName) DJBErpEncryt(plainText, moduleName,
* groupSeq)
*
* 파라미터: plainText : 암호화할 평문 (String) moduleName : DB에 등록된 암호화 모듈명 (String)
* groupSeq : 키 도출용 그룹 시퀀스 (String, 선택). 미전달 시 빈 context로 호출.
*
* 반환값: Base64 인코딩된 암호문 (String)
*/
public class DJBEncrypt extends PostfixMathCommand {
public DJBEncrypt() {
numberOfParameters = -1;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public void run(Stack inStack) throws ParseException {
checkStack(inStack);
if (curNumberOfParameters != 2) {
throw new ParseException("DJBErpEncryt: 파라미터는 2개여야 합니다 (plainText, moduleName)");
}
String moduleName = inStack.pop().toString();
String plainText = inStack.pop().toString();
try {
byte[] cipherBytes = CryptoModuleService.getInstance().encrypt(moduleName, new HashMap<>(), null,
plainText.getBytes(StandardCharsets.UTF_8));
inStack.push(Base64.getEncoder().encodeToString(cipherBytes));
} catch (ParseException e) {
throw e;
} catch (Exception e) {
throw new ParseException("DJBErpEncryt 암호화 실패: " + e.getMessage());
}
}
}
@@ -0,0 +1,40 @@
package com.eactive.eai.manage.inflow;
public class GroupMetricDTO {
private String groupId;
private String groupName;
private boolean activate;
private long allowed;
private long rejectedPerSecond;
private long rejectedThreshold;
private long totalRequests;
private double rejectRatio;
private long lastResetTime;
public String getGroupId() { return groupId; }
public void setGroupId(String groupId) { this.groupId = groupId; }
public String getGroupName() { return groupName; }
public void setGroupName(String groupName) { this.groupName = groupName; }
public boolean isActivate() { return activate; }
public void setActivate(boolean activate) { this.activate = activate; }
public long getAllowed() { return allowed; }
public void setAllowed(long allowed) { this.allowed = allowed; }
public long getRejectedPerSecond() { return rejectedPerSecond; }
public void setRejectedPerSecond(long rejectedPerSecond) { this.rejectedPerSecond = rejectedPerSecond; }
public long getRejectedThreshold() { return rejectedThreshold; }
public void setRejectedThreshold(long rejectedThreshold) { this.rejectedThreshold = rejectedThreshold; }
public long getTotalRequests() { return totalRequests; }
public void setTotalRequests(long totalRequests) { this.totalRequests = totalRequests; }
public double getRejectRatio() { return rejectRatio; }
public void setRejectRatio(double rejectRatio) { this.rejectRatio = rejectRatio; }
public long getLastResetTime() { return lastResetTime; }
public void setLastResetTime(long lastResetTime) { this.lastResetTime = lastResetTime; }
}
@@ -1,21 +1,20 @@
package com.eactive.eai.manage.inflow; package com.eactive.eai.manage.inflow;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.CustomGroupBucket; import com.eactive.eai.common.inflow.CustomGroupBucket;
import com.eactive.eai.common.inflow.InflowControlManager; import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowGroupVO; import com.eactive.eai.common.inflow.InflowGroupVO;
@Service @Service
public class InflowGroupBucketService { public class InflowGroupBucketService {
public GroupBucketStatusDTO getGroupBucketStatus(String groupId) { public GroupBucketStatusDTO getGroupBucketStatus(String groupId) {
InflowControlManager manager = InflowControlManager.getInstance(); AbstractInflowControlManager manager = InflowControlUtil.getInflowControlManager();
InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId); InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId);
if (groupVo == null) { if (groupVo == null) {
@@ -72,25 +71,12 @@ public class InflowGroupBucketService {
return dto; return dto;
} }
/**
* 그룹 버킷 조회 (리플렉션 사용)
*/
public CustomGroupBucket getCustomGroupBucket(String groupId) { public CustomGroupBucket getCustomGroupBucket(String groupId) {
try { return InflowControlUtil.getInflowControlManager().getGroupBucket(groupId);
InflowControlManager manager = InflowControlManager.getInstance();
Field field = InflowControlManager.class.getDeclaredField("groupBucketList");
field.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, CustomGroupBucket> groupBucketList =
(Map<String, CustomGroupBucket>) field.get(manager);
return groupBucketList.get(groupId);
} catch (Exception e) {
return null;
}
} }
public List<GroupBucketStatusDTO> getAllGroupBucketStatus() { public List<GroupBucketStatusDTO> getAllGroupBucketStatus() {
InflowControlManager manager = InflowControlManager.getInstance(); AbstractInflowControlManager manager = InflowControlUtil.getInflowControlManager();
String[] groupIds = manager.getGroupAllKeys(); String[] groupIds = manager.getGroupAllKeys();
List<GroupBucketStatusDTO> result = new ArrayList<>(); List<GroupBucketStatusDTO> result = new ArrayList<>();
@@ -0,0 +1,85 @@
package com.eactive.eai.manage.inflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/manage/inflow/group")
public class InflowGroupMetricController {
@Autowired
private InflowGroupMetricService metricService;
/**
* 특정 그룹의 메트릭 조회
* GET /manage/inflow/group/{groupId}/metric
*/
@GetMapping("/{groupId}/metric")
public ResponseEntity<?> getGroupMetric(@PathVariable String groupId) {
GroupMetricDTO metric = metricService.getGroupMetric(groupId);
if (metric == null) {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("message", "그룹을 찾을 수 없습니다: " + groupId);
return ResponseEntity.ok(error);
}
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", metric);
return ResponseEntity.ok(result);
}
/**
* 모든 그룹의 메트릭 조회
* GET /manage/inflow/group/metric
*/
@GetMapping("/metric")
public ResponseEntity<?> getAllGroupMetrics() {
List<GroupMetricDTO> list = metricService.getAllGroupMetrics();
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", list);
result.put("count", list.size());
return ResponseEntity.ok(result);
}
/**
* 특정 그룹의 메트릭 초기화
* POST /manage/inflow/group/{groupId}/metric/reset
*/
@PostMapping("/{groupId}/metric/reset")
public ResponseEntity<?> resetGroupMetric(@PathVariable String groupId) {
boolean ok = metricService.resetGroupMetric(groupId);
Map<String, Object> result = new HashMap<>();
result.put("success", ok);
result.put("message", ok ? "초기화 완료: " + groupId : "그룹을 찾을 수 없습니다: " + groupId);
return ResponseEntity.ok(result);
}
/**
* 전체 그룹 메트릭 초기화
* POST /manage/inflow/group/metric/reset
*/
@PostMapping("/metric/reset")
public ResponseEntity<?> resetAllGroupMetrics() {
metricService.resetAllGroupMetrics();
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "전체 그룹 메트릭 초기화 완료");
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,81 @@
package com.eactive.eai.manage.inflow;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.Bucket;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowGroupVO;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
@Service
public class InflowGroupMetricService {
public GroupMetricDTO getGroupMetric(String groupId) {
DualInflowControlManager manager = getManager();
if (manager == null) return null;
InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId);
if (groupVo == null) return null;
return buildDTO(groupId, groupVo, manager.getGroupMetrics(groupId));
}
public List<GroupMetricDTO> getAllGroupMetrics() {
DualInflowControlManager manager = getManager();
if (manager == null) return new ArrayList<>();
List<GroupMetricDTO> result = new ArrayList<>();
for (String groupId : manager.getGroupAllKeys()) {
GroupMetricDTO dto = getGroupMetric(groupId);
if (dto != null) result.add(dto);
}
return result;
}
public boolean resetGroupMetric(String groupId) {
DualInflowControlManager manager = getManager();
if (manager == null) return false;
if (manager.getGroupInflowThreshold(groupId) == null) return false;
manager.resetGroupMetrics(groupId);
return true;
}
public void resetAllGroupMetrics() {
DualInflowControlManager manager = getManager();
if (manager != null) manager.resetAllGroupMetrics();
}
protected DualInflowControlManager getManager() {
Bucket bucket = InflowControlUtil.getBucket();
return (bucket instanceof DualInflowControlManager)
? (DualInflowControlManager) bucket
: null;
}
private GroupMetricDTO buildDTO(String groupId, InflowGroupVO groupVo,
DualInflowControlManager.TargetMetrics m) {
GroupMetricDTO dto = new GroupMetricDTO();
dto.setGroupId(groupId);
dto.setGroupName(groupVo.getGroupName());
dto.setActivate(groupVo.isActivate());
if (m != null) {
long allowed = m.allowed.get();
long rejPs = m.rejectedPerSecond.get();
long rejTh = m.rejectedThreshold.get();
long total = allowed + rejPs + rejTh;
dto.setAllowed(allowed);
dto.setRejectedPerSecond(rejPs);
dto.setRejectedThreshold(rejTh);
dto.setTotalRequests(total);
dto.setRejectRatio(total > 0
? Math.round((double)(rejPs + rejTh) / total * 10000) / 100.0
: 0.0);
dto.setLastResetTime(m.lastResetTime);
}
return dto;
}
}
@@ -0,0 +1,88 @@
package com.eactive.eai.manage.inflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
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.RestController;
/**
* 어댑터/인터페이스/클라이언트 버킷 상태 모니터링 API.
*
* DualInflowControlManager 가 활성화된 환경에서만 정상 응답한다.
* 비활성화 환경에서는 success=false 또는 빈 목록을 반환한다.
*
* GET /manage/inflow/adapter/bucket-status → 전체 어댑터 버킷 상태
* GET /manage/inflow/adapter/{adapterId}/bucket-status → 특정 어댑터 버킷 상태
* GET /manage/inflow/interface/bucket-status → 전체 인터페이스 버킷 상태
* GET /manage/inflow/interface/{interfaceId}/bucket-status → 특정 인터페이스 버킷 상태
*/
@RestController
@RequestMapping("/manage/inflow")
public class InflowTargetBucketController {
@Autowired
private InflowTargetBucketService bucketService;
// =========================================================================
// 어댑터
// =========================================================================
@GetMapping("/adapter/bucket-status")
public ResponseEntity<?> getAllAdapterBucketStatus() {
List<TargetBucketStatusDTO> list = bucketService.getAllAdapterBucketStatus();
return ok(list);
}
@GetMapping("/adapter/{adapterId}/bucket-status")
public ResponseEntity<?> getAdapterBucketStatus(@PathVariable String adapterId) {
TargetBucketStatusDTO dto = bucketService.getAdapterBucketStatus(adapterId);
return single(dto, "어댑터를 찾을 수 없습니다: " + adapterId);
}
// =========================================================================
// 인터페이스
// =========================================================================
@GetMapping("/interface/bucket-status")
public ResponseEntity<?> getAllInterfaceBucketStatus() {
List<TargetBucketStatusDTO> list = bucketService.getAllInterfaceBucketStatus();
return ok(list);
}
@GetMapping("/interface/{interfaceId}/bucket-status")
public ResponseEntity<?> getInterfaceBucketStatus(@PathVariable String interfaceId) {
TargetBucketStatusDTO dto = bucketService.getInterfaceBucketStatus(interfaceId);
return single(dto, "인터페이스를 찾을 수 없습니다: " + interfaceId);
}
// =========================================================================
// Helpers
// =========================================================================
private ResponseEntity<?> ok(List<TargetBucketStatusDTO> list) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", list);
result.put("count", list.size());
return ResponseEntity.ok(result);
}
private ResponseEntity<?> single(TargetBucketStatusDTO dto, String notFoundMsg) {
if (dto == null) {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("message", notFoundMsg);
return ResponseEntity.ok(error);
}
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", dto);
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,104 @@
package com.eactive.eai.manage.inflow;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
/**
* 어댑터/인터페이스/클라이언트 버킷 상태 조회 서비스.
*
* DualInflowControlManager 가 활성화된 경우에만 동작한다.
* InflowControlManager 가 기본 구현체인 경우 빈 목록 또는 null 을 반환한다.
*/
@Service
public class InflowTargetBucketService {
// -------------------------------------------------------------------------
// 어댑터
// -------------------------------------------------------------------------
public TargetBucketStatusDTO getAdapterBucketStatus(String adapterId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getAdapterBucket(adapterId);
if (bucket == null) return null;
return toDto(adapterId, "ADAPTER", bucket);
}
public List<TargetBucketStatusDTO> getAllAdapterBucketStatus() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("ADAPTER", manager.getAdapterBucketMap());
}
// -------------------------------------------------------------------------
// 인터페이스
// -------------------------------------------------------------------------
public TargetBucketStatusDTO getInterfaceBucketStatus(String interfaceId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getInterfaceBucket(interfaceId);
if (bucket == null) return null;
return toDto(interfaceId, "INTERFACE", bucket);
}
public List<TargetBucketStatusDTO> getAllInterfaceBucketStatus() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("INTERFACE", manager.getInterfaceBucketMap());
}
// -------------------------------------------------------------------------
// Private helpers
// -------------------------------------------------------------------------
protected DualInflowControlManager getDualManager() {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
return (base instanceof DualInflowControlManager) ? (DualInflowControlManager) base : null;
}
private TargetBucketStatusDTO toDto(String targetId, String targetType, DualCustomBucket bucket) {
InflowTargetVO vo = bucket.getInflowTargetVo();
List<GroupBucketStatusDTO.BucketInfo> buckets = new ArrayList<>();
if (vo.getThresholdPerSecond() > 0) {
long capacity = vo.getThresholdPerSecond();
long available = bucket.getPerSecondAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"perSecond", capacity, Math.min(available, capacity), "SEC"));
}
if (vo.getThreshold() > 0) {
long capacity = vo.getThreshold();
long available = bucket.getThresholdAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"threshold", capacity, Math.min(available, capacity), vo.getThresholdTimeUnit()));
}
TargetBucketStatusDTO dto = new TargetBucketStatusDTO();
dto.setTargetId(targetId);
dto.setTargetType(targetType);
dto.setActivate(vo.isActivate());
dto.setBuckets(buckets);
return dto;
}
private List<TargetBucketStatusDTO> toDtoList(String targetType, Map<String, DualCustomBucket> bucketMap) {
List<TargetBucketStatusDTO> result = new ArrayList<>();
for (Map.Entry<String, DualCustomBucket> entry : bucketMap.entrySet()) {
result.add(toDto(entry.getKey(), targetType, entry.getValue()));
}
return result;
}
}
@@ -0,0 +1,133 @@
package com.eactive.eai.manage.inflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 어댑터/인터페이스 유량제어 메트릭 API.
*
* DualInflowControlManager 가 활성화된 환경에서만 정상 응답한다.
*
* GET /manage/inflow/adapter/metric → 전체 어댑터 메트릭
* GET /manage/inflow/adapter/{adapterId}/metric → 특정 어댑터 메트릭
* POST /manage/inflow/adapter/metric/reset → 전체 어댑터 메트릭 초기화
* POST /manage/inflow/adapter/{adapterId}/metric/reset → 특정 어댑터 메트릭 초기화
*
* GET /manage/inflow/interface/metric → 전체 인터페이스 메트릭
* GET /manage/inflow/interface/{interfaceId}/metric → 특정 인터페이스 메트릭
* POST /manage/inflow/interface/metric/reset → 전체 인터페이스 메트릭 초기화
* POST /manage/inflow/interface/{interfaceId}/metric/reset → 특정 인터페이스 메트릭 초기화
*/
@RestController
@RequestMapping("/manage/inflow")
public class InflowTargetMetricController {
@Autowired
private InflowTargetMetricService metricService;
// =========================================================================
// 어댑터
// =========================================================================
@GetMapping("/adapter/metric")
public ResponseEntity<?> getAllAdapterMetrics() {
List<TargetMetricDTO> list = metricService.getAllAdapterMetrics();
return okList(list);
}
@GetMapping("/adapter/{adapterId}/metric")
public ResponseEntity<?> getAdapterMetric(@PathVariable String adapterId) {
TargetMetricDTO dto = metricService.getAdapterMetric(adapterId);
return okSingle(dto, "어댑터를 찾을 수 없습니다: " + adapterId);
}
@PostMapping("/adapter/metric/reset")
public ResponseEntity<?> resetAllAdapterMetrics() {
metricService.resetAllAdapterMetrics();
return okReset("전체 어댑터 메트릭 초기화 완료");
}
@PostMapping("/adapter/{adapterId}/metric/reset")
public ResponseEntity<?> resetAdapterMetric(@PathVariable String adapterId) {
boolean ok = metricService.resetAdapterMetric(adapterId);
return okResetSingle(ok, adapterId, "어댑터");
}
// =========================================================================
// 인터페이스
// =========================================================================
@GetMapping("/interface/metric")
public ResponseEntity<?> getAllInterfaceMetrics() {
List<TargetMetricDTO> list = metricService.getAllInterfaceMetrics();
return okList(list);
}
@GetMapping("/interface/{interfaceId}/metric")
public ResponseEntity<?> getInterfaceMetric(@PathVariable String interfaceId) {
TargetMetricDTO dto = metricService.getInterfaceMetric(interfaceId);
return okSingle(dto, "인터페이스를 찾을 수 없습니다: " + interfaceId);
}
@PostMapping("/interface/metric/reset")
public ResponseEntity<?> resetAllInterfaceMetrics() {
metricService.resetAllInterfaceMetrics();
return okReset("전체 인터페이스 메트릭 초기화 완료");
}
@PostMapping("/interface/{interfaceId}/metric/reset")
public ResponseEntity<?> resetInterfaceMetric(@PathVariable String interfaceId) {
boolean ok = metricService.resetInterfaceMetric(interfaceId);
return okResetSingle(ok, interfaceId, "인터페이스");
}
// =========================================================================
// Helpers
// =========================================================================
private ResponseEntity<?> okList(List<TargetMetricDTO> list) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", list);
result.put("count", list.size());
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okSingle(TargetMetricDTO dto, String notFoundMsg) {
if (dto == null) {
Map<String, Object> error = new HashMap<>();
error.put("success", false);
error.put("message", notFoundMsg);
return ResponseEntity.ok(error);
}
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", dto);
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okReset(String message) {
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", message);
return ResponseEntity.ok(result);
}
private ResponseEntity<?> okResetSingle(boolean ok, String targetId, String targetLabel) {
Map<String, Object> result = new HashMap<>();
result.put("success", ok);
result.put("message", ok
? "초기화 완료: " + targetId
: targetLabel + "를 찾을 수 없습니다: " + targetId);
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,121 @@
package com.eactive.eai.manage.inflow;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
@Service
public class InflowTargetMetricService {
// -------------------------------------------------------------------------
// 어댑터
// -------------------------------------------------------------------------
public TargetMetricDTO getAdapterMetric(String adapterId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
InflowTargetVO vo = manager.getAdapterInflowThreashold(adapterId);
if (vo == null) return null;
return buildDTO(adapterId, "ADAPTER", vo, manager.getAdapterMetrics(adapterId));
}
public List<TargetMetricDTO> getAllAdapterMetrics() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
List<TargetMetricDTO> result = new ArrayList<>();
for (String id : manager.getAdapterAllKeys()) {
TargetMetricDTO dto = getAdapterMetric(id);
if (dto != null) result.add(dto);
}
return result;
}
public boolean resetAdapterMetric(String adapterId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return false;
if (manager.getAdapterInflowThreashold(adapterId) == null) return false;
manager.resetAdapterMetrics(adapterId);
return true;
}
public void resetAllAdapterMetrics() {
DualInflowControlManager manager = getDualManager();
if (manager != null) manager.resetAllAdapterMetrics();
}
// -------------------------------------------------------------------------
// 인터페이스
// -------------------------------------------------------------------------
public TargetMetricDTO getInterfaceMetric(String interfaceId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
InflowTargetVO vo = manager.getInterfaceInflowThreashold(interfaceId);
if (vo == null) return null;
return buildDTO(interfaceId, "INTERFACE", vo, manager.getInterfaceMetrics(interfaceId));
}
public List<TargetMetricDTO> getAllInterfaceMetrics() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
List<TargetMetricDTO> result = new ArrayList<>();
for (String id : manager.getInterfaceAllKeys()) {
TargetMetricDTO dto = getInterfaceMetric(id);
if (dto != null) result.add(dto);
}
return result;
}
public boolean resetInterfaceMetric(String interfaceId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return false;
if (manager.getInterfaceInflowThreashold(interfaceId) == null) return false;
manager.resetInterfaceMetrics(interfaceId);
return true;
}
public void resetAllInterfaceMetrics() {
DualInflowControlManager manager = getDualManager();
if (manager != null) manager.resetAllInterfaceMetrics();
}
// -------------------------------------------------------------------------
// Private helpers
// -------------------------------------------------------------------------
protected DualInflowControlManager getDualManager() {
AbstractInflowControlManager base = InflowControlUtil.getInflowControlManager();
return (base instanceof DualInflowControlManager) ? (DualInflowControlManager) base : null;
}
private TargetMetricDTO buildDTO(String targetId, String targetType,
InflowTargetVO vo,
DualInflowControlManager.TargetMetrics m) {
TargetMetricDTO dto = new TargetMetricDTO();
dto.setTargetId(targetId);
dto.setTargetType(targetType);
dto.setActivate(vo.isActivate());
if (m != null) {
long allowed = m.allowed.get();
long rejPs = m.rejectedPerSecond.get();
long rejTh = m.rejectedThreshold.get();
long total = allowed + rejPs + rejTh;
dto.setAllowed(allowed);
dto.setRejectedPerSecond(rejPs);
dto.setRejectedThreshold(rejTh);
dto.setTotalRequests(total);
dto.setRejectRatio(total > 0
? Math.round((double)(rejPs + rejTh) / total * 10000) / 100.0
: 0.0);
dto.setLastResetTime(m.lastResetTime);
}
return dto;
}
}
@@ -0,0 +1,27 @@
package com.eactive.eai.manage.inflow;
import java.util.List;
/**
* 어댑터/인터페이스/클라이언트 버킷 상태 DTO.
* {@link GroupBucketStatusDTO}와 동일한 BucketInfo 구조를 공유한다.
*/
public class TargetBucketStatusDTO {
private String targetId; // 어댑터명 | 인터페이스ID | 클라이언트ID
private String targetType; // "ADAPTER" | "INTERFACE" | "CLIENT"
private boolean activate;
private List<GroupBucketStatusDTO.BucketInfo> buckets;
public String getTargetId() { return targetId; }
public void setTargetId(String targetId) { this.targetId = targetId; }
public String getTargetType() { return targetType; }
public void setTargetType(String targetType) { this.targetType = targetType; }
public boolean isActivate() { return activate; }
public void setActivate(boolean activate) { this.activate = activate; }
public List<GroupBucketStatusDTO.BucketInfo> getBuckets() { return buckets; }
public void setBuckets(List<GroupBucketStatusDTO.BucketInfo> buckets) { this.buckets = buckets; }
}
@@ -0,0 +1,44 @@
package com.eactive.eai.manage.inflow;
/**
* 어댑터/인터페이스/클라이언트 메트릭 DTO.
*/
public class TargetMetricDTO {
private String targetId;
private String targetType; // "ADAPTER" | "INTERFACE" | "CLIENT"
private boolean activate;
private long allowed;
private long rejectedPerSecond;
private long rejectedThreshold;
private long totalRequests;
private double rejectRatio;
private long lastResetTime;
public String getTargetId() { return targetId; }
public void setTargetId(String targetId) { this.targetId = targetId; }
public String getTargetType() { return targetType; }
public void setTargetType(String targetType) { this.targetType = targetType; }
public boolean isActivate() { return activate; }
public void setActivate(boolean activate) { this.activate = activate; }
public long getAllowed() { return allowed; }
public void setAllowed(long allowed) { this.allowed = allowed; }
public long getRejectedPerSecond() { return rejectedPerSecond; }
public void setRejectedPerSecond(long rejectedPerSecond) { this.rejectedPerSecond = rejectedPerSecond; }
public long getRejectedThreshold() { return rejectedThreshold; }
public void setRejectedThreshold(long rejectedThreshold) { this.rejectedThreshold = rejectedThreshold; }
public long getTotalRequests() { return totalRequests; }
public void setTotalRequests(long totalRequests) { this.totalRequests = totalRequests; }
public double getRejectRatio() { return rejectRatio; }
public void setRejectRatio(double rejectRatio) { this.rejectRatio = rejectRatio; }
public long getLastResetTime() { return lastResetTime; }
public void setLastResetTime(long lastResetTime) { this.lastResetTime = lastResetTime; }
}
Binary file not shown.
@@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhXoqB4PrgZpJISjBe9ht
Y1R3Ne9ehxugWucwA4cBWAnYwvmrRAK0p8p+HuDikdZPq2hyAG02ucNt9xoru+Va
K4spNGieORbh0hmLRdvVBBM7Ureia3WhKED5abNnnPQw+jCLZNVYtO9rbtRhpUEG
t73sN1+0bOZlVBkbLenvWKJs2+tyE0gHhwgS8Fzrb++LHYN/c0KoTm+G9ITuPWoM
Vu/iME5WHqR95TkLKpx6s5J/le4BvncQDmkvKFIX9/DFN57orXQVB2lzDF8fMeWC
xaaHXtgfo2ercKKEdHQ5GFIgWN8+j2ZgU2JqfucazJpOpOGcizHiQKzh//NE7beD
IwIDAQAB
-----END PUBLIC KEY-----
@@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqCW0auFk5bqt7OZ2AtFw
xa/se93/hgNwDNC1kxKZpnvNM5YVj5gjlf0jOSVGNJlFTVvjIBcyPC7s1zlFDhgm
ebUKplRuw82lkIkS7mPjsqfPvMQlFjjLgrnECQ3AD86EkRcUT/bVliOtwLY6YJUa
5/1eqZCIRfLPVxOApSHuQLJ9JmSPhttwfKwTED3G2dB85D+QN5+Nre5nnWDjMScT
KOcyUZHOLO6m0UupBYU94XGJG4EEMwzSE/Lq1eJ49/wUsvaKY6Kz5G30d/ANwRZI
ex82Wp91ZPOasKKOB6vnQ/LNcMhhyYf6IzCliMUUFl53YeheXmvfWX6VLfWgjlLk
HQIDAQAB
-----END PUBLIC KEY-----
@@ -1,27 +0,0 @@
#-----------------------------------------------------------------------------
# comment start with #
# level; // 0 : root ~ n
# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
# size // 0 : variable, > 0 fixed
# fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
# length;
# dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
commonHeader ,1 ,2 ,1 ,0 ,0 ,0 , , ,,공통헤더
firstReqSystemCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,최초요청시스템코드
firstReqSystemIp ,2 ,1 ,1 ,0 ,0 ,0 , , ,,최초요청IP주소
msgCreationTime ,2 ,1 ,1 ,0 ,0 ,0 , , ,,전문생성일시
globalId ,2 ,1 ,1 ,0 ,0 ,0 , , ,,guid
traceSeqNo ,2 ,1 ,1 ,0 ,0 ,1 , , ,1,시스템경유이력번호
serviceCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,거래코드
personalInfoYn ,2 ,1 ,1 ,0 ,0 ,0 , , ,,개인정보포함여부
receivingSystemCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,수신시스템코드
reqResTypeCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,요청응답구분코드
msgList ,2 ,3 ,0 ,0 ,0 ,0 , , ,,메시지목록
resultCode ,3 ,1 ,1 ,0 ,0 ,0 , , ,,결과코드
resultMsg ,3 ,1 ,1 ,0 ,0 ,0 , , ,,결과메시지
msgStackTrace ,2 ,1 ,1 ,0 ,0 ,0 , , ,,에러내용
payload ,1 ,9 ,0 ,0 ,0 ,0 , , ,,업무데이터
1 #-----------------------------------------------------------------------------
2 # comment start with #
3 # level; // 0 : root ~ n
4 # type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
5 # size // 0 : variable, > 0 fixed
6 # fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
7 # length;
8 # dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
9 #-----------------------------------------------------------------------------
10 # name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
11 #-----------------------------------------------------------------------------
12 # name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
13 commonHeader ,1 ,2 ,1 ,0 ,0 ,0 , , ,,공통헤더
14 firstReqSystemCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,최초요청시스템코드
15 firstReqSystemIp ,2 ,1 ,1 ,0 ,0 ,0 , , ,,최초요청IP주소
16 msgCreationTime ,2 ,1 ,1 ,0 ,0 ,0 , , ,,전문생성일시
17 globalId ,2 ,1 ,1 ,0 ,0 ,0 , , ,,guid
18 traceSeqNo ,2 ,1 ,1 ,0 ,0 ,1 , , ,1,시스템경유이력번호
19 serviceCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,거래코드
20 personalInfoYn ,2 ,1 ,1 ,0 ,0 ,0 , , ,,개인정보포함여부
21 receivingSystemCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,수신시스템코드
22 reqResTypeCode ,2 ,1 ,1 ,0 ,0 ,0 , , ,,요청응답구분코드
23 msgList ,2 ,3 ,0 ,0 ,0 ,0 , , ,,메시지목록
24 resultCode ,3 ,1 ,1 ,0 ,0 ,0 , , ,,결과코드
25 resultMsg ,3 ,1 ,1 ,0 ,0 ,0 , , ,,결과메시지
26 msgStackTrace ,2 ,1 ,1 ,0 ,0 ,0 , , ,,에러내용
27 payload ,1 ,9 ,0 ,0 ,0 ,0 , , ,,업무데이터
-233
View File
@@ -1,233 +0,0 @@
#-----------------------------------------------------------------------------
# comment start with #
# level; // 0 : root ~ n
# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
# size // 0 : variable, > 0 fixed
# fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
# length;
# dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
#-----------------------------------------------------------------------------
# name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
Header,1,3,1,1,0,1,,,
Sys_Info,2,3,1,1,0,1,,,
STND_MESG_LEN,3,2,1,1,8,12,,,
ENCD_CMPI_DVCD,3,2,1,1,1,1,,,0
GUID,3,2,1,1,36,1,,,
MESG_DMAN_DVCD,3,2,1,1,1,1,,,S
MESG_VER_NO,3,2,1,1,3,1,,,R10
Src_System,2,3,1,1,0,1,,,
FRST_TRNM_IPAD,3,2,1,1,39,1,,,
FRST_TRNM_SYS_CD,3,2,1,1,3,1,,,API
TRNM_SYS_CD,3,2,1,1,3,1,,,
TRNM_NODE_NO,3,2,1,1,4,1,,,
MCI_SESN_ID,3,2,1,1,8,1,,,
GNRZ_TMOT_TKTM,3,2,1,1,3,1,,,070
TX_TMOT_TKTM,3,2,1,1,3,1,,,060
KJB_Add,2,3,1,1,0,1,,,
OTSD_DMAN_SYS_CD,3,2,1,1,3,1,,,OBP
EAI_NODE_NO,3,2,1,1,2,1,,,
FEP_NODE_NO,3,2,1,1,2,1,,,
FEP_SESN_ID,3,2,1,1,6,1,,,
Spare_Zone,2,3,1,1,0,1,,,
HEDR_SPR_CTNT,3,2,1,1,25,1,,,
Common,1,3,1,1,0,1,,,
Service_info,2,3,1,1,0,1,,,
GROUP_CMP_CD,3,2,1,1,3,1,,,034
SRVC_ID,3,2,1,1,11,1,,,
PROCS_RSLT_RCMS_SRVC_ID,3,2,1,1,11,1,,,
IF_ID,3,2,1,1,20,1,,,
TX_SYNZ_DVCD,3,2,1,1,1,1,,,
HMAB_DVCD,3,2,1,1,1,1,,,2
OTSD_CHNL_INST_CD,3,2,1,1,3,1,,,
SYS_OPRT_ENV_DVCD,3,2,1,1,1,1,,,
TX_TYP_DVCD,3,2,1,1,1,1,,,O
ORTR_RESTR_YN,3,2,1,1,1,1,,,
ORTR_GUID,3,2,1,1,36,1,,,
Channel_Info,2,3,1,1,0,1,,,
BANK_CD,3,2,1,1,3,1,,,
TX_BRCD,3,2,1,1,4,1,,,
DSPC_RCV_BRN_DVCD,3,2,1,1,2,1,,,
RLTR_BRCD,3,2,1,1,4,1,,,
TRMN_INSL_BRCD,3,2,1,1,4,1,,,
CHNL_TYCD,3,2,1,1,1,1,,,
CHNL_DTLS_CLCD,3,2,1,1,3,1,,,
TMNL_KIND_DVCD,3,2,1,1,2,1,,,
TRMN_NO,3,2,1,1,6,1,,,
SCN_NO,3,2,1,1,13,1,,,
SCN_FILE_VER,3,2,1,1,10,2,,,
SCN_FILE_NM,3,2,1,1,30,1,,,
LANG_DVCD,3,2,1,1,3,1,,,KOR
CHNL_COM_SCTN_EXIS_YN,3,2,1,1,1,1,,,N
Confirm_Info,2,3,1,1,0,1,,,
PRCG_APRV_PROCS_STCD,3,2,1,1,1,1,,,
PRCG_APRV_TYCD,3,2,1,1,1,1,,,
APRV_PRCG_EMPNO,3,2,1,1,7,1,,,
NURN_RSBT_EMPNO,3,2,1,1,7,1,,,
PRCG_APRV_SEQNO,3,2,1,1,10,2,,,
NURN_AGNCY_APRV_YN,3,2,1,1,1,1,,,
DSGT_PRCG_CHNG_YN,3,2,1,1,1,1,,,
CHNG_DSGT_PRCG_EMPNO,3,2,1,1,7,1,,,
PRCG_APRV_DMAN_RSN,3,2,1,1,40,1,,,
PRCG_APRV_RSN,3,2,1,1,40,1,,,
BizProc_Info,2,3,1,1,0,1,,,
BZOP_DT,3,2,1,1,8,1,,,
ANTT_YN,3,2,1,1,1,1,,,
MESG_IQRY_DVCD,3,2,1,1,1,1,,,
ATMC_CLSN_DVCD,3,2,1,1,1,1,,,
TLRNO,3,2,1,1,7,1,,,
ASST_TLRNO,3,2,1,1,7,1,,,
PSWD_VALDTN_YN,3,2,1,1,1,1,,,
TX_TELR_PSWD,3,2,1,1,44,1,,,
CSIF_IDNT_DVCD,3,2,1,1,3,1,,,
CSIF_ID,3,2,1,1,30,1,,,
CSIF_CUST_NM,3,2,1,1,30,1,,,
CSIF_MASK_REVOC_YN,3,2,1,1,1,1,,,
CUST_PTLET_MASK_YN,3,2,1,1,1,1,,,
IDC_IMG_NO,3,2,1,1,32,1,,,
SMTWKP_TX_YN,3,2,1,1,1,1,,,
SECU_ACCO_REG_YN,3,2,1,1,1,1,,,
ABC_TX_DTLS_DVCD,3,2,1,1,2,1,,,
CLNT_TELR_CSHN_RFLC_YN,3,2,1,1,1,1,,,
SLIP_DIV_YN,3,2,1,1,1,1,,,
SLIP_NO,3,2,1,1,9,1,,,
TELR_SLIP_SEQNO,3,2,1,1,10,2,,,
TELR_CASH_AMT,3,2,1,1,17,2,,,
TELR_CBPC_AMT,3,2,1,1,17,2,,,
TELR_TRFAMT,3,2,1,1,17,2,,,
LOGIN_DVCD,3,2,1,1,1,1,,,
TX_DT_EXTNS_YN ,3,2,1,1,1,1,,,
TX_DT,3,2,1,1,8,1,,,
TX_TIME,3,2,1,1,8,1,,,
SYS_DT,3,2,1,1,8,1,,,
SYS_TIME,3,2,1,1,8,1,,,
MESG_DMAN_DT,3,2,1,1,8,1,,,
MESG_DMAN_TKTM,3,2,1,1,9,1,,,
MESG_CNTY_YN,3,2,1,1,1,1,,,
MESG_RSPN_DT,3,2,1,1,8,1,,,
MESG_RSPN_TKTM,3,2,1,1,9,1,,,
PROCS_RSLT_DVCD,3,2,1,1,2,1,,,
OUTPUT_MESG_TYCD,3,2,1,1,1,1,,,
LRQN_OUTPUT_DSCT_TRGT_YN,3,2,1,1,1,1,,,
MESG_CNTY_SEQNO,3,2,1,1,3,1,,,
Error_Info,2,3,1,1,0,1,,,
ERR_CD,3,2,1,1,6,1,,,
ERR_SYS_CD,3,2,1,1,3,1,,,
KJB_Add,2,3,1,1,0,1,,,
ORTR_SCN_ID,3,2,1,1,13,1,,,
CORP_DPRM_NO,3,2,1,1,5,1,,,
CSIF_IQRY_RSCD,3,2,1,1,2,1,,,
Com_Spare_Zone,2,3,1,1,0,1,,,
COM_SPR_CTNT,3,2,1,1,212,1,,,
Channel_Common,1,3,0,1,0,1,Std_Header.Common.Channel_Info.CHNL_COM_SCTN_EXIS_YN,Y,
Data_Header,2,3,0,1,0,1,,,
DATA_HEDR_KNCD,3,2,1,1,2,1,,,
DATA_HEDR_LEN,3,2,1,1,8,1,,,
Data_For_Each,2,3,0,1,0,1,,,
PSWD_ERR_DVCD,3,2,1,1,2,1,,,
ELFN_CUST_TYCD,3,2,1,1,2,1,,,
USER_ID_S14,3,2,1,1,14,1,,,
MST_ID_S14,3,2,1,1,14,1,,,
SVR_TX_NO,3,2,1,1,10,1,,,
HOST_TX_NO_S10,3,2,1,1,10,1,,,
NEXT_PAGE_EXIS_YN1,3,2,1,1,1,1,,,
SCCR_ISS_CD,3,2,1,1,2,1,,,
SQ1_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
SQ2_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
SECU_MEDIA_SEQNO_S4,3,2,1,1,4,1,,,
SECU_MEDIA_DTL_DVCD_N3,3,2,1,1,3,1,,,
PAGE_NO,3,2,1,1,5,1,,,
PAGE_SIZE,3,2,1,1,5,1,,,
TTCN_N5,3,2,1,1,5,1,,,
IQRY_CCNT_N5,3,2,1,1,5,1,,,
PRIQR_TX_NO,3,2,1,1,10,1,,,
SQ1_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
SQ2_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
MAC_S17,3,2,1,1,17,1,,,
HDD_SEQ_NO_S24,3,2,1,1,24,1,,,
CMCM_CD,3,2,1,1,1,1,,,
TLNO_S14,3,2,1,1,14,1,,,
OTP_EXPR_GDNC_DVCD_S1,3,2,1,1,1,1,,,
KFTC_ENCD_MST_KEY_VER_S2,3,2,1,1,2,1,,,
KFTC_ENCD_RAND1_S32,3,2,1,1,32,1,,,
KFTC_ENCD_RAND2_S32,3,2,1,1,32,1,,,
ADDT_ATHN_YN_S1,3,2,1,1,1,1,,,
ADDT_ATHN_METH_DVCD_S2,3,2,1,1,2,1,,,
ADDT_ATHN_ATHN_VAL_S40,3,2,1,1,40,1,,,
DUP_TX_YN_S1,3,2,1,1,1,1,,,
ABR_IP_BLC_YN_S1,3,2,1,1,1,1,,,
VIRT_ACCO_DVCD_S1,3,2,1,1,1,1,,,
BZWK_DVCD1_S1,3,2,1,1,1,1,,,
BZWK_DVCD2_S1,3,2,1,1,1,1,,,
BZWK_DVCD3_S1,3,2,1,1,1,1,,,
BZWK_DVCD4_S1,3,2,1,1,1,1,,,
BZWK_DVCD5_S1,3,2,1,1,1,1,,,
TX_SER_SEQNO_N3,3,2,1,1,3,1,,,
SECU_MEDIA_SEQNO_DMAN_VAL_S4,3,2,1,1,4,1,,,
MEDIA_D1_UZ_POSB_AMT_N12,3,2,1,1,12,1,,,
CPHR_KEY_SECU_CO_CD_S1,3,2,1,1,1,1,,,
HDD_VOLU_ID_S35,3,2,1,1,35,1,,,
SPR_FILD_S197,3,2,1,1,197,1,,,
Message,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
Msg_Header,2,3,0,1,0,1,,,
MSG_HEDR_KNCD,3,2,1,1,2,1,,,NM
MSG_HEDR_LEN,3,2,1,1,8,2,,,
Msg_Body,2,3,0,1,0,1,,,
OUTPUT_ATRB_CD,3,2,1,1,1,1,,,0
OUTPUT_MSG_CD,3,2,1,1,10,1,,,
OUTPUT_MSG_CTNT,3,2,1,1,200,1,,,
OUTPUT_MSG_DESC,3,2,1,1,300,1,,,
ERR_MNGM_CTNT,3,2,1,1,200,1,,,
ERR_CHGR_NM,3,2,1,1,10,1,,,
ERR_CHGR_CNPL_NO,3,2,1,1,20,1,,,
OUTPUT_MSG_NCNT,3,2,1,1,4,2,,,0000
Output_Msg_Grid,3,4,0,1,0,1,Message.Msg_Body.OUTPUT_MSG_NCNT,,
OUTPUT_MSG_CD,4,2,0,1,10,1,,,
OUTPUT_MSG_CTNT,4,2,0,1,200,1,,,
OUTPUT_MSG_DESC,4,2,0,1,300,1,,,
ERR_MNGM_CTNT,4,2,0,1,200,1,,,
ERR_LOCT_CTNT,4,2,0,1,200,1,,,
ERR_OCCU_ITEM_NM,4,2,0,1,20,1,,,
Manager_Confirm,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
Data_Header,2,3,0,1,0,1,,,
DATA_HEDR_KNCD,3,2,1,1,2,1,,,
DATA_HEDR_LEN,3,2,1,1,8,2,,,
Data_Header_Etc,2,3,0,1,0,1,,,
OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
OUTPUT_SCN_ID,3,2,1,1,13,1,,,
OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
DCG_DVCD,3,2,1,1,1,1,,,
Data_For_Each,2,3,0,1,0,1,,,
ACNO,3,2,1,1,16,1,,,
TRMN_CUST_FLNM,3,2,1,1,20,1,,,
TX_AMT,3,2,1,1,17,2,,,
APRV_RSCD_CCNT,3,2,1,1,5,2,,,
APRV_RSCD,3,2,1,1,5,1,,,
PRCG_APRV_DESC,3,2,1,1,50,1,,,
PRCG_APRV_TYCD,3,2,1,1,1,1,,,
PRCG_APRV_LIST_CCNT,3,2,1,1,5,2,,,
TX_DVCD,3,2,1,1,2,1,,,
PRCG_EMPNO,3,2,1,1,6,1,,,
KOR_FLNM,3,2,1,1,40,1,,,
BLNG_BRCD,3,2,1,1,4,1,,,
BRN_KOR_NM ,3,2,1,1,100,1,,,
LOGIN_IPAD,3,2,1,1,30,1,,,
JOBCLS_CD,3,2,1,1,2,1,,,
LOGIN_STCD,3,2,1,1,2,1,,,
ABSC_YN,3,2,1,1,1,1,,,
AGNCY_APRV_TLRNO,3,2,1,1,7,1,,,
BRMNR_YN,3,2,1,1,1,1,,,
AUDT_UNCN_PRCG_YN,3,2,1,1,1,1,,,
Data_Part,1,3,0,1,0,1,,,
Data_Header,2,3,0,1,0,1,,,
DATA_HEDR_KNCD,3,2,1,1,2,1,,,IO
DATA_HEDR_LEN,3,2,1,1,8,2,,,
Data_Header_Etc,2,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
OUTPUT_SCN_ID,3,2,1,1,13,1,,,
OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
DCG_DVCD,3,2,1,1,1,1,,,
Data_For_Each,2,3,0,1,0,1,,,
BizData,3,9,1,1,0,1,,,
END_BIT_CTNT,1,2,1,1,2,11,,,@@
1 #-----------------------------------------------------------------------------
2 # comment start with #
3 # level; // 0 : root ~ n
4 # type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
5 # size // 0 : variable, > 0 fixed
6 # fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
7 # length;
8 # dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
9 #-----------------------------------------------------------------------------
10 # name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
11 #-----------------------------------------------------------------------------
12 # name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
13 Header,1,3,1,1,0,1,,,
14 Sys_Info,2,3,1,1,0,1,,,
15 STND_MESG_LEN,3,2,1,1,8,12,,,
16 ENCD_CMPI_DVCD,3,2,1,1,1,1,,,0
17 GUID,3,2,1,1,36,1,,,
18 MESG_DMAN_DVCD,3,2,1,1,1,1,,,S
19 MESG_VER_NO,3,2,1,1,3,1,,,R10
20 Src_System,2,3,1,1,0,1,,,
21 FRST_TRNM_IPAD,3,2,1,1,39,1,,,
22 FRST_TRNM_SYS_CD,3,2,1,1,3,1,,,API
23 TRNM_SYS_CD,3,2,1,1,3,1,,,
24 TRNM_NODE_NO,3,2,1,1,4,1,,,
25 MCI_SESN_ID,3,2,1,1,8,1,,,
26 GNRZ_TMOT_TKTM,3,2,1,1,3,1,,,070
27 TX_TMOT_TKTM,3,2,1,1,3,1,,,060
28 KJB_Add,2,3,1,1,0,1,,,
29 OTSD_DMAN_SYS_CD,3,2,1,1,3,1,,,OBP
30 EAI_NODE_NO,3,2,1,1,2,1,,,
31 FEP_NODE_NO,3,2,1,1,2,1,,,
32 FEP_SESN_ID,3,2,1,1,6,1,,,
33 Spare_Zone,2,3,1,1,0,1,,,
34 HEDR_SPR_CTNT,3,2,1,1,25,1,,,
35 Common,1,3,1,1,0,1,,,
36 Service_info,2,3,1,1,0,1,,,
37 GROUP_CMP_CD,3,2,1,1,3,1,,,034
38 SRVC_ID,3,2,1,1,11,1,,,
39 PROCS_RSLT_RCMS_SRVC_ID,3,2,1,1,11,1,,,
40 IF_ID,3,2,1,1,20,1,,,
41 TX_SYNZ_DVCD,3,2,1,1,1,1,,,
42 HMAB_DVCD,3,2,1,1,1,1,,,2
43 OTSD_CHNL_INST_CD,3,2,1,1,3,1,,,
44 SYS_OPRT_ENV_DVCD,3,2,1,1,1,1,,,
45 TX_TYP_DVCD,3,2,1,1,1,1,,,O
46 ORTR_RESTR_YN,3,2,1,1,1,1,,,
47 ORTR_GUID,3,2,1,1,36,1,,,
48 Channel_Info,2,3,1,1,0,1,,,
49 BANK_CD,3,2,1,1,3,1,,,
50 TX_BRCD,3,2,1,1,4,1,,,
51 DSPC_RCV_BRN_DVCD,3,2,1,1,2,1,,,
52 RLTR_BRCD,3,2,1,1,4,1,,,
53 TRMN_INSL_BRCD,3,2,1,1,4,1,,,
54 CHNL_TYCD,3,2,1,1,1,1,,,
55 CHNL_DTLS_CLCD,3,2,1,1,3,1,,,
56 TMNL_KIND_DVCD,3,2,1,1,2,1,,,
57 TRMN_NO,3,2,1,1,6,1,,,
58 SCN_NO,3,2,1,1,13,1,,,
59 SCN_FILE_VER,3,2,1,1,10,2,,,
60 SCN_FILE_NM,3,2,1,1,30,1,,,
61 LANG_DVCD,3,2,1,1,3,1,,,KOR
62 CHNL_COM_SCTN_EXIS_YN,3,2,1,1,1,1,,,N
63 Confirm_Info,2,3,1,1,0,1,,,
64 PRCG_APRV_PROCS_STCD,3,2,1,1,1,1,,,
65 PRCG_APRV_TYCD,3,2,1,1,1,1,,,
66 APRV_PRCG_EMPNO,3,2,1,1,7,1,,,
67 NURN_RSBT_EMPNO,3,2,1,1,7,1,,,
68 PRCG_APRV_SEQNO,3,2,1,1,10,2,,,
69 NURN_AGNCY_APRV_YN,3,2,1,1,1,1,,,
70 DSGT_PRCG_CHNG_YN,3,2,1,1,1,1,,,
71 CHNG_DSGT_PRCG_EMPNO,3,2,1,1,7,1,,,
72 PRCG_APRV_DMAN_RSN,3,2,1,1,40,1,,,
73 PRCG_APRV_RSN,3,2,1,1,40,1,,,
74 BizProc_Info,2,3,1,1,0,1,,,
75 BZOP_DT,3,2,1,1,8,1,,,
76 ANTT_YN,3,2,1,1,1,1,,,
77 MESG_IQRY_DVCD,3,2,1,1,1,1,,,
78 ATMC_CLSN_DVCD,3,2,1,1,1,1,,,
79 TLRNO,3,2,1,1,7,1,,,
80 ASST_TLRNO,3,2,1,1,7,1,,,
81 PSWD_VALDTN_YN,3,2,1,1,1,1,,,
82 TX_TELR_PSWD,3,2,1,1,44,1,,,
83 CSIF_IDNT_DVCD,3,2,1,1,3,1,,,
84 CSIF_ID,3,2,1,1,30,1,,,
85 CSIF_CUST_NM,3,2,1,1,30,1,,,
86 CSIF_MASK_REVOC_YN,3,2,1,1,1,1,,,
87 CUST_PTLET_MASK_YN,3,2,1,1,1,1,,,
88 IDC_IMG_NO,3,2,1,1,32,1,,,
89 SMTWKP_TX_YN,3,2,1,1,1,1,,,
90 SECU_ACCO_REG_YN,3,2,1,1,1,1,,,
91 ABC_TX_DTLS_DVCD,3,2,1,1,2,1,,,
92 CLNT_TELR_CSHN_RFLC_YN,3,2,1,1,1,1,,,
93 SLIP_DIV_YN,3,2,1,1,1,1,,,
94 SLIP_NO,3,2,1,1,9,1,,,
95 TELR_SLIP_SEQNO,3,2,1,1,10,2,,,
96 TELR_CASH_AMT,3,2,1,1,17,2,,,
97 TELR_CBPC_AMT,3,2,1,1,17,2,,,
98 TELR_TRFAMT,3,2,1,1,17,2,,,
99 LOGIN_DVCD,3,2,1,1,1,1,,,
100 TX_DT_EXTNS_YN ,3,2,1,1,1,1,,,
101 TX_DT,3,2,1,1,8,1,,,
102 TX_TIME,3,2,1,1,8,1,,,
103 SYS_DT,3,2,1,1,8,1,,,
104 SYS_TIME,3,2,1,1,8,1,,,
105 MESG_DMAN_DT,3,2,1,1,8,1,,,
106 MESG_DMAN_TKTM,3,2,1,1,9,1,,,
107 MESG_CNTY_YN,3,2,1,1,1,1,,,
108 MESG_RSPN_DT,3,2,1,1,8,1,,,
109 MESG_RSPN_TKTM,3,2,1,1,9,1,,,
110 PROCS_RSLT_DVCD,3,2,1,1,2,1,,,
111 OUTPUT_MESG_TYCD,3,2,1,1,1,1,,,
112 LRQN_OUTPUT_DSCT_TRGT_YN,3,2,1,1,1,1,,,
113 MESG_CNTY_SEQNO,3,2,1,1,3,1,,,
114 Error_Info,2,3,1,1,0,1,,,
115 ERR_CD,3,2,1,1,6,1,,,
116 ERR_SYS_CD,3,2,1,1,3,1,,,
117 KJB_Add,2,3,1,1,0,1,,,
118 ORTR_SCN_ID,3,2,1,1,13,1,,,
119 CORP_DPRM_NO,3,2,1,1,5,1,,,
120 CSIF_IQRY_RSCD,3,2,1,1,2,1,,,
121 Com_Spare_Zone,2,3,1,1,0,1,,,
122 COM_SPR_CTNT,3,2,1,1,212,1,,,
123 Channel_Common,1,3,0,1,0,1,Std_Header.Common.Channel_Info.CHNL_COM_SCTN_EXIS_YN,Y,
124 Data_Header,2,3,0,1,0,1,,,
125 DATA_HEDR_KNCD,3,2,1,1,2,1,,,
126 DATA_HEDR_LEN,3,2,1,1,8,1,,,
127 Data_For_Each,2,3,0,1,0,1,,,
128 PSWD_ERR_DVCD,3,2,1,1,2,1,,,
129 ELFN_CUST_TYCD,3,2,1,1,2,1,,,
130 USER_ID_S14,3,2,1,1,14,1,,,
131 MST_ID_S14,3,2,1,1,14,1,,,
132 SVR_TX_NO,3,2,1,1,10,1,,,
133 HOST_TX_NO_S10,3,2,1,1,10,1,,,
134 NEXT_PAGE_EXIS_YN1,3,2,1,1,1,1,,,
135 SCCR_ISS_CD,3,2,1,1,2,1,,,
136 SQ1_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
137 SQ2_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
138 SECU_MEDIA_SEQNO_S4,3,2,1,1,4,1,,,
139 SECU_MEDIA_DTL_DVCD_N3,3,2,1,1,3,1,,,
140 PAGE_NO,3,2,1,1,5,1,,,
141 PAGE_SIZE,3,2,1,1,5,1,,,
142 TTCN_N5,3,2,1,1,5,1,,,
143 IQRY_CCNT_N5,3,2,1,1,5,1,,,
144 PRIQR_TX_NO,3,2,1,1,10,1,,,
145 SQ1_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
146 SQ2_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
147 MAC_S17,3,2,1,1,17,1,,,
148 HDD_SEQ_NO_S24,3,2,1,1,24,1,,,
149 CMCM_CD,3,2,1,1,1,1,,,
150 TLNO_S14,3,2,1,1,14,1,,,
151 OTP_EXPR_GDNC_DVCD_S1,3,2,1,1,1,1,,,
152 KFTC_ENCD_MST_KEY_VER_S2,3,2,1,1,2,1,,,
153 KFTC_ENCD_RAND1_S32,3,2,1,1,32,1,,,
154 KFTC_ENCD_RAND2_S32,3,2,1,1,32,1,,,
155 ADDT_ATHN_YN_S1,3,2,1,1,1,1,,,
156 ADDT_ATHN_METH_DVCD_S2,3,2,1,1,2,1,,,
157 ADDT_ATHN_ATHN_VAL_S40,3,2,1,1,40,1,,,
158 DUP_TX_YN_S1,3,2,1,1,1,1,,,
159 ABR_IP_BLC_YN_S1,3,2,1,1,1,1,,,
160 VIRT_ACCO_DVCD_S1,3,2,1,1,1,1,,,
161 BZWK_DVCD1_S1,3,2,1,1,1,1,,,
162 BZWK_DVCD2_S1,3,2,1,1,1,1,,,
163 BZWK_DVCD3_S1,3,2,1,1,1,1,,,
164 BZWK_DVCD4_S1,3,2,1,1,1,1,,,
165 BZWK_DVCD5_S1,3,2,1,1,1,1,,,
166 TX_SER_SEQNO_N3,3,2,1,1,3,1,,,
167 SECU_MEDIA_SEQNO_DMAN_VAL_S4,3,2,1,1,4,1,,,
168 MEDIA_D1_UZ_POSB_AMT_N12,3,2,1,1,12,1,,,
169 CPHR_KEY_SECU_CO_CD_S1,3,2,1,1,1,1,,,
170 HDD_VOLU_ID_S35,3,2,1,1,35,1,,,
171 SPR_FILD_S197,3,2,1,1,197,1,,,
172 Message,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
173 Msg_Header,2,3,0,1,0,1,,,
174 MSG_HEDR_KNCD,3,2,1,1,2,1,,,NM
175 MSG_HEDR_LEN,3,2,1,1,8,2,,,
176 Msg_Body,2,3,0,1,0,1,,,
177 OUTPUT_ATRB_CD,3,2,1,1,1,1,,,0
178 OUTPUT_MSG_CD,3,2,1,1,10,1,,,
179 OUTPUT_MSG_CTNT,3,2,1,1,200,1,,,
180 OUTPUT_MSG_DESC,3,2,1,1,300,1,,,
181 ERR_MNGM_CTNT,3,2,1,1,200,1,,,
182 ERR_CHGR_NM,3,2,1,1,10,1,,,
183 ERR_CHGR_CNPL_NO,3,2,1,1,20,1,,,
184 OUTPUT_MSG_NCNT,3,2,1,1,4,2,,,0000
185 Output_Msg_Grid,3,4,0,1,0,1,Message.Msg_Body.OUTPUT_MSG_NCNT,,
186 OUTPUT_MSG_CD,4,2,0,1,10,1,,,
187 OUTPUT_MSG_CTNT,4,2,0,1,200,1,,,
188 OUTPUT_MSG_DESC,4,2,0,1,300,1,,,
189 ERR_MNGM_CTNT,4,2,0,1,200,1,,,
190 ERR_LOCT_CTNT,4,2,0,1,200,1,,,
191 ERR_OCCU_ITEM_NM,4,2,0,1,20,1,,,
192 Manager_Confirm,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
193 Data_Header,2,3,0,1,0,1,,,
194 DATA_HEDR_KNCD,3,2,1,1,2,1,,,
195 DATA_HEDR_LEN,3,2,1,1,8,2,,,
196 Data_Header_Etc,2,3,0,1,0,1,,,
197 OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
198 OUTPUT_SCN_ID,3,2,1,1,13,1,,,
199 OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
200 DCG_DVCD,3,2,1,1,1,1,,,
201 Data_For_Each,2,3,0,1,0,1,,,
202 ACNO,3,2,1,1,16,1,,,
203 TRMN_CUST_FLNM,3,2,1,1,20,1,,,
204 TX_AMT,3,2,1,1,17,2,,,
205 APRV_RSCD_CCNT,3,2,1,1,5,2,,,
206 APRV_RSCD,3,2,1,1,5,1,,,
207 PRCG_APRV_DESC,3,2,1,1,50,1,,,
208 PRCG_APRV_TYCD,3,2,1,1,1,1,,,
209 PRCG_APRV_LIST_CCNT,3,2,1,1,5,2,,,
210 TX_DVCD,3,2,1,1,2,1,,,
211 PRCG_EMPNO,3,2,1,1,6,1,,,
212 KOR_FLNM,3,2,1,1,40,1,,,
213 BLNG_BRCD,3,2,1,1,4,1,,,
214 BRN_KOR_NM ,3,2,1,1,100,1,,,
215 LOGIN_IPAD,3,2,1,1,30,1,,,
216 JOBCLS_CD,3,2,1,1,2,1,,,
217 LOGIN_STCD,3,2,1,1,2,1,,,
218 ABSC_YN,3,2,1,1,1,1,,,
219 AGNCY_APRV_TLRNO,3,2,1,1,7,1,,,
220 BRMNR_YN,3,2,1,1,1,1,,,
221 AUDT_UNCN_PRCG_YN,3,2,1,1,1,1,,,
222 Data_Part,1,3,0,1,0,1,,,
223 Data_Header,2,3,0,1,0,1,,,
224 DATA_HEDR_KNCD,3,2,1,1,2,1,,,IO
225 DATA_HEDR_LEN,3,2,1,1,8,2,,,
226 Data_Header_Etc,2,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
227 OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
228 OUTPUT_SCN_ID,3,2,1,1,13,1,,,
229 OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
230 DCG_DVCD,3,2,1,1,1,1,,,
231 Data_For_Each,2,3,0,1,0,1,,,
232 BizData,3,9,1,1,0,1,,,
233 END_BIT_CTNT,1,2,1,1,2,11,,,@@
@@ -1,28 +0,0 @@
#-----------------------------------------------------------------------------
# comment start with #
# level; // 0 : root ~ n
# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
# size // 0 : variable, > 0 fixed
# fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
# length;
# dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
#-----------------------------------------------------------------------------
#name ,level,type,size,fieldType,length,dataType,refPath ,refValue,value
ElinkHeader ,0 ,0 ,1 ,0 ,0 ,0 , , ,
Header ,1 ,2 ,1 ,1 ,0 ,0 , , ,
StndCicsTrncd ,2 ,1 ,1 ,1 ,10 ,0 , , ,
StndIntnlStndTelgmLen,2 ,1 ,1 ,1 ,10 ,11 , , ,0
StndTranBaseYmd ,2 ,1 ,1 ,1 ,10 ,0 , , ,
Common ,1 ,2 ,0 ,0 ,0 ,0 ,Header.StndCicsTrncd,JI6H ,
TranInfo ,2 ,2 ,1 ,0 ,0 ,0 , , ,
StndCicsTrncd ,3 ,1 ,1 ,0 ,3 ,0 , , ,
StndTelgmRecvTranCd ,3 ,1 ,1 ,0 ,10 ,0 , , ,
StndPrcssRtdTranCd ,3 ,1 ,1 ,0 ,10 ,0 , , ,
Array ,1 ,3 ,0 ,0 ,3 ,0 , , ,
Item1 ,2 ,1 ,1 ,0 ,10 ,0 , , ,JI6H
Group ,2 ,3 ,1 ,0 ,1 ,0 , , ,
gitem1 ,3 ,1 ,1 ,0 ,10 ,1 , , ,726
gitem2 ,3 ,1 ,1 ,0 ,10 ,0 , , ,20220905
FArray ,1 ,4 ,0 ,0 ,10 ,0 , , ,
bizData ,1 ,9 ,1 ,0 ,0 ,0 , , ,
zzData ,1 ,1 ,1 ,0 ,2 ,10 , , ,ZZ
1 #-----------------------------------------------------------------------------
2 # comment start with #
3 # level; // 0 : root ~ n
4 # type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA
5 # size // 0 : variable, > 0 fixed
6 # fieldType; // 0: ELEMENT, 1: ATTRIBUTE,
7 # length;
8 # dataType; // 0: String, 1: Number,10: ZZ String, 11: LL Number
9 #-----------------------------------------------------------------------------
10 #name ,level,type,size,fieldType,length,dataType,refPath ,refValue,value
11 ElinkHeader ,0 ,0 ,1 ,0 ,0 ,0 , , ,
12 Header ,1 ,2 ,1 ,1 ,0 ,0 , , ,
13 StndCicsTrncd ,2 ,1 ,1 ,1 ,10 ,0 , , ,
14 StndIntnlStndTelgmLen,2 ,1 ,1 ,1 ,10 ,11 , , ,0
15 StndTranBaseYmd ,2 ,1 ,1 ,1 ,10 ,0 , , ,
16 Common ,1 ,2 ,0 ,0 ,0 ,0 ,Header.StndCicsTrncd,JI6H ,
17 TranInfo ,2 ,2 ,1 ,0 ,0 ,0 , , ,
18 StndCicsTrncd ,3 ,1 ,1 ,0 ,3 ,0 , , ,
19 StndTelgmRecvTranCd ,3 ,1 ,1 ,0 ,10 ,0 , , ,
20 StndPrcssRtdTranCd ,3 ,1 ,1 ,0 ,10 ,0 , , ,
21 Array ,1 ,3 ,0 ,0 ,3 ,0 , , ,
22 Item1 ,2 ,1 ,1 ,0 ,10 ,0 , , ,JI6H
23 Group ,2 ,3 ,1 ,0 ,1 ,0 , , ,
24 gitem1 ,3 ,1 ,1 ,0 ,10 ,1 , , ,726
25 gitem2 ,3 ,1 ,1 ,0 ,10 ,0 , , ,20220905
26 FArray ,1 ,4 ,0 ,0 ,10 ,0 , , ,
27 bizData ,1 ,9 ,1 ,0 ,0 ,0 , , ,
28 zzData ,1 ,1 ,1 ,0 ,2 ,10 , , ,ZZ

Some files were not shown because too many files have changed in this diff Show More