33 KiB
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.transactionContext는Serializable이므로 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.javasrc/main/java/com/eactive/eai/adapter/service/ApiAdapterService.java
elink-online-common (서브모듈)
동기 처리
src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.javasrc/main/java/com/eactive/eai/adapter/RequestDispatcher.javasrc/main/java/com/eactive/eai/inbound/processor/RequestProcessorSupport.javasrc/main/java/com/eactive/eai/inbound/processor/RequestProcessor.javasrc/main/java/com/eactive/eai/common/routing/IFRouter.javasrc/main/java/com/eactive/eai/outbound/DefaultProcess.javasrc/main/java/com/eactive/eai/outbound/RESTProcess.javasrc/main/java/com/eactive/eai/control/HttpSender.javasrc/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 Producersrc/main/java/com/eactive/eai/flowcontrol/activemq/QueueConsumerService.java- ActiveMQ Consumer 서비스src/main/java/com/eactive/eai/flowcontrol/activemq/DefaultQueueConsumer.java- ActiveMQ Consumersrc/main/java/com/eactive/eai/flowcontrol/jeus/QueueConsumerService.java- JEUS Consumer 서비스src/main/java/com/eactive/eai/flowcontrol/jeus/DefaultQueueConsumer.java- JEUS Consumersrc/main/java/com/eactive/eai/flowcontrol/websphere/QueueConsumerService.java- WebSphere Consumer 서비스src/main/java/com/eactive/eai/flowcontrol/websphere/DefaultQueueConsumer.java- WebSphere Consumersrc/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiver.java- WebLogic JMS Consumer