Files
eapim-online/docs/API_TRANSACTION_FLOW.md
T

33 KiB

API 거래 플로우 정리

전체 플로우 다이어그램

[Client Request]
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 1. ApiAdapterController (/api/**, /mapi/**)                     │
│    - HTTP 요청 수신, 어댑터 정보 조회                              │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. ApiAdapterService                                            │
│    - 요청 파싱 (GET/POST/PUT/DELETE)                             │
│    - 암/복호화 처리 (AES128, AES256 등)                           │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. HttpAdapterServiceSupport.service()                          │
│    - Pre/Post Filter 실행                                       │
│    - RequestDispatcher 호출                                     │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. RequestDispatcher.handle()                                   │
│    - Processor 인스턴스 생성/획득                                 │
│    - Adapter 상태 관리                                          │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 5. RequestProcessor.hookup()                                    │
│    - EAIMessage 생성 (StandardMessage → EAIMessage)             │
│    - 유량제어, 라우팅 판단                                        │
│    - FlowRouter.process() 호출                                  │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 6. IFRouter.process()                                           │
│    - Outbound 라우팅                                            │
│    - FailOver 처리                                              │
│    - ElinkESBProcessProxy 호출                                  │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 7. RESTProcess (extends DefaultProcess)                         │
│    - flow() 메소드 실행                                          │
│    - 송신 변환, 로그, 응답 처리                                    │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 8. HttpSender.callService()                                     │
│    - ElinkAdapter 획득                                          │
│    - Adapter 호출                                               │
└─────────────────────────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────────────────────────┐
│ 9. HttpClient5AdapterServiceRest.execute()                      │
│    - 실제 HTTP 통신 (Apache HttpClient 5)                        │
│    - OAuth 토큰 관리                                             │
│    - 암/복호화 처리                                               │
└─────────────────────────────────────────────────────────────────┘
       ↓
[Target System]

각 클래스 설명

1. ApiAdapterController

항목 내용
위치 eapim-online/src/main/java/com/eactive/eai/adapter/controller/
역할 REST API 진입점 (Spring Controller)
주요 기능 - /api/**, /mapi/** 엔드포인트 매핑
- TSEAIHS04 테이블에서 어댑터 정보 조회
- HttpDynamicInAdapterManager로 어댑터 찾기
- ApiAdapterService.callApi() 호출

2. ApiAdapterService

항목 내용
위치 eapim-online/src/main/java/com/eactive/eai/adapter/service/
역할 Inbound 서비스 레이어
상속 HttpAdapterServiceSupport
주요 기능 - HTTP Method별 요청 파싱
- Inbound 암/복호화 (AES128, AES256 등)
- 부모 클래스 service() 호출

3. HttpAdapterServiceSupport

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/adapter/http/dynamic/
역할 Inbound 어댑터 추상 클래스
주요 기능 - service() 메소드: 핵심 디스패처
- Pre-Filter / Post-Filter 실행
- StandardMessage 생성
- RequestDispatcher.handle() 호출

4. RequestDispatcher

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/adapter/
역할 요청 분배자
주요 기능 - Processor 인스턴스 생성/획득
- processor.execute() 호출
- AdapterGroup 상태 관리 (동시 처리 수 증감)

5. RequestProcessorSupport / RequestProcessor

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/inbound/processor/
역할 요청 처리 프로세서
관계 RequestProcessor extends RequestProcessorSupport
주요 기능 - execute()hookup() 호출
- StandardMessage → EAIMessage 변환
- 유량제어 (RateLimiter)
- SYNC/ASYNC 분기 처리
- FlowRouter.process() 호출

6. IFRouter

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/common/routing/
역할 FlowControl → Outbound 라우터
주요 기능 - Outbound Process로 라우팅
- Local/Remote 호출 판단
- FailOver 처리
- TAS(시뮬레이터) 거래 처리
- ElinkESBProcessProxy 호출

7. DefaultProcess / RESTProcess

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/outbound/
역할 Outbound 처리 프로세스
관계 RESTProcess extends HTTPProcess extends DefaultProcess
주요 기능 (DefaultProcess) - flow(): 핵심 처리 흐름
- 송신 전/후 처리
- 메시지 변환 (Transform)
- 로그 처리
주요 기능 (RESTProcess) - outboundCtrlCallService(): HttpSender 호출
- REST 특화 처리
- 표준/비표준 메시지 처리

8. HttpSender

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/control/
역할 HTTP 송신 제어
주요 기능 - ElinkAdapterFactory에서 HTTP Adapter 획득
- adapter.callService() 호출
- SocketTimeout, HttpStatusException 처리

9. HttpClient5AdapterServiceRest

항목 내용
위치 elink-online-common/src/main/java/com/eactive/eai/adapter/http/client/impl/
역할 실제 HTTP 클라이언트 구현체
주요 기능 - Apache HttpClient 5 사용
- GET/POST/PUT/DELETE 메소드 처리
- OAuth2 토큰 관리 (발급/갱신)
- Outbound 암/복호화 (AES128, AES256, AES256GCM 등)
- Forward Proxy 지원
- 응답 헤더 릴레이

클래스 관계도

┌─────────────────────────────────────────────────────────────────────────┐
│                           eapim-online (프로젝트)                        │
├─────────────────────────────────────────────────────────────────────────┤
│  ApiAdapterController ──uses──▶ ApiAdapterService                       │
│                                      │                                  │
│                                      │ extends                          │
│                                      ▼                                  │
└──────────────────────────────────────┼──────────────────────────────────┘
                                       │
┌──────────────────────────────────────┼──────────────────────────────────┐
│                        elink-online-common (서브모듈)                    │
├──────────────────────────────────────┼──────────────────────────────────┤
│                                      ▼                                  │
│                      HttpAdapterServiceSupport                          │
│                               │                                         │
│                               │ calls                                   │
│                               ▼                                         │
│                      RequestDispatcher ──creates──▶ RequestProcessor    │
│                                                           │             │
│                                                           │ extends     │
│                                                           ▼             │
│                                               RequestProcessorSupport   │
│                                                           │             │
│                                                           │ calls       │
│                                                           ▼             │
│                      FlowRouter ────────────────▶ IFRouter              │
│                                                      │                  │
│                                                      │ calls            │
│                                                      ▼                  │
│                      RESTProcess ◀──extends── HTTPProcess               │
│                           │                       │                     │
│                           │ extends               │ extends             │
│                           ▼                       ▼                     │
│                      DefaultProcess ◀────────────┘                      │
│                           │                                             │
│                           │ calls                                       │
│                           ▼                                             │
│                      HttpSender                                         │
│                           │                                             │
│                           │ uses                                        │
│                           ▼                                             │
│                      ElinkAdapterFactory                                │
│                           │                                             │
│                           │ creates                                     │
│                           ▼                                             │
│                      HttpClient5AdapterServiceRest                      │
│                           │                                             │
│                           │ uses                                        │
│                           ▼                                             │
│                      Apache HttpClient 5                                │
└─────────────────────────────────────────────────────────────────────────┘

메시지 변환 흐름

[HTTP Request Body]
       ↓
  StandardMessage (표준전문)
       ↓
  EAIMessage (내부 전문)
       ↓
  Transform (변환)
       ↓
  [Target System Request]
       ↓
  [Target System Response]
       ↓
  Transform (역변환)
       ↓
  EAIMessage
       ↓
  StandardMessage
       ↓
  [HTTP Response Body]

주요 처리 패턴

패턴 설명 처리 위치
SS (Sync-Sync) 동기 요청 → 동기 응답 RequestProcessor, RESTProcess
SA (Sync-Async) 동기 요청 → 비동기 응답 (Topic 대기) RESTProcess.getTopicProperty()
AS (Async-Sync) 비동기 요청 → 동기 응답 DefaultProcess.isAsyncSyncPattern()
AA (Async-Async) 비동기 요청 → 비동기 응답 RequestProcessor

비동기(Async) 처리 플로우

비동기 전체 흐름

┌─────────────────────────────────────────────────────────────────────────┐
│ [송신 스레드 - 요청 수신]                                                 │
│                                                                         │
│ RequestProcessor.hookup()                                               │
│   ├─ ROUTING_TYPE = "QUEUE" 판단                                        │
│   │                                                                     │
│   └─ FlowRouter.process()                                               │
│       └─ JMSSender.sendToQueue(eaiMessage, ...)                        │
│           └─ EAIMessage 직렬화 → JMS Queue 전송                         │
│                         │                                               │
│   ← 즉시 응답 반환 (202 Accepted 등)                                    │
└─────────────────────────┼───────────────────────────────────────────────┘
                          │
                    [JMS Queue]
                    (ActiveMQ / WebLogic JMS / WebSphere MQ)
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ [수신 스레드 - QueueConsumer]                                            │
│                                                                         │
│ DefaultQueueConsumer.run()                                              │
│   ├─ consumer.receive() - 메시지 수신 대기                              │
│   │                                                                     │
│   ├─ EAIMessage 역직렬화                                                │
│   │   └─ transactionContext Map 복원                                    │
│   │                                                                     │
│   ├─ ElinkTransactionContext.initialize(...)                           │
│   │                                                                     │
│   └─ ElinkESBProcessProxy.callElinkESBProcess()                        │
│       └─ DefaultProcess / RESTProcess 호출                              │
│           └─ 실제 대외기관 호출                                          │
│                                                                         │
│   (finally) ElinkTransactionContext.clear()                            │
└─────────────────────────────────────────────────────────────────────────┘

Queue 송신 (FlowRouter → JMSSender)

┌─────────────────────────────────────────────────────────────────────────┐
│ FlowRouter.process()                                                    │
│   │                                                                     │
│   ├─ route_type == "QUEUE" 확인                                         │
│   │                                                                     │
│   ├─ RoutingVO에서 asyncRoutingPath(Queue 이름) 조회                    │
│   │                                                                     │
│   ├─ Properties에 추가 정보 설정                                         │
│   │   ├─ EAIBWKCLS  (업무그룹코드)                                       │
│   │   ├─ EAISVCCD   (서비스코드)                                         │
│   │   └─ OSIDINSTCD (대외기관코드)                                       │
│   │                                                                     │
│   └─ JMSSender.sendToQueue(eaiMessage, factory, queue, prop)           │
└─────────────────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ JMSSender.sendToQueue()                                                 │
│   │                                                                     │
│   ├─ ElinkConfig.isUseInternalQueue() 확인                              │
│   │                                                                     │
│   ├─ [내부 Queue] AmqQueueProducer.sendMessage()                        │
│   │   └─ ActiveMQ 내장 브로커 사용 (vm://localhost)                      │
│   │                                                                     │
│   └─ [외부 Queue] sendToJmsQueue()                                      │
│       ├─ JmsServiceLocator에서 QueueConnectionFactory 획득              │
│       ├─ QueueConnection → QueueSession → QueueSender 생성             │
│       ├─ ObjectMessage 생성                                             │
│       │   ├─ msg.setObject(eaiMessage)  ← Serializable                 │
│       │   └─ msg.setStringProperty(...)  ← Properties 복사              │
│       └─ qsender.send(msg)                                              │
└─────────────────────────────────────────────────────────────────────────┘

Queue Consumer 수신 및 처리

┌─────────────────────────────────────────────────────────────────────────┐
│ QueueConsumerService (Spring Bean)                                      │
│   │                                                                     │
│   ├─ afterPropertiesSet() → startConsumer()                            │
│   │                                                                     │
│   ├─ ActiveMQConnectionFactory 생성                                     │
│   │   └─ setTrustAllPackages(true)  ← 역직렬화 허용                     │
│   │                                                                     │
│   ├─ ExecutorService (FixedThreadPool) 생성                             │
│   │                                                                     │
│   └─ DefaultQueueConsumer[maxThread] 생성 및 submit                     │
│       └─ 각 Consumer가 별도 스레드에서 실행                              │
└─────────────────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Consumer.run() [Loop] (DefaultQueueConsumer / FCQueueReceiver)          │
│   │                                                                     │
│   ├─ while(run) {                                                       │
│   │     message = consumer.receive(2000)  ← 2초 타임아웃               │
│   │                                                                     │
│   │     if(message == null) continue;                                   │
│   │                                                                     │
│   │     // ObjectMessage 검증 및 EAIMessage 역직렬화                    │
│   │     omsg = (ObjectMessage) message;                                 │
│   │     eaiMessage = (EAIMessage) omsg.getObject();                    │
│   │                                                                     │
│   │     // RoutingVO에서 Process 경로 조회                              │
│   │     routingVO = RoutingManager.getRoutingVO(flwCntlRtnNm);         │
│   │     serviceURI = routingVO.getSyncRoutingPath();  // BaseFCProcess │
│   │                                                                     │
│   │     // Process 호출 (ElinkESBProcessProxy 내부에서 컨텍스트 관리)   │
│   │     ElinkESBProcessProxy.callElinkESBProcess(serviceURI, ...)      │
│   │ }                                                                   │
└─────────────────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ ElinkESBProcessProxy.callElinkESBProcess()                              │
│   │                                                                     │
│   ├─ [조건 충족: ASYNC && !outbound] → 컨텍스트 초기화                  │
│   │   ElinkTransactionContext.initialize(eaiMessage.getTransactionContext())
│   │                                                                     │
│   ├─ BaseFCProcess.callService()                                       │
│   │   └─ ElinkESBProcessProxy (RESTProcess) ← 조건 미충족, 초기화 안함 │
│   │       └─ RESTProcess 실행                                          │
│   │                                                                     │
│   └─ finally { ElinkTransactionContext.clear() }  ← 조건부 해제        │
└─────────────────────────────────────────────────────────────────────────┘

비동기 관련 클래스

클래스 위치 역할
FlowRouter elink-online-common/.../routing/ ROUTING_TYPE에 따라 CALL/QUEUE/TOPIC 분기
JMSSender elink-online-common/.../util/ JMS Queue/Topic 메시지 송신
AmqQueueProducer elink-online-common/.../activemq/ ActiveMQ 내장 브로커용 Producer

JMS Provider별 Consumer 구현체

Provider Consumer 비고
ActiveMQ flowcontrol/activemq/DefaultQueueConsumer.java 내장 브로커 (vm://localhost)
JEUS flowcontrol/jeus/DefaultQueueConsumer.java JNDI Lookup
WebSphere flowcontrol/websphere/DefaultQueueConsumer.java JNDI Lookup
WebLogic flowcontrol/jms/FCQueueReceiver.java JNDI Lookup (weblogic.jndi.WLInitialContextFactory)

ElinkTransactionContext 초기화/해제는 Consumer가 아닌 ElinkESBProcessProxy에서 조건부로 처리됩니다.

Queue 연결 방식

방식 설정 사용 환경
내장 브로커 vm://localhost 단일 인스턴스, 테스트 환경
TCP 연결 tcp://host:61617 분산 환경, 다중 인스턴스
외부 JMS JNDI Lookup WebLogic, WebSphere MQ 등

환경별 Consumer 설정 (Spring XML)

WebContent/WEB-INF/
├─ applicationContext.xml           ← 메인 설정
│    ├─ import: mq/applicationContext-activemq.xml
│    └─ import: mq/applicationContext-websphere.xml
│
└─ mq/
    ├─ applicationContext-activemq.xml    ← ActiveMQ (현재 활성화)
    │    └─ flowcontrol.activemq.QueueConsumerService
    │       └─ uri: vm://localhost (내장 브로커)
    │
    └─ applicationContext-websphere.xml   ← WebSphere MQ (주석처리 = 비활성화)
         └─ flowcontrol.websphere.QueueConsumerService
            └─ 외부 WebSphere MQ 연결

Note

: WebLogic/JEUS 환경에서 외부 JMS 사용 시 해당 XML 파일 추가 또는 수정 필요. 현재 프로젝트는 ActiveMQ 내장 브로커를 기본으로 사용.

TransactionContext 비동기 전달

[송신 스레드]                              [수신 스레드]
     │                                          │
     ├─ eaiMsg.transactionContext               │
     │   └─ {"SEED_SALT": "abc123", ...}       │
     │                                          │
     ▼                                          │
┌──────────────┐                                │
│ Serialize    │   ──── JMS Queue ────▶         │
│ (EAIMessage) │                                │
└──────────────┘                                │
                                                ▼
                                    ┌──────────────────┐
                                    │ Deserialize      │
                                    │ (EAIMessage)     │
                                    │  └─ context 복원 │
                                    └──────────────────┘
                                                │
                                                ▼
                                    ElinkESBProcessProxy
                                      └─ 조건부 initialize()
                                                │
                                    ElinkTransactionContext
                                      .getSeedSalt() → "abc123"

Note

: EAIMessage.transactionContextSerializable이므로 JMS Queue를 통해 전달되어도 데이터가 유지됩니다. ElinkTransactionContext.initialize()ElinkESBProcessProxy에서 ASYNC 거래 && !outbound 조건일 때만 호출됩니다.


암호화 지원 (HttpClient5AdapterServiceRest)

알고리즘 용도 Key 추출 방식
AES128-TOSS 토스 연동 clientSecret[22:38]
AES128-TOGETHER 투게더 연동 clientSecret[44:60]
AES256 일반 clientSecret[10:42]
AES256-KAKAO 카카오 연동 IV/Key 별도 설정
AES256-NICEON 나이스지키미 연동 Adapter Token 기반
AES256GCM GCM 모드 동적 Key 생성

관련 파일 경로

eapim-online (메인 프로젝트)

  • src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java
  • src/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java

동기 처리

  • src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java
  • src/main/java/com/eactive/eai/adapter/RequestDispatcher.java
  • src/main/java/com/eactive/eai/inbound/processor/RequestProcessorSupport.java
  • src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java
  • src/main/java/com/eactive/eai/common/routing/IFRouter.java
  • src/main/java/com/eactive/eai/outbound/DefaultProcess.java
  • src/main/java/com/eactive/eai/outbound/RESTProcess.java
  • src/main/java/com/eactive/eai/control/HttpSender.java
  • src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java

비동기 처리 (Queue)

  • src/main/java/com/eactive/eai/common/routing/FlowRouter.java - 라우팅 분기 (CALL/QUEUE/TOPIC)
  • src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java - Process 호출 (비동기 컨텍스트 관리)
  • src/main/java/com/eactive/eai/common/util/JMSSender.java - Queue/Topic 송신
  • src/main/java/com/eactive/eai/common/activemq/AmqQueueProducer.java - ActiveMQ Producer
  • src/main/java/com/eactive/eai/flowcontrol/activemq/QueueConsumerService.java - ActiveMQ Consumer 서비스
  • src/main/java/com/eactive/eai/flowcontrol/activemq/DefaultQueueConsumer.java - ActiveMQ Consumer
  • src/main/java/com/eactive/eai/flowcontrol/jeus/QueueConsumerService.java - JEUS Consumer 서비스
  • src/main/java/com/eactive/eai/flowcontrol/jeus/DefaultQueueConsumer.java - JEUS Consumer
  • src/main/java/com/eactive/eai/flowcontrol/websphere/QueueConsumerService.java - WebSphere Consumer 서비스
  • src/main/java/com/eactive/eai/flowcontrol/websphere/DefaultQueueConsumer.java - WebSphere Consumer
  • src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiver.java - WebLogic JMS Consumer